/****************************************************************************
**
** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of the Qt Mobility Components.
**
** $QT_BEGIN_LICENSE:LGPL$
** No Commercial Usage
** This file contains pre-release code and may not be distributed.
** You may use this file in accordance with the terms and conditions
** contained in the Technology Preview License Agreement accompanying
** this package.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
**
**
**
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include "qmessagestore_symbian_p.h"
#include "qmtmengine_symbian_p.h"
#include "qmessage_symbian_p.h"
#include "qmessagesortorder_p.h"
#include "qmessageaccount.h"
#include "qmessageaccount_p.h"
#include "qmessageaccountfilter.h"
#include "qmessageaccountfilter_p.h"
#include "qmessageaccountsortorder_p.h"
#include "qmessagefoldersortorder_p.h"
#include "qmessagesortorder_p.h"
#include "qmessagefolder.h"
#include "qmessagefolder_p.h"
#include "qmessagefolderfilter.h"
#include "qmessagefolderfilter_p.h"
#include "qmessageservice_symbian_p.h"
#include "qmessagecontentcontainer_symbian_p.h"
#include "qmessagecontentcontainer_p.h"
#include <msvstd.h>
#include <msvids.h> // TMsvId's
#include <mtclreg.h> // CClientMtmRegistry
#include <smsclnt.h> // CSmsClientMtm
#include <mmsclient.h> // CMmsClientMtm
#include <smtcmtm.h> // CSmtpClientMtm
#include <impcmtm.h> // CImap4ClientMtm
#include <popcmtm.h> // CPop3ClientMtm
#include <cemailaccounts.h> //CEmailAccounts
#include <msvfind.h> // CMsvFindOperation
#include <mtmdef.h> // TMsvPartList
#include <utf.h> // CnvUtfConverter
#include <mmsvattachmentmanager.h>
#include <cmsvmimeheaders.h> // Attachemt mimeheader
#include <eikenv.h>
#include <smut.h>
#include <smuthdr.h>
#include <mtuireg.h> // CMtmUiRegistry
#include <mtmuibas.h> // CBaseMtmUi
#include <SendUiConsts.h>
#include <sendui.h> // SendUi API
#include <CMessageData.h> //CMessageData
#include <apgcli.h>
#include <rsendas.h>
#include <rsendasmessage.h>
#include <cmsvrecipientlist.h>
#include <imapset.h>
#include <miutmsg.h>
#include <charconv.h>
#include <imcvtext.h> // KImcvMultipart declaration
#include <QTextCodec>
QTM_BEGIN_NAMESPACE
const TInt KWaitAfterReceivedMessage = 100000; // = 0.1 seconds
#define KDocumentsEntryIdValue 0x1008
Q_GLOBAL_STATIC(CMTMEngine,mtmEngine);
CMTMEngine::CMTMEngine()
: CActive(EPriorityStandard)
{
iFsSession.Connect();
CActiveScheduler::Add(this);
iTimer.CreateLocal();
TRAPD(err,
ipMsvSession = CMsvSession::OpenSyncL(*this);
iSessionReady = ETrue;
ipClientMtmReg = CClientMtmRegistry::NewL(*ipMsvSession);
ipSmsMtm = static_cast<CSmsClientMtm*>(ipClientMtmReg->NewMtmL(KUidMsgTypeSMS));
ipMmsMtm = static_cast<CMmsClientMtm*>(ipClientMtmReg->NewMtmL(KUidMsgTypeMultimedia));
ipSmtpMtm = static_cast<CSmtpClientMtm*>(ipClientMtmReg->NewMtmL(KUidMsgTypeSMTP));
ipImap4Mtm = static_cast<CImap4ClientMtm*>(ipClientMtmReg->NewMtmL(KUidMsgTypeIMAP4));
ipPop3Mtm = static_cast<CPop3ClientMtm*>(ipClientMtmReg->NewMtmL(KUidMsgTypePOP3));
);
Q_UNUSED(err)
// Create & Add SMS Account
TRAPD(accountError,
iSMSAccountidAsString = QString::number(mtmServiceEntryIdL(CMTMEngine::MTMTypeSMS));
QMessageAccount smsAcc = QMessageAccountPrivate::from(QMessageAccountId(iSMSAccountidAsString),
QString("SMS"),
mtmServiceEntryIdL(CMTMEngine::MTMTypeSMS),
0,
QMessage::Sms);
iAccounts.insert(iSMSAccountidAsString, smsAcc);
// Create & Add MMS Account
iMMSAccountidAsString = QString::number(mtmServiceEntryIdL(CMTMEngine::MTMTypeMMS));
QMessageAccount mmsAcc = QMessageAccountPrivate::from(QMessageAccountId(iMMSAccountidAsString),
QString("MMS"),
mtmServiceEntryIdL(CMTMEngine::MTMTypeMMS),
0,
QMessage::Mms | QMessage::Email);
iAccounts.insert(iMMSAccountidAsString, mmsAcc);
updateEmailAccountsL();
);
Q_UNUSED(accountError)
TRAPD(err2,
TBuf<KMaxPath> privatePath;
FsSession().CreatePrivatePath(EDriveC);
FsSession().PrivatePath(privatePath);
iPath.Append(_L("c:"));
iPath.Append(privatePath);
iPath.Append(_L("tempattachments\\"));
CFileMan* pFileMan = CFileMan::NewL(FsSession());
CleanupStack::PushL(pFileMan);
pFileMan->RmDir(iPath);
FsSession().MkDirAll(iPath);
CleanupStack::PopAndDestroy(pFileMan);
);
Q_UNUSED(err2)
}
CMTMEngine::~CMTMEngine()
{
iCmsvEntryPoolFree.ResetAndDestroy();
iCmsvEntryPoolInUse.ResetAndDestroy();
delete ipPop3Mtm;
delete ipImap4Mtm;
delete ipSmtpMtm;
delete ipMmsMtm;
delete ipSmsMtm;
delete ipClientMtmReg;
delete ipMsvSession;
TRAPD(error,
TBuf<KMaxPath> privatePath;
FsSession().CreatePrivatePath(EDriveC);
FsSession().PrivatePath(privatePath);
TBuf<KMaxPath> path;
path.Append(_L("c:"));
path.Append(privatePath);
path.Append(_L("tempattachments\\"));
CFileMan* pFileMan=CFileMan::NewL(FsSession());
CleanupStack::PushL(pFileMan);
pFileMan->RmDir(path);
CleanupStack::PopAndDestroy(pFileMan);
);
Q_UNUSED(error)
Cancel();
iTimer.Close();
iFsSession.Close();
}
CMTMEngine* CMTMEngine::instance()
{
return mtmEngine();
}
bool CMTMEngine::accountLessThan(const QMessageAccountId accountId1, const QMessageAccountId accountId2)
{
CMTMEngine* pMTMEngine = mtmEngine();
return QMessageAccountSortOrderPrivate::lessThan(pMTMEngine->iCurrentAccountOrdering,
pMTMEngine->account(accountId1),
pMTMEngine->account(accountId2));
}
void CMTMEngine::orderAccounts(QMessageAccountIdList& accountIds, const QMessageAccountSortOrder &sortOrder) const
{
iCurrentAccountOrdering = sortOrder;
qSort(accountIds.begin(), accountIds.end(), CMTMEngine::accountLessThan);
}
bool CMTMEngine::folderLessThan(const QMessageFolderId folderId1, const QMessageFolderId folderId2)
{
CMTMEngine* pMTMEngine = mtmEngine();
return QMessageFolderSortOrderPrivate::lessThan(pMTMEngine->iCurrentFolderOrdering,
pMTMEngine->folder(folderId1),
pMTMEngine->folder(folderId2));
}
void CMTMEngine::orderFolders(QMessageFolderIdList& folderIds, const QMessageFolderSortOrder &sortOrder) const
{
iCurrentFolderOrdering = sortOrder;
qSort(folderIds.begin(), folderIds.end(), CMTMEngine::folderLessThan);
}
bool CMTMEngine::messageLessThan(const QMessage& message1, const QMessage& message2)
{
CMTMEngine* pMTMEngine = mtmEngine();
return QMessageSortOrderPrivate::lessThan(pMTMEngine->iCurrentMessageOrdering, message1, message2);
}
void CMTMEngine::orderMessages(QMessageIdList& messageIds, const QMessageSortOrder &sortOrder) const
{
iCurrentMessageOrdering = sortOrder;
QList<QMessage> messages;
for (int i=0; i < messageIds.count(); i++) {
messages.append(message(messageIds[i]));
}
qSort(messages.begin(), messages.end(), CMTMEngine::messageLessThan);
messageIds.clear();
for (int i=0; i < messages.count(); i++) {
messageIds.append(messages[i].id());
}
}
QMessageAccountIdList CMTMEngine::queryAccounts(const QMessageAccountFilter &filter, const QMessageAccountSortOrder &sortOrder, uint limit, uint offset) const
{
QMessageAccountIdList accountIds;
TRAPD(err, updateEmailAccountsL());
Q_UNUSED(err)
QMessageAccountFilterPrivate* privateMessageAccountFilter = QMessageAccountFilterPrivate::implementation(filter);
if (filter.isEmpty()) {
if (!privateMessageAccountFilter->_notFilter) {
// All accounts are returned for empty filter
foreach (QMessageAccount value, iAccounts) {
accountIds.append(value.id());
}
}
} else {
if (privateMessageAccountFilter->_valid) {
foreach (QMessageAccount value, iAccounts) {
if (privateMessageAccountFilter->filter(value)) {
accountIds.append(value.id());
}
}
} else {
foreach (QMessageAccount value, iAccounts) {
if (privateMessageAccountFilter->filter(value)) {
accountIds.append(value.id());
}
}
}
}
if (!sortOrder.isEmpty()) {
orderAccounts(accountIds, sortOrder);
}
applyOffsetAndLimitToAccountIds(accountIds, offset, limit);
return accountIds;
}
void CMTMEngine::applyOffsetAndLimitToAccountIds(QMessageAccountIdList& idList, int offset, int limit) const
{
if (offset > 0) {
if (offset > idList.count()) {
idList.clear();
} else {
for (int i = 0; i < offset; i++) {
idList.removeFirst();
}
}
}
if (limit > 0) {
for (int i = idList.count()-1; i >= limit; i--) {
idList.removeAt(i);
}
}
}
int CMTMEngine::countAccounts(const QMessageAccountFilter &filter) const
{
return queryAccounts(filter, QMessageAccountSortOrder(), 0, 0).count();
}
QMessageAccount CMTMEngine::account(const QMessageAccountId &id) const
{
TRAPD(err, updateEmailAccountsL());
Q_UNUSED(err)
return iAccounts[id.toString()];
}
QMessageAccountId CMTMEngine::accountIdByServiceId(TMsvId serviceId) const
{
TRAPD(err, updateEmailAccountsL());
Q_UNUSED(err)
foreach (QMessageAccount value, iAccounts) {
if (value.d_ptr->_service1EntryId == serviceId ||
value.d_ptr->_service2EntryId == serviceId) {
return value.id();
}
}
return QMessageAccountId();
}
QMessageAccountId CMTMEngine::defaultAccount(QMessage::Type type) const
{
TRAPD(err, updateEmailAccountsL());
Q_UNUSED(err)
if (type == QMessage::Email) {
// Email
return idefaultEmailAccountId;
} else {
// Sms & Mms
foreach (QMessageAccount value, iAccounts) {
if ((value.messageTypes() & type) == (int)type) {
return value.id();
}
}
}
return QMessageAccountId();
}
QMessageAccountIdList CMTMEngine::accountsByType(QMessage::Type type) const
{
QMessageAccountIdList accountIds;
foreach (QMessageAccount value, iAccounts) {
if ((value.messageTypes() & type) == (int)type) {
accountIds.append(value.id());
}
}
return accountIds;
}
void CMTMEngine::updateEmailAccountsL() const
{
QStringList keys = iAccounts.keys();
keys.removeOne(iSMSAccountidAsString);
keys.removeOne(iMMSAccountidAsString);
CEmailAccounts* pEmailAccounts = CEmailAccounts::NewLC();
// Default Email account will be the first Email account in the iAccounts list
TSmtpAccount defaultAccount;
TInt err = pEmailAccounts->DefaultSmtpAccountL(defaultAccount);
if (err == KErrNone) {
QString idAsString;
if (defaultAccount.iRelatedService != 0) {
idAsString = QString::number(defaultAccount.iRelatedService);
} else {
idAsString = QString::number(defaultAccount.iSmtpService);
}
if (!iAccounts.contains(idAsString)) {
QMessageAccount account = QMessageAccountPrivate::from(QMessageAccountId(idAsString),
QString::fromUtf16(defaultAccount.iSmtpAccountName.Ptr(), defaultAccount.iSmtpAccountName.Length()),
defaultAccount.iRelatedService,
defaultAccount.iSmtpService,
QMessage::Email);
iAccounts.insert(idAsString, account);
idefaultEmailAccountId = account.id();
} else {
keys.removeOne(idAsString);
}
} else {
idefaultEmailAccountId = QMessageAccountId();
}
RArray<TImapAccount> imapAccounts(10);
pEmailAccounts->GetImapAccountsL(imapAccounts);
CleanupClosePushL(imapAccounts);
for (int i=0; i < imapAccounts.Count(); i++) {
QString idAsString = QString::number(imapAccounts[i].iImapService);
if (!iAccounts.contains(idAsString)) {
QMessageAccount account = QMessageAccountPrivate::from(QMessageAccountId(idAsString),
QString::fromUtf16(imapAccounts[i].iImapAccountName.Ptr(), imapAccounts[i].iImapAccountName.Length()),
imapAccounts[i].iImapService,
imapAccounts[i].iSmtpService,
QMessage::Email);
iAccounts.insert(idAsString, account);
} else {
keys.removeOne(idAsString);
}
}
CleanupStack::PopAndDestroy(&imapAccounts);
RArray<TPopAccount> popAccounts(10);
pEmailAccounts->GetPopAccountsL(popAccounts);
CleanupClosePushL(popAccounts);
for (int i=0; i < popAccounts.Count(); i++) {
QString idAsString = QString::number(popAccounts[i].iPopService);
if (!iAccounts.contains(idAsString)) {
QMessageAccount account = QMessageAccountPrivate::from(QMessageAccountId(QString::number(popAccounts[i].iPopService)),
QString::fromUtf16(popAccounts[i].iPopAccountName.Ptr(), popAccounts[i].iPopAccountName.Length()),
popAccounts[i].iPopService,
popAccounts[i].iSmtpService,
QMessage::Email);
iAccounts.insert(idAsString, account);
} else {
keys.removeOne(idAsString);
}
}
CleanupStack::PopAndDestroy(&popAccounts);
RArray<TSmtpAccount> smtpAccounts(10);
pEmailAccounts->GetSmtpAccountsL(smtpAccounts);
CleanupClosePushL(smtpAccounts);
for (int i=0; i < smtpAccounts.Count(); i++) {
if (smtpAccounts[i].iRelatedService == 0) {
QString idAsString = QString::number(smtpAccounts[i].iSmtpService);
if (!iAccounts.contains(idAsString)) {
QMessageAccount account = QMessageAccountPrivate::from(QMessageAccountId(QString::number(smtpAccounts[i].iSmtpService)),
QString::fromUtf16(smtpAccounts[i].iSmtpAccountName.Ptr(), smtpAccounts[i].iSmtpAccountName.Length()),
smtpAccounts[i].iRelatedService,
smtpAccounts[i].iSmtpService,
QMessage::Email);
iAccounts.insert(idAsString, account);
} else {
keys.removeOne(idAsString);
}
}
}
CleanupStack::PopAndDestroy(&smtpAccounts);
for (int i=0; i < keys.count(); i++) {
iAccounts.remove(keys[i]);
}
CleanupStack::PopAndDestroy(pEmailAccounts);
}
TUid CMTMEngine::mtmUidByType(MTMType aMTMType)
{
switch(aMTMType) {
case CMTMEngine::MTMTypeSMS: return KUidMsgTypeSMS;
case CMTMEngine::MTMTypeMMS: return KUidMsgTypeMultimedia;
case CMTMEngine::MTMTypeSMTP: return KUidMsgTypeSMTP;
case CMTMEngine::MTMTypeIMAP: return KUidMsgTypeIMAP4;
case CMTMEngine::MTMTypePOP3: return KUidMsgTypePOP3;
}
return TUid();
}
CBaseMtm* CMTMEngine::mtmByUid(TUid aMTMUid)
{
if (aMTMUid == KUidMsgTypeSMS) {
return ipSmsMtm;
} else if (aMTMUid == KUidMsgTypeMultimedia) {
return ipMmsMtm;
} else if (aMTMUid == KUidMsgTypeSMTP) {
return ipSmtpMtm;
} else if (aMTMUid == KUidMsgTypeIMAP4) {
return ipImap4Mtm;
} else if (aMTMUid == KUidMsgTypePOP3) {
return ipPop3Mtm;
}
return 0;
}
TMsvId CMTMEngine::mtmServiceEntryIdL(MTMType aMTMType) const
{
TUid mtmUID;
switch(aMTMType) {
case CMTMEngine::MTMTypeSMS:
mtmUID = KUidMsgTypeSMS;
break;
case CMTMEngine::MTMTypeMMS:
mtmUID = KUidMsgTypeMultimedia;
break;
case CMTMEngine::MTMTypeSMTP:
mtmUID = KUidMsgTypeSMTP;
break;
case CMTMEngine::MTMTypeIMAP:
mtmUID = KUidMsgTypeIMAP4;
break;
case CMTMEngine::MTMTypePOP3:
mtmUID = KUidMsgTypePOP3;
break;
}
CMsvEntry* pCurrentEntry = ipMsvSession->GetEntryL(KMsvRootIndexEntryId);
CleanupStack::PushL(pCurrentEntry);
// Sorting or grouping is not needed
pCurrentEntry->SetSortTypeL(TMsvSelectionOrdering(KMsvNoGrouping,EMsvSortByNone, ETrue));
// Loop through child entries until MTM specific
// root entry has been found
TMsvId mtmRootEntryId = KMsvRootIndexEntryId;
TInt count = pCurrentEntry->Count();
for(TInt i = 0; i<count; i++) {
const TMsvEntry& child = (*pCurrentEntry)[i];
if (child.iMtm == mtmUID) {
mtmRootEntryId = child.Id();
break;
}
}
CleanupStack::PopAndDestroy(pCurrentEntry);
if (mtmRootEntryId == KMsvRootIndexEntryId) {
// MTM specific root entry was not found
return 0;
}
TMsvEntry indexEntry;
TMsvId mtmServiceEntryId;
TInt error = ipMsvSession->GetEntry(mtmRootEntryId, mtmServiceEntryId, indexEntry);
if (error != KErrNone) {
// MTM specific service entry Id was not found
return 0;
}
return mtmServiceEntryId;
}
bool CMTMEngine::switchToMTMRootEntry(MTMType aMTMType)
{
TRAPD(err,
CBaseMtm* pMTM = mtmByType(aMTMType);
TMsvId mtmEntryId = mtmServiceEntryIdL(aMTMType);
CMsvEntry* pMTMServiceEntry = ipMsvSession->GetEntryL(mtmEntryId);
CleanupStack::PushL(pMTMServiceEntry);
// Set service entry as current entry of ClientMTM class
pMTM->SetCurrentEntryL(pMTMServiceEntry); // Takes ownership of pMTMServiceEntry
CleanupStack::Pop(pMTMServiceEntry);
);
if (err != KErrNone)
return false;
else
return true;
}
CBaseMtm* CMTMEngine::mtmByType(MTMType aMTMType)
{
switch(aMTMType) {
case CMTMEngine::MTMTypeSMS: return ipSmsMtm;
case CMTMEngine::MTMTypeMMS: return ipMmsMtm;
case CMTMEngine::MTMTypeSMTP: return ipSmtpMtm;
case CMTMEngine::MTMTypeIMAP: return ipImap4Mtm;
case CMTMEngine::MTMTypePOP3: return ipPop3Mtm;
}
return 0;
}
TMsvId CMTMEngine::standardFolderId(QMessage::StandardFolder standardFolder)
{
switch(standardFolder) {
case QMessage::InboxFolder: return KMsvGlobalInBoxIndexEntryIdValue;
case QMessage::OutboxFolder: return KMsvGlobalOutBoxIndexEntryIdValue;
case QMessage::DraftsFolder: return KMsvDraftEntryIdValue;
case QMessage::SentFolder: return KMsvSentEntryIdValue;
case QMessage::TrashFolder: return KMsvDeletedEntryFolderEntryIdValue;
}
return TMsvId();
}
bool CMTMEngine::addMessage(QMessage* message)
{
bool retVal = false;
if (message->type() == QMessage::NoType) {
if (message->parentAccountId().isValid()){
QMessageAccount account = QMessageAccount(message->parentAccountId());
QMessage::TypeFlags types = account.messageTypes();
if (types & QMessage::Sms) {
message->setType(QMessage::Sms);
} else if (types & QMessage::Mms) {
message->setType(QMessage::Mms);
} else if (types & QMessage::Email) {
message->setType(QMessage::Email);
}
} else {
return false;
}
}
if (!message->parentAccountId().isValid() && message->type() != QMessage::NoType) {
message->setParentAccountId(QMessageAccount::defaultAccount(message->type()));
}
if (message->type() == QMessage::Sms){
retVal = storeSMS(*message);
}
else if (message->type() == QMessage::Mms){
retVal = storeMMS(*message);
}
else if (message->type() == QMessage::Email){
retVal = storeEmail(*message);
}
return retVal;
}
bool CMTMEngine::updateMessage(QMessage* m)
{
bool retVal = true;
if (m->parentAccountId().isValid()){
QMessageAccount account = QMessageAccount(m->parentAccountId());
QMessage::TypeFlags types = account.messageTypes();
if (types & QMessage::Sms){
m->setType(QMessage::Sms);
} else if (types & QMessage::Mms){
m->setType(QMessage::Mms);
} else if (types & QMessage::Email){
m->setType(QMessage::Email);
}
}
if (m->type() == QMessage::Sms){
TRAPD(err, updateSMSL(*m));
if (err != KErrNone)
retVal = false;
} else if (m->type() == QMessage::Mms){
TRAPD(err, updateMMSL(*m));
if (err != KErrNone)
retVal = false;
} else if (m->type() == QMessage::Email){
TRAPD(err, updateEmailL(*m));
if (err != KErrNone)
retVal = false;
}
return retVal;
}
// Copy message to another folder.
void CMTMEngine::copyMessageL(TMsvId aMessageId, TMsvId aFolder)
{
ipSmsMtm->SwitchCurrentEntryL(aMessageId);
TMsvSelectionOrdering selection;
selection.SetShowInvisibleEntries(ETrue);
CMsvEntry* pParentEntry = CMsvEntry::NewL(ipSmsMtm->Session(),
ipSmsMtm->Entry().Entry().Parent(),
selection);
CleanupStack::PushL(pParentEntry);
// iSmsMtm points to the parent
pParentEntry->CopyL(aMessageId, aFolder);
CleanupStack::PopAndDestroy(); // parentEntry
}
bool CMTMEngine::removeMessage(const QMessageId &id, QMessageManager::RemovalOption option)
{
if (!iSessionReady)
return false;
bool retVal = false;
TRAPD(err, retVal = removeMessageL(id, option));
if (err != KErrNone)
retVal = false;
return retVal;
}
bool CMTMEngine::showMessage(const QMessageId &id)
{
if (!iSessionReady)
return false;
TRAPD(err, showMessageL(id));
if (err != KErrNone)
return false;
else
return true;
}
void CMTMEngine::showMessageL(const QMessageId &id)
{
long int messageId = id.toString().toLong();
CMsvEntry* pEntry = ipMsvSession->GetEntryL(messageId);
CleanupStack::PushL(pEntry);
CBaseMtm* mtm = ipClientMtmReg->NewMtmL(pEntry->Entry().iMtm);
CleanupStack::PushL(mtm);
CMtmUiRegistry* mtmUiRegistry = CMtmUiRegistry::NewL(*ipMsvSession);
CleanupStack::PushL(mtmUiRegistry);
CBaseMtmUi* ui = mtmUiRegistry->NewMtmUiL(*mtm);
CleanupStack::PushL(ui);
ui->BaseMtm().SwitchCurrentEntryL(messageId);
CMsvOperationWait* waiter = CMsvOperationWait::NewLC();
waiter->Start();
CMsvOperation* op = ui->OpenL(waiter->iStatus);
CleanupStack::PushL(op);
CActiveScheduler::Start();
CleanupStack::PopAndDestroy(6); // op,waiter,ui,mtmuiregistry,mtm,pEntry
}
bool CMTMEngine::composeMessage(const QMessage &message)
{
bool retVal = true;
if (message.parentAccountId().isValid()){
QMessageAccount account = QMessageAccount(message.parentAccountId());
QMessage::TypeFlags types = account.messageTypes();
if (types & QMessage::Sms){
TRAPD(err, retVal = composeSMSL(message));
if (err != KErrNone)
retVal = false;
} else if (types & QMessage::Mms){
TRAPD(err, retVal = composeMMSL(message));
if (err != KErrNone)
retVal = false;
} else if (types & QMessage::Email){
TRAPD(err, retVal = composeEmailL(message));
if (err != KErrNone)
retVal = false;
}
} else {
if (message.type() == QMessage::Sms){
TRAPD(err, retVal = composeSMSL(message));
if (err != KErrNone)
retVal = false;
}
else if (message.type() == QMessage::Mms){
TRAPD(err, retVal = composeMMSL(message));
if (err != KErrNone)
retVal = false;
}
else if (message.type() == QMessage::Email){
TRAPD(err, retVal = composeEmailL(message));
if (err != KErrNone)
retVal = false;
}
}
return retVal;
}
bool CMTMEngine::composeSMSL(const QMessage &message)
{
CSendUi *sendUi = CSendUi::NewL();
CleanupStack::PushL(sendUi);
CMessageData* messageData = CMessageData::NewLC();
// Add receivers
QList<QMessageAddress> list(message.to());
TPtrC16 receiver(KNullDesC);
QString qreceiver;
for (int i = 0; i < list.size(); ++i) {
qreceiver = list.at(i).addressee();
receiver.Set(reinterpret_cast<const TUint16*>(qreceiver.utf16()));
messageData->AppendToAddressL(receiver, KNullDesC);
}
// Set Body text
QString body = message.textContent();
TPtrC16 msg(reinterpret_cast<const TUint16*>(body.utf16()));
HBufC* bd = msg.AllocLC();
TPtr ptr(bd->Des());
ipParaFormatLayer = CParaFormatLayer::NewL();
ipCharFormatLayer = CCharFormatLayer::NewL();
ipRichText = CRichText::NewL(ipParaFormatLayer,ipCharFormatLayer);
TInt pos = 0; // Insertion position of text will be zero
ipRichText->Reset();
ipRichText->InsertL(pos, ptr);
messageData->SetBodyTextL(ipRichText);
sendUi->CreateAndSendMessageL(KSenduiMtmSmsUid, messageData, KNullUid, ETrue);
CleanupStack::PopAndDestroy(3); //bd, messageData and sendUi
return true;
}
bool CMTMEngine::composeMMSL(const QMessage &message)
{
CSendUi *sendUi = CSendUi::NewL();
CleanupStack::PushL(sendUi);
TUid bioTypeUid = KNullUid;
CMessageData* messageData = CMessageData::NewLC();
// Add receivers
QList<QMessageAddress> list(message.to());
TPtrC16 receiver(KNullDesC);
QString qreceiver;
for (int i = 0; i < list.size(); ++i) {
qreceiver = list.at(i).addressee();
receiver.Set(reinterpret_cast<const TUint16*>(qreceiver.utf16()));
messageData->AppendToAddressL(receiver, KNullDesC);
}
// Set Subject
QString subject = message.subject();
TPtrC16 sbj(reinterpret_cast<const TUint16*>(subject.utf16()));
messageData->SetSubjectL(&sbj);
QByteArray filePath;
QMessageContentContainerIdList contentIds = message.contentIds();
foreach (QMessageContentContainerId id, contentIds){
QMessageContentContainer container = message.find(id);
QByteArray filePath = QMessageContentContainerPrivate::attachmentFilename(container);
QString fileName = QString(filePath);
QString body = container.textContent();
if (!fileName.isEmpty()){ // content is attachment
filePath.replace(QByteArray("/"), QByteArray("\\"));
QString temp_path = QString(filePath);
TPtrC16 attachmentPath(KNullDesC);
attachmentPath.Set(reinterpret_cast<const TUint16*>(temp_path.utf16()));
messageData->AppendAttachmentL(attachmentPath);
}
else if (!body.isEmpty()) { // content is Body text
TPtrC16 msg(reinterpret_cast<const TUint16*>(body.utf16()));
HBufC* bd = msg.AllocLC();
TPtr ptr(bd->Des());
ipParaFormatLayer = CParaFormatLayer::NewL();
ipCharFormatLayer = CCharFormatLayer::NewL();
ipRichText = CRichText::NewL(ipParaFormatLayer, ipCharFormatLayer);
TInt pos = 0; // Insertion position of text will be zero
ipRichText->Reset();
ipRichText->InsertL(pos, ptr);
messageData->SetBodyTextL(ipRichText);
CleanupStack::PopAndDestroy(bd);
}
}
QString messageBody = message.textContent();
if (!messageBody.isEmpty()) { // no contents, only body text
TPtrC16 msg(reinterpret_cast<const TUint16*>(messageBody.utf16()));
HBufC* bd = msg.AllocLC();
TPtr ptr(bd->Des());
ipParaFormatLayer = CParaFormatLayer::NewL();
ipCharFormatLayer = CCharFormatLayer::NewL();
ipRichText = CRichText::NewL(ipParaFormatLayer, ipCharFormatLayer);
TInt pos = 0; // Insertion position of text will be zero
ipRichText->Reset();
ipRichText->InsertL(pos, ptr);
messageData->SetBodyTextL(ipRichText);
CleanupStack::PopAndDestroy(bd);
}
sendUi->CreateAndSendMessageL(KSenduiMtmMmsUid, messageData, KNullUid, ETrue);
CleanupStack::PopAndDestroy(2); //messageData and sendUi
return true;
}
bool CMTMEngine::composeEmailL(const QMessage &message)
{
CSendUi *sendUi = CSendUi::NewL();
CleanupStack::PushL(sendUi);
CMessageData* messageData = CMessageData::NewLC();
// Add receivers
QList<QMessageAddress> list(message.to());
TPtrC16 receiver(KNullDesC);
QString qreceiver;
for (int i = 0; i < list.size(); ++i) {
qreceiver = list.at(i).addressee();
receiver.Set(reinterpret_cast<const TUint16*>(qreceiver.utf16()));
messageData->AppendToAddressL(receiver, KNullDesC);
}
//cc
QList<QMessageAddress> ccList(message.cc());
TPtrC16 ccReceiver(KNullDesC);
QString ccQreceiver;
for (int i = 0; i < ccList.size(); ++i) {
ccQreceiver = ccList.at(i).addressee();
ccReceiver.Set(reinterpret_cast<const TUint16*>(ccQreceiver.utf16()));
messageData->AppendCcAddressL(ccReceiver, KNullDesC);
}
//bcc
QList<QMessageAddress> bccList(message.bcc());
TPtrC16 bccReceiver(KNullDesC);
QString bccQreceiver;
for (int i = 0; i < bccList.size(); ++i) {
bccQreceiver = bccList.at(i).addressee();
bccReceiver.Set(reinterpret_cast<const TUint16*>(bccQreceiver.utf16()));
messageData->AppendBccAddressL(bccReceiver, KNullDesC);
}
// Set Subject
QString subject = message.subject();
TPtrC16 sbj(reinterpret_cast<const TUint16*>(subject.utf16()));
messageData->SetSubjectL(&sbj);
QByteArray filePath;
QMessageContentContainerIdList contentIds = message.contentIds();
foreach (QMessageContentContainerId id, contentIds){
QMessageContentContainer container = message.find(id);
QByteArray filePath = QMessageContentContainerPrivate::attachmentFilename(container);
QString body = container.textContent();
QString fileName = QString(filePath);
if (!fileName.isEmpty()){ // content is attachment
filePath.replace(QByteArray("/"), QByteArray("\\"));
QString temp_path = QString(filePath);
TPtrC16 attachmentPath(KNullDesC);
attachmentPath.Set(reinterpret_cast<const TUint16*>(temp_path.utf16()));
messageData->AppendAttachmentL(attachmentPath);
}
else if (!body.isEmpty()) { // content is Body text
TPtrC16 msg(reinterpret_cast<const TUint16*>(body.utf16()));
HBufC* bd = msg.AllocLC();
TPtr ptr(bd->Des());
ipParaFormatLayer = CParaFormatLayer::NewL();
ipCharFormatLayer = CCharFormatLayer::NewL();
ipRichText = CRichText::NewL(ipParaFormatLayer, ipCharFormatLayer);
TInt pos = 0; // Insertion position of text will be zero
ipRichText->Reset();
ipRichText->InsertL(pos, ptr);
messageData->SetBodyTextL(ipRichText);
CleanupStack::PopAndDestroy(bd);
}
}
QString messageBody = message.textContent();
if (!messageBody.isEmpty()) { // no contents, only body text
TPtrC16 msg(reinterpret_cast<const TUint16*>(messageBody.utf16()));
HBufC* bd = msg.AllocLC();
TPtr ptr(bd->Des());
ipParaFormatLayer = CParaFormatLayer::NewL();
ipCharFormatLayer = CCharFormatLayer::NewL();
ipRichText = CRichText::NewL(ipParaFormatLayer, ipCharFormatLayer);
TInt pos = 0; // Insertion position of text will be zero
ipRichText->Reset();
ipRichText->InsertL(pos, ptr);
messageData->SetBodyTextL(ipRichText);
CleanupStack::PopAndDestroy(bd);
}
sendUi->CreateAndSendMessageL(KSenduiMtmSmtpUid, messageData, KNullUid, ETrue);
CleanupStack::PopAndDestroy(2); //messageData and sendUi
return true;
}
bool CMTMEngine::retrieve(const QMessageId &messageId, const QMessageContentContainerId& id)
{
TRAPD(err, retrieveL(messageId, id));
if (err != KErrNone)
return false;
else
return true;
}
void CMTMEngine::retrieveL(const QMessageId &messageId, const QMessageContentContainerId& id)
{
Q_UNUSED(id); // all attachments are retrieved (cannot retrieve only one)
long int messId = messageId.toString().toLong();
CMsvEntry* pEntry = ipMsvSession->GetEntryL(messId);
CleanupStack::PushL(pEntry);
CMsvEntrySelection* sel = new(ELeave) CMsvEntrySelection;
CleanupStack::PushL(sel);
CMsvOperationWait* wait = CMsvOperationWait::NewLC();
if (pEntry->Entry().iMtm == KUidMsgTypeIMAP4){
TPckgBuf<TInt> parameter;
ipImap4Mtm->SwitchCurrentEntryL(pEntry->OwningService());
sel->AppendL(messId);
CMsvOperation* opConnect = ipImap4Mtm->InvokeAsyncFunctionL(KIMAP4MTMConnect,
*sel, parameter, wait->iStatus);
CleanupStack::PushL(opConnect);
wait->Start();
CActiveScheduler::Start();
TImImap4GetPartialMailInfo info;
info.iPartialMailOptions = EAttachmentsOnly;
TPckg<TImImap4GetPartialMailInfo> bodyInfo(info);
CMsvOperation* opPopulate = ipImap4Mtm->InvokeAsyncFunctionL(KIMAP4MTMPopulate,
*sel, bodyInfo, wait->iStatus);
CleanupStack::PushL(opPopulate);
wait->Start();
CActiveScheduler::Start();
if (wait->iStatus.Int() != KErrNone) {
if (wait->iStatus.Int() == KErrNotFound){
// TODO: set messagestatus removed
}
}
CMsvOperation* opDisconnect = ipImap4Mtm->InvokeAsyncFunctionL(KIMAP4MTMDisconnect,
*sel, parameter, wait->iStatus);
CleanupStack::PushL(opDisconnect);
wait->Start();
CActiveScheduler::Start();
CleanupStack::PopAndDestroy(3);
}
if (pEntry->Entry().iMtm == KUidMsgTypePOP3){
TPckgBuf<TInt> parameter;
ipPop3Mtm->SwitchCurrentEntryL(pEntry->OwningService());
sel->AppendL(pEntry->EntryId());
CMsvOperation* opConnect = ipPop3Mtm->InvokeAsyncFunctionL(KPOP3MTMConnect,
*sel, parameter, wait->iStatus);
CleanupStack::PushL(opConnect);
wait->Start();
CActiveScheduler::Start();
CImPop3Settings *popSettings = new (ELeave) CImPop3Settings;
CleanupStack::PushL(popSettings);
CEmailAccounts *emailAccounts = CEmailAccounts::NewLC();
TPopAccount account;
emailAccounts->GetPopAccountL(pEntry->OwningService(), account);
emailAccounts->LoadPopSettingsL(account, *popSettings);
// cannot retrieve only attachment, have to retrieve entire message
popSettings->SetGetMailOptions(EGetPop3EmailMessages);
emailAccounts->SavePopSettingsL(account,*popSettings);
CleanupStack::PopAndDestroy(emailAccounts);
CleanupStack::PopAndDestroy(popSettings);
CMsvOperation* opPopulate = ipPop3Mtm->InvokeAsyncFunctionL(KPOP3MTMPopulate,
*sel, parameter, wait->iStatus);
CleanupStack::PushL(opPopulate);
wait->Start();
CActiveScheduler::Start();
CMsvOperation* opDisconnect = ipPop3Mtm->InvokeAsyncFunctionL(KPOP3MTMDisconnect,
*sel, parameter, wait->iStatus);
CleanupStack::PushL(opDisconnect);
wait->Start();
CActiveScheduler::Start();
CleanupStack::PopAndDestroy(3);
}
CleanupStack::PopAndDestroy(wait);
CleanupStack::PopAndDestroy(sel);
CleanupStack::PopAndDestroy(pEntry);
}
bool CMTMEngine::retrieveBody(const QMessageId& id)
{
TRAPD(err, retrieveBodyL(id));
if (err != KErrNone)
return false;
else
return true;
}
void CMTMEngine::retrieveBodyL(const QMessageId& id) const
{
long int messageId = id.toString().toLong();
CMsvEntry* pEntry = ipMsvSession->GetEntryL(messageId);
CleanupStack::PushL(pEntry);
CMsvEntrySelection* sel = new(ELeave) CMsvEntrySelection;
CleanupStack::PushL(sel);
CMsvOperationWait* wait = CMsvOperationWait::NewLC();
if (pEntry->Entry().iMtm == KUidMsgTypeIMAP4){
TPckgBuf<TInt> parameter;
ipImap4Mtm->SwitchCurrentEntryL(pEntry->OwningService());
sel->AppendL(messageId);
CMsvOperation* opConnect = ipImap4Mtm->InvokeAsyncFunctionL(KIMAP4MTMConnect,
*sel, parameter, wait->iStatus);
CleanupStack::PushL(opConnect);
wait->Start();
CActiveScheduler::Start();
TImImap4GetPartialMailInfo info;
info.iPartialMailOptions = EBodyTextOnly;
TPckg<TImImap4GetPartialMailInfo> bodyInfo(info);
CMsvOperation* opPopulate = ipImap4Mtm->InvokeAsyncFunctionL(KIMAP4MTMPopulate,
*sel, bodyInfo, wait->iStatus);
CleanupStack::PushL(opPopulate);
wait->Start();
CActiveScheduler::Start();
if (wait->iStatus.Int() != KErrNone) {
if (wait->iStatus.Int() == KErrNotFound){
// TODO: set messagestatus removed
}
}
CMsvOperation* opDisconnect = ipImap4Mtm->InvokeAsyncFunctionL(KIMAP4MTMDisconnect,
*sel, parameter, wait->iStatus);
CleanupStack::PushL(opDisconnect);
wait->Start();
CActiveScheduler::Start();
CleanupStack::PopAndDestroy(3);
}
if (pEntry->Entry().iMtm == KUidMsgTypePOP3){
TPckgBuf<TInt> parameter;
ipPop3Mtm->SwitchCurrentEntryL(pEntry->OwningService());
sel->AppendL(pEntry->EntryId());
CMsvOperation* opConnect = ipPop3Mtm->InvokeAsyncFunctionL(KPOP3MTMConnect,
*sel, parameter, wait->iStatus);
CleanupStack::PushL(opConnect);
wait->Start();
CActiveScheduler::Start();
CImPop3Settings *popSettings = new (ELeave) CImPop3Settings;
CleanupStack::PushL(popSettings);
CEmailAccounts *emailAccounts = CEmailAccounts::NewLC();
TPopAccount account;
emailAccounts->GetPopAccountL(pEntry->OwningService(), account);
emailAccounts->LoadPopSettingsL(account, *popSettings);
// cannot retrieve only body, have to retrieve entire message
popSettings->SetGetMailOptions(EGetPop3EmailMessages);
emailAccounts->SavePopSettingsL(account,*popSettings);
CleanupStack::PopAndDestroy(emailAccounts);
CleanupStack::PopAndDestroy(popSettings);
CMsvOperation* opPopulate = ipPop3Mtm->InvokeAsyncFunctionL(KPOP3MTMPopulate,
*sel, parameter, wait->iStatus);
CleanupStack::PushL(opPopulate);
wait->Start();
CActiveScheduler::Start();
CMsvOperation* opDisconnect = ipPop3Mtm->InvokeAsyncFunctionL(KPOP3MTMDisconnect,
*sel, parameter, wait->iStatus);
CleanupStack::PushL(opDisconnect);
wait->Start();
CActiveScheduler::Start();
CleanupStack::PopAndDestroy(3);
}
CleanupStack::PopAndDestroy(wait);
CleanupStack::PopAndDestroy(sel);
CleanupStack::PopAndDestroy(pEntry);
}
bool CMTMEngine::retrieveHeader(const QMessageId& id)
{
TRAPD(err, retrieveHeaderL(id));
if (err != KErrNone)
return false;
else
return true;
}
void CMTMEngine::retrieveHeaderL(const QMessageId& id) const
{
long int messageId = id.toString().toLong();
CMsvEntry* pEntry = ipMsvSession->GetEntryL(messageId);
CleanupStack::PushL(pEntry);
CMsvEntrySelection* sel = new(ELeave) CMsvEntrySelection;
CleanupStack::PushL(sel);
CMsvOperationWait* wait = CMsvOperationWait::NewLC();
if (pEntry->Entry().iMtm == KUidMsgTypeIMAP4){
TPckgBuf<TInt> parameter;
ipImap4Mtm->SwitchCurrentEntryL(pEntry->OwningService());
sel->AppendL(messageId);
CMsvOperation* opConnect = ipImap4Mtm->InvokeAsyncFunctionL(KIMAP4MTMConnect,
*sel, parameter, wait->iStatus);
CleanupStack::PushL(opConnect);
wait->Start();
CActiveScheduler::Start();
TImImap4GetMailInfo info;
info.iGetMailBodyParts = EGetImap4EmailHeaders;
TPckg<TImImap4GetMailInfo> bodyInfo(info);
CMsvOperation* opPopulate = ipImap4Mtm->InvokeAsyncFunctionL(KIMAP4MTMPopulate,
*sel, bodyInfo, wait->iStatus);
CleanupStack::PushL(opPopulate);
wait->Start();
CActiveScheduler::Start();
CMsvOperation* opDisconnect = ipImap4Mtm->InvokeAsyncFunctionL(KIMAP4MTMDisconnect,
*sel, parameter, wait->iStatus);
CleanupStack::PushL(opDisconnect);
wait->Start();
CActiveScheduler::Start();
CleanupStack::PopAndDestroy(3);
}
if (pEntry->Entry().iMtm == KUidMsgTypePOP3){
TPckgBuf<TInt> parameter;
ipPop3Mtm->SwitchCurrentEntryL(pEntry->OwningService());
sel->AppendL(pEntry->EntryId());
CMsvOperation* opConnect = ipPop3Mtm->InvokeAsyncFunctionL(KPOP3MTMConnect,
*sel, parameter, wait->iStatus);
CleanupStack::PushL(opConnect);
wait->Start();
CActiveScheduler::Start();
CImPop3Settings *popSettings = new (ELeave) CImPop3Settings;
CleanupStack::PushL(popSettings);
CEmailAccounts *emailAccounts = CEmailAccounts::NewLC();
TPopAccount account;
emailAccounts->GetPopAccountL(pEntry->OwningService(), account);
emailAccounts->LoadPopSettingsL(account, *popSettings);
popSettings->SetGetMailOptions(EGetPop3EmailHeaders);
emailAccounts->SavePopSettingsL(account,*popSettings);
CleanupStack::PopAndDestroy(emailAccounts);
CleanupStack::PopAndDestroy(popSettings);
CMsvOperation* opPopulate = ipPop3Mtm->InvokeAsyncFunctionL(KPOP3MTMPopulate,
*sel, parameter, wait->iStatus);
CleanupStack::PushL(opPopulate);
wait->Start();
CActiveScheduler::Start();
CMsvOperation* opDisconnect = ipPop3Mtm->InvokeAsyncFunctionL(KPOP3MTMDisconnect,
*sel, parameter, wait->iStatus);
CleanupStack::PushL(opDisconnect);
wait->Start();
CActiveScheduler::Start();
CleanupStack::PopAndDestroy(3);
}
CleanupStack::PopAndDestroy(wait);
CleanupStack::PopAndDestroy(sel);
CleanupStack::PopAndDestroy(pEntry);
}
bool CMTMEngine::exportUpdates(const QMessageAccountId &id)
{
TRAPD(err, exportUpdatesL(id));
if (err != KErrNone) {
return false;
} else {
return true;
}
}
void CMTMEngine::exportUpdatesL(const QMessageAccountId &id) const
{
QMessageAccount account = this->account(id);
CMsvEntry* pEntry = retrieveCMsvEntryAndPushToCleanupStack(account.d_ptr->_service1EntryId);
if (!pEntry) {
User::Leave(KErrNotFound);
}
if (pEntry->Entry().iMtm == KUidMsgTypeIMAP4) {
TPckgBuf<TInt> parameter;
CMsvEntrySelection* pMsvEntrySelection = new(ELeave) CMsvEntrySelection;
CleanupStack::PushL(pMsvEntrySelection);
CMsvOperationWait* pMsvOperationWait = CMsvOperationWait::NewLC();
ipImap4Mtm->SwitchCurrentEntryL(account.d_ptr->_service1EntryId);
pMsvEntrySelection->AppendL(account.d_ptr->_service1EntryId);
CMsvOperation* pMsvOperation = ipImap4Mtm->InvokeAsyncFunctionL(KIMAP4MTMConnect, *pMsvEntrySelection,
parameter, pMsvOperationWait->iStatus);
CleanupStack::PushL(pMsvOperation);
pMsvOperationWait->Start();
CActiveScheduler::Start();
CleanupStack::PopAndDestroy(pMsvOperation);
pMsvOperation = ipImap4Mtm->InvokeAsyncFunctionL(KIMAP4MTMFullSync, *pMsvEntrySelection,
parameter, pMsvOperationWait->iStatus);
CleanupStack::PushL(pMsvOperation);
pMsvOperationWait->Start();
CActiveScheduler::Start();
CleanupStack::PopAndDestroy(pMsvOperation);
pMsvOperation = ipImap4Mtm->InvokeAsyncFunctionL(KIMAP4MTMDisconnect, *pMsvEntrySelection,
parameter, pMsvOperationWait->iStatus);
CleanupStack::PushL(pMsvOperation);
pMsvOperationWait->Start();
CActiveScheduler::Start();
CleanupStack::PopAndDestroy(pMsvOperation);
CleanupStack::PopAndDestroy(pMsvOperationWait);
CleanupStack::PopAndDestroy(pMsvEntrySelection);
}
releaseCMsvEntryAndPopFromCleanupStack(pEntry);
}
bool CMTMEngine::removeMessageL(const QMessageId &id, QMessageManager::RemovalOption /*option*/)
{
long int messageId = id.toString().toLong();
CMsvEntry* pEntry = ipMsvSession->GetEntryL(messageId);
CleanupStack::PushL(pEntry);
if (pEntry->Entry().iMtm == KUidMsgTypeSMS) {
if (!ipSmsMtm)
return false;
ipSmsMtm->SwitchCurrentEntryL(messageId);
TMsvId parent = ipSmsMtm->Entry().Entry().Parent();
ipSmsMtm->SwitchCurrentEntryL(parent);
ipSmsMtm->Entry().DeleteL(messageId);
} else if (pEntry->Entry().iMtm == KUidMsgTypeMultimedia) {
if (!ipMmsMtm)
return false;
ipMmsMtm->SwitchCurrentEntryL(messageId);
TMsvId parent = ipMmsMtm->Entry().Entry().Parent();
ipMmsMtm->SwitchCurrentEntryL(parent);
ipMmsMtm->Entry().DeleteL(messageId);
} else if (pEntry->Entry().iMtm == KUidMsgTypeSMTP) {
if (!ipSmtpMtm)
return false;
ipSmtpMtm->SwitchCurrentEntryL(messageId);
TMsvId parent = ipSmtpMtm->Entry().Entry().Parent();
ipSmtpMtm->SwitchCurrentEntryL(parent);
ipSmtpMtm->Entry().DeleteL(messageId);
} else if (pEntry->Entry().iMtm == KUidMsgTypeIMAP4) {
if (!ipImap4Mtm)
return false;
ipImap4Mtm->SwitchCurrentEntryL(messageId);
TMsvId parent = ipImap4Mtm->Entry().Entry().Parent();
ipImap4Mtm->SwitchCurrentEntryL(parent);
CMsvOperationWait* pMsvOperationWait = CMsvOperationWait::NewLC();
CMsvOperation* pMsvOperation = ipImap4Mtm->Entry().DeleteL(messageId, pMsvOperationWait->iStatus);
CleanupStack::PushL(pMsvOperation);
pMsvOperationWait->Start();
CActiveScheduler::Start();
CleanupStack::PopAndDestroy(pMsvOperation);
CleanupStack::PopAndDestroy(pMsvOperationWait);
} else if (pEntry->Entry().iMtm == KUidMsgTypePOP3) {
if (!ipPop3Mtm)
return false;
ipPop3Mtm->SwitchCurrentEntryL(messageId);
TMsvId parent = ipPop3Mtm->Entry().Entry().Parent();
ipPop3Mtm->SwitchCurrentEntryL(parent);
CMsvOperationWait* pMsvOperationWait = CMsvOperationWait::NewLC();
CMsvOperation* pMsvOperation = ipPop3Mtm->Entry().DeleteL(messageId, pMsvOperationWait->iStatus);
CleanupStack::PushL(pMsvOperation);
pMsvOperationWait->Start();
CActiveScheduler::Start();
CleanupStack::PopAndDestroy(pMsvOperation);
CleanupStack::PopAndDestroy(pMsvOperationWait);
}
CleanupStack::PopAndDestroy(pEntry);
return true;
}
bool CMTMEngine::removeMessages(const QMessageFilter& /*filter*/, QMessageManager::RemovalOption /*option*/)
{
return false;
}
void CMTMEngine::handleNestedFiltersFromMessageFilter(QMessageFilter &filter) const
{
QMessageFilterPrivate* pMFFilter = QMessageFilterPrivate::implementation(filter);
if (pMFFilter->_filterList.count() > 0) {
int filterListCount = pMFFilter->_filterList.count();
for (int i=0; i < filterListCount; i++) {
for (int j=0; j < pMFFilter->_filterList[i].count(); j++) {
QMessageFilterPrivate* pMFFilter2 = QMessageFilterPrivate::implementation(pMFFilter->_filterList[i][j]);
if (pMFFilter2->_field == QMessageFilterPrivate::ParentAccountIdFilter) {
QMessageAccountIdList accountIds = queryAccounts(*pMFFilter2->_accountFilter, QMessageAccountSortOrder(), 0, 0);
QMessageDataComparator::InclusionComparator cmp(static_cast<QMessageDataComparator::InclusionComparator>(pMFFilter2->_comparatorValue));
if (accountIds.count() > 0) {
pMFFilter->_filterList[i].removeAt(j);
if (cmp == QMessageDataComparator::Includes) {
for (int x = 0; x < accountIds.count(); x++) {
if (x == 0) {
if (x+1 < accountIds.count()) {
pMFFilter->_filterList.append(pMFFilter->_filterList[i]);
}
pMFFilter->_filterList[i].append(QMessageFilter::byParentAccountId(accountIds[x],QMessageDataComparator::Equal));
qSort(pMFFilter->_filterList[i].begin(), pMFFilter->_filterList[i].end(), QMessageFilterPrivate::lessThan);
} else {
if (x+1 < accountIds.count()) {
pMFFilter->_filterList.append(pMFFilter->_filterList[pMFFilter->_filterList.count()-1]);
pMFFilter->_filterList[pMFFilter->_filterList.count()-2].append(QMessageFilter::byParentAccountId(accountIds[x],QMessageDataComparator::Equal));
qSort(pMFFilter->_filterList[pMFFilter->_filterList.count()-2].begin(), pMFFilter->_filterList[pMFFilter->_filterList.count()-2].end(), QMessageFilterPrivate::lessThan);
} else {
pMFFilter->_filterList[pMFFilter->_filterList.count()-1].append(QMessageFilter::byParentAccountId(accountIds[x],QMessageDataComparator::Equal));
qSort(pMFFilter->_filterList[pMFFilter->_filterList.count()-1].begin(), pMFFilter->_filterList[pMFFilter->_filterList.count()-1].end(), QMessageFilterPrivate::lessThan);
}
}
}
} else { // Excludes
for (int x = 0; x < accountIds.count(); x++) {
pMFFilter->_filterList[i].append(QMessageFilter::byParentAccountId(accountIds[x],QMessageDataComparator::NotEqual));
}
qSort(pMFFilter->_filterList[i].begin(), pMFFilter->_filterList[i].end(), QMessageFilterPrivate::lessThan);
}
} else {
delete pMFFilter2->_accountFilter;
pMFFilter2->_accountFilter = 0;
pMFFilter2->_field = QMessageFilterPrivate::Id;
qSort(pMFFilter->_filterList[i].begin(), pMFFilter->_filterList[i].end(), QMessageFilterPrivate::lessThan);
}
} else if (pMFFilter2->_field == QMessageFilterPrivate::ParentFolderIdFilter) {
QMessageFolderIdList folderIds = queryFolders(*pMFFilter2->_folderFilter, QMessageFolderSortOrder(), 0, 0);
QMessageDataComparator::InclusionComparator cmp(static_cast<QMessageDataComparator::InclusionComparator>(pMFFilter2->_comparatorValue));
if (folderIds.count() > 0) {
pMFFilter->_filterList[i].removeAt(j);
if (cmp == QMessageDataComparator::Includes) {
for (int x = 0; x < folderIds.count(); x++) {
if (x == 0) {
if (x+1 < folderIds.count()) {
pMFFilter->_filterList.append(pMFFilter->_filterList[i]);
}
pMFFilter->_filterList[i].append(QMessageFilter::byParentFolderId(folderIds[x],QMessageDataComparator::Equal));
qSort(pMFFilter->_filterList[i].begin(), pMFFilter->_filterList[i].end(), QMessageFilterPrivate::lessThan);
} else {
if (x+1 < folderIds.count()) {
pMFFilter->_filterList.append(pMFFilter->_filterList[pMFFilter->_filterList.count()-1]);
pMFFilter->_filterList[pMFFilter->_filterList.count()-2].append(QMessageFilter::byParentFolderId(folderIds[x],QMessageDataComparator::Equal));
qSort(pMFFilter->_filterList[pMFFilter->_filterList.count()-2].begin(), pMFFilter->_filterList[pMFFilter->_filterList.count()-2].end(), QMessageFilterPrivate::lessThan);
} else {
pMFFilter->_filterList[pMFFilter->_filterList.count()-1].append(QMessageFilter::byParentFolderId(folderIds[x],QMessageDataComparator::Equal));
qSort(pMFFilter->_filterList[pMFFilter->_filterList.count()-1].begin(), pMFFilter->_filterList[pMFFilter->_filterList.count()-1].end(), QMessageFilterPrivate::lessThan);
}
}
}
} else { // Excludes
for (int x = 0; x < folderIds.count(); x++) {
pMFFilter->_filterList[i].append(QMessageFilter::byParentFolderId(folderIds[x],QMessageDataComparator::NotEqual));
}
qSort(pMFFilter->_filterList[i].begin(), pMFFilter->_filterList[i].end(), QMessageFilterPrivate::lessThan);
}
} else {
delete pMFFilter2->_folderFilter;
pMFFilter2->_folderFilter = 0;
pMFFilter2->_field = QMessageFilterPrivate::Id;
qSort(pMFFilter->_filterList[i].begin(), pMFFilter->_filterList[i].end(), QMessageFilterPrivate::lessThan);
}
} else {
break;
}
}
}
} else {
if (pMFFilter->_field == QMessageFilterPrivate::ParentAccountIdFilter) {
QMessageAccountIdList accountIds = queryAccounts(*pMFFilter->_accountFilter, QMessageAccountSortOrder(), 0, 0);
QMessageDataComparator::InclusionComparator cmp(static_cast<QMessageDataComparator::InclusionComparator>(pMFFilter->_comparatorValue));
if (accountIds.count() > 0) {
for (int i=0; i < accountIds.count(); i++) {
if (i == 0) {
delete pMFFilter->_accountFilter;
pMFFilter->_accountFilter = 0;
pMFFilter->_field = QMessageFilterPrivate::ParentAccountId;
pMFFilter->_value = accountIds[0].toString();
pMFFilter->_comparatorType = QMessageFilterPrivate::Equality;
if (cmp == QMessageDataComparator::Includes) {
pMFFilter->_comparatorValue = static_cast<int>(QMessageDataComparator::Equal);
} else { // Excludes
pMFFilter->_comparatorValue = static_cast<int>(QMessageDataComparator::NotEqual);
}
} else {
if (cmp == QMessageDataComparator::Includes) {
filter |= QMessageFilter::byParentAccountId(accountIds[i],QMessageDataComparator::Equal);
} else { // Excludes
filter &= QMessageFilter::byParentAccountId(accountIds[i],QMessageDataComparator::NotEqual);
}
}
}
} else {
delete pMFFilter->_accountFilter;
pMFFilter->_accountFilter = 0;
pMFFilter->_field = QMessageFilterPrivate::Id;
}
} else if (pMFFilter->_field == QMessageFilterPrivate::ParentFolderIdFilter) {
QMessageFolderIdList folderIds = queryFolders(*pMFFilter->_folderFilter, QMessageFolderSortOrder(), 0, 0);
QMessageDataComparator::InclusionComparator cmp(static_cast<QMessageDataComparator::InclusionComparator>(pMFFilter->_comparatorValue));
if (folderIds.count() > 0) {
for (int i=0; i < folderIds.count(); i++) {
if (i == 0) {
delete pMFFilter->_folderFilter;
pMFFilter->_folderFilter = 0;
pMFFilter->_field = QMessageFilterPrivate::ParentFolderId;
pMFFilter->_value = folderIds[0].toString();
pMFFilter->_comparatorType = QMessageFilterPrivate::Equality;
if (cmp == QMessageDataComparator::Includes) {
pMFFilter->_comparatorValue = static_cast<int>(QMessageDataComparator::Equal);
} else { // Excludes
pMFFilter->_comparatorValue = static_cast<int>(QMessageDataComparator::NotEqual);
}
} else {
if (cmp == QMessageDataComparator::Includes) {
filter |= QMessageFilter::byParentFolderId(folderIds[i],QMessageDataComparator::Equal);
} else { // Excludes
filter &= QMessageFilter::byParentFolderId(folderIds[i],QMessageDataComparator::NotEqual);
}
}
}
} else {
delete pMFFilter->_folderFilter;
pMFFilter->_folderFilter = 0;
pMFFilter->_field = QMessageFilterPrivate::Id;
}
}
}
}
bool CMTMEngine::queryMessages(QMessageServicePrivate& privateService, const QMessageFilter &filter, const QMessageSortOrder &sortOrder, uint limit, uint offset) const
{
TRAPD(err, queryMessagesL(privateService, filter, sortOrder, limit, offset));
if (err != KErrNone) {
return false;
}
return true;
}
void CMTMEngine::queryMessagesL(QMessageServicePrivate& privateService, const QMessageFilter &filter, const QMessageSortOrder &sortOrder, uint limit, uint offset) const
{
MessageQueryInfo queryInfo;
queryInfo.operationId = ++iOperationIds;
if (queryInfo.operationId == 100000) {
queryInfo.operationId = 1;
}
queryInfo.isQuery = true;
queryInfo.filter = filter;
queryInfo.sortOrder = sortOrder;
queryInfo.offset = offset;
queryInfo.limit = limit;
queryInfo.findOperation = new CMessagesFindOperation((CMTMEngine&)*this, ipMsvSession, queryInfo.operationId);
queryInfo.privateService = &privateService;
queryInfo.currentFilterListIndex = 0;
iMessageQueries.append(queryInfo);
handleNestedFiltersFromMessageFilter(iMessageQueries[iMessageQueries.count()-1].filter);
QMessageFilterPrivate* pf = QMessageFilterPrivate::implementation(iMessageQueries[iMessageQueries.count()-1].filter);
if (pf->_filterList.count() == 0) {
queryInfo.findOperation->filterAndOrderMessages(iMessageQueries[iMessageQueries.count()-1].filter,
iMessageQueries[iMessageQueries.count()-1].sortOrder);
} else {
queryInfo.findOperation->filterAndOrderMessages(pf->_filterList[0], iMessageQueries[iMessageQueries.count()-1].sortOrder);
}
}
bool CMTMEngine::queryMessages(QMessageServicePrivate& privateService, const QMessageFilter &filter, const QString &body, QMessageDataComparator::MatchFlags matchFlags, const QMessageSortOrder &sortOrder, uint limit, uint offset) const
{
TRAPD(err, queryMessagesL(privateService, filter, body, matchFlags, sortOrder, limit, offset));
if (err != KErrNone) {
return false;
}
return true;
}
void CMTMEngine::queryMessagesL(QMessageServicePrivate& privateService, const QMessageFilter &filter, const QString &body, QMessageDataComparator::MatchFlags matchFlags, const QMessageSortOrder &sortOrder, uint limit, uint offset) const
{
MessageQueryInfo queryInfo;
queryInfo.operationId = ++iOperationIds;
if (queryInfo.operationId == 100000) {
queryInfo.operationId = 1;
}
queryInfo.isQuery = true;
queryInfo.body = body;
queryInfo.matchFlags = matchFlags;
queryInfo.filter = filter;
queryInfo.sortOrder = sortOrder;
queryInfo.offset = offset;
queryInfo.limit = limit;
queryInfo.findOperation = new CMessagesFindOperation((CMTMEngine&)*this, ipMsvSession, queryInfo.operationId);
queryInfo.privateService = &privateService;
queryInfo.currentFilterListIndex = 0;
iMessageQueries.append(queryInfo);
handleNestedFiltersFromMessageFilter(iMessageQueries[iMessageQueries.count()-1].filter);
QMessageFilterPrivate* pf = QMessageFilterPrivate::implementation(iMessageQueries[iMessageQueries.count()-1].filter);
if (pf->_filterList.count() == 0) {
queryInfo.findOperation->filterAndOrderMessages(iMessageQueries[iMessageQueries.count()-1].filter,
iMessageQueries[iMessageQueries.count()-1].sortOrder,
body,
matchFlags);
} else {
queryInfo.findOperation->filterAndOrderMessages(pf->_filterList[0],
iMessageQueries[iMessageQueries.count()-1].sortOrder,
body,
matchFlags);
}
}
bool CMTMEngine::countMessages(QMessageServicePrivate& privateService, const QMessageFilter &filter)
{
TRAPD(err, countMessagesL(privateService, filter));
if (err != KErrNone) {
return false;
}
return true;
}
void CMTMEngine::countMessagesL(QMessageServicePrivate& privateService, const QMessageFilter &filter)
{
MessageQueryInfo queryInfo;
queryInfo.operationId = ++iOperationIds;
if (queryInfo.operationId == 100000) {
queryInfo.operationId = 1;
}
queryInfo.isQuery = false;
queryInfo.matchFlags = 0;
queryInfo.filter = filter;
queryInfo.sortOrder = QMessageSortOrder();
queryInfo.offset = 0;
queryInfo.limit = 0;
queryInfo.findOperation = new CMessagesFindOperation((CMTMEngine&)*this, ipMsvSession, queryInfo.operationId);
queryInfo.privateService = &privateService;
queryInfo.currentFilterListIndex = 0;
queryInfo.count = 0;
iMessageQueries.append(queryInfo);
handleNestedFiltersFromMessageFilter(iMessageQueries[iMessageQueries.count()-1].filter);
QMessageFilterPrivate* pf = QMessageFilterPrivate::implementation(iMessageQueries[iMessageQueries.count()-1].filter);
if (pf->_filterList.count() == 0) {
queryInfo.findOperation->filterAndOrderMessages(iMessageQueries[iMessageQueries.count()-1].filter,
iMessageQueries[iMessageQueries.count()-1].sortOrder);
} else {
queryInfo.findOperation->filterAndOrderMessages(pf->_filterList[0], iMessageQueries[iMessageQueries.count()-1].sortOrder);
}
}
void CMTMEngine::filterAndOrderMessagesReady(bool success, int operationId, QMessageIdList ids, int numberOfHandledFilters,
bool resultSetOrdered)
{
int index=0;
for (; index < iMessageQueries.count(); index++) {
if (iMessageQueries[index].operationId == operationId) {
break;
}
}
if (success) {
// If there are unhandled filters, loop through all filters and do filtering for ids using unhandled filters.
QMessageFilterPrivate* pf = QMessageFilterPrivate::implementation(iMessageQueries[index].filter);
if (pf->_filterList.count() > 0) {
if (pf->_filterList[iMessageQueries[index].currentFilterListIndex].count() > numberOfHandledFilters) {
for (int i=0; i < ids.count(); i++) {
QMessage msg = message(ids[i]);
for (int j=numberOfHandledFilters; j < pf->_filterList[iMessageQueries[index].currentFilterListIndex].count(); j++) {
QMessageFilterPrivate* pf2 = QMessageFilterPrivate::implementation(pf->_filterList[iMessageQueries[index].currentFilterListIndex][j]);
if (!pf2->filter(msg)) {
ids.removeAt(i);
i--;
break;
}
}
}
}
}
if (pf->_filterList.count() > 0) {
// Filter contains filterlist (or filterlists), not just one single filter
if (iMessageQueries[index].currentFilterListIndex == 0) {
iMessageQueries[index].ids << ids;
iMessageQueries[index].count = ids.count();
} else {
// Append new ids to resultset
for (int i=0; i < ids.count(); i++) {
if (!iMessageQueries[index].ids.contains(ids[i])) {
iMessageQueries[index].ids.append(ids[i]);
iMessageQueries[index].count++;;
}
}
}
iMessageQueries[index].currentFilterListIndex++;
if (iMessageQueries[index].currentFilterListIndex < pf->_filterList.count()) {
// There are still unhandled filter lists left
iMessageQueries[index].findOperation->filterAndOrderMessages(pf->_filterList[iMessageQueries[index].currentFilterListIndex],
iMessageQueries[index].sortOrder,
iMessageQueries[index].body,
iMessageQueries[index].matchFlags);
return;
} else {
// All filters successfully handled
if (iMessageQueries[index].isQuery) {
if (!iMessageQueries[index].sortOrder.isEmpty()) {
// Make sure that messages are correctly ordered
orderMessages(iMessageQueries[index].ids, iMessageQueries[index].sortOrder);
}
applyOffsetAndLimitToMsgIds(iMessageQueries[index].ids,
iMessageQueries[index].offset,
iMessageQueries[index].limit);
emit iMessageQueries[index].privateService->messagesFound(iMessageQueries[index].ids);
} else {
emit iMessageQueries[index].privateService->messagesCounted(iMessageQueries[index].count);
}
iMessageQueries[index].privateService->_active = false;
emit iMessageQueries[index].privateService->stateChanged(QMessageService::FinishedState);
}
} else {
// There was only one single filter to handle
if (numberOfHandledFilters == 0) {
// The one and only filter was not handled
// => Do filtering for all returned messages
for (int i=ids.count()-1; i >= 0; i--) {
QMessage msg = message(ids[i]);
if (!pf->filter(msg)) {
ids.removeAt(i);
}
}
}
// => All filters successfully handled
if (iMessageQueries[index].isQuery) {
// Make sure that messages are correctly ordered
if (!iMessageQueries[index].sortOrder.isEmpty() && !resultSetOrdered) {
orderMessages(ids, iMessageQueries[index].sortOrder);
}
// Handle offest & limit
applyOffsetAndLimitToMsgIds(ids, iMessageQueries[index].offset, iMessageQueries[index].limit);
emit iMessageQueries[index].privateService->messagesFound(ids);
} else {
emit iMessageQueries[index].privateService->messagesCounted(ids.count());
}
iMessageQueries[index].privateService->_active = false;
emit iMessageQueries[index].privateService->stateChanged(QMessageService::FinishedState);
}
} else {
iMessageQueries[index].privateService->_active = false;
if (iMessageQueries[index].privateService->_error == QMessageManager::NoError) {
iMessageQueries[index].privateService->_error = QMessageManager::RequestIncomplete;
}
emit iMessageQueries[index].privateService->stateChanged(QMessageService::FinishedState);
}
delete iMessageQueries[index].findOperation;
iMessageQueries.removeAt(index);
}
void CMTMEngine::applyOffsetAndLimitToMsgIds(QMessageIdList& idList, int offset, int limit) const
{
if (offset > 0) {
if (offset > idList.count()) {
idList.clear();
} else {
for (int i = 0; i < offset; i++) {
idList.removeFirst();
}
}
}
if (limit > 0) {
for (int i = idList.count()-1; i >= limit; i--) {
idList.removeAt(i);
}
}
}
QMessageFolderIdList CMTMEngine::filterMessageFolders(const QMessageFolderFilter& filter, bool& filterHandled) const
{
QMessageFolderIdList ids;
TRAPD(err, ids = filterMessageFoldersL(filter, filterHandled));
Q_UNUSED(err)
return ids;
}
QMessageFolderIdList CMTMEngine::filterMessageFoldersL(const QMessageFolderFilter& filter, bool& filterHandled) const
{
filterHandled = false;
QMessageFolderIdList ids;
if (filter.isEmpty()) {
QMessageFolderFilterPrivate* pf = QMessageFolderFilterPrivate::implementation(filter);
if (!pf->_notFilter) {
ids = allFolders();
}
filterHandled = true;
} else {
QMessageFolderFilterPrivate* pf = QMessageFolderFilterPrivate::implementation(filter);
if (!pf->_valid) {
return QMessageFolderIdList();
}
switch (pf->_field) {
case QMessageFolderFilterPrivate::Id:
{
if (pf->_comparatorType == QMessageFolderFilterPrivate::Equality) {
QMessageDataComparator::EqualityComparator cmp(static_cast<QMessageDataComparator::EqualityComparator>(pf->_comparatorValue));
if (pf->_value.toString().length() > 0) {
bool folderOk = false;
long int folderId = folderIdFromQMessageFolderId(QMessageFolderId(pf->_value.toString()));
CMsvEntry* pEntry = retrieveCMsvEntryAndPushToCleanupStack(folderId);
if (pEntry) {
if (pEntry->Entry().iType == KUidMsvFolderEntry) {
folderOk = true;
}
releaseCMsvEntryAndPopFromCleanupStack(pEntry);
}
if (cmp == QMessageDataComparator::Equal) {
if (folderOk) {
ids.append(QMessageFolderId(pf->_value.toString()));
}
} else { // NotEqual
ids = allFolders();
if (folderOk) {
ids.removeOne(QMessageFolderId(pf->_value.toString()));
}
}
} else {
if (cmp == QMessageDataComparator::NotEqual) {
ids = allFolders();
}
}
filterHandled = true;
} else if (pf->_comparatorType == QMessageFolderFilterPrivate::Inclusion) {
QMessageDataComparator::InclusionComparator cmp(static_cast<QMessageDataComparator::InclusionComparator>(pf->_comparatorValue));
if (pf->_ids.count() > 0) { // QMessageIdList
QMessageFolderIdList ids2;
for (int i=0; i < pf->_ids.count(); i++) {
long int folderId = folderIdFromQMessageFolderId(QMessageFolderId(pf->_ids[i].toString()));
CMsvEntry* pEntry = retrieveCMsvEntryAndPushToCleanupStack(folderId);
if (pEntry) {
const TMsvEntry& entry = pEntry->Entry();
if (entry.iType == KUidMsvFolderEntry) {
ids2.append(pf->_ids[i]);
}
releaseCMsvEntryAndPopFromCleanupStack(pEntry);
}
}
if (cmp == QMessageDataComparator::Includes) {
ids << ids2;
} else { // Excludes
ids = allFolders();
for (int i=0; i < ids2.count(); i++) {
ids.removeOne(ids2[i]);
}
}
filterHandled = true;
} else {
// Empty QMessageIdList as a list
if (cmp == QMessageDataComparator::Excludes) {
ids = allFolders();
}
filterHandled = true;
// QMessageFilter
/*if (cmp == QMessageDataComparator::Includes) {
// TODO:
} else { // Excludes
// TODO:
}*/
}
}
break;
}
case QMessageFolderFilterPrivate::Name:
{
if (pf->_comparatorType == QMessageFolderFilterPrivate::Equality) {
QMessageDataComparator::EqualityComparator cmp(static_cast<QMessageDataComparator::EqualityComparator>(pf->_comparatorValue));
if (cmp == QMessageDataComparator::Equal) {
// TODO:
} else { // NotEqual
// TODO:
}
} else if (pf->_comparatorType == QMessageFolderFilterPrivate::Inclusion) {
QMessageDataComparator::InclusionComparator cmp(static_cast<QMessageDataComparator::InclusionComparator>(pf->_comparatorValue));
if (cmp == QMessageDataComparator::Includes) {
// TODO:
} else { // Excludes
if (pf->_value.toString().isEmpty() || pf->_value.toString().length() == 0) {
filterHandled = true;
}
}
}
break;
}
case QMessageFolderFilterPrivate::Path:
{
if (pf->_comparatorType == QMessageFolderFilterPrivate::Equality) {
QMessageDataComparator::EqualityComparator cmp(static_cast<QMessageDataComparator::EqualityComparator>(pf->_comparatorValue));
if (cmp == QMessageDataComparator::Equal) {
// TODO:
} else { // NotEqual
// TODO:
}
} else if (pf->_comparatorType == QMessageFolderFilterPrivate::Inclusion) {
QMessageDataComparator::InclusionComparator cmp(static_cast<QMessageDataComparator::InclusionComparator>(pf->_comparatorValue));
if (cmp == QMessageDataComparator::Includes) {
// TODO:
} else { // Excludes
if (pf->_value.toString().isEmpty() || pf->_value.toString().length() == 0) {
filterHandled = true;
}
}
}
break;
}
case QMessageFolderFilterPrivate::ParentAccountId:
{
if (pf->_comparatorType == QMessageFolderFilterPrivate::Equality) {
QMessageDataComparator::EqualityComparator cmp(static_cast<QMessageDataComparator::EqualityComparator>(pf->_comparatorValue));
if (cmp == QMessageDataComparator::Equal) {
if (pf->_value.toString().length() > 0) {
ids = folderIdsByAccountId(QMessageAccountId(pf->_value.toString()));
}
} else { // NotEqual
ids = allFolders();
if (pf->_value.toString().length() > 0) {
QMessageFolderIdList ids2 = folderIdsByAccountId(QMessageAccountId(pf->_value.toString()));
for (int i = 0; i < ids2.count(); i++) {
ids.removeOne(ids2[i]);
}
}
}
filterHandled = true;
} else if (pf->_comparatorType == QMessageFolderFilterPrivate::Inclusion) {
QMessageDataComparator::InclusionComparator cmp(static_cast<QMessageDataComparator::InclusionComparator>(pf->_comparatorValue));
if (cmp == QMessageDataComparator::Includes) {
// TODO:
} else { // Excludes
// TODO:
}
}
break;
}
case QMessageFolderFilterPrivate::ParentFolderId:
{
if (pf->_comparatorType == QMessageFolderFilterPrivate::Equality) {
QMessageDataComparator::EqualityComparator cmp(static_cast<QMessageDataComparator::EqualityComparator>(pf->_comparatorValue));
if (cmp == QMessageDataComparator::Equal) {
long int folderId = pf->_value.toString().toLong();
CMsvEntry* pEntry = retrieveCMsvEntryAndPushToCleanupStack(folderId);
if (pEntry) {
const TMsvEntry& entry = pEntry->Entry();
if (entry.iType == KUidMsvFolderEntry) {
CMsvEntrySelection* pSelection = pEntry->ChildrenWithTypeL(KUidMsvFolderEntry);
CleanupStack::PushL(pSelection);
if (pSelection->Count() > 0) {
for(TInt i = 0; i < pSelection->Count(); i++) {
ids.append(QMessageFolderId(QString::number(pSelection->At(i))));
}
}
CleanupStack::PopAndDestroy(pSelection);
}
releaseCMsvEntryAndPopFromCleanupStack(pEntry);
}
} else { // NotEqual
// TODO:
}
} else if (pf->_comparatorType == QMessageFolderFilterPrivate::Inclusion) {
QMessageDataComparator::InclusionComparator cmp(static_cast<QMessageDataComparator::InclusionComparator>(pf->_comparatorValue));
if (cmp == QMessageDataComparator::Includes) {
// TODO:
} else { // Excludes
// TODO:
}
}
break;
}
case QMessageFolderFilterPrivate::AncestorFolderIds:
{
if (pf->_comparatorType == QMessageFolderFilterPrivate::Inclusion) {
QMessageDataComparator::InclusionComparator cmp(static_cast<QMessageDataComparator::InclusionComparator>(pf->_comparatorValue));
if (!pf->_value.isNull()) { // QMessageFolderId
if (cmp == QMessageDataComparator::Includes) {
// TODO:
} else { // Excludes
// TODO:
}
} else { // QMessageFolderFilter
if (cmp == QMessageDataComparator::Includes) {
// TODO:
} else { // Excludes
// TODO:
}
}
}
break;
}
case QMessageFolderFilterPrivate::ParentAccountIdFilter:
case QMessageFolderFilterPrivate::None:
break;
}
}
if (!filterHandled) {
ids = allFolders();
}
return ids;
}
QMessageFolderIdList CMTMEngine::allFolders() const
{
QMessageFolderIdList ids;
TRAPD(err, updateEmailAccountsL());
Q_UNUSED(err)
foreach (QMessageAccount value, iAccounts) {
QMessageFolderIdList ids2 = folderIdsByAccountId(value.id());
ids << ids2;
}
return ids;
}
QMessageFolderIdList CMTMEngine::folderIdsByAccountId(const QMessageAccountId& accountId) const
{
QMessageAccount messageAccount = account(accountId);
QMessageFolderIdList ids = folderIdsByServiceEntryId(messageAccount.d_ptr->_service1EntryId,
messageAccount.d_ptr->_service1EntryId);
if (messageAccount.d_ptr->_service2EntryId) {
QMessageFolderIdList ids2 = folderIdsByServiceEntryId(messageAccount.d_ptr->_service2EntryId,
messageAccount.d_ptr->_service1EntryId);
ids << ids2;
}
return ids;
}
QMessageFolderIdList CMTMEngine::folderIdsByServiceEntryId(const TMsvId& serviceEntryId,
const TMsvId& folderServiceEntryId) const
{
QMessageFolderIdList ids;
CMsvEntry* pEntry = retrieveCMsvEntryAndPushToCleanupStack(serviceEntryId);
if (pEntry) {
const TMsvEntry& entry = pEntry->Entry();
if (entry.iMtm == KUidMsgTypeSMS || entry.iMtm == KUidMsgTypeMultimedia || entry.iMtm == KUidMsgTypeSMTP) {
// Add all Standard Folders to FolderIdList
if (entry.iMtm != KUidMsgTypeSMTP) {
// SMTP is for sending only => Don't add Inbox for SMTP
ids.append(createQMessageFolderId(folderServiceEntryId, KMsvGlobalInBoxIndexEntryId));
}
ids.append(createQMessageFolderId(folderServiceEntryId, KMsvGlobalOutBoxIndexEntryId));
ids.append(createQMessageFolderId(folderServiceEntryId, KMsvDraftEntryId));
ids.append(createQMessageFolderId(folderServiceEntryId, KMsvSentEntryId));
ids.append(createQMessageFolderId(folderServiceEntryId, KMsvDeletedEntryFolderEntryId));
pEntry->SetEntryL(KDocumentsEntryIdValue);
}
if (entry.iMtm == KUidMsgTypePOP3) {
ids.append(createQMessageFolderId(folderServiceEntryId, serviceEntryId));
} else {
CMsvEntryFilter* pFilter = CMsvEntryFilter::NewLC();
pFilter->SetService(serviceEntryId);
pFilter->SetType(KUidMsvFolderEntry);
CMsvEntrySelection* pSelection = new(ELeave) CMsvEntrySelection;
CleanupStack::PushL(pSelection);
ipMsvSession->GetChildIdsL(pEntry->Entry().Id(), *pFilter, *pSelection);
if (pSelection->Count() > 0) {
for(TInt i = 0; i < pSelection->Count(); i++) {
ids.append(createQMessageFolderId(folderServiceEntryId, pSelection->At(i)));
}
}
CleanupStack::PopAndDestroy(pSelection);
CleanupStack::PopAndDestroy(pFilter);
}
releaseCMsvEntryAndPopFromCleanupStack(pEntry);
}
return ids;
}
QMessageFolderId CMTMEngine::createQMessageFolderId(const TMsvId& serviceEntryId, const TMsvId& folderId) const
{
QString nullString = "00000000";
QString serviceEntryIdString = QString::number(serviceEntryId);
serviceEntryIdString = nullString.left(8-serviceEntryIdString.length()) + serviceEntryIdString;
QString folderIdString = QString::number(folderId);
folderIdString = nullString.left(8-folderIdString.length()) + folderIdString;
return serviceEntryIdString+folderIdString;
}
TMsvId CMTMEngine::serviceEntryIdFromQMessageFolderId(const QMessageFolderId& folderId) const
{
return folderId.toString().left(8).toLong();
}
TMsvId CMTMEngine::folderIdFromQMessageFolderId(const QMessageFolderId& folderId) const
{
return folderId.toString().right(8).toLong();
}
void CMTMEngine::handleNestedFiltersFromFolderFilter(QMessageFolderFilter &filter) const
{
QMessageFolderFilterPrivate* pMFFilter = QMessageFolderFilterPrivate::implementation(filter);
if (pMFFilter->_filterList.count() > 0) {
int filterListCount = pMFFilter->_filterList.count();
for (int i=0; i < filterListCount; i++) {
for (int j=0; j < pMFFilter->_filterList[i].count(); j++) {
QMessageFolderFilterPrivate* pMFFilter2 = QMessageFolderFilterPrivate::implementation(pMFFilter->_filterList[i][j]);
if (pMFFilter2->_field == QMessageFolderFilterPrivate::ParentAccountIdFilter) {
QMessageAccountIdList accountIds = queryAccounts(*pMFFilter2->_accountFilter, QMessageAccountSortOrder(), 0, 0);
QMessageDataComparator::InclusionComparator cmp(static_cast<QMessageDataComparator::InclusionComparator>(pMFFilter2->_comparatorValue));
if (accountIds.count() > 0) {
pMFFilter->_filterList[i].removeAt(j);
if (cmp == QMessageDataComparator::Includes) {
for (int x = 0; x < accountIds.count(); x++) {
if (x == 0) {
if (x+1 < accountIds.count()) {
pMFFilter->_filterList.append(pMFFilter->_filterList[i]);
}
pMFFilter->_filterList[i].append(QMessageFolderFilter::byParentAccountId(accountIds[x],QMessageDataComparator::Equal));
qSort(pMFFilter->_filterList[i].begin(), pMFFilter->_filterList[i].end(), QMessageFolderFilterPrivate::lessThan);
} else {
if (x+1 < accountIds.count()) {
pMFFilter->_filterList.append(pMFFilter->_filterList[pMFFilter->_filterList.count()-1]);
pMFFilter->_filterList[pMFFilter->_filterList.count()-2].append(QMessageFolderFilter::byParentAccountId(accountIds[x],QMessageDataComparator::Equal));
qSort(pMFFilter->_filterList[pMFFilter->_filterList.count()-2].begin(), pMFFilter->_filterList[pMFFilter->_filterList.count()-2].end(), QMessageFolderFilterPrivate::lessThan);
} else {
pMFFilter->_filterList[pMFFilter->_filterList.count()-1].append(QMessageFolderFilter::byParentAccountId(accountIds[x],QMessageDataComparator::Equal));
qSort(pMFFilter->_filterList[pMFFilter->_filterList.count()-1].begin(), pMFFilter->_filterList[pMFFilter->_filterList.count()-1].end(), QMessageFolderFilterPrivate::lessThan);
}
}
}
} else { // Excludes
for (int x = 0; x < accountIds.count(); x++) {
pMFFilter->_filterList[i].append(QMessageFolderFilter::byParentAccountId(accountIds[x],QMessageDataComparator::NotEqual));
}
qSort(pMFFilter->_filterList[i].begin(), pMFFilter->_filterList[i].end(), QMessageFolderFilterPrivate::lessThan);
}
} else {
delete pMFFilter2->_accountFilter;
pMFFilter2->_accountFilter = 0;
pMFFilter2->_field = QMessageFolderFilterPrivate::Id;
qSort(pMFFilter->_filterList[i].begin(), pMFFilter->_filterList[i].end(), QMessageFolderFilterPrivate::lessThan);
}
} else {
break;
}
}
}
} else {
if (pMFFilter->_field == QMessageFolderFilterPrivate::ParentAccountIdFilter) {
QMessageAccountIdList accountIds = queryAccounts(*pMFFilter->_accountFilter, QMessageAccountSortOrder(), 0, 0);
QMessageDataComparator::InclusionComparator cmp(static_cast<QMessageDataComparator::InclusionComparator>(pMFFilter->_comparatorValue));
if (accountIds.count() > 0) {
for (int i=0; i < accountIds.count(); i++) {
if (i == 0) {
delete pMFFilter->_accountFilter;
pMFFilter->_accountFilter = 0;
pMFFilter->_field = QMessageFolderFilterPrivate::ParentAccountId;
pMFFilter->_value = accountIds[0].toString();
pMFFilter->_comparatorType = QMessageFolderFilterPrivate::Equality;
if (cmp == QMessageDataComparator::Includes) {
pMFFilter->_comparatorValue = static_cast<int>(QMessageDataComparator::Equal);
} else { // Excludes
pMFFilter->_comparatorValue = static_cast<int>(QMessageDataComparator::NotEqual);
}
} else {
if (cmp == QMessageDataComparator::Includes) {
filter |= QMessageFolderFilter::byParentAccountId(accountIds[i],QMessageDataComparator::Equal);
} else { // Excludes
filter &= QMessageFolderFilter::byParentAccountId(accountIds[i],QMessageDataComparator::NotEqual);
}
}
}
} else {
delete pMFFilter->_accountFilter;
pMFFilter->_accountFilter = 0;
pMFFilter->_field = QMessageFolderFilterPrivate::Id;
}
}
}
}
QMessageFolderIdList CMTMEngine::queryFolders(const QMessageFolderFilter &filter, const QMessageFolderSortOrder &sortOrder, uint limit, uint offset) const
{
QMessageFolderIdList ids;
QMessageFolderFilter copyOfFilter = filter;
handleNestedFiltersFromFolderFilter(copyOfFilter);
QMessageFolderFilterPrivate* pMFFilter = QMessageFolderFilterPrivate::implementation(copyOfFilter);
if (pMFFilter->_filterList.count() > 0) {
for (int i=0; i < pMFFilter->_filterList.count(); i++) {
bool filterHandled;
QMessageFolderIdList ids2 = filterMessageFolders(pMFFilter->_filterList[i][0], filterHandled);
for (int x=ids2.count()-1; x >= 0; x--) {
QMessageFolder mf = folder(ids2[x]);
int j = filterHandled ? 1 : 0;
for (; j < pMFFilter->_filterList[i].count(); j++) {
if (!QMessageFolderFilterPrivate::implementation(pMFFilter->_filterList[i][j])->filter(mf)) {
ids2.removeAt(x);
break;
}
}
}
for (int j=0; j < ids2.count(); j++) {
if (!ids.contains(ids2[j])) {
ids.append(ids2[j]);
}
}
}
} else {
bool filterHandled;
ids = filterMessageFolders(copyOfFilter, filterHandled);
if (!filterHandled) {
for (int i=ids.count()-1; i >= 0; i--) {
if (!QMessageFolderFilterPrivate::implementation(copyOfFilter)->filter(ids[i])) {
ids.removeAt(i);
}
}
}
}
if (!sortOrder.isEmpty()) {
orderFolders(ids, sortOrder);
}
applyOffsetAndLimitToMsgFolderIds(ids, offset, limit);
return ids;
}
void CMTMEngine::applyOffsetAndLimitToMsgFolderIds(QMessageFolderIdList& idList, int offset, int limit) const
{
if (offset > 0) {
if (offset > idList.count()) {
idList.clear();
} else {
for (int i = 0; i < offset; i++) {
idList.removeFirst();
}
}
}
if (limit > 0) {
for (int i = idList.count()-1; i >= limit; i--) {
idList.removeAt(i);
}
}
}
int CMTMEngine::countFolders(const QMessageFolderFilter &filter) const
{
return queryFolders(filter, QMessageFolderSortOrder(), 0, 0).count();
}
QMessageFolder CMTMEngine::folder(const QMessageFolderId &id) const
{
if (!iSessionReady)
return QMessageFolder();
QMessageFolder folder;
TRAPD(err, folder = folderL(id));
Q_UNUSED(err)
return folder;
}
QMessageFolder CMTMEngine::folderL(const QMessageFolderId &id) const
{
QMessageFolder folder;
TMsvId folderId = folderIdFromQMessageFolderId(id);
TMsvId serviceId = serviceEntryIdFromQMessageFolderId(id);
CMsvEntry* pEntry = retrieveCMsvEntryAndPushToCleanupStack(folderId);
if (pEntry) {
if (pEntry->Entry().iMtm == KUidMsgTypePOP3) {
pEntry->SetEntryL(KMsvGlobalInBoxIndexEntryId);
}
QMessageAccountId accountId(accountIdByServiceId(serviceId));
QMessageFolderId parentId;
QString name = QString::fromUtf16(pEntry->Entry().iDetails.Ptr(), pEntry->Entry().iDetails.Length());
folder = QMessageFolderPrivate::from(id, accountId, parentId, name, name);
releaseCMsvEntryAndPopFromCleanupStack(pEntry);
}
return folder;
}
QMessage CMTMEngine::message(const QMessageId& id) const
{
if (!iSessionReady)
return QMessage();
QMessage message;
TRAPD(err, message = messageL(id));
Q_UNUSED(err)
return message;
}
QMessage CMTMEngine::messageL(const QMessageId& id) const
{
QMessage message;
long int messageId = id.toString().toLong();
CMsvEntry* pEntry = ipMsvSession->GetEntryL(messageId);
CleanupStack::PushL(pEntry);
if (pEntry->Entry().iMtm == KUidMsgTypeSMS) {
if (!ipSmsMtm)
return message;
message = smsMessageL(*pEntry, messageId);
} else if (pEntry->Entry().iMtm == KUidMsgTypeMultimedia) {
if (!ipMmsMtm)
return message;
message = mmsMessageL(*pEntry, messageId);
} else if (pEntry->Entry().iMtm == KUidMsgTypeSMTP) {
if (!ipSmtpMtm)
return message;
message = emailMessageL(*pEntry, messageId);
} else if (pEntry->Entry().iMtm == KUidMsgTypeIMAP4) {
if (!ipImap4Mtm)
return message;
message = emailMessageL(*pEntry, messageId);
} else if (pEntry->Entry().iMtm == KUidMsgTypePOP3) {
if (!ipPop3Mtm)
return message;
message = emailMessageL(*pEntry, messageId);
}
CleanupStack::PopAndDestroy(pEntry);
QMessagePrivate* privateMessage = QMessagePrivate::implementation(message);
privateMessage->_id = id;
privateMessage->_modified = false;
return message;
}
bool CMTMEngine::storeMMS(QMessage &message)
{
if (!iSessionReady) {
return false;
}
TRAPD(err, storeMMSL(message));
if (err != KErrNone) {
return false;
}
return true;
}
bool CMTMEngine::sendMMS(QMessage &message)
{
if (!iSessionReady) {
return false;
}
TRAPD(err, sendMMSL(message));
if (err != KErrNone) {
return false;
}
return true;
}
bool CMTMEngine::storeEmail(QMessage &message)
{
if (!iSessionReady) {
return false;
}
TRAPD(err, storeEmailL(message));
if (err != KErrNone) {
return false;
}
return true;
}
bool CMTMEngine::sendEmail(QMessage &message)
{
if (!iSessionReady) {
return false;
}
TRAPD(err, sendEmailL(message));
if (err != KErrNone) {
return false;
}
return true;
}
bool CMTMEngine::storeSMS(QMessage &message)
{
if (!iSessionReady)
return false;
TRAPD(err, storeSMSL(message));
if (err != KErrNone) {
return false;
}
return true;
}
void CMTMEngine::storeSMSL(QMessage &message)
{
if (!iSessionReady) {
User::Leave(KErrNotReady);
}
TMsvId destinationFolderId;
if (message.parentFolderId().isValid()) {
destinationFolderId = folderIdFromQMessageFolderId(message.parentFolderId());
} else {
// parentFolderId was not defined for new Message
// => Message will be created into defined standard Folder (Default value is Drafts Folder)
destinationFolderId = standardFolderId(message.standardFolder());
}
// Current entry is the Draft folder.
ipSmsMtm->SwitchCurrentEntryL(destinationFolderId);
// Create a new SMS message entry as a child of the current context.
ipSmsMtm->CreateMessageL(KUidMsgTypeSMS.iUid);
TMsvEntry entry = ipSmsMtm->Entry().Entry();
switch (message.priority()) {
case QMessage::HighPriority:
entry.SetPriority(EMsvHighPriority);
break;
case QMessage::NormalPriority:
entry.SetPriority(EMsvMediumPriority);
break;
case QMessage::LowPriority:
entry.SetPriority(EMsvLowPriority);
break;
}
if (message.status() & QMessage::Read) {
entry.SetUnread(false);
entry.SetNew(false);
} else {
entry.SetUnread(true);
entry.SetNew(true);
}
ipSmsMtm->Entry().ChangeL(entry);
QList<QMessageAddress> list(message.to());
if (!list.empty()){
TPtrC16 receiver(KNullDesC);
QString qreceiver;
for (int i = 0; i < list.size(); ++i) {
qreceiver = list.at(i).addressee();
receiver.Set(reinterpret_cast<const TUint16*>(qreceiver.utf16()));
ipSmsMtm->AddAddresseeL(receiver);
ipSmsMtm->SaveMessageL();
}
}
CMsvStore* store = ipSmsMtm->Entry().EditStoreL();
CleanupStack::PushL(store);
QString body = message.textContent();
if (!body.isEmpty()){
TPtrC16 msg(reinterpret_cast<const TUint16*>(body.utf16()));
if (!ipRichText) {
ipCharFormatLayer = CCharFormatLayer::NewL();
ipParaFormatLayer = CParaFormatLayer::NewL();
ipRichText=CRichText::NewL(ipParaFormatLayer,ipCharFormatLayer);
}
ipRichText->Reset();
ipRichText->InsertL(0, msg);
store->StoreBodyTextL(*ipRichText);
store->CommitL();
}
CleanupStack::PopAndDestroy(store);
QMessagePrivate* privateMessage = QMessagePrivate::implementation(message);
privateMessage->_id = QMessageId(QString::number(entry.Id()));
if (!message.receivedDate().isNull() || !message.date().isNull()) {
// Change the date to given date
CMsvEntry* pEntry = ipMsvSession->GetEntryL(entry.Id());
CleanupStack::PushL(pEntry);
TMsvEntry changedEntry = pEntry->Entry();
if (!message.date().isNull()) {
changedEntry.iDate = qDateTimeToSymbianTTime(message.date());
} else {
changedEntry.iDate = qDateTimeToSymbianTTime(message.receivedDate());
}
pEntry->ChangeL(changedEntry);
CleanupStack::PopAndDestroy(pEntry);
}
}
bool CMTMEngine::sendSMS(QMessage &message)
{
if (!iSessionReady) {
return false;
}
TRAPD(err, sendSMSL(message));
if (err != KErrNone) {
return false;
}
return true;
}
void CMTMEngine::sendSMSL(QMessage &message)
{
if (!iSessionReady) {
User::Leave(KErrNotReady);
}
if (!message.id().isValid()) {
QMessagePrivate::setStandardFolder(message, QMessage::DraftsFolder);
storeSMSL(message);
}
long int messageId = message.id().toString().toLong();
if (messageId == 0) {
User::Leave(KErrNotReady);
}
CMsvEntry* pMsvEntry = retrieveCMsvEntryAndPushToCleanupStack(messageId);
CMsvOperationWait* pMsvOperationWait = CMsvOperationWait::NewLC();
ipSmsMtm->SwitchCurrentEntryL(pMsvEntry->Entry().Parent());
// Following sends SMS and _moves_ SMS from Drafts Folder to Sent Folder
CMsvOperation* pMsvOperation = ipSmsMtm->Entry().CopyL(messageId, ipSmsMtm->ServiceId(), pMsvOperationWait->iStatus);
pMsvOperationWait->Start();
CActiveScheduler::Start();
delete pMsvOperation;
CleanupStack::PopAndDestroy(pMsvOperationWait);
releaseCMsvEntryAndPopFromCleanupStack(pMsvEntry);
}
void CMTMEngine::storeMMSL(QMessage &message)
{
if (!iSessionReady) {
User::Leave(KErrNotReady);
}
TMsvId destinationFolderId;
if (message.parentFolderId().isValid()) {
destinationFolderId = folderIdFromQMessageFolderId(message.parentFolderId());
} else {
// parentFolderId was not defined for new Message
// => Message will be created into defined standard Folder (Default value is Drafts Folder)
destinationFolderId = standardFolderId(message.standardFolder());
}
CMsvOperationWait* wait = CMsvOperationWait::NewLC();
wait->Start();
CMsvOperation* operation = ipMmsMtm->CreateNewEntryL(destinationFolderId, wait->iStatus);
CleanupStack::PushL(operation);
CActiveScheduler::Start();
if (wait->iStatus.Int() != KErrNone){
//TODO: handle error
}
TPckgBuf<TMsvId> pkg;
pkg.Copy( operation->ProgressL());
TMsvId indexEntry= pkg();
CleanupStack::PopAndDestroy(2); // operation and wait
ipMmsMtm->SwitchCurrentEntryL(indexEntry);
ipMmsMtm->LoadMessageL();
// Add receivers
QList<QMessageAddress> list(message.to());
TPtrC16 receiver(KNullDesC);
QString qreceiver;
for (int i = 0; i < list.size(); ++i) {
qreceiver = list.at(i).addressee();
receiver.Set(reinterpret_cast<const TUint16*>(qreceiver.utf16()));
ipMmsMtm->AddAddresseeL(receiver);
}
// Set Subject
QString subject = message.subject();
TPtrC16 sbj(reinterpret_cast<const TUint16*>(subject.utf16()));
ipMmsMtm->SetSubjectL(sbj);
TMsvEntry ent = ipMmsMtm->Entry().Entry();
ent.SetInPreparation(EFalse);
ent.SetVisible(ETrue);
switch (message.priority()) {
case QMessage::HighPriority:
ent.SetPriority(EMsvHighPriority);
break;
case QMessage::NormalPriority:
ent.SetPriority(EMsvMediumPriority);
break;
case QMessage::LowPriority:
ent.SetPriority(EMsvLowPriority);
break;
}
if (message.status() & QMessage::Read) {
ent.SetUnread(false);
ent.SetNew(false);
} else {
ent.SetUnread(true);
ent.SetNew(true);
}
ipMmsMtm->Entry().ChangeL(ent);
// Save the changes
ipMmsMtm->SaveMessageL();
CMsvStore* store = ipMmsMtm->Entry().EditStoreL();
CleanupStack::PushL(store);
// attachments.
QByteArray filePath;
QMessageContentContainerIdList contentIds = message.contentIds();
foreach (QMessageContentContainerId id, contentIds){
QMessageContentContainer container = message.find(id);
filePath = QMessageContentContainerPrivate::attachmentFilename(container);
QString body = container.textContent();
if (!filePath.isEmpty()) { // content is attachment
int last = filePath.lastIndexOf("/");
int count = filePath.count();
QByteArray name = filePath.right(count-last-1);
QString fileName = QString(name);
filePath.replace(QByteArray("/"), QByteArray("\\"));
QString temp_path = QString(filePath);
TPtrC16 attachmentPath(KNullDesC);
attachmentPath.Set(reinterpret_cast<const TUint16*>(temp_path.utf16()));
TFileName attachmentFile;
attachmentFile.Append(attachmentPath);
RFile attachment;
User::LeaveIfError(attachment.Open(FsSession(),attachmentFile, EFileShareReadersOnly | EFileRead));
CleanupClosePushL(attachment);
TInt fileSize;
attachment.Size(fileSize);
TInt maxFileSize = 600000;
if (fileSize > maxFileSize){
return;
}
HBufC8* pFileContent = HBufC8::NewL(fileSize);
TPtr8 fileContent(pFileContent->Des());
attachment.Read(fileContent);
attachment.Close();
CleanupStack::PushL(pFileContent);
RFile file2;
TFileName tempFileName;
RFs fileServer;
User::LeaveIfError(fileServer.Connect());
CleanupClosePushL(fileServer);
TInt err = file2.Temp(fileServer,iPath,tempFileName,EFileWrite);
if (err != KErrNone){
return;
}
CleanupClosePushL(file2);
err = file2.Write(*pFileContent);
if (err != KErrNone){
return;
}
file2.Close();
User::LeaveIfError(file2.Open(FsSession(),tempFileName, EFileShareAny|EFileRead));
// Mime header
CMsvMimeHeaders* mimeHeaders = CMsvMimeHeaders::NewL();
CleanupStack::PushL(mimeHeaders);
TPtrC16 suggestedName(reinterpret_cast<const TUint16*>(fileName.utf16()));
mimeHeaders->SetSuggestedFilenameL(suggestedName);
// Represents a single attachment and information about the attachment
CMsvAttachment* attaInfo = CMsvAttachment::NewL(CMsvAttachment::EMsvFile);
CleanupStack::PushL(attaInfo);
// Mime Type
QByteArray content = container.contentType();
if (content.isEmpty()){
RApaLsSession session;
//TPtrC16 filePtr(reinterpret_cast<const TUint16*>(fileString.utf16()));
TBuf8<20> fileType;
if(session.Connect() == KErrNone){
TDataRecognitionResult fileDataType;
session.RecognizeData(tempFileName, *pFileContent, *&fileDataType);
fileType.Copy(fileDataType.iDataType.Des8());
content = QByteArray((const char*)fileType.Ptr(), fileType.Length());
session.Close();
}
}
else{
content.append("/");
content.append(container.contentSubType());
}
QString mime = QString(content);
TPtrC16 mType(reinterpret_cast<const TUint16*>(mime.utf16()));
HBufC8* mimeType = CnvUtfConverter::ConvertFromUnicodeToUtf8L(mType);
TMsvAttachmentId attachId = KMsvNullIndexEntryId;
ipMmsMtm->CreateAttachment2L(*store, file2, *mimeType, *mimeHeaders, attaInfo, attachId);
store->CommitL();
file2.Close();
CleanupStack::Pop(attaInfo);
CleanupStack::PopAndDestroy(mimeHeaders);
CleanupStack::Pop(&file2);
CleanupStack::PopAndDestroy(&fileServer);
CleanupStack::PopAndDestroy(pFileContent);
CleanupStack::PopAndDestroy(); //attachment
}
else if (!body.isEmpty()) { // Add body
TPtrC16 msg(reinterpret_cast<const TUint16*>(body.utf16()));
TMsvAttachmentId attachmentid = KMsvNullIndexEntryId;
TFileName bodyFile( _L("body.txt") );
ipMmsMtm->CreateTextAttachmentL(*store, attachmentid, msg, bodyFile, ETrue);
store->CommitL();
}
}
QString messageBody = message.textContent();
if (!messageBody.isEmpty()) { // no contents, only body text
TPtrC16 msg(reinterpret_cast<const TUint16*>(messageBody.utf16()));
TMsvAttachmentId attachmentid = KMsvNullIndexEntryId;
TFileName bodyFile( _L("body.txt") );
ipMmsMtm->CreateTextAttachmentL(*store, attachmentid, msg, bodyFile, ETrue);
store->CommitL();
}
CleanupStack::PopAndDestroy(); // store
QMessagePrivate* privateMessage = QMessagePrivate::implementation(message);
privateMessage->_id = QMessageId(QString::number(indexEntry));
// Save the changes
ipMmsMtm->SaveMessageL();
if (!message.receivedDate().isNull() || !message.date().isNull()) {
// Change the date to given date
CMsvEntry* pEntry = ipMsvSession->GetEntryL(indexEntry);
CleanupStack::PushL(pEntry);
TMsvEntry changedEntry = pEntry->Entry();
if (!message.date().isNull()) {
changedEntry.iDate = qDateTimeToSymbianTTime(message.date());
} else {
changedEntry.iDate = qDateTimeToSymbianTTime(message.receivedDate());
}
pEntry->ChangeL(changedEntry);
CleanupStack::PopAndDestroy(pEntry);
}
}
void CMTMEngine::updateSMSL(QMessage &message)
{
if (!iSessionReady) {
User::Leave(KErrNotReady);
}
QMessageId id = message.id();
long int messageId = id.toString().toLong();
if (messageId == 0)
return;
CMsvEntry* entry = ipMsvSession->GetEntryL(messageId);
CleanupStack::PushL(entry);
ipSmsMtm->SwitchCurrentEntryL(messageId);
ipSmsMtm->LoadMessageL();
TMsvEntry tEntry = ipSmsMtm->Entry().Entry();
switch (message.priority()) {
case QMessage::HighPriority:
tEntry.SetPriority(EMsvHighPriority);
break;
case QMessage::NormalPriority:
tEntry.SetPriority(EMsvMediumPriority);
break;
case QMessage::LowPriority:
tEntry.SetPriority(EMsvLowPriority);
break;
}
if (message.status() & QMessage::Read) {
tEntry.SetUnread(false);
tEntry.SetNew(false);
} else {
tEntry.SetUnread(true);
tEntry.SetNew(true);
}
ipSmsMtm->Entry().ChangeL(tEntry);
// Save the changes
ipSmsMtm->SaveMessageL();
QList<QMessageAddress> list(message.to());
if (!list.empty()){
TPtrC16 receiver(KNullDesC);
QString qreceiver;
for (int i = 0; i < list.size(); ++i) {
qreceiver = list.at(i).addressee();
receiver.Set(reinterpret_cast<const TUint16*>(qreceiver.utf16()));
ipSmsMtm->AddAddresseeL(receiver);
ipSmsMtm->SaveMessageL();
}
}
CMsvStore* store = ipSmsMtm->Entry().EditStoreL();
CleanupStack::PushL(store);
QString body = message.textContent();
if (!body.isEmpty()){
TPtrC16 msg(reinterpret_cast<const TUint16*>(body.utf16()));
if (!ipRichText) {
ipCharFormatLayer = CCharFormatLayer::NewL();
ipParaFormatLayer = CParaFormatLayer::NewL();
ipRichText=CRichText::NewL(ipParaFormatLayer,ipCharFormatLayer);
}
ipRichText->Reset();
ipRichText->InsertL(0, msg);
store->StoreBodyTextL(*ipRichText);
store->CommitL();
}
CleanupStack::PopAndDestroy(2); // store, entry
if (!message.receivedDate().isNull() || !message.date().isNull()) {
// Change the date to given date
CMsvEntry* pEntry = ipMsvSession->GetEntryL(messageId);
CleanupStack::PushL(pEntry);
TMsvEntry changedEntry = pEntry->Entry();
if (!message.date().isNull()) {
changedEntry.iDate = qDateTimeToSymbianTTime(message.date());
} else {
changedEntry.iDate = qDateTimeToSymbianTTime(message.receivedDate());
}
pEntry->ChangeL(changedEntry);
CleanupStack::PopAndDestroy(pEntry);
}
}
void CMTMEngine::updateMMSL(QMessage &message)
{
if (!iSessionReady) {
User::Leave(KErrNotReady);
}
QMessageId id = message.id();
long int messageId = id.toString().toLong();
if (messageId == 0)
return;
ipMmsMtm->SwitchCurrentEntryL(messageId);
ipMmsMtm->LoadMessageL();
// Add receivers
QList<QMessageAddress> list(message.to());
if (!list.empty()){
TPtrC16 receiver(KNullDesC);
QString qreceiver;
for (int i = 0; i < list.size(); ++i) {
qreceiver = list.at(i).addressee();
receiver.Set(reinterpret_cast<const TUint16*>(qreceiver.utf16()));
ipMmsMtm->AddAddresseeL(receiver);
}
}
// Set Subject
QString subject = message.subject();
if (!subject.isEmpty()){
TPtrC16 sbj(reinterpret_cast<const TUint16*>(subject.utf16()));
ipMmsMtm->SetSubjectL(sbj);
}
TMsvEntry ent = ipMmsMtm->Entry().Entry();
ent.SetInPreparation(EFalse);
ent.SetVisible(ETrue);
switch (message.priority()) {
case QMessage::HighPriority:
ent.SetPriority(EMsvHighPriority);
break;
case QMessage::NormalPriority:
ent.SetPriority(EMsvMediumPriority);
break;
case QMessage::LowPriority:
ent.SetPriority(EMsvLowPriority);
break;
}
if (message.status() & QMessage::Read) {
ent.SetUnread(false);
ent.SetNew(false);
} else {
ent.SetUnread(true);
ent.SetNew(true);
}
ipMmsMtm->Entry().ChangeL(ent);
// Save the changes
ipMmsMtm->SaveMessageL();
CMsvStore* store = ipMmsMtm->Entry().EditStoreL();
CleanupStack::PushL(store);
// attachments.
QByteArray filePath;
QMessageContentContainerIdList contentIds = message.contentIds();
foreach (QMessageContentContainerId id, contentIds){
QMessageContentContainer container = message.find(id);
QMessageContentContainerPrivate* pPrivateContainer = QMessageContentContainerPrivate::implementation(container);
filePath = QMessageContentContainerPrivate::attachmentFilename(container);
if (!filePath.isEmpty()) { // content is attachment
int last = filePath.lastIndexOf("/");
int count = filePath.count();
QByteArray name = filePath.right(count-last-1);
QString fileName = QString(name);
filePath.replace(QByteArray("/"), QByteArray("\\"));
QString temp_path = QString(filePath);
TPtrC16 attachmentPath(KNullDesC);
attachmentPath.Set(reinterpret_cast<const TUint16*>(temp_path.utf16()));
TFileName attachmentFile;
attachmentFile.Append(attachmentPath);
RFile attachment;
User::LeaveIfError(attachment.Open(FsSession(),attachmentFile, EFileShareReadersOnly | EFileRead));
CleanupClosePushL(attachment);
TInt fileSize;
attachment.Size(fileSize);
TInt maxFileSize = 600000;
if (fileSize > maxFileSize){
return;
}
HBufC8* pFileContent = HBufC8::NewL(fileSize);
TPtr8 fileContent(pFileContent->Des());
attachment.Read(fileContent);
attachment.Close();
CleanupStack::PushL(pFileContent);
RFile file2;
TFileName tempFileName;
RFs fileServer;
User::LeaveIfError(fileServer.Connect());
CleanupClosePushL(fileServer);
TInt err = file2.Temp(fileServer,iPath,tempFileName,EFileWrite);
if (err != KErrNone){
return;
}
CleanupClosePushL(file2);
err = file2.Write(*pFileContent);
if (err != KErrNone){
return;
}
file2.Close();
User::LeaveIfError(file2.Open(FsSession(),tempFileName, EFileShareAny|EFileRead));
// Mime header
CMsvMimeHeaders* mimeHeaders = CMsvMimeHeaders::NewL();
CleanupStack::PushL(mimeHeaders);
TPtrC16 suggestedName(reinterpret_cast<const TUint16*>(fileName.utf16()));
mimeHeaders->SetSuggestedFilenameL(suggestedName);
// Represents a single attachment and information about the attachment
CMsvAttachment* attaInfo = CMsvAttachment::NewL(CMsvAttachment::EMsvFile);
CleanupStack::PushL(attaInfo);
// Mime Type
QByteArray content = container.contentType();
if (content.isEmpty()){
RApaLsSession session;
TBuf8<20> fileType;
if(session.Connect() == KErrNone){
TDataRecognitionResult fileDataType;
session.RecognizeData(tempFileName, *pFileContent, *&fileDataType);
fileType.Copy(fileDataType.iDataType.Des8());
content = QByteArray((const char*)fileType.Ptr(), fileType.Length());
session.Close();
}
}
else{
content.append("/");
content.append(container.contentSubType());
}
QString mime = QString(content);
TPtrC16 mType(reinterpret_cast<const TUint16*>(mime.utf16()));
HBufC8* mimeType = CnvUtfConverter::ConvertFromUnicodeToUtf8L(mType);
TMsvAttachmentId attachId = KMsvNullIndexEntryId;
ipMmsMtm->CreateAttachment2L(*store, file2, *mimeType, *mimeHeaders, attaInfo, attachId);
store->CommitL();
file2.Close();
CleanupStack::Pop(attaInfo);
CleanupStack::PopAndDestroy(mimeHeaders);
CleanupStack::Pop(&file2);
CleanupStack::PopAndDestroy(&fileServer);
CleanupStack::PopAndDestroy(pFileContent);
CleanupStack::PopAndDestroy(); //attachment
}
else if (pPrivateContainer->_id == message.bodyId()) { // content is body text
QString body = container.textContent();
TPtrC16 msg(reinterpret_cast<const TUint16*>(body.utf16()));
TMsvAttachmentId attachmentid = KMsvNullIndexEntryId;
TFileName bodyFile( _L("body.txt") );
ipMmsMtm->CreateTextAttachmentL(*store, attachmentid, msg, bodyFile, ETrue);
store->CommitL();
}
}
QString messageBody = message.textContent();
if (!messageBody.isEmpty()) { // no contents, only body text
TPtrC16 msg(reinterpret_cast<const TUint16*>(messageBody.utf16()));
TMsvAttachmentId attachmentid = KMsvNullIndexEntryId;
TFileName bodyFile( _L("body.txt") );
ipMmsMtm->CreateTextAttachmentL(*store, attachmentid, msg, bodyFile, ETrue);
store->CommitL();
}
CleanupStack::PopAndDestroy(); // store
// Save the changes
ipMmsMtm->SaveMessageL();
if (!message.receivedDate().isNull() || !message.date().isNull()) {
// Change the date to given date
CMsvEntry* pEntry = ipMsvSession->GetEntryL(messageId);
CleanupStack::PushL(pEntry);
TMsvEntry changedEntry = pEntry->Entry();
if (!message.date().isNull()) {
changedEntry.iDate = qDateTimeToSymbianTTime(message.date());
} else {
changedEntry.iDate = qDateTimeToSymbianTTime(message.receivedDate());
}
pEntry->ChangeL(changedEntry);
CleanupStack::PopAndDestroy(pEntry);
}
}
void CMTMEngine::updateEmailL(QMessage &message)
{
if (!iSessionReady) {
User::Leave(KErrNotReady);
}
QMessageId id = message.id();
long int messageId = id.toString().toLong();
if (messageId == 0)
return;
CMsvEntry* pEntry = ipMsvSession->GetEntryL(messageId);
TUid mtmUid = pEntry->Entry().iMtm;
delete pEntry;
TMsvEntry msvEntry;
if (mtmUid == KUidMsgTypeSMTP) {
ipSmtpMtm->SwitchCurrentEntryL(messageId);
ipSmtpMtm->LoadMessageL();
msvEntry = ipSmtpMtm->Entry().Entry();
} else if (mtmUid == KUidMsgTypePOP3) {
ipPop3Mtm->SwitchCurrentEntryL(messageId);
ipPop3Mtm->LoadMessageL();
msvEntry = ipPop3Mtm->Entry().Entry();
} else if (mtmUid == KUidMsgTypeIMAP4) {
ipImap4Mtm->SwitchCurrentEntryL(messageId);
ipImap4Mtm->LoadMessageL();
msvEntry = ipImap4Mtm->Entry().Entry();
}
switch (message.priority()) {
case QMessage::HighPriority:
msvEntry.SetPriority(EMsvHighPriority);
break;
case QMessage::NormalPriority:
msvEntry.SetPriority(EMsvMediumPriority);
break;
case QMessage::LowPriority:
msvEntry.SetPriority(EMsvLowPriority);
break;
}
if (message.status() & QMessage::Read) {
msvEntry.SetUnread(false);
msvEntry.SetNew(false);
} else {
msvEntry.SetUnread(true);
msvEntry.SetNew(true);
}
msvEntry.iDescription.Set(TPtrC(reinterpret_cast<const TUint16*>(message.subject().utf16())));
msvEntry.iDetails.Set(TPtrC(reinterpret_cast<const TUint16*>(message.from().addressee().utf16())));
if (mtmUid == KUidMsgTypeSMTP) {
ipSmtpMtm->Entry().ChangeL(msvEntry);
} else {
CMsvOperationWait* pMsvOperationWait = CMsvOperationWait::NewLC();
CMsvOperation* pMsvOperation = NULL;
if (mtmUid == KUidMsgTypePOP3) {
pMsvOperation = ipPop3Mtm->Entry().ChangeL(msvEntry, pMsvOperationWait->iStatus);
} else {
pMsvOperation = ipImap4Mtm->Entry().ChangeL(msvEntry, pMsvOperationWait->iStatus);
}
pMsvOperationWait->Start();
CActiveScheduler::Start();
delete pMsvOperation;
CleanupStack::PopAndDestroy(pMsvOperationWait);
}
// Save the changes
ipSmtpMtm->SaveMessageL();
CMsvEntry* entry = ipMsvSession->GetEntryL(messageId);
CleanupStack::PushL(entry);
CImEmailMessage* mailMsg = CImEmailMessage::NewLC(*entry);
CMsvOperationWait* waiter = CMsvOperationWait::NewLC();
CImMimeHeader* mime = CImMimeHeader::NewLC();
QByteArray filePath;
QMessageContentContainerIdList contentIds = message.contentIds();
foreach (QMessageContentContainerId id, contentIds){
QMessageContentContainer container = message.find(id);
QMessageContentContainerPrivate* pPrivateContainer = QMessageContentContainerPrivate::implementation(container);
filePath = QMessageContentContainerPrivate::attachmentFilename(container);
if (!filePath.isEmpty()) { // content is attachment
filePath.replace(QByteArray("/"), QByteArray("\\"));
QString temp_path = QString(filePath);
TPtrC16 attachmentPath(KNullDesC);
attachmentPath.Set(reinterpret_cast<const TUint16*>(temp_path.utf16()));
TFileName attachmentFile;
attachmentFile.Append(attachmentPath);
RFile attachment;
User::LeaveIfError(attachment.Open(FsSession(),attachmentFile, EFileShareReadersOnly | EFileRead));
CleanupClosePushL(attachment);
CMsvAttachment* attachmentInfo = CMsvAttachment::NewL(CMsvAttachment::EMsvFile);
QByteArray filePath = QMessageContentContainerPrivate::attachmentFilename(container);
int last = filePath.lastIndexOf("/");
int count = filePath.count();
QByteArray name = filePath.right(count-last-1);
QString fileName = QString(name);
CleanupStack::PushL(attachmentInfo);
attachmentInfo->SetAttachmentNameL(TPtrC(reinterpret_cast<const TUint16*>(fileName.utf16())));
mailMsg->AttachmentManager().AddAttachmentL(attachment, attachmentInfo, waiter->iStatus);
waiter->Start();
CActiveScheduler::Start();
CleanupStack::Pop(attachmentInfo);
CleanupStack::Pop(&attachment); // close file
} else if (pPrivateContainer->_id == message.bodyId()) { // content is body text
CParaFormatLayer* paragraphFormatLayer = CParaFormatLayer::NewL();
CleanupStack::PushL(paragraphFormatLayer);
CCharFormatLayer* characterFormatLayer = CCharFormatLayer::NewL();
CleanupStack::PushL(characterFormatLayer);
CRichText* bodyText = CRichText::NewL(paragraphFormatLayer, characterFormatLayer, CEditableText::EFlatStorage, 256);
CleanupStack::PushL(bodyText);
//content type
QByteArray contentType = container.contentType();
TPtrC8 content((TUint8 *)(contentType.constData()));
mime->SetContentTypeL(content);
// content subtype
QByteArray subType = container.contentSubType();
TPtrC8 contentSubType((TUint8 *)(subType.constData()));
mime->SetContentSubTypeL(contentSubType);
// content charset
QByteArray charset = container.contentCharset();
if (charset == "UTF-8") {
mime->SetMimeCharset(KCharacterSetIdentifierUtf8);
}
if (charset == "UTF-16") {
mime->SetMimeCharset(KCharacterSetIdentifierUcs2);
}
// Insert the contents of a buffer into the document at specified position
bodyText->InsertL(0, TPtrC(reinterpret_cast<const TUint16*>(container.textContent().utf16())));
mailMsg->StoreBodyTextWithMimeHeaderL(messageId, *bodyText, *mime, waiter->iStatus);
waiter->Start();
CActiveScheduler::Start();
CleanupStack::PopAndDestroy(3); // bodyText, characterFormatLayer, paragraphFormatLayer
}
}
QString messageBody = message.textContent();
if (!messageBody.isEmpty()) {
CParaFormatLayer* paragraphFormatLayer = CParaFormatLayer::NewL();
CleanupStack::PushL(paragraphFormatLayer);
CCharFormatLayer* characterFormatLayer = CCharFormatLayer::NewL();
CleanupStack::PushL(characterFormatLayer);
CRichText* bodyText = CRichText::NewL(paragraphFormatLayer, characterFormatLayer, CEditableText::EFlatStorage, 256);
CleanupStack::PushL(bodyText);
//content type
QByteArray contentType = message.contentType();
TPtrC8 content((TUint8 *)(contentType.constData()));
mime->SetContentTypeL(content);
// content subtype
QByteArray subType = message.contentSubType();
TPtrC8 contentSubType((TUint8 *)(subType.constData()));
mime->SetContentSubTypeL(contentSubType);
// content charset
QByteArray charset = message.contentCharset();
if (charset == "UTF-8") {
mime->SetMimeCharset(KCharacterSetIdentifierUtf8);
}
if (charset == "UTF-16") {
mime->SetMimeCharset(KCharacterSetIdentifierUcs2);
}
// Insert the contents of a buffer into the document at specified position
bodyText->InsertL(0, TPtrC(reinterpret_cast<const TUint16*>(message.textContent().utf16())));
mailMsg->StoreBodyTextWithMimeHeaderL(messageId, *bodyText, *mime, waiter->iStatus);
waiter->Start();
CActiveScheduler::Start();
CleanupStack::PopAndDestroy(3);
//bodyText, characterFormatLayer, paragraphFormatLayer,
}
CMsvStore* store = entry->EditStoreL();
CleanupStack::PushL(store);
CImHeader* emailEntry = CImHeader::NewLC();
TRAP_IGNORE(emailEntry->RestoreL(*store));
mime->StoreL(*store);
emailEntry->SetSubjectL(TPtrC(reinterpret_cast<const TUint16*>(message.subject().utf16())));
QList<QMessageAddress> toList(message.to());
if (toList.count() > 0){
TPtrC16 receiver(KNullDesC);
QString qreceiver;
for (int i = 0; i < toList.size(); ++i) {
qreceiver = toList.at(i).addressee();
receiver.Set(reinterpret_cast<const TUint16*>(qreceiver.utf16()));
emailEntry->ToRecipients().AppendL(receiver);
}
}
QList<QMessageAddress> ccList(message.cc());
if (ccList.count() > 0){
TPtrC16 receiver(KNullDesC);
QString qreceiver;
for (int i = 0; i < ccList.size(); ++i) {
qreceiver = ccList.at(i).addressee();
receiver.Set(reinterpret_cast<const TUint16*>(qreceiver.utf16()));
emailEntry->CcRecipients().AppendL(receiver);
}
}
QList<QMessageAddress> bccList(message.bcc());
if (bccList.count() > 0){
TPtrC16 receiver(KNullDesC);
QString qreceiver;
for (int i = 0; i < bccList.size(); ++i) {
qreceiver = bccList.at(i).addressee();
receiver.Set(reinterpret_cast<const TUint16*>(qreceiver.utf16()));
emailEntry->BccRecipients().AppendL(receiver);
}
}
emailEntry->StoreL(*store);
// Store the changes permanently
store->CommitL();
CleanupStack::PopAndDestroy(6, entry);
// mailMsg, emailEntry, store, waiter, entry, mime
if (!message.receivedDate().isNull() || !message.date().isNull()) {
// Change the date to given date
CMsvEntry* pEntry = ipMsvSession->GetEntryL(messageId);
CleanupStack::PushL(pEntry);
TMsvEntry changedEntry = pEntry->Entry();
if (!message.date().isNull()) {
changedEntry.iDate = qDateTimeToSymbianTTime(message.date());
} else {
changedEntry.iDate = qDateTimeToSymbianTTime(message.receivedDate());
}
if (mtmUid == KUidMsgTypeSMTP) {
ipSmtpMtm->Entry().ChangeL(changedEntry);
} else {
CMsvOperationWait* pMsvOperationWait = CMsvOperationWait::NewLC();
CMsvOperation* pMsvOperation = NULL;
if (mtmUid == KUidMsgTypePOP3) {
pMsvOperation = ipPop3Mtm->Entry().ChangeL(changedEntry, pMsvOperationWait->iStatus);
} else {
pMsvOperation = ipImap4Mtm->Entry().ChangeL(changedEntry, pMsvOperationWait->iStatus);
}
pMsvOperationWait->Start();
CActiveScheduler::Start();
delete pMsvOperation;
CleanupStack::PopAndDestroy(pMsvOperationWait);
}
CleanupStack::PopAndDestroy(pEntry);
}
}
void CMTMEngine::sendMMSL(QMessage &message)
{
if (!iSessionReady) {
User::Leave(KErrNotReady);
}
bool messageCreated = false;
if (!message.id().isValid()) {
QMessagePrivate::setStandardFolder(message, QMessage::OutboxFolder);
storeMMSL(message);
messageCreated = true;
}
long int messageId = message.id().toString().toLong();
if (messageId == 0) {
User::Leave(KErrNotReady);
}
CMsvEntry* pMsvEntry = retrieveCMsvEntryAndPushToCleanupStack(messageId);
CMsvOperationWait* pMsvOperationWait = CMsvOperationWait::NewLC();
CMsvOperation* pMsvOperation = NULL;
if (!messageCreated) {
ipMmsMtm->SwitchCurrentEntryL(pMsvEntry->Entry().Parent());
pMsvOperation = ipMmsMtm->Entry().CopyL(messageId, KMsvGlobalOutBoxIndexEntryId, pMsvOperationWait->iStatus);
pMsvOperationWait->Start();
CActiveScheduler::Start();
delete pMsvOperation;
pMsvOperation = NULL;
}
// Start sending the message via the Server MTM to the MMS server
CMsvEntrySelection* pMsvEntrySelection = new(ELeave) CMsvEntrySelection;
pMsvEntrySelection->AppendL(messageId);
ipMmsMtm->SwitchCurrentEntryL(KMsvGlobalOutBoxIndexEntryId);
pMsvOperation = ipMmsMtm->SendL(*pMsvEntrySelection, pMsvOperationWait->iStatus);
pMsvOperationWait->Start();
CActiveScheduler::Start();
delete pMsvOperation;
while (pMsvOperationWait->iStatus == KRequestPending) {
CActiveScheduler::Start();
}
CleanupStack::PopAndDestroy(pMsvOperationWait);
releaseCMsvEntryAndPopFromCleanupStack(pMsvEntry);
}
QString CMTMEngine::privateFolderPath()
{
// Take drive letter from Application full name (Note: TUidName is 10 characters long <=> TBuf<10>)
//TUidName applicationDrive;
//applicationDrive.Copy(CEikonEnv::Static()->EikAppUi()->Application()->AppFullName().Left(2));
// Get Application private folder path from FileSession
TPath applicationPrivateFolderPathWithoutDriveLetter;
FsSession().PrivatePath(applicationPrivateFolderPathWithoutDriveLetter);
// Combine drive letter and private folder path to complete path
TPath driveLetterAndPath;
driveLetterAndPath.Copy(_L("C:"));
driveLetterAndPath.Append(applicationPrivateFolderPathWithoutDriveLetter);
return QString::fromUtf16(driveLetterAndPath.Ptr(), driveLetterAndPath.Length());
}
void CMTMEngine::storeEmailL(QMessage &message)
{
if (!iSessionReady) {
User::Leave(KErrNotReady);
}
TMsvId destinationFolderId = 0;
TMsvId imapDestinationFolderId = 0;
if (message.parentFolderId().isValid()) {
destinationFolderId = folderIdFromQMessageFolderId(message.parentFolderId());
CMsvEntry* pMsvEntry = retrieveCMsvEntryAndPushToCleanupStack(destinationFolderId);
if (pMsvEntry->Entry().iMtm == KUidMsgTypeIMAP4 || pMsvEntry->Entry().iMtm == KUidMsgTypePOP3) {
// New IMAP or POP3 message can not be created to IMAP or POP3 service folder.
// => Create IMAP or POP3 message into Drafts folder instead
destinationFolderId = KMsvDraftEntryId;
if (pMsvEntry->Entry().iMtm == KUidMsgTypeIMAP4) {
// It's possible to copy newly created IMAP message from Drafts folder
// to IMAP service folder.
// Note: IMAP message can not be created directly to IMAP service folder.
imapDestinationFolderId = destinationFolderId;
}
}
releaseCMsvEntryAndPopFromCleanupStack(pMsvEntry);
} else {
// parentFolderId was not defined for new Message
// => Message will be created into defined standard Folder (Default value is Drafts Folder)
destinationFolderId = standardFolderId(message.standardFolder());
}
QMessageAccount messageAccount = this->account(message.parentAccountId());
CMsvOperationWait* pMsvOperationWait = CMsvOperationWait::NewLC();
TMsvEmailTypeList msvEmailTypeList = 0;
TMsvPartList msvPartList = 0;
if (message.status() & QMessage::HasAttachments == QMessage::HasAttachments) {
msvPartList = (KMsvMessagePartBody | KMsvMessagePartAttachments);
} else {
msvPartList = KMsvMessagePartBody;
}
CImEmailOperation* pImEmailOperation = CImEmailOperation::CreateNewL(pMsvOperationWait->iStatus, *ipMsvSession, destinationFolderId,
messageAccount.d_ptr->_service2EntryId, msvPartList,
msvEmailTypeList, KUidMsgTypeSMTP);
CleanupStack::PushL(pImEmailOperation);
pMsvOperationWait->Start();
CActiveScheduler::Start();
TMsvId newMessageId;
TPckgC<TMsvId> paramPack(newMessageId);
paramPack.Set(pImEmailOperation->ProgressL());
newMessageId = paramPack();
CleanupStack::PopAndDestroy(pImEmailOperation);
ipSmtpMtm->SwitchCurrentEntryL(newMessageId);
ipSmtpMtm->LoadMessageL();
TMsvEntry msvEntry = ipSmtpMtm->Entry().Entry();
switch (message.priority()) {
case QMessage::HighPriority:
msvEntry.SetPriority(EMsvHighPriority);
break;
case QMessage::NormalPriority:
msvEntry.SetPriority(EMsvMediumPriority);
break;
case QMessage::LowPriority:
msvEntry.SetPriority(EMsvLowPriority);
break;
}
if (message.status() & QMessage::Read) {
msvEntry.SetUnread(false);
msvEntry.SetNew(false);
} else {
msvEntry.SetUnread(true);
msvEntry.SetNew(true);
}
ipSmtpMtm->Entry().ChangeL(msvEntry);
ipSmtpMtm->SaveMessageL();
CMsvEntry* pMsvEntry = retrieveCMsvEntryAndPushToCleanupStack(newMessageId);
// Create email message MIME header
CImMimeHeader* pImMimeHeader = CImMimeHeader::NewLC();
QByteArray contentType = message.contentType();
TPtrC8 content((TUint8 *)(contentType.constData()));
pImMimeHeader->SetContentTypeL(content);
QByteArray subType = message.contentSubType();
TPtrC8 contentSubType((TUint8 *)(subType.constData()));
pImMimeHeader->SetContentSubTypeL(contentSubType);
QByteArray charset = message.contentCharset();
if (charset == "UTF-8") {
pImMimeHeader->SetMimeCharset(KCharacterSetIdentifierUtf8);
}
if (charset == "UTF-16") {
pImMimeHeader->SetMimeCharset(KCharacterSetIdentifierUcs2);
}
CImEmailMessage* pImEmailMessage = CImEmailMessage::NewL(*pMsvEntry);
CleanupStack::PushL(pImEmailMessage);
if (message.bodyId() == QMessageContentContainerPrivate::bodyContentId()) {
// Message contains only body (not attachments)
QString messageBody = message.textContent();
if (!messageBody.isEmpty()) {
CParaFormatLayer* pParaFormatLayer = CParaFormatLayer::NewL();
CleanupStack::PushL(pParaFormatLayer);
CCharFormatLayer* pCharFormatLayer = CCharFormatLayer::NewL();
CleanupStack::PushL(pCharFormatLayer);
CRichText* pBodyRichText = CRichText::NewL(pParaFormatLayer, pCharFormatLayer, CEditableText::EFlatStorage, 256);
CleanupStack::PushL(pBodyRichText);
// Insert the contents of a buffer into the document at specified position
pBodyRichText->InsertL(0, TPtrC(reinterpret_cast<const TUint16*>(message.textContent().utf16())));
// Note: Email message MIME header is same as Body MIME header
pImEmailMessage->StoreBodyTextWithMimeHeaderL(newMessageId, *pBodyRichText, *pImMimeHeader,
pMsvOperationWait->iStatus);
pMsvOperationWait->Start();
CActiveScheduler::Start();
CleanupStack::PopAndDestroy(pBodyRichText);
CleanupStack::PopAndDestroy(pCharFormatLayer);
CleanupStack::PopAndDestroy(pParaFormatLayer);
}
} else {
// Message contains body and attachments
QMessageContentContainerIdList contentIds = message.contentIds();
foreach (QMessageContentContainerId id, contentIds){
QMessageContentContainer container = message.find(id);
QMessageContentContainerPrivate* pPrivateContainer = QMessageContentContainerPrivate::implementation(container);
if (pPrivateContainer->_id == message.bodyId()) {
// ContentContainer is body
if (!container.textContent().isEmpty()) {
// Create MIME header for body
CImMimeHeader* pBodyImMimeHeader = CImMimeHeader::NewLC();
QByteArray contentType = container.contentType();
TPtrC8 content((TUint8 *)(contentType.constData()));
pBodyImMimeHeader->SetContentTypeL(content);
QByteArray subType = container.contentSubType();
TPtrC8 contentSubType((TUint8 *)(subType.constData()));
pBodyImMimeHeader->SetContentSubTypeL(contentSubType);
QByteArray charset = container.contentCharset();
if (charset == "UTF-8") {
pBodyImMimeHeader->SetMimeCharset(KCharacterSetIdentifierUtf8);
}
if (charset == "UTF-16") {
pBodyImMimeHeader->SetMimeCharset(KCharacterSetIdentifierUcs2);
}
// Create CRichText containing body text
CParaFormatLayer* pParaFormatLayer = CParaFormatLayer::NewL();
CleanupStack::PushL(pParaFormatLayer);
CCharFormatLayer* pCharFormatLayer = CCharFormatLayer::NewL();
CleanupStack::PushL(pCharFormatLayer);
CRichText* pBodyRichText = CRichText::NewL(pParaFormatLayer, pCharFormatLayer, CEditableText::EFlatStorage);
CleanupStack::PushL(pBodyRichText);
// Insert the contents of a buffer into the document at specified position
pBodyRichText->InsertL(0, TPtrC(reinterpret_cast<const TUint16*>(container.textContent().utf16())));
// Store MIME Header and Body text to message
pImEmailMessage->StoreBodyTextWithMimeHeaderL(newMessageId, *pBodyRichText, *pBodyImMimeHeader, pMsvOperationWait->iStatus);
pMsvOperationWait->Start();
CActiveScheduler::Start();
CleanupStack::PopAndDestroy(pBodyRichText);
CleanupStack::PopAndDestroy(pCharFormatLayer);
CleanupStack::PopAndDestroy(pParaFormatLayer);
CleanupStack::PopAndDestroy(pBodyImMimeHeader);
}
} else {
// ContentContainer is attachment
QByteArray filePath = QMessageContentContainerPrivate::attachmentFilename(container);
// Replace Qt style path separator "/" with Symbian path separator "\"
filePath.replace(QByteArray("/"), QByteArray("\\"));
// Make sure that "." folder is translated to application private folder
// For example: "." = "<drive letter>:\private\<application specific private folder>\"
if (filePath.startsWith('.')) {
filePath.remove(0,2); // Remove ".\"
filePath.insert(0,privateFolderPath().toAscii());
}
QString temp_path = QString(filePath);
TPtrC16 attachmentPath(KNullDesC);
attachmentPath.Set(reinterpret_cast<const TUint16*>(temp_path.utf16()));
TFileName attachmentFileName;
attachmentFileName.Append(attachmentPath);
RFile attachmentFile;
User::LeaveIfError(attachmentFile.Open(FsSession(), attachmentFileName,
EFileShareReadersOnly | EFileRead));
CleanupClosePushL(attachmentFile);
CMsvAttachment* pMsvAttachment = CMsvAttachment::NewL(CMsvAttachment::EMsvFile);
int last = filePath.lastIndexOf("\\");
int count = filePath.count();
QByteArray name = filePath.right(count-last-1);
QString fileName = QString(name);
CleanupStack::PushL(pMsvAttachment);
pMsvAttachment->SetAttachmentNameL(TPtrC(reinterpret_cast<const TUint16*>(fileName.utf16())));
// Note: Following call transfers ownership of attachmentFile and pMsvAttachment to AttachmentManager
pImEmailMessage->AttachmentManager().AddAttachmentL(attachmentFile, pMsvAttachment, pMsvOperationWait->iStatus);
pMsvOperationWait->Start();
CActiveScheduler::Start();
CleanupStack::Pop(pMsvAttachment); // Pop attachment from CleanupStack
CleanupStack::Pop(&attachmentFile); // Pop file from CleanupStack
}
}
}
CleanupStack::PopAndDestroy(pImEmailMessage);
CMsvStore* pMsvStore = pMsvEntry->EditStoreL();
CleanupStack::PushL(pMsvStore);
pImMimeHeader->StoreL(*pMsvStore);
CImHeader* pImHeader = CImHeader::NewLC();
pImHeader->RestoreL(*pMsvStore);
pImHeader->SetSubjectL(TPtrC(reinterpret_cast<const TUint16*>(message.subject().utf16())));
pImHeader->SetFromL(TPtrC(reinterpret_cast<const TUint16*>(message.from().addressee().utf16())));
QList<QMessageAddress> toList(message.to());
if (toList.count() > 0) {
TPtrC16 receiver(KNullDesC);
QString qreceiver;
for (int i = 0; i < toList.size(); ++i) {
qreceiver = toList.at(i).addressee();
receiver.Set(reinterpret_cast<const TUint16*>(qreceiver.utf16()));
pImHeader->ToRecipients().AppendL(receiver);
}
}
QList<QMessageAddress> ccList(message.cc());
if (ccList.count() > 0) {
TPtrC16 receiver(KNullDesC);
QString qreceiver;
for (int i = 0; i < ccList.size(); ++i) {
qreceiver = ccList.at(i).addressee();
receiver.Set(reinterpret_cast<const TUint16*>(qreceiver.utf16()));
pImHeader->CcRecipients().AppendL(receiver);
}
}
QList<QMessageAddress> bccList(message.bcc());
if (bccList.count() > 0) {
TPtrC16 receiver(KNullDesC);
QString qreceiver;
for (int i = 0; i < bccList.size(); ++i) {
qreceiver = bccList.at(i).addressee();
receiver.Set(reinterpret_cast<const TUint16*>(qreceiver.utf16()));
pImHeader->BccRecipients().AppendL(receiver);
}
}
pImHeader->StoreL(*pMsvStore);
CleanupStack::PopAndDestroy(pImHeader);
// Store the changes permanently
pMsvStore->CommitL();
CleanupStack::PopAndDestroy(pMsvStore);
CleanupStack::PopAndDestroy(pImMimeHeader);
TMsvEntry changedEntry = pMsvEntry->Entry();
changedEntry.iDescription.Set(TPtrC(reinterpret_cast<const TUint16*>(message.subject().utf16())));
if (toList.count() > 0) {
changedEntry.iDetails.Set(TPtrC(reinterpret_cast<const TUint16*>(toList.at(0).addressee().utf16())));
}
if (!message.receivedDate().isNull() || !message.date().isNull()) {
// Change the date to given date
if (!message.date().isNull()) {
changedEntry.iDate = qDateTimeToSymbianTTime(message.date());
} else {
changedEntry.iDate = qDateTimeToSymbianTTime(message.receivedDate());
}
}
pMsvEntry->ChangeL(changedEntry);
if (imapDestinationFolderId != 0) {
TMsvId parent = pMsvEntry->Entry().Parent();
ipImap4Mtm->SwitchCurrentEntryL(parent);
CMsvOperation* pMsvOperation = ipImap4Mtm->Entry().MoveL(newMessageId, imapDestinationFolderId,
pMsvOperationWait->iStatus);
CleanupStack::PushL(pMsvOperation);
pMsvOperationWait->Start();
CActiveScheduler::Start();
CleanupStack::PopAndDestroy(pMsvOperation);
}
releaseCMsvEntryAndPopFromCleanupStack(pMsvEntry);
CleanupStack::PopAndDestroy(pMsvOperationWait);
QMessagePrivate* privateMessage = QMessagePrivate::implementation(message);
privateMessage->_id = QMessageId(QString::number(newMessageId));
}
void CMTMEngine::sendEmailL(QMessage &message)
{
if (!iSessionReady) {
User::Leave(KErrNotReady);
}
QMessageAccountId accountId = message.parentAccountId();
QMessageAccount messageAccount;
if (accountId.isValid()) {
messageAccount = account(accountId);
} else {
accountId = defaultAccount(QMessage::Email);
messageAccount = account(accountId);
}
bool messageCreated = false;
if (!message.id().isValid()) {
// Message id is not valid
// => Message is not in message store
// => New message must be created into Outbox folder
QMessagePrivate::setStandardFolder(message, QMessage::OutboxFolder);
message.setParentAccountId(accountId);
storeEmailL(message);
messageCreated = true;
}
long int messageId = message.id().toString().toLong();
if (messageId == 0) {
User::Leave(KErrNotReady);
}
CMsvEntry* pMsvEntry = retrieveCMsvEntryAndPushToCleanupStack(messageId);
CMsvOperationWait* pMsvOperationWait = CMsvOperationWait::NewLC();
CMsvOperation* pMsvOperation = NULL;
if (!messageCreated) {
// Sending (old) message that's in message store
// => Copy message from its original location to Outbox folder
ipSmtpMtm->SwitchCurrentEntryL(pMsvEntry->Entry().Parent());
pMsvOperation = ipSmtpMtm->Entry().CopyL(messageId, KMsvGlobalOutBoxIndexEntryId, pMsvOperationWait->iStatus);
pMsvOperationWait->Start();
CActiveScheduler::Start();
delete pMsvOperation;
pMsvOperation = NULL;
}
ipSmtpMtm->SwitchCurrentEntryL(pMsvEntry->Entry().Parent());
// Following sends Email and _moves_ Email from Outbox Folder to Sent Folder
pMsvOperation = ipSmtpMtm->Entry().CopyL(messageId, messageAccount.d_ptr->_service2EntryId, pMsvOperationWait->iStatus);
pMsvOperationWait->Start();
CActiveScheduler::Start();
delete pMsvOperation;
CleanupStack::PopAndDestroy(pMsvOperationWait);
releaseCMsvEntryAndPopFromCleanupStack(pMsvEntry);
}
QDateTime CMTMEngine::symbianTTimetoQDateTime(const TTime& time) const
{
TDateTime dateTime = time.DateTime();
QDate qdate = QDate(dateTime.Year(), static_cast<int>(dateTime.Month())+1, dateTime.Day()+1);
QTime qtime = QTime(dateTime.Hour(), dateTime.Minute(), dateTime.Second(), dateTime.MicroSecond()/1000 );
return QDateTime(qdate, qtime, Qt::UTC);
}
TTime CMTMEngine::qDateTimeToSymbianTTime(const QDateTime& date) const
{
TDateTime dateTime;
dateTime.SetYear(date.date().year());
dateTime.SetMonth(static_cast<TMonth>(date.date().month()-1));
dateTime.SetDay(date.date().day()-1);
dateTime.SetHour(date.time().hour());
dateTime.SetMinute(date.time().minute());
dateTime.SetSecond(date.time().second());
dateTime.SetMicroSecond(date.time().msec()*1000);
return TTime(dateTime);
}
QMessage CMTMEngine::smsMessageL(CMsvEntry& receivedEntry, long int messageId) const
{
QMessage message;
int size = 0;
message.setType(QMessage::Sms);
CMsvStore* pStore = receivedEntry.ReadStoreL();
CleanupStack::PushL(pStore);
const TMsvEntry& entry = receivedEntry.Entry();
message.setDate(symbianTTimetoQDateTime(entry.iDate));
message.setReceivedDate(symbianTTimetoQDateTime(entry.iDate));
QMessageAccount account = accountsByType(QMessage::Sms)[0];
QMessagePrivate* privateMessage = QMessagePrivate::implementation(message);
privateMessage->_parentFolderId = createQMessageFolderId(account.d_ptr->_service1EntryId, entry.Parent());
privateMessage->_parentAccountId = account.id();
if (!entry.Unread()) {
privateMessage->_status = privateMessage->_status | QMessage::Read;
}
switch (entry.Priority()) {
case EMsvHighPriority:
message.setPriority(QMessage::HighPriority);
break;
case EMsvMediumPriority:
message.setPriority(QMessage::NormalPriority);
break;
case EMsvLowPriority:
message.setPriority(QMessage::LowPriority);
break;
}
if (entry.Parent() == KMsvGlobalInBoxIndexEntryId) {
QMessagePrivate::setStandardFolder(message,QMessage::InboxFolder);
} else if (entry.Parent() == KMsvDraftEntryId) {
QMessagePrivate::setStandardFolder(message,QMessage::DraftsFolder);
} else if (entry.Parent() == KMsvSentEntryId) {
QMessagePrivate::setStandardFolder(message,QMessage::SentFolder);
} else if (entry.Parent() == KMsvDeletedEntryFolderEntryId) {
QMessagePrivate::setStandardFolder(message,QMessage::TrashFolder);
}
// Read message sender
ipSmsMtm->SwitchCurrentEntryL(messageId);
ipSmsMtm->LoadMessageL();
CSmsHeader& header = ipSmsMtm->SmsHeader();
message.setFrom(QMessageAddress(QMessageAddress::Phone, QString::fromUtf16(header.FromAddress().Ptr(), header.FromAddress().Length())));
QMessagePrivate::setSenderName(message, QString::fromUtf16(header.FromAddress().Ptr(), header.FromAddress().Length()));
// Read message recipients
const CArrayPtrFlat<CSmsNumber>& array = header.Recipients();
QMessageAddressList messageAddresslist;
for (int i=0; i < array.Count(); i++) {
CSmsNumber* smsNumber = array.At(i);
TPtrC recipientNumber = smsNumber->Address();
messageAddresslist.append(QMessageAddress(QMessageAddress::Phone, QString::fromUtf16(recipientNumber.Ptr(), recipientNumber.Length())));
}
message.setTo(messageAddresslist);
// Read message body
if (pStore->HasBodyTextL()) {
if (!ipRichText) {
ipCharFormatLayer = CCharFormatLayer::NewL();
ipParaFormatLayer = CParaFormatLayer::NewL();
ipRichText=CRichText::NewL(ipParaFormatLayer, ipCharFormatLayer);
}
ipRichText->Reset();
pStore->RestoreBodyTextL(*ipRichText);
HBufC* pMessage = HBufC::NewLC(ipRichText->DocumentLength());
TPtr ptr2(pMessage->Des());
ipRichText->Extract(ptr2);
if (pMessage->Length() > 0) {
size += pMessage->Length();
message.setBody(QString::fromUtf16(pMessage->Ptr(), pMessage->Length()));
if (pMessage->Length() <= 100) {
message.setSubject(QString::fromUtf16(pMessage->Ptr(), pMessage->Length()));
} else {
message.setSubject(QString::fromUtf16(pMessage->Ptr(), 100));
}
}
CleanupStack::PopAndDestroy(pMessage);
}
CleanupStack::PopAndDestroy(pStore);
privateMessage->_size = size;
return message;
}
QMessage CMTMEngine::mmsMessageL(CMsvEntry& receivedEntry, long int messageId) const
{
QMessage message;
int size = 0;
message.setType(QMessage::Mms);
CMsvStore* pStore = receivedEntry.ReadStoreL();
CleanupStack::PushL(pStore);
const TMsvEntry& entry = receivedEntry.Entry();
message.setDate(symbianTTimetoQDateTime(entry.iDate));
message.setReceivedDate(symbianTTimetoQDateTime(entry.iDate));
QMessageAccount account = accountsByType(QMessage::Mms)[0];
QMessagePrivate* privateMessage = QMessagePrivate::implementation(message);
privateMessage->_parentFolderId = createQMessageFolderId(account.d_ptr->_service1EntryId, entry.Parent());
privateMessage->_parentAccountId = account.id();
if (!entry.Unread()) {
privateMessage->_status = privateMessage->_status | QMessage::Read;
}
switch (entry.Priority()) {
case EMsvHighPriority:
message.setPriority(QMessage::HighPriority);
break;
case EMsvMediumPriority:
message.setPriority(QMessage::NormalPriority);
break;
case EMsvLowPriority:
message.setPriority(QMessage::LowPriority);
break;
}
if (entry.Parent() == KMsvGlobalInBoxIndexEntryId) {
QMessagePrivate::setStandardFolder(message,QMessage::InboxFolder);
} else if (entry.Parent() == KMsvDraftEntryId) {
QMessagePrivate::setStandardFolder(message,QMessage::DraftsFolder);
} else if (entry.Parent() == KMsvSentEntryId) {
QMessagePrivate::setStandardFolder(message,QMessage::SentFolder);
} else if (entry.Parent() == KMsvDeletedEntryFolderEntryId) {
QMessagePrivate::setStandardFolder(message,QMessage::TrashFolder);
}
// Read message sender
ipMmsMtm->SwitchCurrentEntryL(messageId);
ipMmsMtm->LoadMessageL();
message.setFrom(QMessageAddress(QMessageAddress::Phone, QString::fromUtf16(ipMmsMtm->Sender().Ptr(), ipMmsMtm->Sender().Length())));
QMessagePrivate::setSenderName(message, QString::fromUtf16(ipMmsMtm->Sender().Ptr(), ipMmsMtm->Sender().Length()));
// Read message subject
if (receivedEntry.Entry().iDescription.Length() > 0) {
message.setSubject(QString::fromUtf16(receivedEntry.Entry().iDescription.Ptr(),
receivedEntry.Entry().iDescription.Length()));
}
// Read message body & attachments
TInt count = pStore->AttachmentManagerL().AttachmentCount();
TBool textAdded = EFalse;
if (count > 0) {
privateMessage->_status = privateMessage->_status | QMessage::HasAttachments;
}
for (TInt i = 0; i < count; i++) {
CMsvAttachment* pAttachment = pStore->AttachmentManagerL().GetAttachmentInfoL(i);
CleanupStack::PushL(pAttachment);
if (pAttachment->MimeType() == _L8("text/plain") && !textAdded) {
// Read message body
textAdded = ETrue;
RFile file = pStore->AttachmentManagerL().GetAttachmentFileL(i);
CleanupClosePushL(file);
TInt fileSize;
size += fileSize;
file.Size(fileSize);
HBufC8* pFileContent = HBufC8::NewLC(fileSize);
TPtr8 fileContent(pFileContent->Des());
file.Read(fileContent);
HBufC* pMsg = CnvUtfConverter::ConvertToUnicodeFromUtf8L(*pFileContent);
CleanupStack::PopAndDestroy(pFileContent);
CleanupStack::PopAndDestroy(&file);
if (pMsg->Length() > 0) {
message.setBody(QString::fromUtf16(pMsg->Ptr(), pMsg->Length()));
if (receivedEntry.Entry().iDescription.Length() <= 0) { // no subject
if (pMsg->Length() <= 100) {
message.setSubject(QString::fromUtf16(pMsg->Ptr(), pMsg->Length()));
}
else {
message.setSubject(QString::fromUtf16(pMsg->Ptr(), 100));
}
}
}
delete pMsg;
} else {
QByteArray mimeType;
QByteArray mimeSubType;
QByteArray mimeTypeAndSubType = QByteArray((const char *)pAttachment->MimeType().Ptr(), pAttachment->MimeType().Length());
int index = mimeTypeAndSubType.indexOf("/");
if (index != -1) {
mimeType = mimeTypeAndSubType.left(index).trimmed();
mimeSubType = mimeTypeAndSubType.mid(index + 1).trimmed();
}
QByteArray path = QString::fromUtf16(pAttachment->FilePath().Ptr(),pAttachment->FilePath().Length()).toLocal8Bit();
index = path.lastIndexOf('\\');
QByteArray name;
if (index != -1) {
name = path.right(path.length()-index-1);
} else {
name = path;
}
int attachmentSize = pAttachment->Size();
size += attachmentSize;
QMessageContentContainer attachment = QMessageContentContainerPrivate::from(messageId, pAttachment->Id(), name, mimeType, mimeSubType, attachmentSize);
appendAttachmentToMessage(message, attachment);
}
CleanupStack::PopAndDestroy(pAttachment);
}
CleanupStack::PopAndDestroy(pStore);
privateMessage->_size = size;
return message;
}
QMessage CMTMEngine::emailMessageL(CMsvEntry& receivedEntry, long int messageId) const
{
QMessage message;
int size = 0;
message.setType(QMessage::Email);
const TMsvEntry& entry = receivedEntry.Entry();
message.setDate(symbianTTimetoQDateTime(entry.iDate));
message.setReceivedDate(symbianTTimetoQDateTime(entry.iDate));
QMessageAccount messageAccount = account(accountIdByServiceId(entry.iServiceId));
message.setParentAccountId(messageAccount.id());
QMessagePrivate* privateMessage = QMessagePrivate::implementation(message);
privateMessage->_parentFolderId = createQMessageFolderId(messageAccount.d_ptr->_service1EntryId, entry.Parent());
if (!entry.Unread()) {
privateMessage->_status = privateMessage->_status | QMessage::Read;
}
switch (entry.Priority()) {
case EMsvHighPriority:
message.setPriority(QMessage::HighPriority);
break;
case EMsvMediumPriority:
message.setPriority(QMessage::NormalPriority);
break;
case EMsvLowPriority:
message.setPriority(QMessage::LowPriority);
break;
}
if (entry.iMtm == KUidMsgTypePOP3) {
// All incoming POP3 messages are in the root of the POP3 service
QMessageAccount messageAccount = account(message.parentAccountId());
if (entry.Parent() == messageAccount.d_ptr->_service1EntryId) {
QMessagePrivate::setStandardFolder(message,QMessage::InboxFolder);
}
} else if (entry.iMtm == KUidMsgTypeIMAP4) {
// All incoming IMAP4 messages are in the folders which can
// be found from the root of the IMAP4 service
QMessageAccount messageAccount = account(message.parentAccountId());
CMsvEntry* pEntry = retrieveCMsvEntryAndPushToCleanupStack(entry.Parent());
if (pEntry->Entry().Parent() == messageAccount.d_ptr->_service1EntryId) {
QMessagePrivate::setStandardFolder(message,QMessage::InboxFolder);
}
releaseCMsvEntryAndPopFromCleanupStack(pEntry);
}
if (entry.Parent() == KMsvDraftEntryId) {
QMessagePrivate::setStandardFolder(message,QMessage::DraftsFolder);
} else if (entry.Parent() == KMsvSentEntryId) {
QMessagePrivate::setStandardFolder(message,QMessage::SentFolder);
} else if (entry.Parent() == KMsvDeletedEntryFolderEntryId) {
QMessagePrivate::setStandardFolder(message,QMessage::TrashFolder);
}
CImHeader* emailEntry = CImHeader::NewLC();
CImEmailMessage* emailMessage = CImEmailMessage::NewLC(receivedEntry);
CImMimeHeader* pImMimeHeader = CImMimeHeader::NewLC();
TInt mimeHeaderReadError = KErrNotFound;
if (receivedEntry.HasStoreL()) {
CMsvStore* msvStore = receivedEntry.ReadStoreL();
CleanupStack::PushL(msvStore);
TRAP_IGNORE(emailEntry->RestoreL(*msvStore));
size += emailEntry->DataSize();
TRAP(mimeHeaderReadError, pImMimeHeader->RestoreL(*msvStore));
if (mimeHeaderReadError == KErrNone) {
size += pImMimeHeader->Size();
}
CleanupStack::PopAndDestroy(); // store
}
if (!ipRichText) {
ipCharFormatLayer = CCharFormatLayer::NewL();
ipParaFormatLayer = CParaFormatLayer::NewL();
ipRichText = CRichText::NewL(ipParaFormatLayer, ipCharFormatLayer);
}
ipRichText->Reset();
emailMessage->GetBodyTextL(messageId,
CImEmailMessage::EThisMessageOnly,
*ipRichText,
*ipParaFormatLayer,
*ipCharFormatLayer);
// From GetBodyTextL() documentation:
// A list containing the entry Ids for each body text part within
// the specified message is created during this call. The list can
// be retrieved after this call has completed by calling Selection().
if (emailMessage->Selection().Count() > 0) {
if (pImMimeHeader->ContentType() == KImcvMultipart) {
// Get body content type (CImMimeHeader) from first body part
CMsvEntry* pEntry = retrieveCMsvEntryAndPushToCleanupStack(emailMessage->Selection()[0]);
if (pEntry->HasStoreL()) {
CMsvStore* pMsvStore = pEntry->ReadStoreL();
CleanupStack::PushL(pMsvStore);
TRAP(mimeHeaderReadError, pImMimeHeader->RestoreL(*pMsvStore));
if (mimeHeaderReadError == KErrNone) {
size += pImMimeHeader->Size();
}
CleanupStack::PopAndDestroy(pMsvStore);
}
releaseCMsvEntryAndPopFromCleanupStack(pEntry);
}
}
QByteArray mimeType;
if (mimeHeaderReadError == KErrNone) {
TPtrC8 type = pImMimeHeader->ContentType();
if (type.Length() > 0) {
QByteArray contentType = QByteArray((const char *)type.Ptr(),type.Length());
mimeType.append(contentType);
mimeType.append("/");
TPtrC8 subType = pImMimeHeader->ContentSubType();
if (subType.Length() > 0) {
QByteArray contentSubType = QByteArray((const char *)subType.Ptr(),subType.Length());
mimeType.append(contentSubType);
}
TUint charset = pImMimeHeader->MimeCharset();
if (charset) {
mimeType.append(";charset=");
if (charset == KCharacterSetIdentifierUcs2)
mimeType.append("UTF-16");
else if (charset == KCharacterSetIdentifierUtf8)
mimeType.append("UTF-8");
}
}
}
CleanupStack::PopAndDestroy(pImMimeHeader);
HBufC* pMessage = HBufC::NewLC(ipRichText->DocumentLength());
TPtr ptr2(pMessage->Des());
ipRichText->Extract(ptr2);
if (pMessage->Length() > 0) {
QString text = QString::fromUtf16(pMessage->Ptr(),pMessage->Length());
message.setBody(text, mimeType);
size += text.size();
}
CleanupStack::PopAndDestroy(pMessage);
//attachment(s)
emailMessage->GetAttachmentsListL(messageId, CImEmailMessage::EAllAttachments, CImEmailMessage::EThisMessageOnly);
TInt c = emailMessage->AttachmentManager().AttachmentCount();
if (c > 0) {
privateMessage->_status = privateMessage->_status | QMessage::HasAttachments;
}
for (TInt i = 0; i < c; i++) {
CMsvAttachment* pAttachment = emailMessage->AttachmentManager().GetAttachmentInfoL(i);
CleanupStack::PushL(pAttachment);
QByteArray mimeType;
QByteArray mimeSubType;
CImMimeHeader* pImMimeHeader = CImMimeHeader::NewLC();
CMsvEntry* pEntry = retrieveCMsvEntryAndPushToCleanupStack(pAttachment->Id());
if (pEntry->HasStoreL()) {
CMsvStore* pMsvStore = pEntry->ReadStoreL();
CleanupStack::PushL(pMsvStore);
TRAP(mimeHeaderReadError, pImMimeHeader->RestoreL(*pMsvStore));
if (mimeHeaderReadError == KErrNone) {
size += pImMimeHeader->Size();
}
CleanupStack::PopAndDestroy(pMsvStore);
}
releaseCMsvEntryAndPopFromCleanupStack(pEntry);
if (mimeHeaderReadError == KErrNone) {
mimeType = QByteArray((const char *)pImMimeHeader->ContentType().Ptr(), pImMimeHeader->ContentType().Length());
mimeSubType = QByteArray((const char *)pImMimeHeader->ContentSubType().Ptr(), pImMimeHeader->ContentSubType().Length());
}
CleanupStack::PopAndDestroy(pImMimeHeader);
QByteArray name = QString::fromUtf16(pAttachment->AttachmentName().Ptr(), pAttachment->AttachmentName().Length()).toLocal8Bit();
int attachmentSize = pAttachment->Size();
size += attachmentSize;
QMessageContentContainer attachment = QMessageContentContainerPrivate::from(messageId, pAttachment->Id(), name, mimeType, mimeSubType, attachmentSize);
appendAttachmentToMessage(message, attachment);
CleanupStack::PopAndDestroy(pAttachment);
}
//from
TPtrC from = emailEntry->From();
if (from.Length() > 0) {
message.setFrom(QMessageAddress(QMessageAddress::Email, QString::fromUtf16(from.Ptr(), from.Length())));
QMessagePrivate::setSenderName(message, QString::fromUtf16(from.Ptr(), from.Length()));
} else {
if (entry.iDetails.Length() > 0) {
QString fromString = QString::fromUtf16(receivedEntry.Entry().iDetails.Ptr(), receivedEntry.Entry().iDetails.Length());
message.setFrom(QMessageAddress(QMessageAddress::Email, fromString));
QMessagePrivate::setSenderName(message, fromString);
}
}
//to
CDesCArray& toArray = emailEntry->ToRecipients();
QList<QMessageAddress> toList;
for (TInt i = 0; i < toArray.Count(); i++)
{
TPtrC16 to(toArray.MdcaPoint(i));
toList.append(QMessageAddress(QMessageAddress::Email, QString::fromUtf16(to.Ptr(), to.Length())));
}
message.setTo(toList);
//cc
CDesCArray& ccArray = emailEntry->CcRecipients();
QList<QMessageAddress> ccList;
for (TInt i = 0; i < ccArray.Count(); i++)
{
TPtrC16 cc(ccArray.MdcaPoint(i));
ccList.append(QMessageAddress(QMessageAddress::Email, QString::fromUtf16(cc.Ptr(), cc.Length())));
}
message.setCc(ccList);
//bcc
CDesCArray& bccArray = emailEntry->BccRecipients();
QList<QMessageAddress> bccList;
for (TInt i = 0; i < bccArray.Count(); i++)
{
TPtrC16 bcc(bccArray.MdcaPoint(i));
bccList.append(QMessageAddress(QMessageAddress::Email, QString::fromUtf16(bcc.Ptr(), bcc.Length())));
}
message.setBcc(bccList);
// Read message subject
TPtrC subject = emailEntry->Subject();
if (subject.Length() > 0) {
message.setSubject(QString::fromUtf16(subject.Ptr(), subject.Length()));
} else {
if (entry.iDescription.Length() > 0) {
message.setSubject(QString::fromUtf16(receivedEntry.Entry().iDescription.Ptr(),
receivedEntry.Entry().iDescription.Length()));
}
}
CleanupStack::PopAndDestroy(emailMessage);
CleanupStack::PopAndDestroy(emailEntry);
privateMessage->_size = size;
return message;
}
void CMTMEngine::appendAttachmentToMessage(QMessage& message, QMessageContentContainer& attachment) const
{
QMessagePrivate* privateMessage = QMessagePrivate::implementation(message);
QMessageContentContainerPrivate* container = QMessagePrivate::containerImplementation(message);
if (container->_attachments.isEmpty()) {
QMessageContentContainerId existingBodyId(message.bodyId());
if (existingBodyId == QMessageContentContainerPrivate::bodyContentId()) {
// The body content is in the message itself - move it to become the first attachment
QMessageContentContainer newBody(message);
QMessageContentContainerPrivate::implementation(newBody)->setDerivedMessage(0);
container->setContentType("multipart", "mixed", "");
privateMessage->_bodyId = container->prependContent(newBody);
} else {
// This message is now multipart
container->setContentType("multipart", "mixed", "");
}
container->_available = true;
}
container->appendContent(attachment);
bool haveAttachments = !container->_attachments.isEmpty();
message.setStatus(QMessage::HasAttachments,haveAttachments);
privateMessage->_modified = true;
}
QByteArray CMTMEngine::attachmentContent(long int messageId, unsigned int attachmentId)
{
QByteArray result;
TRAP_IGNORE(result = attachmentContentL(messageId, attachmentId));
return result;
}
QByteArray CMTMEngine::attachmentContentL(long int messageId, unsigned int attachmentId)
{
QByteArray result;
CMsvEntry* pEntry = retrieveCMsvEntryAndPushToCleanupStack(messageId);
if (pEntry->Entry().iMtm == KUidMsgTypeMultimedia) { // MMS
CMsvStore* pStore = pEntry->ReadStoreL();
CleanupStack::PushL(pStore);
RFile file = pStore->AttachmentManagerL().GetAttachmentFileL(attachmentId);
CleanupClosePushL(file);
TInt fileSize;
file.Size(fileSize);
TBuf<KMaxFileName> fileName;
file.Name(fileName);
HBufC8* pFileContent = HBufC8::NewL(fileSize);
TPtr8 fileContent(pFileContent->Des());
file.Read(fileContent);
CleanupStack::PopAndDestroy(&file);
CleanupStack::PushL(pFileContent);
result = QByteArray((char*)pFileContent->Ptr(),pFileContent->Length());
CleanupStack::PopAndDestroy(pFileContent);
CleanupStack::PopAndDestroy(pStore);
} else { // Email
CImEmailMessage* pImEmailMessage = CImEmailMessage::NewLC(*pEntry);
RFile file = pImEmailMessage->AttachmentManager().GetAttachmentFileL(attachmentId);
CleanupClosePushL(file);
TInt fileSize;
file.Size(fileSize);
TBuf<KMaxFileName> fileName;
file.Name(fileName);
HBufC8* pFileContent = HBufC8::NewL(fileSize);
TPtr8 fileContent(pFileContent->Des());
file.Read(fileContent);
CleanupStack::PopAndDestroy(&file);
CleanupStack::PushL(pFileContent);
result = QByteArray((char*)pFileContent->Ptr(),pFileContent->Length());
CleanupStack::PopAndDestroy(pFileContent);
CleanupStack::PopAndDestroy(pImEmailMessage);
}
releaseCMsvEntryAndPopFromCleanupStack(pEntry);
return result;
}
QString CMTMEngine::attachmentTextContent(long int messageId, unsigned int attachmentId, const QByteArray &charset)
{
QString result;
QByteArray data = attachmentContent(messageId, attachmentId);
if (!data.isEmpty()) {
// Convert attachment data to string form
QTextCodec *codec;
if (!charset.isEmpty()) {
codec = QTextCodec::codecForName(charset);
} else {
codec = QTextCodec::codecForLocale();
}
if (codec) {
result = codec->toUnicode(data);
}
}
return result;
}
QMessage CMTMEngine::pop3MessageL(CMsvEntry& /*receivedEntry*/, long int /*messageId*/) const
{
return QMessage();
}
QMessage CMTMEngine::imap4MessageL(CMsvEntry& /*receivedEntry*/, long int /*messageId*/) const
{
return QMessage();
}
CMsvEntry* CMTMEngine::retrieveCMsvEntryAndPushToCleanupStack(TMsvId id) const
{
CMsvEntry* pEntry = NULL;
if (iCmsvEntryPoolFree.Count() > 0) {
pEntry = iCmsvEntryPoolFree[iCmsvEntryPoolFree.Count()-1];
TInt retVal = iCmsvEntryPoolInUse.Append(pEntry);
if (retVal != KErrNone) {
delete pEntry;
pEntry = NULL;
}
} else {
if (id == 0) {
id = KMsvRootIndexEntryId;
}
TRAPD(err, pEntry = ipMsvSession->GetEntryL(id));
if (err == KErrNone) {
TInt retVal = iCmsvEntryPoolInUse.Append(pEntry);
if (retVal != KErrNone) {
delete pEntry;
pEntry = NULL;
}
}
}
if (id != 0 && pEntry) {
TRAPD(err, pEntry->SetEntryL(id));
if (err != KErrNone) {
TInt pos = iCmsvEntryPoolInUse.Find(pEntry);
if (pos != KErrNotFound) {
iCmsvEntryPoolInUse.Remove(pos);
TInt retVal = iCmsvEntryPoolFree.Append(pEntry);
if (retVal != KErrNone) {
delete pEntry;
}
}
pEntry = NULL;
}
}
if (pEntry) {
TCleanupItem entryCleanup(cmsvEntryCleanup, pEntry);
CleanupStack::PushL(entryCleanup);
}
return pEntry;
}
void CMTMEngine::cmsvEntryCleanup(TAny* aCMsvEntry)
{
CMTMEngine* pMTMEngine = mtmEngine();
CMsvEntry* pEntry = (CMsvEntry*)aCMsvEntry;
TInt pos = pMTMEngine->iCmsvEntryPoolInUse.Find(pEntry);
if (pos != KErrNotFound) {
pMTMEngine->iCmsvEntryPoolInUse.Remove(pos);
TInt retVal = pMTMEngine->iCmsvEntryPoolFree.Append(pEntry);
if (retVal != KErrNone) {
delete pEntry;
}
}
}
void CMTMEngine::releaseCMsvEntryAndPopFromCleanupStack(CMsvEntry* pEntry) const
{
if (pEntry) {
CleanupStack::Pop(); // Entry cleanup
}
TInt pos = iCmsvEntryPoolInUse.Find(pEntry);
if (pos != KErrNotFound) {
iCmsvEntryPoolInUse.Remove(pos);
TInt retVal = iCmsvEntryPoolFree.Append(pEntry);
if (retVal != KErrNone) {
delete pEntry;
}
}
}
QMessageManager::NotificationFilterId CMTMEngine::registerNotificationFilter(QMessageStorePrivate& aPrivateStore,
const QMessageFilter &filter)
{
ipMessageStorePrivate = &aPrivateStore;
iListenForNotifications = true;
int filterId = ++_filterId;
_filters.insert(filterId, filter);
return filterId;
}
void CMTMEngine::unregisterNotificationFilter(QMessageManager::NotificationFilterId notificationFilterId)
{
_filters.remove(notificationFilterId);
if (_filters.count() == 0) {
iListenForNotifications = false;
}
}
void CMTMEngine::notification(TMsvSessionEvent aEvent, TUid aMsgType, TMsvId aFolderId, TMsvId aMessageId)
{
if (aFolderId == 0x100001 || aFolderId == 0x100002) { // MMS Notifications Folder
// Ignore MMS Notifications <=> Wait until actual MMS message has been received
return;
}
QMessageManager::NotificationFilterIdSet matchingFilters;
// Copy the filter map to protect against modification during traversal
QMap<int, QMessageFilter> filters(_filters);
QMap<int, QMessageFilter>::const_iterator it = filters.begin(), end = filters.end();
QMessage message;
bool messageRetrieved = false;
bool unableToReadAndFilterMessage = false;
for ( ; it != end; ++it) {
const QMessageFilter &filter(it.value());
if (filter.isEmpty()) {
// Empty filter matches to all messages
matchingFilters.insert(it.key());
} else {
QMessageFilterPrivate* privateMessageFilter = QMessageFilterPrivate::implementation(filter);
if (privateMessageFilter->_field == QMessageFilterPrivate::Type) {
if (aMsgType == KUidMsgTypeSMS) {
message.setType(QMessage::Sms);
} else if (aMsgType == KUidMsgTypeMultimedia) {
message.setType(QMessage::Mms);
} else if (aMsgType == KUidMsgTypeSMTP ||
aMsgType == KUidMsgTypePOP3 ||
aMsgType == KUidMsgTypeIMAP4) {
message.setType(QMessage::Email);
} else {
message.setType(QMessage::NoType);
}
} else if ((privateMessageFilter->_field == QMessageFilterPrivate::StandardFolder) &&
(aMsgType == KUidMsgTypeSMS || aMsgType == KUidMsgTypeMultimedia)) {
if (aFolderId == KMsvGlobalInBoxIndexEntryId) {
QMessagePrivate::setStandardFolder(message,QMessage::InboxFolder);
} else if (aFolderId == KMsvDraftEntryId) {
QMessagePrivate::setStandardFolder(message,QMessage::DraftsFolder);
} else if (aFolderId == KMsvSentEntryId) {
QMessagePrivate::setStandardFolder(message,QMessage::SentFolder);
} else if (aFolderId == KMsvDeletedEntryFolderEntryId) {
QMessagePrivate::setStandardFolder(message,QMessage::TrashFolder);
}
} else if (!messageRetrieved) {
message = this->message(QMessageId(QString::number(aMessageId)));
if (message.type() == QMessage::NoType) {
unableToReadAndFilterMessage = true;
matchingFilters.clear();
break;
} else {
messageRetrieved = true;
}
}
if (privateMessageFilter->filter(message)) {
matchingFilters.insert(it.key());
}
}
}
QMessageStorePrivate::NotificationType notificationType = QMessageStorePrivate::Removed;
if (aEvent == EMsvEntriesCreated) {
notificationType = QMessageStorePrivate::Added;
} else if (aEvent == EMsvEntriesChanged || aEvent == EMsvEntriesMoved) {
notificationType = QMessageStorePrivate::Updated;
} if (aEvent == EMsvEntriesDeleted) {
notificationType = QMessageStorePrivate::Removed;
}
if (matchingFilters.count() > 0) {
// Check if there are already pending events for
// currently handled MessageId
bool pendingEventsForCurrentlyHandledMessageId = false;
for (int i=0; i < iUndeliveredMessageEvents.count(); i++) {
if (iUndeliveredMessageEvents[i].messageId == aMessageId) {
pendingEventsForCurrentlyHandledMessageId = true;
break;
}
}
if (pendingEventsForCurrentlyHandledMessageId) {
// There are pending notification events for this messageId.
// => Add new notification event to notification event queue to
// make sure that all events will be delivered in correct order.
MessageEvent event;
event.messageId = aMessageId;
event.notificationType = notificationType;
event.matchingFilters = matchingFilters;
event.unfiltered = false;
if (iUndeliveredMessageEvents.count() == 0) {
iDeliveryTriesCounter = 0;
}
iUndeliveredMessageEvents.append(event);
tryToDeliverMessageNotifications();
} else {
// No pending notification events for this messageId.
// => Deliver notification immediately
ipMessageStorePrivate->messageNotification(notificationType,
QMessageId(QString::number(aMessageId)),
matchingFilters);
}
} else if (unableToReadAndFilterMessage) {
if (notificationType != QMessageStorePrivate::Removed) {
MessageEvent event;
event.messageId = aMessageId;
event.notificationType = notificationType;
event.unfiltered = true;
if (iUndeliveredMessageEvents.count() == 0) {
iDeliveryTriesCounter = 0;
}
iUndeliveredMessageEvents.append(event);
tryToDeliverMessageNotifications();
} else {
// Message was removed before reading was possible
// => All avents related to removed messageId can be ignored
// => Remove all related events from undelivered message events queue
for (int i=iUndeliveredMessageEvents.count()-1; i >= 0; i--) {
if (iUndeliveredMessageEvents[i].messageId == aMessageId) {
iUndeliveredMessageEvents.removeAt(i);
}
}
}
}
}
void CMTMEngine::tryToDeliverMessageNotifications()
{
if (!IsActive()) {
int count = iUndeliveredMessageEvents.count();
while (count--) {
// Try to deliver the oldest message event notification first
MessageEvent event = iUndeliveredMessageEvents[0];
bool eventHandlingPossible = true;
if (event.notificationType != QMessageStorePrivate::Removed && event.unfiltered) {
QMessage message = this->message(QMessageId(QString::number(event.messageId)));
if (message.type() == QMessage::NoType) {
eventHandlingPossible = false;
} else {
event.matchingFilters.clear();
// Copy the filter map to protect against modification during traversal
QMap<int, QMessageFilter> filters(_filters);
QMap<int, QMessageFilter>::const_iterator it = filters.begin(), end = filters.end();
for ( ; it != end; ++it) {
const QMessageFilter &filter(it.value());
if (filter.isEmpty()) {
// Empty filter matches to all messages
event.matchingFilters.insert(it.key());
} else {
QMessageFilterPrivate* privateMessageFilter = QMessageFilterPrivate::implementation(filter);
if (privateMessageFilter->filter(message)) {
event.matchingFilters.insert(it.key());
}
}
}
}
}
if (eventHandlingPossible) {
// New message entry was ready to be read
// Remove message event from queue
iUndeliveredMessageEvents.removeFirst();
iDeliveryTriesCounter = 0;
if (event.matchingFilters.count() > 0) {
// Deliver message event notification
ipMessageStorePrivate->messageNotification(event.notificationType,
QMessageId(QString::number(event.messageId)),
event.matchingFilters);
}
} else {
// New message entry was NOT ready to be read
iDeliveryTriesCounter++;
if (iDeliveryTriesCounter < 50) {
// Wait for 0.1 seconds to see if message would
// be ready to be read & delivered after wait.
iTimer.After(iStatus, KWaitAfterReceivedMessage);
SetActive();
break;
} else {
// Remove problematic message event from queue
iUndeliveredMessageEvents.removeFirst();
iDeliveryTriesCounter = 0;
}
}
}
}
}
void CMTMEngine::RunL()
{
tryToDeliverMessageNotifications();
}
void CMTMEngine::DoCancel()
{
iTimer.Cancel();
}
void CMTMEngine::HandleSessionEventL(TMsvSessionEvent aEvent, TAny* aArg1,
TAny* aArg2, TAny* /*aArg3*/)
{
switch (aEvent) {
case EMsvServerReady:
iSessionReady = ETrue;
break;
case EMsvEntriesCreated:
case EMsvEntriesChanged:
case EMsvEntriesDeleted:
case EMsvEntriesMoved:
if (aArg2 && iListenForNotifications) {
CMsvEntrySelection* entries = static_cast<CMsvEntrySelection*>(aArg1);
if (entries != NULL) {
TInt count = entries->Count();
while (count--) {
const TMsvId id = (*entries)[count];
if (aEvent == EMsvEntriesDeleted) {
notification(aEvent, TUid(), *(static_cast<TMsvId*>(aArg2)), id);
} else {
CMsvEntry* pReceivedEntry = NULL;
TRAPD(err, pReceivedEntry = ipMsvSession->GetEntryL(id));
if (err == KErrNone) {
const TMsvEntry& entry = pReceivedEntry->Entry();
if (entry.iType == KUidMsvMessageEntry) {
notification(aEvent, entry.iMtm, *(static_cast<TMsvId*>(aArg2)), id);
}
delete pReceivedEntry;
}
}
}
}
}
break;
default:
break;
}
}
CMessagesFindOperation::CMessagesFindOperation(CMTMEngine& aOwner, CMsvSession* apMsvSession, int aOperationId)
: CActive(CActive::EPriorityStandard), iOwner(aOwner), ipMsvSession(apMsvSession), iOperationId(aOperationId),
iResultCorrectlyOrdered(false)
{
CActiveScheduler::Add(this);
iTimer.CreateLocal();
}
CMessagesFindOperation::~CMessagesFindOperation()
{
Cancel();
iTimer.Close();
delete ipMsvFindOperation;
delete ipEntrySelection;
}
void CMessagesFindOperation::DoCancel()
{
ipMsvFindOperation->Cancel();
}
void CMessagesFindOperation::filterAndOrderMessages(const QMessageFilter &filter, const QMessageSortOrder& sortOrder,
QString body, QMessageDataComparator::MatchFlags matchFlags)
{
iFilterList.clear();
iFilterList.append(filter);
filterAndOrderMessages(iFilterList, sortOrder, body, matchFlags);
}
void CMessagesFindOperation::filterAndOrderMessages(const QMessageFilterPrivate::SortedMessageFilterList& filters,
const QMessageSortOrder& sortOrder,
QString body,
QMessageDataComparator::MatchFlags matchFlags)
{
delete ipMsvFindOperation;
ipMsvFindOperation = NULL;
delete ipEntrySelection;
ipEntrySelection = NULL;
iNumberOfHandledFilters = 0;
if (filters.count() == 0) {
iIdList = QMessageIdList();
iTimer.After(iStatus, 1);
if (!IsActive()) {
SetActive();
}
return;
}
QMessageFilterPrivate* pf = QMessageFilterPrivate::implementation(filters[iNumberOfHandledFilters]);
if ((filters.count() == 1) &&
(pf->_field == QMessageFilterPrivate::None) &&
(pf->_filterList.count() == 0)) {
if (pf->_notFilter) {
// There is only one filter: empty ~QMessageFilter()
// => return empty QMessageIdList
iIdList = QMessageIdList();
} else {
// There is only one filter: empty QMessageFilter()
// => return all messages
ipEntrySelection = new(ELeave)CMsvEntrySelection;
getAllMessagesL(iOrdering);
iIdList = QMessageIdList();
for (int i=0; i < ipEntrySelection->Count(); i++) {
iIdList.append(QMessageId(QString::number((*ipEntrySelection)[i])));
}
}
iNumberOfHandledFilters++;
iTimer.After(iStatus, 1);
if (!IsActive()) {
SetActive();
}
return;
}
// Set sortOrder
if (!sortOrder.isEmpty() ) {
QMessageSortOrderPrivate* privateMessageOrdering = QMessageSortOrderPrivate::implementation(sortOrder);
iOrdering.SetShowInvisibleEntries(EFalse);
QPair<QMessageSortOrderPrivate::Field, Qt::SortOrder> fieldOrder = privateMessageOrdering->_fieldOrderList.at(0);
switch (fieldOrder.first) {
case QMessageSortOrderPrivate::Type:
iOrdering.SetGroupByMtm(true);
break;
case QMessageSortOrderPrivate::Sender:
if (fieldOrder.second == Qt::AscendingOrder) {
iOrdering.SetSorting(EMsvSortByDetails); // To/From (A-Z folded)
} else {
iOrdering.SetSorting(EMsvSortByDetailsReverse); // To/From (Z-A folded)
}
break;
case QMessageSortOrderPrivate::Recipients:
if (fieldOrder.second == Qt::AscendingOrder) {
iOrdering.SetSorting(EMsvSortByDetails); // To/From (A-Z folded)
} else {
iOrdering.SetSorting(EMsvSortByDetailsReverse); // To/From (Z-A folded)
}
break;
case QMessageSortOrderPrivate::Subject:
if (fieldOrder.second == Qt::AscendingOrder) {
iOrdering.SetSorting(EMsvSortByDescription); // Description (A-Z folded)
} else {
iOrdering.SetSorting(EMsvSortByDescriptionReverse); // Description (Z-A folded)
}
break;
case QMessageSortOrderPrivate::TimeStamp:
if (fieldOrder.second == Qt::AscendingOrder) {
iOrdering.SetSorting(EMsvSortByDate); // Date (earliest-latest)
} else {
iOrdering.SetSorting(EMsvSortByDateReverse); // Date (latest-earliest)
}
break;
case QMessageSortOrderPrivate::ReceptionTimeStamp:
if (fieldOrder.second == Qt::AscendingOrder) {
iOrdering.SetSorting(EMsvSortByDate); // Date (earliest-latest)
} else {
iOrdering.SetSorting(EMsvSortByDateReverse); // Date (latest-earliest)
}
break;
case QMessageSortOrderPrivate::Read:
//TODO:
break;
case QMessageSortOrderPrivate::HasAttachments:
//TODO:
break;
case QMessageSortOrderPrivate::Incoming:
//TODO:
break;
case QMessageSortOrderPrivate::Removed:
//TODO:
break;
case QMessageSortOrderPrivate::Priority:
//iOrdering.SetGroupByPriority(true);
break;
case QMessageSortOrderPrivate::Size:
if (fieldOrder.second == Qt::AscendingOrder) {
iOrdering.SetSorting(EMsvSortBySize); // (smallest-largest)
} else {
iOrdering.SetSorting(EMsvSortBySizeReverse); // (largest-smallest)
}
break;
}
}
switch (pf->_field) {
case QMessageFilterPrivate::Id:
{
iNumberOfHandledFilters++;
if (pf->_comparatorType == QMessageFilterPrivate::Equality) { // QMessageId
QMessageDataComparator::EqualityComparator cmp(static_cast<QMessageDataComparator::EqualityComparator>(pf->_comparatorValue));
if (!pf->_value.isNull() && pf->_value.toString().length() > 0) {
if (cmp == QMessageDataComparator::Equal) {
long int messageId = pf->_value.toString().toLong();
CMsvEntry* pEntry = iOwner.retrieveCMsvEntryAndPushToCleanupStack(messageId);
if (pEntry) {
const TMsvEntry& entry = pEntry->Entry();
if (entry.iType == KUidMsvMessageEntry) {
ipEntrySelection = new(ELeave)CMsvEntrySelection;
ipEntrySelection->AppendL(messageId);
}
iOwner.releaseCMsvEntryAndPopFromCleanupStack(pEntry);
}
iResultCorrectlyOrdered = true;
} else { // NotEqual
ipEntrySelection = new(ELeave)CMsvEntrySelection;
getAllMessagesL(iOrdering);
long int messageId = pf->_value.toString().toLong();
for (int i=0; i < ipEntrySelection->Count(); i++) {
if (ipEntrySelection->At(i) == messageId) {
ipEntrySelection->Delete(i);
break;
}
}
}
} else {
ipEntrySelection = new(ELeave)CMsvEntrySelection;
if (cmp == QMessageDataComparator::NotEqual) {
getAllMessagesL(iOrdering);
}
}
} else if (pf->_comparatorType == QMessageFilterPrivate::Inclusion) {
QMessageDataComparator::InclusionComparator cmp(static_cast<QMessageDataComparator::InclusionComparator>(pf->_comparatorValue));
if (pf->_ids.count() > 0) { // QMessageIdList
if (cmp == QMessageDataComparator::Includes) {
ipEntrySelection = new(ELeave)CMsvEntrySelection;
for (int i=0; i < pf->_ids.count(); i++) {
long int messageId = pf->_ids[i].toString().toLong();
CMsvEntry* pEntry = iOwner.retrieveCMsvEntryAndPushToCleanupStack(messageId);
if (pEntry) {
const TMsvEntry& entry = pEntry->Entry();
if (entry.iType == KUidMsvMessageEntry) {
ipEntrySelection->AppendL(messageId);
}
iOwner.releaseCMsvEntryAndPopFromCleanupStack(pEntry);
}
}
} else { // Excludes
ipEntrySelection = new(ELeave)CMsvEntrySelection;
getAllMessagesL(iOrdering);
for (int i=0; i < pf->_ids.count(); i++) {
long int messageId = pf->_ids[i].toString().toLong();
for (int i=0; i < ipEntrySelection->Count(); i++) {
if (ipEntrySelection->At(i) == messageId) {
ipEntrySelection->Delete(i);
break;
}
}
}
}
} else {
ipEntrySelection = new(ELeave)CMsvEntrySelection;
if (cmp == QMessageDataComparator::Excludes) {
getAllMessagesL(iOrdering);
}
/*// QMessageFilter
if (cmp == QMessageDataComparator::Includes) {
// TODO:
} else { // Excludes
// TODO:
}*/
}
}
break;
}
case QMessageFilterPrivate::ParentAccountId:
{
if (pf->_comparatorType == QMessageFilterPrivate::Equality) { // QMessageAccountId
iNumberOfHandledFilters++;
QMessageDataComparator::EqualityComparator cmp(static_cast<QMessageDataComparator::EqualityComparator>(pf->_comparatorValue));
if (cmp == QMessageDataComparator::Equal) {
ipEntrySelection = new(ELeave)CMsvEntrySelection;
QMessageAccount messageAccount = iOwner.account(pf->_value.toString());
QMessageFilterPrivate* privateFilter = NULL;
if (filters.count() > iNumberOfHandledFilters) {
privateFilter = QMessageFilterPrivate::implementation(filters[iNumberOfHandledFilters]);
if (privateFilter->_field != QMessageFilterPrivate::StandardFolder) {
privateFilter = NULL;
} else {
iNumberOfHandledFilters++;
}
}
getAccountSpecificMessagesL(messageAccount, iOrdering, privateFilter);
} else { // NotEqual
ipEntrySelection = new(ELeave)CMsvEntrySelection;
QStringList exludedAccounts;
exludedAccounts << pf->_value.toString();
QMessageFilterPrivate* privateFilter = NULL;
for (int i=iNumberOfHandledFilters; i < filters.count(); i++) {
privateFilter = QMessageFilterPrivate::implementation(filters[i]);
if (privateFilter->_field == QMessageFilterPrivate::ParentAccountId &&
privateFilter->_comparatorType == QMessageFilterPrivate::Equality) {
cmp = static_cast<QMessageDataComparator::EqualityComparator>(privateFilter->_comparatorValue);
if (cmp == QMessageDataComparator::NotEqual) {
exludedAccounts << privateFilter->_value.toString();
iNumberOfHandledFilters++;
} else {
break;
}
} else {
break;
}
}
privateFilter = NULL;
if (filters.count() > iNumberOfHandledFilters) {
privateFilter = QMessageFilterPrivate::implementation(filters[iNumberOfHandledFilters]);
if (privateFilter->_field == QMessageFilterPrivate::StandardFolder &&
privateFilter->_comparatorType == QMessageFilterPrivate::Equality) {
cmp = static_cast<QMessageDataComparator::EqualityComparator>(privateFilter->_comparatorValue);
if (cmp == QMessageDataComparator::Equal) {
iNumberOfHandledFilters++;
}
} else {
privateFilter = NULL;
}
}
foreach (QMessageAccount value, iOwner.iAccounts) {
if (!exludedAccounts.contains(value.id().toString())) {
getAccountSpecificMessagesL(value, iOrdering, privateFilter);
}
}
}
} else if (pf->_comparatorType == QMessageFilterPrivate::Inclusion) { // QMessageAccountFilter
QMessageDataComparator::InclusionComparator cmp(static_cast<QMessageDataComparator::InclusionComparator>(pf->_comparatorValue));
if (cmp == QMessageDataComparator::Includes) {
//TODO:
} else { // Excludes
//TODO:
}
}
break;
}
case QMessageFilterPrivate::ParentFolderId:
{
if (pf->_comparatorType == QMessageFilterPrivate::Equality) { // QMessageFolderId
QMessageDataComparator::EqualityComparator cmp(static_cast<QMessageDataComparator::EqualityComparator>(pf->_comparatorValue));
if (cmp == QMessageDataComparator::Equal) {
long int folderId = iOwner.folderIdFromQMessageFolderId(QMessageFolderId(pf->_value.toString()));
long int serviceEntryId = iOwner.serviceEntryIdFromQMessageFolderId(QMessageFolderId(pf->_value.toString()));
QMessageAccount messageAccount = iOwner.account(iOwner.accountIdByServiceId(serviceEntryId));
if (messageAccount.messageTypes() == QMessage::Email) {
iNumberOfHandledFilters++;
CMsvEntryFilter* pFilter = CMsvEntryFilter::NewLC();
pFilter->SetOrder(iOrdering);
pFilter->SetType(KUidMsvMessageEntry);
// Get POP3 or IMAP messages from folder
CMsvEntrySelection* pEntrySelection1 = new(ELeave)CMsvEntrySelection;
CleanupStack::PushL(pEntrySelection1);
pFilter->SetService(messageAccount.d_ptr->_service1EntryId);
ipMsvSession->GetChildIdsL(folderId, *pFilter, *pEntrySelection1);
// Get SMTP messages from folder
CMsvEntrySelection* pEntrySelection2 = new(ELeave)CMsvEntrySelection;
CleanupStack::PushL(pEntrySelection2);
pFilter->SetService(messageAccount.d_ptr->_service2EntryId);
ipMsvSession->GetChildIdsL(folderId, *pFilter, *pEntrySelection2);
if (pEntrySelection1->Count() > 0 && pEntrySelection2->Count() > 0) {
ipEntrySelection = pEntrySelection1;
for (int i = 0; i < pEntrySelection2->Count(); i++) {
ipEntrySelection->AppendL(pEntrySelection2->At(i));
}
CleanupStack::PopAndDestroy(pEntrySelection2);
CleanupStack::Pop(pEntrySelection1);
} else if (pEntrySelection1->Count() > 0) {
ipEntrySelection = pEntrySelection1;
CleanupStack::PopAndDestroy(pEntrySelection2);
CleanupStack::Pop(pEntrySelection1);
iResultCorrectlyOrdered = true;
} else {
// (pEntrySelection2->Count() > 0) or both selections are empty
ipEntrySelection = pEntrySelection2;
CleanupStack::Pop(pEntrySelection2);
CleanupStack::PopAndDestroy(pEntrySelection1);
iResultCorrectlyOrdered = true;
}
CleanupStack::PopAndDestroy(pFilter);
} else if (messageAccount.messageTypes() == QMessage::Sms || messageAccount.messageTypes() == QMessage::Mms) {
iNumberOfHandledFilters++;
CMsvEntry* pEntry = iOwner.retrieveCMsvEntryAndPushToCleanupStack(serviceEntryId);
if (pEntry) {
TUid mtm = pEntry->Entry().iMtm;
iOwner.releaseCMsvEntryAndPopFromCleanupStack(pEntry);
CMsvEntryFilter* pFilter = CMsvEntryFilter::NewLC();
pFilter->SetMtm(mtm);
pFilter->SetOrder(iOrdering);
pFilter->SetType(KUidMsvMessageEntry);
ipEntrySelection = new(ELeave)CMsvEntrySelection;
ipMsvSession->GetChildIdsL(folderId, *pFilter, *ipEntrySelection);
CleanupStack::PopAndDestroy(pFilter);
}
iResultCorrectlyOrdered = true;
}
} else { // NotEqual
// TODO:
}
} else if (pf->_comparatorType == QMessageFilterPrivate::Inclusion) { // QMessageFolderFilter
QMessageDataComparator::InclusionComparator cmp(static_cast<QMessageDataComparator::InclusionComparator>(pf->_comparatorValue));
if (cmp == QMessageDataComparator::Includes) {
// TODO:
} else { // Excludes
// TODO:
}
}
break;
}
case QMessageFilterPrivate::AncestorFolderIds:
{
iNumberOfHandledFilters++;
if (pf->_comparatorType == QMessageFilterPrivate::Inclusion) {
QMessageDataComparator::InclusionComparator cmp(static_cast<QMessageDataComparator::InclusionComparator>(pf->_comparatorValue));
if (!pf->_value.isNull()) { // QMessageFolderId
if (cmp == QMessageDataComparator::Includes) {
// TODO:
} else { // Excludes
// TODO:
}
} else { // QMessageFolderFilter
if (cmp == QMessageDataComparator::Includes) {
// TODO:
} else { // Excludes
// TODO:
}
}
}
break;
}
case QMessageFilterPrivate::Type:
{
iNumberOfHandledFilters++;
QMessageFilterPrivate* privateFilter = NULL;
// Check if next filter is StandardFolder filter
if (filters.count() > iNumberOfHandledFilters) {
privateFilter = QMessageFilterPrivate::implementation(filters[iNumberOfHandledFilters]);
if (privateFilter->_field != QMessageFilterPrivate::StandardFolder) {
privateFilter = NULL;
} else {
iNumberOfHandledFilters++;
}
}
if (pf->_comparatorType == QMessageFilterPrivate::Equality) { // QMessage::Type
QMessage::Type type = static_cast<QMessage::Type>(pf->_value.toInt());
QMessageDataComparator::EqualityComparator cmp(static_cast<QMessageDataComparator::EqualityComparator>(pf->_comparatorValue));
if (cmp == QMessageDataComparator::Equal) {
ipEntrySelection = new(ELeave)CMsvEntrySelection;
QMessageAccountIdList accountIds = iOwner.accountsByType(type);
for (int i = 0; i < accountIds.count(); i++) {
QMessageAccount messageAccount = iOwner.account(accountIds[i]);
getAccountSpecificMessagesL(messageAccount, iOrdering, privateFilter);
}
} else { // NotEqual
foreach (QMessageAccount value, iOwner.iAccounts) {
if (!(value.messageTypes() & type)) {
getAccountSpecificMessagesL(value, iOrdering, privateFilter);
}
}
}
} else if (pf->_comparatorType == QMessageFilterPrivate::Inclusion) { // QMessage::TypeFlags
QMessage::TypeFlags typeFlags = static_cast<QMessage::TypeFlags>(pf->_value.toInt());
QMessageDataComparator::InclusionComparator cmp(static_cast<QMessageDataComparator::InclusionComparator>(pf->_comparatorValue));
if (cmp == QMessageDataComparator::Includes) {
foreach (QMessageAccount value, iOwner.iAccounts) {
if (value.messageTypes() | typeFlags) {
getAccountSpecificMessagesL(value, iOrdering, privateFilter);
}
}
} else { // Excludes
foreach (QMessageAccount value, iOwner.iAccounts) {
if (!(value.messageTypes() & typeFlags)) {
getAccountSpecificMessagesL(value, iOrdering, privateFilter);
}
}
}
}
break;
}
case QMessageFilterPrivate::StandardFolder:
{
iNumberOfHandledFilters++;
QMessageDataComparator::EqualityComparator cmp(static_cast<QMessageDataComparator::EqualityComparator>(pf->_comparatorValue));
QMessage::StandardFolder standardFolder = static_cast<QMessage::StandardFolder>(pf->_value.toInt());
TMsvId stdFolderId = iOwner.standardFolderId(standardFolder);
if (cmp == QMessageDataComparator::Equal) {
CMsvEntry* pStandardFolderContext = iOwner.retrieveCMsvEntryAndPushToCleanupStack(stdFolderId);
if (pStandardFolderContext) {
pStandardFolderContext->SetSortTypeL(iOrdering);
ipEntrySelection = pStandardFolderContext->ChildrenL();
iOwner.releaseCMsvEntryAndPopFromCleanupStack(pStandardFolderContext);
}
iResultCorrectlyOrdered = true;
} else { // NotEqual
ipEntrySelection = new(ELeave)CMsvEntrySelection;
QMessage::StandardFolder i = QMessage::InboxFolder;
while (i <= QMessage::TrashFolder) {
if (i != standardFolder) {
CMsvEntry* pStandardFolderContext = iOwner.retrieveCMsvEntryAndPushToCleanupStack(iOwner.standardFolderId(i));
if (pStandardFolderContext) {
pStandardFolderContext->SetSortTypeL(iOrdering);
CMsvEntrySelection* pEntries = pStandardFolderContext->ChildrenL();
CleanupStack::PushL(pEntries);
for (int i = 0; i < pEntries->Count(); i++) {
ipEntrySelection->AppendL(pEntries->At(i));
}
CleanupStack::PopAndDestroy(pEntries);
iOwner.releaseCMsvEntryAndPopFromCleanupStack(pStandardFolderContext);
}
}
i = static_cast<QMessage::StandardFolder>(static_cast<int>(i) + 1);
}
}
break;
}
case QMessageFilterPrivate::ParentAccountIdFilter:
case QMessageFilterPrivate::ParentFolderIdFilter:
case QMessageFilterPrivate::TimeStamp:
case QMessageFilterPrivate::ReceptionTimeStamp:
case QMessageFilterPrivate::Sender:
case QMessageFilterPrivate::Recipients:
case QMessageFilterPrivate::Subject:
case QMessageFilterPrivate::Status:
case QMessageFilterPrivate::Priority:
case QMessageFilterPrivate::Size:
case QMessageFilterPrivate::None:
break;
}
TMsvPartList partlist = 0;
TPtrC16 value(KNullDesC);
if (body.isEmpty()) {
if (iNumberOfHandledFilters < filters.count()) {
pf = QMessageFilterPrivate::implementation(filters[iNumberOfHandledFilters]);
if (pf->_matchFlags & QMessageDataComparator::MatchCaseSensitive) {
partlist |= KMsvFindCaseSensitive;
}
if (pf->_matchFlags & QMessageDataComparator::MatchFullWord) {
partlist |= KMsvFindWholeWord;
}
switch (pf->_field) {
case QMessageFilterPrivate::Sender:
{
if (pf->_comparatorType == QMessageFilterPrivate::Equality) {
QMessageDataComparator::EqualityComparator cmp(static_cast<QMessageDataComparator::EqualityComparator>(pf->_comparatorValue));
if (cmp == QMessageDataComparator::Equal) {
if (pf->_value.toString().length() > 0) {
value.Set(reinterpret_cast<const TUint16*>(pf->_value.toString().utf16()));
partlist |= KMsvMessagePartOriginator;
iNumberOfHandledFilters++;
}
} else { // NotEqual
// TODO:
}
} else if (pf->_comparatorType == QMessageFilterPrivate::Inclusion) {
QMessageDataComparator::InclusionComparator cmp(static_cast<QMessageDataComparator::InclusionComparator>(pf->_comparatorValue));
if (cmp == QMessageDataComparator::Includes) {
// TODO:
} else { // Excludes
// TODO:
}
}
break;
}
case QMessageFilterPrivate::Recipients: // to, cc & bcc fields
{
if (pf->_comparatorType == QMessageFilterPrivate::Inclusion) {
QMessageDataComparator::InclusionComparator cmp(static_cast<QMessageDataComparator::InclusionComparator>(pf->_comparatorValue));
if (cmp == QMessageDataComparator::Includes) {
if (pf->_value.toString().length() > 0) {
value.Set(reinterpret_cast<const TUint16*>(pf->_value.toString().utf16()));
partlist |= KMsvMessagePartRecipient;
iNumberOfHandledFilters++;
}
} else { // Excludes
//TODO:
}
}
break;
}
case QMessageFilterPrivate::Subject:
{
if (pf->_comparatorType == QMessageFilterPrivate::Equality) {
QMessageDataComparator::EqualityComparator cmp(static_cast<QMessageDataComparator::EqualityComparator>(pf->_comparatorValue));
if (cmp == QMessageDataComparator::Equal) {
if (pf->_value.toString().length() > 0) {
value.Set(reinterpret_cast<const TUint16*>(pf->_value.toString().utf16()));
partlist |= KMsvMessagePartDescription;
iNumberOfHandledFilters++;
}
} else { // NotEqual
// TODO:
}
} else if (pf->_comparatorType == QMessageFilterPrivate::Inclusion) {
QMessageDataComparator::InclusionComparator cmp(static_cast<QMessageDataComparator::InclusionComparator>(pf->_comparatorValue));
if (cmp == QMessageDataComparator::Includes) {
// TODO:
} else { // Excludes
// TODO:
}
}
break;
}
case QMessageFilterPrivate::TimeStamp:
{
if (pf->_comparatorType == QMessageFilterPrivate::Equality) {
QMessageDataComparator::EqualityComparator cmp(static_cast<QMessageDataComparator::EqualityComparator>(pf->_comparatorValue));
if (cmp == QMessageDataComparator::Equal) {
// TODO:
} else { // NotEqual
// TODO:
}
} else if (pf->_comparatorType == QMessageFilterPrivate::Relation) {
QMessageDataComparator::RelationComparator cmp(static_cast<QMessageDataComparator::RelationComparator>(pf->_comparatorValue));
if (cmp == QMessageDataComparator::LessThan) {
// TODO:
} else if (cmp == QMessageDataComparator::LessThanEqual) {
// TODO:
} else if (cmp == QMessageDataComparator::GreaterThan) {
// TODO:
} else { // GreaterThanEqual
// TODO:
}
}
break;
}
case QMessageFilterPrivate::ReceptionTimeStamp:
{
if (pf->_comparatorType == QMessageFilterPrivate::Equality) {
QMessageDataComparator::EqualityComparator cmp(static_cast<QMessageDataComparator::EqualityComparator>(pf->_comparatorValue));
if (cmp == QMessageDataComparator::Equal) {
value.Set(reinterpret_cast<const TUint16*>(pf->_value.toString().utf16()));
partlist |= KMsvMessagePartDate;
iNumberOfHandledFilters++;
} else { // NotEqual
// TODO:
}
} else if (pf->_comparatorType == QMessageFilterPrivate::Relation) {
QMessageDataComparator::RelationComparator cmp(static_cast<QMessageDataComparator::RelationComparator>(pf->_comparatorValue));
if (cmp == QMessageDataComparator::LessThan) {
// TODO:
} else if (cmp == QMessageDataComparator::LessThanEqual) {
// TODO:
} else if (cmp == QMessageDataComparator::GreaterThan) {
// TODO:
} else { // GreaterThanEqual
// TODO:
}
}
break;
}
case QMessageFilterPrivate::Status:
{
if (pf->_comparatorType == QMessageFilterPrivate::Equality) {
QMessageDataComparator::EqualityComparator cmp(static_cast<QMessageDataComparator::EqualityComparator>(pf->_comparatorValue));
if (cmp == QMessageDataComparator::Equal) {
// TODO:
} else { // NotEqual
// TODO:
}
} else if (pf->_comparatorType == QMessageFilterPrivate::Inclusion) {
QMessageDataComparator::InclusionComparator cmp(static_cast<QMessageDataComparator::InclusionComparator>(pf->_comparatorValue));
if (cmp == QMessageDataComparator::Includes) {
// TODO:
} else { // Excludes
// TODO:
}
}
break;
}
case QMessageFilterPrivate::Priority:
{
QMessageDataComparator::EqualityComparator cmp(static_cast<QMessageDataComparator::EqualityComparator>(pf->_comparatorValue));
if (cmp == QMessageDataComparator::Equal) {
// TODO:
} else { // NotEqual
// TODO:
}
break;
}
case QMessageFilterPrivate::Size:
{
if (pf->_comparatorType == QMessageFilterPrivate::Equality) {
QMessageDataComparator::EqualityComparator cmp(static_cast<QMessageDataComparator::EqualityComparator>(pf->_comparatorValue));
if (cmp == QMessageDataComparator::Equal) {
// TODO:
} else { // NotEqual
// TODO:
}
} else if (pf->_comparatorType == QMessageFilterPrivate::Relation) {
QMessageDataComparator::RelationComparator cmp(static_cast<QMessageDataComparator::RelationComparator>(pf->_comparatorValue));
if (cmp == QMessageDataComparator::LessThan) {
// TODO:
} else if (cmp == QMessageDataComparator::LessThanEqual) {
// TODO:
} else if (cmp == QMessageDataComparator::GreaterThan) {
// TODO:
} else { // GreaterThanEqual
// TODO:
}
}
break;
}
case QMessageFilterPrivate::ParentAccountIdFilter:
case QMessageFilterPrivate::ParentFolderIdFilter:
case QMessageFilterPrivate::Id:
case QMessageFilterPrivate::ParentFolderId:
case QMessageFilterPrivate::AncestorFolderIds:
case QMessageFilterPrivate::ParentAccountId:
case QMessageFilterPrivate::Type:
case QMessageFilterPrivate::StandardFolder:
case QMessageFilterPrivate::None:
break;
}
}
} else {
// Body
if (matchFlags & QMessageDataComparator::MatchCaseSensitive) {
partlist |= KMsvFindCaseSensitive;
}
if (matchFlags & QMessageDataComparator::MatchFullWord) {
partlist |= KMsvFindWholeWord;
}
value.Set(reinterpret_cast<const TUint16*>(body.utf16()));
partlist |= KMsvMessagePartBody;
}
if (iResultCorrectlyOrdered && iOrdering.Sorting() == EMsvSortByNone && !iOrdering.GroupingOn()) {
iResultCorrectlyOrdered = false;
}
if (!ipEntrySelection) {
ipEntrySelection = new(ELeave)CMsvEntrySelection;
getAllMessagesL(iOrdering);
}
if (partlist != 0 && ipEntrySelection->Count() > 0) {
ipMsvFindOperation = CMsvFindOperation::FindInSelectionL(*ipMsvSession, value, *ipEntrySelection, partlist, iStatus);
if (!IsActive()) {
SetActive();
}
} else {
iIdList = QMessageIdList();
for (int i=0; i < ipEntrySelection->Count(); i++) {
iIdList.append(QMessageId(QString::number((*ipEntrySelection)[i])));
}
iTimer.After(iStatus, 100);
if (!IsActive()) {
SetActive();
}
}
}
void CMessagesFindOperation::RunL()
{
if (iStatus.Int() != KErrNone) {
iOwner.filterAndOrderMessagesReady(false, iOperationId, QMessageIdList(), 0, false);
} else {
if (ipMsvFindOperation) {
const CMsvFindResultSelection& findResultSelection = ipMsvFindOperation->GetFindResult();
QMessageIdList msgIds;
for (int i=0; i < findResultSelection.Count(); i++) {
msgIds.append(QMessageId(QString::number(findResultSelection[i].iId)));
}
iOwner.filterAndOrderMessagesReady(true, iOperationId, msgIds, iNumberOfHandledFilters, iResultCorrectlyOrdered);
} else {
iOwner.filterAndOrderMessagesReady(true, iOperationId, iIdList, iNumberOfHandledFilters, iResultCorrectlyOrdered);
}
}
}
void CMessagesFindOperation::getAllMessagesL(const TMsvSelectionOrdering sortOrder)
{
// Get all messages from every known account
foreach (QMessageAccount value, iOwner.iAccounts) {
getAccountSpecificMessagesL(value, sortOrder);
}
}
void CMessagesFindOperation::getAccountSpecificMessagesL(QMessageAccount& messageAccount, const TMsvSelectionOrdering sortOrder, QMessageFilterPrivate* privateFolderFilter)
{
CMsvEntry* pService = iOwner.retrieveCMsvEntryAndPushToCleanupStack(messageAccount.d_ptr->_service1EntryId);
if (pService) {
TUid mtmUid = pService->Entry().iMtm;
iOwner.releaseCMsvEntryAndPopFromCleanupStack(pService);
getServiceSpecificMessagesL(messageAccount.d_ptr->_service1EntryId, sortOrder, privateFolderFilter);
}
TMsvId serviceId = messageAccount.d_ptr->_service2EntryId;
if (serviceId != 0) {
CMsvEntry* pService = iOwner.retrieveCMsvEntryAndPushToCleanupStack(serviceId);
if (pService) {
TUid mtmUid = pService->Entry().iMtm;
iOwner.releaseCMsvEntryAndPopFromCleanupStack(pService);
int count = ipEntrySelection->Count();
getServiceSpecificMessagesL(messageAccount.d_ptr->_service2EntryId, sortOrder, privateFolderFilter);
if (ipEntrySelection->Count() > count) {
iResultCorrectlyOrdered = false;
}
}
}
}
void CMessagesFindOperation::getServiceSpecificMessagesL(TMsvId serviceId, const TMsvSelectionOrdering sortOrder, QMessageFilterPrivate* privateFolderFilter)
{
if (privateFolderFilter) {
QMessageDataComparator::EqualityComparator cmp2(static_cast<QMessageDataComparator::EqualityComparator>(privateFolderFilter->_comparatorValue));
QMessage::StandardFolder standardFolder = static_cast<QMessage::StandardFolder>(privateFolderFilter->_value.toInt());
if (cmp2 == QMessageDataComparator::Equal) {
iResultCorrectlyOrdered = true;
getServiceSpecificMessagesFromFolderL(serviceId, sortOrder, iOwner.standardFolderId(standardFolder));
} else { // NotEqual
// Loop through all standard folders
QMessage::StandardFolder i = QMessage::InboxFolder;
while (i <= QMessage::TrashFolder) {
if (i != standardFolder) {
getServiceSpecificMessagesFromFolderL(serviceId, sortOrder, iOwner.standardFolderId(i));
}
i = static_cast<QMessage::StandardFolder>(static_cast<int>(i) + 1);
}
}
}
else {
// List all service specific messages from Standard Folders
QMessage::StandardFolder i = QMessage::InboxFolder;
while (i <= QMessage::TrashFolder) {
getServiceSpecificMessagesFromFolderL(serviceId, sortOrder, iOwner.standardFolderId(i));
i = static_cast<QMessage::StandardFolder>(static_cast<int>(i) + 1);
}
// List all service specific messages from user created folders
CMsvEntry* pEntry = iOwner.retrieveCMsvEntryAndPushToCleanupStack(serviceId);
if (pEntry) {
TUid mtmUid = pEntry->Entry().iMtm;
if (mtmUid == KUidMsgTypeSMS || mtmUid == KUidMsgTypeMultimedia || mtmUid == KUidMsgTypeSMTP) {
pEntry->SetEntryL(KDocumentsEntryIdValue);
CMsvEntrySelection* pSelection = pEntry->ChildrenWithTypeL(KUidMsvFolderEntry);
CleanupStack::PushL(pSelection);
for(TInt i = 0; i < pSelection->Count(); i++) {
CMsvEntryFilter* pFilter = CMsvEntryFilter::NewLC();
if (mtmUid == KUidMsgTypeSMS || mtmUid == KUidMsgTypeMultimedia) {
pFilter->SetMtm(mtmUid);
} else {
pFilter->SetService(serviceId);
}
pFilter->SetOrder(sortOrder);
pFilter->SetType(KUidMsvMessageEntry);
CMsvEntrySelection* pEntries = new(ELeave) CMsvEntrySelection;;
CleanupStack::PushL(pEntries);
ipMsvSession->GetChildIdsL(pSelection->At(i), *pFilter, *pEntries);
for(TInt j = 0; j < pEntries->Count(); j++) {
ipEntrySelection->AppendL(pEntries->At(j));
}
CleanupStack::PopAndDestroy(pEntries);
CleanupStack::PopAndDestroy(pFilter);
}
CleanupStack::PopAndDestroy(pSelection);
}
iOwner.releaseCMsvEntryAndPopFromCleanupStack(pEntry);
}
}
}
void CMessagesFindOperation::getServiceSpecificMessagesFromFolderL(TMsvId serviceId, const TMsvSelectionOrdering sortOrder, TMsvId standardFolderId)
{
CMsvEntry* pEntry = iOwner.retrieveCMsvEntryAndPushToCleanupStack(serviceId);
if (pEntry) {
pEntry->SetSortTypeL(sortOrder);
TUid mtmUid = pEntry->Entry().iMtm;
if (mtmUid == KUidMsgTypePOP3) {
if (standardFolderId == KMsvGlobalInBoxIndexEntryIdValue) {
// POP3 service has (Inbox) messages in service root
CMsvEntrySelection* pMessageEntries = pEntry->ChildrenWithTypeL(KUidMsvMessageEntry);
CleanupStack::PushL(pMessageEntries);
for (int i = 0; i < pMessageEntries->Count(); i++) {
ipEntrySelection->AppendL(pMessageEntries->At(i));
}
CleanupStack::PopAndDestroy(pMessageEntries);
}
} else if (mtmUid == KUidMsgTypeIMAP4) {
if (standardFolderId == KMsvGlobalInBoxIndexEntryIdValue) {
// All IMAP4 folders are treated as Inbox folders
// IMAP4 service has folders in service root
CMsvEntrySelection* pFolderEntries = pEntry->ChildrenWithTypeL(KUidMsvFolderEntry);
CleanupStack::PushL(pFolderEntries);
for (int i = 0; i < pFolderEntries->Count(); i++) {
pEntry->SetEntryL(pFolderEntries->At(i));
CMsvEntrySelection* pMessageEntries = pEntry->ChildrenWithTypeL(KUidMsvMessageEntry);
CleanupStack::PushL(pMessageEntries);
for (int j = 0; j < pMessageEntries->Count(); j++) {
ipEntrySelection->AppendL(pMessageEntries->At(j));
}
CleanupStack::PopAndDestroy(pMessageEntries);
}
CleanupStack::PopAndDestroy(pFolderEntries);
}
} else {
// Handle SMS, MMS & SMTP Standard Folders
CMsvEntryFilter* pFilter = CMsvEntryFilter::NewLC();
if (mtmUid == KUidMsgTypeSMTP) {
// There maybe multiple SMTP Services
// => Messages must be queried using ServiceId
pFilter->SetService(serviceId);
} else {
// There is only one service per SMS and per MMS
// => Messages can be queried using MTM Uid
pFilter->SetMtm(mtmUid);
}
pFilter->SetOrder(sortOrder);
pFilter->SetType(KUidMsvMessageEntry);
CMsvEntrySelection* pEntries = new(ELeave) CMsvEntrySelection;;
CleanupStack::PushL(pEntries);
ipMsvSession->GetChildIdsL(standardFolderId, *pFilter, *pEntries);
for (int i = 0; i < pEntries->Count(); i++) {
ipEntrySelection->AppendL(pEntries->At(i));
}
CleanupStack::PopAndDestroy(pEntries);
CleanupStack::PopAndDestroy(pFilter);
}
iOwner.releaseCMsvEntryAndPopFromCleanupStack(pEntry);
}
}
QTM_END_NAMESPACE