qtmobility/src/messaging/qfsengine_symbian.cpp
changeset 14 6fbed849b4f4
child 15 1f895d8a5b2b
equal deleted inserted replaced
11:06b8e2af4411 14:6fbed849b4f4
       
     1 /****************************************************************************
       
     2 **
       
     3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
     4 ** All rights reserved.
       
     5 ** Contact: Nokia Corporation (qt-info@nokia.com)
       
     6 **
       
     7 ** This file is part of the Qt Mobility Components.
       
     8 **
       
     9 ** $QT_BEGIN_LICENSE:LGPL$
       
    10 ** No Commercial Usage
       
    11 ** This file contains pre-release code and may not be distributed.
       
    12 ** You may use this file in accordance with the terms and conditions
       
    13 ** contained in the Technology Preview License Agreement accompanying
       
    14 ** this package.
       
    15 **
       
    16 ** GNU Lesser General Public License Usage
       
    17 ** Alternatively, this file may be used under the terms of the GNU Lesser
       
    18 ** General Public License version 2.1 as published by the Free Software
       
    19 ** Foundation and appearing in the file LICENSE.LGPL included in the
       
    20 ** packaging of this file.  Please review the following information to
       
    21 ** ensure the GNU Lesser General Public License version 2.1 requirements
       
    22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
       
    23 **
       
    24 ** In addition, as a special exception, Nokia gives you certain additional
       
    25 ** rights.  These rights are described in the Nokia Qt LGPL Exception
       
    26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
       
    27 **
       
    28 ** If you have questions regarding the use of this file, please contact
       
    29 ** Nokia at qt-info@nokia.com.
       
    30 **
       
    31 **
       
    32 **
       
    33 **
       
    34 **
       
    35 **
       
    36 **
       
    37 **
       
    38 ** $QT_END_LICENSE$
       
    39 **
       
    40 ****************************************************************************/
       
    41 
       
    42 #include "qmessageservice.h"
       
    43 #include "qmessageservice_symbian_p.h"
       
    44 #include "qfsengine_symbian_p.h"
       
    45 #include "qmessage_symbian_p.h"
       
    46 #include "messagingutil_p.h"
       
    47 #include "qmessageaccount.h"
       
    48 #include "qmessageaccount_p.h"
       
    49 #include "qmessageaccountfilter.h"
       
    50 #include "qmessageaccountfilter_p.h"
       
    51 #include "qmessagecontentcontainer_symbian_p.h"
       
    52 #include "qmessagefolder.h"
       
    53 #include "qmessagefolder_p.h"
       
    54 #include "qmessagefolderfilter.h"
       
    55 #include "qmessagefolderfilter_p.h"
       
    56 #include "qmessageaccountsortorder_p.h"
       
    57 #include "qmessagestore_symbian_p.h"
       
    58 #include "qmessagefoldersortorder_p.h"
       
    59 #include "qmessagesortorder_p.h"
       
    60 
       
    61 #include <emailinterfacefactory.h>
       
    62 #include <QTextCodec>
       
    63 #include <emailapidefs.h>
       
    64 #include <memailmailbox.h>
       
    65 #include <memailfolder.h>
       
    66 #include <memailmessage.h>
       
    67 #include <memailaddress.h>
       
    68 #include <memailcontent.h>
       
    69 #include <mmessageiterator.h>
       
    70 
       
    71 using namespace EmailInterface;
       
    72 
       
    73 QTM_BEGIN_NAMESPACE
       
    74 
       
    75 using namespace SymbianHelpers;
       
    76 
       
    77 Q_GLOBAL_STATIC(CFSEngine,fsEngine);
       
    78 
       
    79 CFSEngine::CFSEngine()
       
    80 {
       
    81     TRAPD(err, {
       
    82         m_factory = CEmailInterfaceFactory::NewL(); 
       
    83         m_ifPtr = m_factory->InterfaceL(KEmailClientApiInterface);
       
    84     });
       
    85     
       
    86     Q_UNUSED(err);
       
    87     m_clientApi = static_cast<MEmailClientApi*>(m_ifPtr);
       
    88 #ifdef FREESTYLEMAILBOXOBSERVERUSED
       
    89     TRAPD(err2, setPluginObserversL());
       
    90     Q_UNUSED(err2);
       
    91 #endif
       
    92 }
       
    93 
       
    94 CFSEngine::~CFSEngine()
       
    95 {
       
    96     m_mtmAccountList.clear();
       
    97     for (TInt i = 0; i < m_attachments.Count(); i++){
       
    98         m_attachments[i]->Release();
       
    99     }
       
   100     m_attachments.Reset();
       
   101     for (TInt i = 0; i < m_mailboxes.Count(); i++){
       
   102         m_mailboxes[i]->Release();
       
   103     }
       
   104     m_mailboxes.Reset();
       
   105     m_clientApi->Release();
       
   106     delete m_factory;
       
   107 }
       
   108 
       
   109 CFSEngine* CFSEngine::instance()
       
   110 {   
       
   111     return fsEngine();
       
   112 }
       
   113 
       
   114 bool CFSEngine::accountLessThan(const QMessageAccountId accountId1, const QMessageAccountId accountId2)
       
   115 {
       
   116     CFSEngine* freestyleEngine = fsEngine();
       
   117     return QMessageAccountSortOrderPrivate::lessThan(freestyleEngine->m_currentAccountOrdering,
       
   118         freestyleEngine->account(accountId1),
       
   119         freestyleEngine->account(accountId2));
       
   120 }
       
   121 
       
   122 void CFSEngine::orderAccounts(QMessageAccountIdList& accountIds, const QMessageAccountSortOrder &sortOrder) const
       
   123 {
       
   124     Q_UNUSED(accountIds);
       
   125     m_currentAccountOrdering = sortOrder;
       
   126     qSort(accountIds.begin(), accountIds.end(), CFSEngine::accountLessThan);
       
   127 }
       
   128 
       
   129 bool CFSEngine::folderLessThan(const QMessageFolderId folderId1, const QMessageFolderId folderId2)
       
   130 {
       
   131     CFSEngine* freestyleEngine = fsEngine();
       
   132     return QMessageFolderSortOrderPrivate::lessThan(freestyleEngine->m_currentFolderOrdering,
       
   133             freestyleEngine->folder(folderId1),
       
   134             freestyleEngine->folder(folderId2));
       
   135 }
       
   136 
       
   137 void CFSEngine::orderFolders(QMessageFolderIdList& folderIds,  const QMessageFolderSortOrder &sortOrder) const
       
   138 {
       
   139     m_currentFolderOrdering = sortOrder;
       
   140     qSort(folderIds.begin(), folderIds.end(), CFSEngine::folderLessThan);
       
   141 }
       
   142 
       
   143 bool CFSEngine::messageLessThan(const QMessage& message1, const QMessage& message2)
       
   144 {
       
   145     CFSEngine* freestyleEngine = fsEngine();
       
   146     return QMessageSortOrderPrivate::lessThan(freestyleEngine->m_currentMessageOrdering, message1, message2);
       
   147 }
       
   148 
       
   149 void CFSEngine::orderMessages(QMessageIdList& messageIds, const QMessageSortOrder &sortOrder) const
       
   150 {
       
   151     m_currentMessageOrdering = sortOrder;
       
   152     QList<QMessage> messages;
       
   153     for (int i=0; i < messageIds.count(); i++) {
       
   154         messages.append(message(messageIds[i]));
       
   155     }
       
   156     qSort(messages.begin(), messages.end(), CFSEngine::messageLessThan);
       
   157     messageIds.clear();
       
   158     for (int i=0; i < messages.count(); i++) {
       
   159         messageIds.append(messages[i].id());
       
   160     }
       
   161 }
       
   162 
       
   163 void CFSEngine::setMtmAccountIdList(QMessageAccountIdList accountList)
       
   164 {
       
   165     for (TInt i = 0; i < accountList.count(); i++) {
       
   166         m_mtmAccountList.append(stripIdPrefix(accountList[i]));
       
   167     }
       
   168 }
       
   169 
       
   170 QMessageAccountIdList CFSEngine::queryAccounts(const QMessageAccountFilter &filter, const QMessageAccountSortOrder &sortOrder, uint limit, uint offset) const
       
   171 {
       
   172     QMessageAccountIdList accountIds;
       
   173 
       
   174     TRAPD(err, updateEmailAccountsL());
       
   175     Q_UNUSED(err);
       
   176     
       
   177     QMessageAccountFilterPrivate* privateMessageAccountFilter = QMessageAccountFilterPrivate::implementation(filter);
       
   178     if (filter.isEmpty()) {
       
   179         if (!privateMessageAccountFilter->_notFilter) {
       
   180             // All accounts are returned for empty filter
       
   181             foreach (QMessageAccount value, m_accounts) {                
       
   182                 accountIds.append(value.id());
       
   183             }
       
   184         }
       
   185     } else {
       
   186         if (privateMessageAccountFilter->_valid) {
       
   187             foreach (QMessageAccount value, m_accounts) {
       
   188                 if (privateMessageAccountFilter->filter(value)) {
       
   189                     accountIds.append(value.id());
       
   190                 }
       
   191             }
       
   192         } else {
       
   193             foreach (QMessageAccount value, m_accounts) {
       
   194                 if (privateMessageAccountFilter->filter(value)) {
       
   195                     accountIds.append(value.id());
       
   196                 }
       
   197             }
       
   198         }
       
   199     }
       
   200     
       
   201     if (!sortOrder.isEmpty()) {
       
   202         orderAccounts(accountIds, sortOrder);
       
   203     }
       
   204 
       
   205     applyOffsetAndLimitToAccountIds(accountIds, offset, limit);
       
   206 
       
   207     return accountIds;
       
   208 }
       
   209 
       
   210 void CFSEngine::applyOffsetAndLimitToAccountIds(QMessageAccountIdList& idList, int offset, int limit) const
       
   211 {
       
   212     if (offset > 0) {
       
   213         if (offset > idList.count()) {
       
   214             idList.clear();
       
   215         } else {
       
   216             for (int i = 0; i < offset; i++) {
       
   217                 idList.removeFirst();
       
   218             }
       
   219         }
       
   220     }
       
   221     if (limit > 0) {
       
   222         for (int i = idList.count()-1; i >= limit; i--) {
       
   223             idList.removeAt(i);
       
   224         }
       
   225     }
       
   226 }
       
   227 
       
   228 int CFSEngine::countAccounts(const QMessageAccountFilter &filter) const
       
   229 {
       
   230     return queryAccounts(filter, QMessageAccountSortOrder(), 0, 0).count();
       
   231 }
       
   232 
       
   233 QMessageAccount CFSEngine::account(const QMessageAccountId &id) const
       
   234 {
       
   235     TRAPD(err, updateEmailAccountsL());
       
   236     Q_UNUSED(err)
       
   237     return m_accounts[id.toString()];
       
   238 }
       
   239 
       
   240 QMessageAccountId CFSEngine::defaultAccount(QMessage::Type type) const
       
   241 {
       
   242     // TODO
       
   243     Q_UNUSED(type);
       
   244     return QMessageAccountId();
       
   245 }
       
   246 
       
   247 QMessageAccountIdList CFSEngine::accountsByType(QMessage::Type type) const
       
   248 {
       
   249     QMessageAccountIdList accountIds = QMessageAccountIdList();
       
   250     
       
   251     foreach (QMessageAccount value, m_accounts) {
       
   252         if ((value.messageTypes() & type) == (int)type) {
       
   253             accountIds.append(value.id());
       
   254         }
       
   255     }
       
   256     
       
   257     return accountIds;
       
   258 }
       
   259 
       
   260 
       
   261 void CFSEngine::updateEmailAccountsL() const
       
   262 {
       
   263     QStringList keys = m_accounts.keys();
       
   264     RMailboxPtrArray mailboxes;
       
   265     CleanupResetAndRelease<MEmailMailbox>::PushL(mailboxes);
       
   266     
       
   267     m_clientApi->GetMailboxesL(mailboxes);
       
   268     
       
   269     for (TInt i = 0; i < mailboxes.Count(); i++) {
       
   270         MEmailMailbox *mailbox = mailboxes[i];
       
   271         QString idAsString = QString::number(mailbox->MailboxId().iId);
       
   272         QString fsIdAsString = addIdPrefix(idAsString, SymbianHelpers::EngineTypeFreestyle);
       
   273         TBool overlap = false;
       
   274         for (TInt j = 0; j < m_mtmAccountList.count(); j++) {
       
   275             if (idAsString == m_mtmAccountList[j].toString())
       
   276                 overlap = true;
       
   277         }
       
   278         if (!m_accounts.contains(fsIdAsString) && !overlap) {     
       
   279             QMessageAccount account = QMessageAccountPrivate::from(
       
   280                                       QMessageAccountId(fsIdAsString),
       
   281                                       QString::fromUtf16(mailbox->MailboxName().Ptr(), mailbox->MailboxName().Length()),
       
   282                                       0,
       
   283                                       0,
       
   284                                       QMessage::Email);
       
   285           
       
   286             m_accounts.insert(fsIdAsString, account);
       
   287             
       
   288         } else {
       
   289             keys.removeOne(fsIdAsString);
       
   290         }
       
   291         mailbox->Release();
       
   292     }  
       
   293     
       
   294     mailboxes.Reset();
       
   295     CleanupStack::PopAndDestroy();
       
   296     
       
   297     for (int i=0; i < keys.count(); i++) {
       
   298         m_accounts.remove(keys[i]);
       
   299     }   
       
   300 }
       
   301 
       
   302 #ifdef FREESTYLEMAILBOXOBSERVERUSED
       
   303 void CFSEngine::setPluginObserversL()
       
   304 {
       
   305     m_clientApi->GetMailboxesL(m_mailboxes);    
       
   306     for (TInt i = 0; i < m_mailboxes.Count(); i++) {
       
   307         MEmailMailbox *mailbox = m_mailboxes[i];
       
   308         mailbox->RegisterObserverL(*this);
       
   309     }  
       
   310 }
       
   311 
       
   312 void CFSEngine::NewMessageEventL(const TMailboxId& aMailbox, const REmailMessageIdArray aNewMessages, const TFolderId& aParentFolderId)
       
   313 {
       
   314     QMessageManager::NotificationFilterIdSet matchingFilters;
       
   315     QMessageStorePrivate::NotificationType notificationType = QMessageStorePrivate::Added;
       
   316   
       
   317     for (TInt i = 0; i < aNewMessages.Count(); i++) {
       
   318         TMessageId messageId(aNewMessages[i]);
       
   319         notificationL(aMailbox, messageId, aParentFolderId, notificationType);
       
   320     }
       
   321 }
       
   322 
       
   323 void CFSEngine::MessageChangedEventL(const TMailboxId& aMailbox, const REmailMessageIdArray aChangedMessages, const TFolderId& aParentFolderId)
       
   324 {
       
   325     QMessageManager::NotificationFilterIdSet matchingFilters;
       
   326     QMessageStorePrivate::NotificationType notificationType = QMessageStorePrivate::Updated;
       
   327   
       
   328     for (TInt i = 0; i < aChangedMessages.Count(); i++) {
       
   329         TMessageId messageId(aChangedMessages[i]);
       
   330         notificationL(aMailbox, messageId, aParentFolderId, notificationType);
       
   331     }
       
   332 }
       
   333 
       
   334 void CFSEngine::MessageDeletedEventL(const TMailboxId& aMailbox, const REmailMessageIdArray aDeletedMessages, const TFolderId& aParentFolderId)
       
   335 {
       
   336     // TODO: add filter handling
       
   337     QMessageManager::NotificationFilterIdSet matchingFilters;
       
   338     QMap<int, QMessageFilter> filters(m_filters);
       
   339     QMap<int, QMessageFilter>::const_iterator it = filters.begin(), end = filters.end();  
       
   340     QMessageStorePrivate::NotificationType notificationType = QMessageStorePrivate::Removed;
       
   341     MEmailMailbox* mailbox = m_clientApi->MailboxL(aMailbox);
       
   342     MEmailFolder* folder = mailbox->FolderL(aParentFolderId); 
       
   343     QString idAsString = QString::number(mailbox->MailboxId().iId);
       
   344     for (TInt j = 0; j < m_mtmAccountList.count(); j++) {
       
   345         if (idAsString == m_mtmAccountList[j].toString())
       
   346             return;
       
   347     } 
       
   348     for (TInt i = 0; i < aDeletedMessages.Count(); i++) {
       
   349         for ( ; it != end; ++it) {
       
   350             // Empty filter matches to all messages
       
   351             matchingFilters.insert(it.key());
       
   352         }
       
   353         TMessageId messageId(aDeletedMessages[i]);
       
   354         ipMessageStorePrivate->messageNotification(notificationType, 
       
   355                             QMessageId(addIdPrefix(QString::number(messageId.iId), SymbianHelpers::EngineTypeFreestyle)), 
       
   356                             matchingFilters);
       
   357     }
       
   358     folder->Release();
       
   359     mailbox->Release();
       
   360 }
       
   361 
       
   362 void CFSEngine::notificationL(const TMailboxId& aMailbox, const TMessageId& aMessageId, 
       
   363                                 const TFolderId& aParentFolderId, QMessageStorePrivate::NotificationType aNotificationType)
       
   364 {
       
   365     Q_UNUSED(aParentFolderId);
       
   366     QMessageManager::NotificationFilterIdSet matchingFilters;
       
   367     // Copy the filter map to protect against modification during traversal
       
   368     QMap<int, QMessageFilter> filters(m_filters);
       
   369     QMap<int, QMessageFilter>::const_iterator it = filters.begin(), end = filters.end();
       
   370     QMessage message;
       
   371     QMessageId realMessageId = QMessageId(addIdPrefix(QString::number(aMessageId.iId), SymbianHelpers::EngineTypeFreestyle));
       
   372     bool messageRetrieved = false;    
       
   373     MEmailMailbox* mailbox = m_clientApi->MailboxL(aMailbox);
       
   374     CleanupReleasePushL(*mailbox);
       
   375     QString idAsString = QString::number(mailbox->MailboxId().iId);
       
   376     for (TInt j = 0; j < m_mtmAccountList.count(); j++) {
       
   377         if (idAsString == m_mtmAccountList[j].toString()) {
       
   378             CleanupStack::Pop(mailbox);
       
   379             return;
       
   380         }
       
   381     }   
       
   382     for ( ; it != end; ++it) {
       
   383         const QMessageFilter &filter(it.value());
       
   384         if (!messageRetrieved) {
       
   385             MEmailMessage* fsMessage = mailbox->MessageL(aMessageId);
       
   386             CleanupReleasePushL(*fsMessage);
       
   387             
       
   388             if (!fsMessage) {
       
   389                 CleanupStack::Pop(fsMessage);
       
   390                 CleanupStack::Pop(mailbox);
       
   391                 return;
       
   392             }
       
   393             message = CreateQMessageL(fsMessage);
       
   394             messageRetrieved = true;
       
   395             CleanupStack::Pop(fsMessage);
       
   396         }
       
   397 
       
   398         if (filter.isEmpty()) {
       
   399             // Empty filter matches to all messages
       
   400             matchingFilters.insert(it.key());
       
   401         } else {
       
   402             if (message.type() == QMessage::NoType) {
       
   403                 matchingFilters.clear();
       
   404                 continue;
       
   405             }
       
   406         }
       
   407         QMessageFilterPrivate* privateMessageFilter = QMessageFilterPrivate::implementation(filter);
       
   408         if (privateMessageFilter->filter(message)) {
       
   409             matchingFilters.insert(it.key());
       
   410         }
       
   411         
       
   412     }
       
   413     int c = matchingFilters.count();
       
   414     QString id = realMessageId.toString();
       
   415     if (matchingFilters.count() > 0)
       
   416         ipMessageStorePrivate->messageNotification(aNotificationType, realMessageId, matchingFilters);
       
   417     
       
   418     CleanupStack::Pop(mailbox);   
       
   419 }
       
   420 
       
   421 #endif
       
   422 
       
   423 MEmailMessage* CFSEngine::createFSMessageL(const QMessage &message, const MEmailMailbox* mailbox)
       
   424 {
       
   425     MEmailMessage* fsMessage = mailbox->CreateDraftMessageL();
       
   426     CleanupReleasePushL(*fsMessage);
       
   427     
       
   428     switch (message.priority()) {
       
   429         case QMessage::HighPriority:
       
   430             fsMessage->SetFlag(EmailInterface::EFlag_Important);
       
   431             fsMessage->ResetFlag(EmailInterface::EFlag_Low);
       
   432             break;
       
   433         case QMessage::NormalPriority:
       
   434             fsMessage->ResetFlag(EmailInterface::EFlag_Important);
       
   435             fsMessage->ResetFlag(EmailInterface::EFlag_Low);
       
   436             break;
       
   437         case QMessage::LowPriority:
       
   438             fsMessage->SetFlag(EmailInterface::EFlag_Low);
       
   439             fsMessage->ResetFlag(EmailInterface::EFlag_Important);
       
   440             break;            
       
   441         }
       
   442         if (message.status() & QMessage::Read) {
       
   443             fsMessage->SetFlag(EmailInterface::EFlag_Read);
       
   444         } else {
       
   445             fsMessage->ResetFlag(EmailInterface::EFlag_Read);
       
   446         }
       
   447     
       
   448     MEmailAddress* sender = mailbox->AddressL();
       
   449     sender->SetRole(MEmailAddress::ESender);
       
   450     fsMessage->SetReplyToAddressL(*sender);
       
   451         
       
   452     QList<QMessageAddress> toList(message.to());
       
   453     if (toList.count() > 0) {
       
   454         TPtrC16 receiver(KNullDesC);
       
   455         QString qreceiver;
       
   456         REmailAddressArray toAddress;
       
   457         for (int i = 0; i < toList.size(); ++i) {
       
   458             qreceiver = toList.at(i).addressee();
       
   459             receiver.Set(reinterpret_cast<const TUint16*>(qreceiver.utf16()));
       
   460             MEmailAddress* address = mailbox->AddressL();
       
   461             address->SetAddressL(receiver);
       
   462             address->SetDisplayNameL(receiver);
       
   463             address->SetRole(MEmailAddress::ETo);
       
   464             toAddress.Append(address);
       
   465         }
       
   466         fsMessage->SetRecipientsL(MEmailAddress::ETo, toAddress);
       
   467     }
       
   468     
       
   469     QList<QMessageAddress> ccList(message.cc());
       
   470     if (ccList.count() > 0) {
       
   471         TPtrC16 receiver(KNullDesC);
       
   472         QString qreceiver;
       
   473         REmailAddressArray ccAddress;
       
   474         for (int i = 0; i < ccList.size(); ++i) {
       
   475             qreceiver = ccList.at(i).addressee();
       
   476             receiver.Set(reinterpret_cast<const TUint16*>(qreceiver.utf16()));
       
   477             MEmailAddress* address = mailbox->AddressL();
       
   478             address->SetDisplayNameL(receiver);
       
   479             address->SetRole(MEmailAddress::ECc);
       
   480             address->SetAddressL(receiver);
       
   481             ccAddress.Append(address);
       
   482         }
       
   483         fsMessage->SetRecipientsL(MEmailAddress::ECc, ccAddress);
       
   484     }
       
   485         
       
   486     QList<QMessageAddress> bccList(message.bcc());
       
   487     if (bccList.count() > 0) {
       
   488         TPtrC16 receiver(KNullDesC);
       
   489         QString qreceiver;
       
   490         REmailAddressArray bccAddress;
       
   491         for (int i = 0; i < bccList.size(); ++i) {
       
   492             qreceiver = bccList.at(i).addressee();
       
   493             receiver.Set(reinterpret_cast<const TUint16*>(qreceiver.utf16()));
       
   494             MEmailAddress* address = mailbox->AddressL();
       
   495             address->SetDisplayNameL(receiver);
       
   496             address->SetRole(MEmailAddress::EBcc);
       
   497             address->SetAddressL(receiver);
       
   498             bccAddress.Append(address);
       
   499         }
       
   500         fsMessage->SetRecipientsL(MEmailAddress::EBcc, bccAddress);
       
   501     }
       
   502     if (message.bodyId() == QMessageContentContainerPrivate::bodyContentId()) {
       
   503         // Message contains only body (not attachments)
       
   504         QString messageBody = message.textContent();
       
   505         if (!messageBody.isEmpty()) {
       
   506             QByteArray type = message.contentType();
       
   507             QByteArray subType = message.contentSubType();
       
   508             MEmailMessageContent* content = fsMessage->ContentL();
       
   509             MEmailTextContent* textContent = content->AsTextContentOrNull();
       
   510             if (textContent) {
       
   511                 if (type == "text" && subType == "plain") {
       
   512                     textContent->SetTextL(MEmailTextContent::EPlainText, TPtrC(reinterpret_cast<const TUint16*>(message.textContent().utf16())));
       
   513                 } 
       
   514                else if (type == "text" && subType == "html") {
       
   515                     textContent->SetTextL(MEmailTextContent::EHtmlText, TPtrC(reinterpret_cast<const TUint16*>(message.textContent().utf16())));
       
   516                 }
       
   517             }
       
   518             else
       
   519                 fsMessage->SetPlainTextBodyL(TPtrC(reinterpret_cast<const TUint16*>(message.textContent().utf16())));
       
   520         }
       
   521     } else {
       
   522         // Message contains body and attachments
       
   523         QMessageContentContainerIdList contentIds = message.contentIds();
       
   524         foreach (QMessageContentContainerId id, contentIds){
       
   525             QMessageContentContainer container = message.find(id);
       
   526             MEmailMessageContent* content = fsMessage->ContentL(); 
       
   527             QMessageContentContainerPrivate* pPrivateContainer = QMessageContentContainerPrivate::implementation(container);
       
   528             if (pPrivateContainer->_id == message.bodyId()) {
       
   529                 // ContentContainer is body
       
   530                 if (!container.textContent().isEmpty()) {               
       
   531                     MEmailTextContent* textContent = content->AsTextContentOrNull();
       
   532                     if (textContent) {
       
   533                         QByteArray type = container.contentType();
       
   534                         QByteArray subType = container.contentSubType();
       
   535                         if (type == "text" && subType == "plain") {
       
   536                             textContent->SetTextL(MEmailTextContent::EPlainText, TPtrC(reinterpret_cast<const TUint16*>(container.textContent().utf16())));
       
   537                         }
       
   538                         else if (type == "text" && subType == "html") {
       
   539                             textContent->SetTextL(MEmailTextContent::EHtmlText, TPtrC(reinterpret_cast<const TUint16*>(container.textContent().utf16())));
       
   540                         } 
       
   541                     }
       
   542                     else
       
   543                         fsMessage->SetPlainTextBodyL(TPtrC(reinterpret_cast<const TUint16*>(container.textContent().utf16())));
       
   544                 }
       
   545             } else {
       
   546                 // ContentContainer is attachment
       
   547                 QByteArray filePath = QMessageContentContainerPrivate::attachmentFilename(container);
       
   548                 // Replace Qt style path separator "/" with Symbian path separator "\"
       
   549                 filePath.replace(QByteArray("/"), QByteArray("\\"));
       
   550                 QString temp_path = QString(filePath);
       
   551                 TPtrC16 attachmentPath(KNullDesC);
       
   552                 attachmentPath.Set(reinterpret_cast<const TUint16*>(temp_path.utf16()));
       
   553                 fsMessage->AddAttachmentL(attachmentPath);
       
   554             }        
       
   555         }
       
   556     }
       
   557     fsMessage->SetSubjectL(TPtrC(reinterpret_cast<const TUint16*>(message.subject().utf16())));
       
   558     
       
   559     QMessagePrivate* privateMessage = QMessagePrivate::implementation(message);
       
   560     privateMessage->_id = QMessageId(addIdPrefix(QString::number(fsMessage->MessageId().iId),SymbianHelpers::EngineTypeFreestyle));
       
   561     
       
   562     fsMessage->SaveChangesL();
       
   563     CleanupStack::Pop(fsMessage);
       
   564     return fsMessage;
       
   565 }
       
   566 
       
   567 bool CFSEngine::addMessage(QMessage* message)
       
   568 {
       
   569     TMailboxId mailboxId(stripIdPrefix(message->parentAccountId().toString()).toInt());
       
   570     MEmailMailbox* mailbox = NULL;
       
   571     TRAPD(mailerr, mailbox = m_clientApi->MailboxL(mailboxId));
       
   572     if (mailerr != KErrNone)
       
   573         return false;
       
   574 
       
   575     MEmailMessage* fsMessage = NULL;
       
   576     TRAPD(err, fsMessage = createFSMessageL(*message, mailbox));
       
   577     if (fsMessage)
       
   578         fsMessage->Release();
       
   579     if (mailbox)
       
   580         mailbox->Release();
       
   581     
       
   582     if (err != KErrNone)
       
   583         return false;
       
   584     else
       
   585         return true;
       
   586 }
       
   587 
       
   588 bool CFSEngine::updateMessage(QMessage* message)
       
   589 {
       
   590     TRAPD(err, updateMessageL(message));
       
   591     if (err != KErrNone)
       
   592         return false;
       
   593     else
       
   594         return true;
       
   595 }
       
   596 
       
   597 void CFSEngine::updateMessageL(QMessage* message)
       
   598 {
       
   599     TMailboxId mailboxId(stripIdPrefix(message->parentAccountId().toString()).toInt());
       
   600     MEmailMailbox* mailbox = m_clientApi->MailboxL(mailboxId);
       
   601     CleanupReleasePushL(*mailbox);
       
   602   
       
   603     TMessageId messageId(message->id().toString().toInt(),
       
   604                             message->parentFolderId().toString().toInt(), 
       
   605                             mailboxId);
       
   606     MEmailMessage* fsMessage = mailbox->MessageL(messageId);
       
   607     CleanupReleasePushL(*fsMessage);
       
   608     
       
   609     switch (message->priority()) {
       
   610         case QMessage::HighPriority:
       
   611             fsMessage->SetFlag(EmailInterface::EFlag_Important);
       
   612             fsMessage->ResetFlag(EmailInterface::EFlag_Low);
       
   613             break;
       
   614         case QMessage::NormalPriority:
       
   615             fsMessage->ResetFlag(EmailInterface::EFlag_Important);
       
   616             fsMessage->ResetFlag(EmailInterface::EFlag_Low);
       
   617             break;
       
   618         case QMessage::LowPriority:
       
   619             fsMessage->SetFlag(EmailInterface::EFlag_Low);
       
   620             fsMessage->ResetFlag(EmailInterface::EFlag_Important);
       
   621             break;            
       
   622         }
       
   623         if (message->status() & QMessage::Read) {
       
   624             fsMessage->SetFlag(EmailInterface::EFlag_Read);
       
   625         } else {
       
   626             fsMessage->ResetFlag(EmailInterface::EFlag_Read);
       
   627         }
       
   628         
       
   629     MEmailAddress* sender = mailbox->AddressL();
       
   630     sender->SetRole(MEmailAddress::ESender);
       
   631     fsMessage->SetReplyToAddressL(*sender);
       
   632         
       
   633     QList<QMessageAddress> toList(message->to());
       
   634     if (toList.count() > 0) {
       
   635         TPtrC16 receiver(KNullDesC);
       
   636         QString qreceiver;
       
   637         REmailAddressArray toAddress;
       
   638         for (int i = 0; i < toList.size(); ++i) {
       
   639             qreceiver = toList.at(i).addressee();
       
   640             receiver.Set(reinterpret_cast<const TUint16*>(qreceiver.utf16()));
       
   641             MEmailAddress* address = mailbox->AddressL();
       
   642             address->SetAddressL(receiver);
       
   643             toAddress.Append(address);
       
   644         }
       
   645         fsMessage->SetRecipientsL(MEmailAddress::ETo, toAddress);
       
   646     }
       
   647     
       
   648     QList<QMessageAddress> ccList(message->cc());
       
   649     if (ccList.count() > 0) {
       
   650         TPtrC16 receiver(KNullDesC);
       
   651         QString qreceiver;
       
   652         REmailAddressArray ccAddress;
       
   653         for (int i = 0; i < ccList.size(); ++i) {
       
   654             qreceiver = ccList.at(i).addressee();
       
   655             receiver.Set(reinterpret_cast<const TUint16*>(qreceiver.utf16()));
       
   656             MEmailAddress* address = mailbox->AddressL();;
       
   657             address->SetAddressL(receiver);
       
   658             ccAddress.Append(address);
       
   659         }
       
   660         fsMessage->SetRecipientsL(MEmailAddress::ECc, ccAddress);
       
   661     }
       
   662         
       
   663     QList<QMessageAddress> bccList(message->bcc());
       
   664     if (bccList.count() > 0) {
       
   665         TPtrC16 receiver(KNullDesC);
       
   666         QString qreceiver;
       
   667         REmailAddressArray bccAddress;
       
   668         for (int i = 0; i < bccList.size(); ++i) {
       
   669             qreceiver = bccList.at(i).addressee();
       
   670             receiver.Set(reinterpret_cast<const TUint16*>(qreceiver.utf16()));
       
   671             MEmailAddress* address = mailbox->AddressL();;
       
   672             address->SetAddressL(receiver);
       
   673             bccAddress.Append(address);
       
   674         }
       
   675         fsMessage->SetRecipientsL(MEmailAddress::EBcc, bccAddress);
       
   676     }
       
   677     
       
   678     if (message->bodyId() == QMessageContentContainerPrivate::bodyContentId()) {
       
   679         // Message contains only body (not attachments)
       
   680         QString messageBody = message->textContent();
       
   681         if (!messageBody.isEmpty()) {
       
   682             MEmailMessageContent* content = fsMessage->ContentL();
       
   683             MEmailTextContent* textContent = content->AsTextContentOrNull();
       
   684             textContent->SetTextL(MEmailTextContent::EPlainText, TPtrC(reinterpret_cast<const TUint16*>(message->textContent().utf16())));
       
   685             // TODO:
       
   686             }
       
   687     } else {
       
   688         // Message contains body and attachments
       
   689         QMessageContentContainerIdList contentIds = message->contentIds();
       
   690         foreach (QMessageContentContainerId id, contentIds){
       
   691             QMessageContentContainer container = message->find(id);
       
   692             QMessageContentContainerPrivate* pPrivateContainer = QMessageContentContainerPrivate::implementation(container);
       
   693             if (pPrivateContainer->_id == message->bodyId()) {
       
   694                 // ContentContainer is body
       
   695                 if (!container.textContent().isEmpty()) {
       
   696                     MEmailMessageContent* content = fsMessage->ContentL();
       
   697                     MEmailTextContent* textContent = content->AsTextContentOrNull();
       
   698                     QByteArray type = container.contentType();
       
   699                     QByteArray subType = container.contentSubType();
       
   700                     if (type == "text" && subType == "plain") {
       
   701                         textContent->SetTextL(MEmailTextContent::EPlainText, TPtrC(reinterpret_cast<const TUint16*>(container.textContent().utf16())));
       
   702                     }
       
   703                     else if (type == "text" && subType == "html") {
       
   704                         textContent->SetTextL(MEmailTextContent::EHtmlText, TPtrC(reinterpret_cast<const TUint16*>(container.textContent().utf16())));
       
   705                     }
       
   706                 }
       
   707             } else {
       
   708                 // ContentContainer is attachment
       
   709                 QByteArray filePath = QMessageContentContainerPrivate::attachmentFilename(container);
       
   710                 // Replace Qt style path separator "/" with Symbian path separator "\"
       
   711                 filePath.replace(QByteArray("/"), QByteArray("\\"));
       
   712                 QString temp_path = QString(filePath);
       
   713                 TPtrC16 attachmentPath(KNullDesC);
       
   714                 attachmentPath.Set(reinterpret_cast<const TUint16*>(temp_path.utf16()));
       
   715                 fsMessage->AddAttachmentL(attachmentPath);
       
   716             }        
       
   717         }
       
   718     }
       
   719     
       
   720     fsMessage->SetSubjectL(TPtrC(reinterpret_cast<const TUint16*>(message->subject().utf16())));
       
   721     fsMessage->SaveChangesL();
       
   722     CleanupStack::PopAndDestroy(fsMessage);
       
   723     CleanupStack::PopAndDestroy(mailbox);
       
   724 }
       
   725 
       
   726 bool CFSEngine::removeMessage(const QMessageId &id, QMessageManager::RemovalOption option)
       
   727 {
       
   728     Q_UNUSED(option);
       
   729     bool retVal = false;
       
   730     foreach (QMessageAccount account, m_accounts) {
       
   731         MEmailMessage* message = NULL;
       
   732         TMailboxId mailboxId(stripIdPrefix(account.id().toString()).toInt());
       
   733         MEmailMailbox* mailbox = m_clientApi->MailboxL(mailboxId);
       
   734         
       
   735         TMessageId messageId(
       
   736             stripIdPrefix(id.toString()).toInt(),
       
   737             0, 
       
   738             mailboxId);
       
   739         
       
   740         TRAPD(err, message = mailbox->MessageL(messageId));
       
   741 
       
   742         if (err == KErrNone) {
       
   743             TFolderId folderId(message->ParentFolderId());
       
   744             TRAPD(err2,
       
   745                 MEmailFolder* folder = mailbox->FolderL(folderId);
       
   746                 REmailMessageIdArray messageIds;
       
   747                 messageIds.Append(message->MessageId());
       
   748                 folder->DeleteMessagesL(messageIds);
       
   749                 folder->Release();
       
   750                 );
       
   751             if (err2 == KErrNone)
       
   752                 retVal = true;
       
   753             mailbox->Release();
       
   754             break; // no need to continue
       
   755         }
       
   756         mailbox->Release();
       
   757     }
       
   758     return retVal;
       
   759 }
       
   760 
       
   761 bool CFSEngine::showMessage(const QMessageId &id)
       
   762 {
       
   763     bool retVal = false;
       
   764     foreach (QMessageAccount account, m_accounts) {
       
   765         MEmailMessage* message = NULL;
       
   766         TMailboxId mailboxId(stripIdPrefix(account.id().toString()).toInt());
       
   767         MEmailMailbox* mailbox = m_clientApi->MailboxL(mailboxId);
       
   768         
       
   769         TMessageId messageId(
       
   770             stripIdPrefix(id.toString()).toInt(),
       
   771             0, 
       
   772             mailboxId);
       
   773         
       
   774         TRAPD(err, message = mailbox->MessageL(messageId));
       
   775 
       
   776         if (err == KErrNone) {
       
   777             TRAPD(err2, message->ShowMessageViewerL());
       
   778             if (err2 == KErrNone)
       
   779                 retVal = true;
       
   780             message->Release();
       
   781             mailbox->Release();
       
   782             break; // no need to continue
       
   783         }
       
   784         mailbox->Release();
       
   785     } 
       
   786     return retVal;
       
   787 }
       
   788 
       
   789 bool CFSEngine::composeMessage(const QMessage &message)
       
   790 {
       
   791     bool retVal = false;
       
   792     MEmailMailbox* mailbox = NULL;
       
   793     TMailboxId mailboxId(stripIdPrefix(message.parentAccountId().toString()).toInt());
       
   794     TRAPD(err, mailbox = m_clientApi->MailboxL(mailboxId));
       
   795     if (err == KErrNone) {
       
   796         TRAPD(err2, mailbox->EditNewMessageL());
       
   797         if (err2 == KErrNone)
       
   798             retVal = true;
       
   799         mailbox->Release();
       
   800     }
       
   801     return retVal;
       
   802 }
       
   803 
       
   804 bool CFSEngine::retrieve(QMessageServicePrivate& privateService, const QMessageId &messageId, const QMessageContentContainerId& id)
       
   805 {
       
   806     Q_UNUSED(id);
       
   807     m_privateService = &privateService;
       
   808     bool retVal = false;
       
   809     foreach (QMessageAccount account, m_accounts) {
       
   810         MEmailMessage* message = NULL;
       
   811         TMailboxId mailboxId(stripIdPrefix(account.id().toString()).toInt());
       
   812         MEmailMailbox* mailbox = NULL;
       
   813         TRAPD(mailboxError, mailbox = m_clientApi->MailboxL(mailboxId));
       
   814         if (mailboxError == KErrNone) {       
       
   815             TMessageId mId(
       
   816                 stripIdPrefix(messageId.toString()).toInt(),
       
   817                 0, 
       
   818                 mailboxId);
       
   819             
       
   820             TRAPD(err, message = mailbox->MessageL(mId));
       
   821             if (err == KErrNone) {
       
   822                 MEmailMessageContent* content = NULL;
       
   823                 TRAPD(contentError, content = message->ContentL());
       
   824                 if (contentError == KErrNone) {
       
   825                     TRAPD(err, retrieveAttachmentsL(message));
       
   826                         if (err == KErrNone)
       
   827                             retVal = true;
       
   828                         }
       
   829                 }
       
   830                 message->Release();
       
   831                 mailbox->Release();
       
   832                 break; // no need to continue
       
   833         }
       
   834         mailbox->Release();
       
   835     } 
       
   836     return retVal;
       
   837 }
       
   838 
       
   839 bool CFSEngine::retrieveBody(QMessageServicePrivate& privateService, const QMessageId& id)
       
   840 {
       
   841     bool retVal = false;
       
   842     m_privateService = &privateService;
       
   843     foreach (QMessageAccount account, m_accounts) {
       
   844         MEmailMessage* message = NULL;
       
   845         TMailboxId mailboxId(stripIdPrefix(account.id().toString()).toInt());
       
   846         MEmailMailbox* mailbox = NULL;
       
   847         TRAPD(mailBoxError, mailbox = m_clientApi->MailboxL(mailboxId));
       
   848         if (mailBoxError == KErrNone) {
       
   849             TMessageId messageId(
       
   850                 stripIdPrefix(id.toString()).toInt(),
       
   851                 0, 
       
   852                 mailboxId);
       
   853             
       
   854             TRAPD(err, message = mailbox->MessageL(messageId));
       
   855             if (err == KErrNone) {
       
   856                 MEmailMessageContent* content = NULL;
       
   857                 TRAPD(contentError, content = message->ContentL());
       
   858                 if (contentError == KErrNone) { 
       
   859                     TRAPD(err, retrieveTotalBodyL(content));
       
   860                     if (err == KErrNone)
       
   861                         retVal = true;
       
   862                     }
       
   863                 }
       
   864                 message->Release();
       
   865                 mailbox->Release();
       
   866                 break; // no need to continue
       
   867             }
       
   868             mailbox->Release();
       
   869         } 
       
   870     return retVal;
       
   871 }
       
   872 
       
   873 void CFSEngine::retrieveTotalBodyL(MEmailMessageContent* aContent)
       
   874 {
       
   875     MEmailMultipart* mPart = aContent->AsMultipartOrNull();
       
   876     if (mPart) {
       
   877         TInt partCount = 0;
       
   878         TRAPD(err, partCount = mPart->PartCountL());
       
   879             if (err == KErrNone) {
       
   880                 for (TInt i = 0; i < partCount; i++) {
       
   881                     MEmailMessageContent* content = NULL;
       
   882                     TRAPD(err2, content = mPart->PartByIndexL(i));
       
   883                     if (err2 == KErrNone) {
       
   884                         retrieveTotalBodyL(content);
       
   885                         content->Release();
       
   886                     }
       
   887                 }
       
   888             }
       
   889             return;
       
   890         }
       
   891  
       
   892     MEmailTextContent* textContent = aContent->AsTextContentOrNull();
       
   893     if (textContent) { 
       
   894         TInt availableSize = textContent->AvailableSize();
       
   895         TInt totalSize = textContent->TotalSize();
       
   896         if (totalSize > availableSize) {
       
   897             TRAPD(textErr, textContent->FetchL(*this));
       
   898             Q_UNUSED(textErr);
       
   899         }      
       
   900     }   
       
   901     return;
       
   902 }
       
   903 
       
   904 void CFSEngine::retrieveAttachmentsL(MEmailMessage* aMessage)
       
   905 {
       
   906     for (TInt i = 0; i < m_attachments.Count(); i++) {
       
   907         m_attachments[i]->Release();
       
   908     }
       
   909     m_attachments.Reset();
       
   910     TInt count = aMessage->GetAttachmentsL(m_attachments);
       
   911     for(TInt i = 0; i < count; i++) {
       
   912         MEmailAttachment* att = m_attachments[i];
       
   913         int totalSize = att->TotalSize();
       
   914         int availableSize = att->AvailableSize();
       
   915         if (totalSize > availableSize) {
       
   916             TRAPD(err, att->FetchL(*this));
       
   917             Q_UNUSED(err);
       
   918         }
       
   919     }
       
   920 }
       
   921 
       
   922 bool CFSEngine::retrieveHeader(QMessageServicePrivate& privateService, const QMessageId& id)
       
   923 {
       
   924     Q_UNUSED(id);
       
   925     Q_UNUSED(privateService);
       
   926     return false;
       
   927 }
       
   928 
       
   929 void CFSEngine::DataFetchedL(const TInt aResult)
       
   930 {
       
   931     if (aResult == KErrNone)
       
   932         m_privateService->setFinished(true);
       
   933     else
       
   934         m_privateService->setFinished(false);      
       
   935 }
       
   936 
       
   937 bool CFSEngine::exportUpdates(const QMessageAccountId &id)
       
   938 {
       
   939     TRAPD(err, exportUpdatesL(id));
       
   940     if (err != KErrNone) {
       
   941         return false;
       
   942     } else {
       
   943         return true;
       
   944     }
       
   945 }
       
   946 
       
   947 void CFSEngine::exportUpdatesL(const QMessageAccountId &id)
       
   948 {
       
   949     TMailboxId mailboxId(stripIdPrefix(id.toString()).toInt());
       
   950     MEmailMailbox* mailbox = m_clientApi->MailboxL(mailboxId);
       
   951     mailbox->SynchroniseL(*this);
       
   952     mailbox->Release();
       
   953 }
       
   954 
       
   955 void CFSEngine::MailboxSynchronisedL(TInt aResult)
       
   956 {
       
   957     Q_UNUSED(aResult);
       
   958 }
       
   959 
       
   960 bool CFSEngine::removeMessages(const QMessageFilter& /*filter*/, QMessageManager::RemovalOption /*option*/)
       
   961 {
       
   962     return false;
       
   963 }
       
   964 
       
   965 void CFSEngine::handleNestedFiltersFromMessageFilter(QMessageFilter &filter) const
       
   966 {
       
   967     QMessageFilterPrivate* pMFFilter = QMessageFilterPrivate::implementation(filter);
       
   968     if (pMFFilter->_filterList.count() > 0) {
       
   969         int filterListCount = pMFFilter->_filterList.count();
       
   970         for (int i=0; i < filterListCount; i++) {
       
   971             for (int j=0; j < pMFFilter->_filterList[i].count(); j++) {
       
   972                 QMessageFilterPrivate* pMFFilter2 = QMessageFilterPrivate::implementation(pMFFilter->_filterList[i][j]);
       
   973                 if (pMFFilter2->_field == QMessageFilterPrivate::ParentAccountIdFilter) {
       
   974                     QMessageAccountIdList accountIds = queryAccounts(*pMFFilter2->_accountFilter, QMessageAccountSortOrder(), 0, 0);
       
   975                     QMessageDataComparator::InclusionComparator cmp(static_cast<QMessageDataComparator::InclusionComparator>(pMFFilter2->_comparatorValue));
       
   976                     if (accountIds.count() > 0) {
       
   977                         pMFFilter->_filterList[i].removeAt(j);
       
   978                         if (cmp == QMessageDataComparator::Includes) {
       
   979                             for (int x = 0; x < accountIds.count(); x++) {
       
   980                                 if (x == 0) {
       
   981                                     if (x+1 < accountIds.count()) {
       
   982                                         pMFFilter->_filterList.append(pMFFilter->_filterList[i]);
       
   983                                     }
       
   984                                     pMFFilter->_filterList[i].append(QMessageFilter::byParentAccountId(accountIds[x],QMessageDataComparator::Equal));
       
   985                                     qSort(pMFFilter->_filterList[i].begin(), pMFFilter->_filterList[i].end(), QMessageFilterPrivate::lessThan);
       
   986                                 } else {
       
   987                                     if (x+1 < accountIds.count()) {
       
   988                                         pMFFilter->_filterList.append(pMFFilter->_filterList[pMFFilter->_filterList.count()-1]);
       
   989                                         pMFFilter->_filterList[pMFFilter->_filterList.count()-2].append(QMessageFilter::byParentAccountId(accountIds[x],QMessageDataComparator::Equal));
       
   990                                         qSort(pMFFilter->_filterList[pMFFilter->_filterList.count()-2].begin(), pMFFilter->_filterList[pMFFilter->_filterList.count()-2].end(), QMessageFilterPrivate::lessThan);
       
   991                                     } else {
       
   992                                         pMFFilter->_filterList[pMFFilter->_filterList.count()-1].append(QMessageFilter::byParentAccountId(accountIds[x],QMessageDataComparator::Equal));
       
   993                                         qSort(pMFFilter->_filterList[pMFFilter->_filterList.count()-1].begin(), pMFFilter->_filterList[pMFFilter->_filterList.count()-1].end(), QMessageFilterPrivate::lessThan);
       
   994                                     }
       
   995                                 }
       
   996                             }
       
   997                         } else { // Excludes
       
   998                             for (int x = 0; x < accountIds.count(); x++) {
       
   999                                 pMFFilter->_filterList[i].append(QMessageFilter::byParentAccountId(accountIds[x],QMessageDataComparator::NotEqual));
       
  1000                             }
       
  1001                             qSort(pMFFilter->_filterList[i].begin(), pMFFilter->_filterList[i].end(), QMessageFilterPrivate::lessThan);
       
  1002                         }
       
  1003                     } else {
       
  1004                         delete pMFFilter2->_accountFilter;
       
  1005                         pMFFilter2->_accountFilter = 0;
       
  1006                         pMFFilter2->_field = QMessageFilterPrivate::Id;
       
  1007                         qSort(pMFFilter->_filterList[i].begin(), pMFFilter->_filterList[i].end(), QMessageFilterPrivate::lessThan);
       
  1008                     }
       
  1009                 } else if (pMFFilter2->_field == QMessageFilterPrivate::ParentFolderIdFilter) { 
       
  1010                     QMessageFolderIdList folderIds = queryFolders(*pMFFilter2->_folderFilter, QMessageFolderSortOrder(), 0, 0);
       
  1011                     QMessageDataComparator::InclusionComparator cmp(static_cast<QMessageDataComparator::InclusionComparator>(pMFFilter2->_comparatorValue));
       
  1012                     if (folderIds.count() > 0) {
       
  1013                         pMFFilter->_filterList[i].removeAt(j);
       
  1014                         if (cmp == QMessageDataComparator::Includes) {
       
  1015                             for (int x = 0; x < folderIds.count(); x++) {
       
  1016                                 if (x == 0) {
       
  1017                                     if (x+1 < folderIds.count()) {
       
  1018                                         pMFFilter->_filterList.append(pMFFilter->_filterList[i]);
       
  1019                                     }
       
  1020                                     pMFFilter->_filterList[i].append(QMessageFilter::byParentFolderId(folderIds[x],QMessageDataComparator::Equal));
       
  1021                                     qSort(pMFFilter->_filterList[i].begin(), pMFFilter->_filterList[i].end(), QMessageFilterPrivate::lessThan);
       
  1022                                 } else {
       
  1023                                     if (x+1 < folderIds.count()) {
       
  1024                                         pMFFilter->_filterList.append(pMFFilter->_filterList[pMFFilter->_filterList.count()-1]);
       
  1025                                         pMFFilter->_filterList[pMFFilter->_filterList.count()-2].append(QMessageFilter::byParentFolderId(folderIds[x],QMessageDataComparator::Equal));
       
  1026                                         qSort(pMFFilter->_filterList[pMFFilter->_filterList.count()-2].begin(), pMFFilter->_filterList[pMFFilter->_filterList.count()-2].end(), QMessageFilterPrivate::lessThan);
       
  1027                                     } else {
       
  1028                                         pMFFilter->_filterList[pMFFilter->_filterList.count()-1].append(QMessageFilter::byParentFolderId(folderIds[x],QMessageDataComparator::Equal));
       
  1029                                         qSort(pMFFilter->_filterList[pMFFilter->_filterList.count()-1].begin(), pMFFilter->_filterList[pMFFilter->_filterList.count()-1].end(), QMessageFilterPrivate::lessThan);
       
  1030                                     }
       
  1031                                 }
       
  1032                             }
       
  1033                         } else { // Excludes
       
  1034                             for (int x = 0; x < folderIds.count(); x++) {
       
  1035                                 pMFFilter->_filterList[i].append(QMessageFilter::byParentFolderId(folderIds[x],QMessageDataComparator::NotEqual));
       
  1036                             }
       
  1037                             qSort(pMFFilter->_filterList[i].begin(), pMFFilter->_filterList[i].end(), QMessageFilterPrivate::lessThan);
       
  1038                         }
       
  1039                     } else {
       
  1040                         delete pMFFilter2->_folderFilter;
       
  1041                         pMFFilter2->_folderFilter = 0;
       
  1042                         pMFFilter2->_field = QMessageFilterPrivate::Id;
       
  1043                         qSort(pMFFilter->_filterList[i].begin(), pMFFilter->_filterList[i].end(), QMessageFilterPrivate::lessThan);
       
  1044                     }
       
  1045                 } else {
       
  1046                     break;
       
  1047                 }
       
  1048             }
       
  1049         }
       
  1050     } else {
       
  1051         if (pMFFilter->_field == QMessageFilterPrivate::ParentAccountIdFilter) {
       
  1052             QMessageAccountIdList accountIds = queryAccounts(*pMFFilter->_accountFilter, QMessageAccountSortOrder(), 0, 0);
       
  1053             QMessageDataComparator::InclusionComparator cmp(static_cast<QMessageDataComparator::InclusionComparator>(pMFFilter->_comparatorValue));
       
  1054             if (accountIds.count() > 0) {
       
  1055                 for (int i=0; i < accountIds.count(); i++) {
       
  1056                     if (i == 0) {
       
  1057                         delete pMFFilter->_accountFilter;
       
  1058                         pMFFilter->_accountFilter = 0;
       
  1059                         pMFFilter->_field = QMessageFilterPrivate::ParentAccountId;
       
  1060                         pMFFilter->_value = accountIds[0].toString();
       
  1061                         pMFFilter->_comparatorType = QMessageFilterPrivate::Equality;
       
  1062                         if (cmp == QMessageDataComparator::Includes) {
       
  1063                             pMFFilter->_comparatorValue = static_cast<int>(QMessageDataComparator::Equal);
       
  1064                         } else { // Excludes
       
  1065                             pMFFilter->_comparatorValue = static_cast<int>(QMessageDataComparator::NotEqual);
       
  1066                         }
       
  1067                     } else {
       
  1068                         if (cmp == QMessageDataComparator::Includes) {
       
  1069                             filter |= QMessageFilter::byParentAccountId(accountIds[i],QMessageDataComparator::Equal);
       
  1070                         } else { // Excludes
       
  1071                             filter &= QMessageFilter::byParentAccountId(accountIds[i],QMessageDataComparator::NotEqual);
       
  1072                         }
       
  1073                     }
       
  1074                 }
       
  1075             } else {
       
  1076                 delete pMFFilter->_accountFilter;
       
  1077                 pMFFilter->_accountFilter = 0;
       
  1078                 pMFFilter->_field = QMessageFilterPrivate::Id;
       
  1079             }
       
  1080         } else if (pMFFilter->_field == QMessageFilterPrivate::ParentFolderIdFilter) {
       
  1081             QMessageFolderIdList folderIds = queryFolders(*pMFFilter->_folderFilter, QMessageFolderSortOrder(), 0, 0);
       
  1082             QMessageDataComparator::InclusionComparator cmp(static_cast<QMessageDataComparator::InclusionComparator>(pMFFilter->_comparatorValue));
       
  1083             if (folderIds.count() > 0) {
       
  1084                 for (int i=0; i < folderIds.count(); i++) {
       
  1085                     if (i == 0) {
       
  1086                         delete pMFFilter->_folderFilter;
       
  1087                         pMFFilter->_folderFilter = 0;
       
  1088                         pMFFilter->_field = QMessageFilterPrivate::ParentFolderId;
       
  1089                         pMFFilter->_value = folderIds[0].toString();
       
  1090                         pMFFilter->_comparatorType = QMessageFilterPrivate::Equality;
       
  1091                         if (cmp == QMessageDataComparator::Includes) {
       
  1092                             pMFFilter->_comparatorValue = static_cast<int>(QMessageDataComparator::Equal);
       
  1093                         } else { // Excludes
       
  1094                             pMFFilter->_comparatorValue = static_cast<int>(QMessageDataComparator::NotEqual);
       
  1095                         }
       
  1096                     } else {
       
  1097                         if (cmp == QMessageDataComparator::Includes) {
       
  1098                             filter |= QMessageFilter::byParentFolderId(folderIds[i],QMessageDataComparator::Equal);
       
  1099                         } else { // Excludes
       
  1100                             filter &= QMessageFilter::byParentFolderId(folderIds[i],QMessageDataComparator::NotEqual);
       
  1101                         }
       
  1102                     }
       
  1103                 }
       
  1104             } else {
       
  1105                 delete pMFFilter->_folderFilter;
       
  1106                 pMFFilter->_folderFilter = 0;
       
  1107                 pMFFilter->_field = QMessageFilterPrivate::Id;
       
  1108             }
       
  1109         }
       
  1110     }
       
  1111 }
       
  1112 
       
  1113 bool CFSEngine::queryMessages(QMessageServicePrivate& privateService, const QMessageFilter &filter, const QMessageSortOrder &sortOrder, uint limit, uint offset) const
       
  1114 {
       
  1115     TRAPD(err, queryMessagesL(privateService, filter, sortOrder, limit, offset));
       
  1116     if (err != KErrNone) {
       
  1117         return false;
       
  1118     }
       
  1119     return true;
       
  1120 }
       
  1121 
       
  1122 
       
  1123 void CFSEngine::queryMessagesL(QMessageServicePrivate& privateService, const QMessageFilter &filter, const QMessageSortOrder &sortOrder, uint limit, uint offset) const
       
  1124 {
       
  1125     
       
  1126     FSMessageQueryInfo queryInfo;
       
  1127     queryInfo.operationId = ++m_operationIds;
       
  1128     if (queryInfo.operationId == 100000) {
       
  1129         queryInfo.operationId = 1;
       
  1130     }
       
  1131     queryInfo.isQuery = true;
       
  1132     queryInfo.filter = filter;
       
  1133     queryInfo.sortOrder = sortOrder;
       
  1134     queryInfo.offset = offset;
       
  1135     queryInfo.limit = limit;
       
  1136     queryInfo.findOperation = new CFSMessagesFindOperation((CFSEngine&)*this, queryInfo.operationId);
       
  1137     queryInfo.privateService = &privateService;
       
  1138     queryInfo.currentFilterListIndex = 0;
       
  1139     m_messageQueries.append(queryInfo);
       
  1140 
       
  1141     handleNestedFiltersFromMessageFilter(m_messageQueries[m_messageQueries.count()-1].filter);
       
  1142     
       
  1143     QMessageFilterPrivate* pf = QMessageFilterPrivate::implementation(m_messageQueries[m_messageQueries.count()-1].filter);
       
  1144     if (pf->_filterList.count() == 0) {
       
  1145         queryInfo.findOperation->filterAndOrderMessages(m_messageQueries[m_messageQueries.count()-1].filter,
       
  1146             m_messageQueries[m_messageQueries.count()-1].sortOrder);
       
  1147     } else {
       
  1148         queryInfo.findOperation->filterAndOrderMessages(pf->_filterList[0], m_messageQueries[m_messageQueries.count()-1].sortOrder);
       
  1149     }
       
  1150 }
       
  1151 
       
  1152 bool CFSEngine::queryMessages(QMessageServicePrivate& privateService, const QMessageFilter &filter, const QString &body, QMessageDataComparator::MatchFlags matchFlags, const QMessageSortOrder &sortOrder, uint limit, uint offset) const
       
  1153 {
       
  1154     TRAPD(err, queryMessagesL(privateService, filter, body, matchFlags, sortOrder, limit, offset));
       
  1155     if (err != KErrNone) {
       
  1156         return false;
       
  1157     }
       
  1158     return true;
       
  1159 }
       
  1160 
       
  1161 void CFSEngine::queryMessagesL(QMessageServicePrivate& privateService, const QMessageFilter &filter, const QString &body, QMessageDataComparator::MatchFlags matchFlags, const QMessageSortOrder &sortOrder, uint limit, uint offset) const
       
  1162 {
       
  1163     FSMessageQueryInfo queryInfo;
       
  1164     queryInfo.operationId = ++m_operationIds;
       
  1165     if (queryInfo.operationId == 100000) {
       
  1166         queryInfo.operationId = 1;
       
  1167     }
       
  1168     queryInfo.isQuery = true;
       
  1169     queryInfo.body = body;
       
  1170     queryInfo.matchFlags = matchFlags;
       
  1171     queryInfo.filter = filter;
       
  1172     queryInfo.sortOrder = sortOrder;
       
  1173     queryInfo.offset = offset;
       
  1174     queryInfo.limit = limit;
       
  1175     queryInfo.findOperation = new CFSMessagesFindOperation((CFSEngine&)*this, queryInfo.operationId);
       
  1176     queryInfo.privateService = &privateService;
       
  1177     queryInfo.currentFilterListIndex = 0;
       
  1178     m_messageQueries.append(queryInfo);
       
  1179     
       
  1180     handleNestedFiltersFromMessageFilter(m_messageQueries[m_messageQueries.count()-1].filter);
       
  1181     
       
  1182     QMessageFilterPrivate* pf = QMessageFilterPrivate::implementation(m_messageQueries[m_messageQueries.count()-1].filter);
       
  1183     if (pf->_filterList.count() == 0) {
       
  1184         queryInfo.findOperation->filterAndOrderMessages(m_messageQueries[m_messageQueries.count()-1].filter,
       
  1185                                                         m_messageQueries[m_messageQueries.count()-1].sortOrder,
       
  1186                                                         body,
       
  1187                                                         matchFlags);
       
  1188     } else {
       
  1189         queryInfo.findOperation->filterAndOrderMessages(pf->_filterList[0],
       
  1190                                                         m_messageQueries[m_messageQueries.count()-1].sortOrder,
       
  1191                                                         body,
       
  1192                                                         matchFlags);
       
  1193     }
       
  1194 }
       
  1195 
       
  1196 bool CFSEngine::countMessages(QMessageServicePrivate& privateService, const QMessageFilter &filter)
       
  1197 {
       
  1198     TRAPD(err, countMessagesL(privateService, filter));
       
  1199     if (err != KErrNone) {
       
  1200         return false;
       
  1201     }
       
  1202     return true;
       
  1203 }
       
  1204 
       
  1205 void CFSEngine::countMessagesL(QMessageServicePrivate& privateService, const QMessageFilter &filter)
       
  1206 {
       
  1207     FSMessageQueryInfo queryInfo;
       
  1208     queryInfo.operationId = ++m_operationIds;
       
  1209     if (queryInfo.operationId == 100000) {
       
  1210         queryInfo.operationId = 1;
       
  1211     }
       
  1212     queryInfo.isQuery = false;
       
  1213     queryInfo.matchFlags = 0;
       
  1214     queryInfo.filter = filter;
       
  1215     queryInfo.sortOrder = QMessageSortOrder();
       
  1216     queryInfo.offset = 0;
       
  1217     queryInfo.limit = 0;
       
  1218     queryInfo.findOperation = new CFSMessagesFindOperation((CFSEngine&)*this, queryInfo.operationId);
       
  1219     queryInfo.privateService = &privateService;
       
  1220     queryInfo.currentFilterListIndex = 0;
       
  1221     queryInfo.count = 0;
       
  1222     m_messageQueries.append(queryInfo);
       
  1223     
       
  1224     handleNestedFiltersFromMessageFilter(m_messageQueries[m_messageQueries.count()-1].filter);
       
  1225     
       
  1226     QMessageFilterPrivate* pf = QMessageFilterPrivate::implementation(m_messageQueries[m_messageQueries.count()-1].filter);
       
  1227     if (pf->_filterList.count() == 0) {
       
  1228         queryInfo.findOperation->filterAndOrderMessages(m_messageQueries[m_messageQueries.count()-1].filter,
       
  1229             m_messageQueries[m_messageQueries.count()-1].sortOrder);
       
  1230     } else {
       
  1231         queryInfo.findOperation->filterAndOrderMessages(pf->_filterList[0], m_messageQueries[m_messageQueries.count()-1].sortOrder);
       
  1232     }
       
  1233 }
       
  1234 
       
  1235 void CFSEngine::filterAndOrderMessagesReady(bool success, int operationId, QMessageIdList ids, int numberOfHandledFilters,
       
  1236                                              bool resultSetOrdered)
       
  1237 {
       
  1238     int index=0;
       
  1239     for (; index < m_messageQueries.count(); index++) {
       
  1240         if (m_messageQueries[index].operationId == operationId) {
       
  1241             break;
       
  1242         }
       
  1243     }
       
  1244     
       
  1245     if (success) {
       
  1246         // If there are unhandled filters, loop through all filters and do filtering for ids using unhandled filters.
       
  1247         QMessageFilterPrivate* pf = QMessageFilterPrivate::implementation(m_messageQueries[index].filter);
       
  1248         if (pf->_filterList.count() > 0) {
       
  1249             if (pf->_filterList[m_messageQueries[index].currentFilterListIndex].count() > numberOfHandledFilters) {
       
  1250                 for (int i=0; i < ids.count(); i++) {
       
  1251                     QMessage msg = message(ids[i]);
       
  1252                     for (int j=numberOfHandledFilters; j < pf->_filterList[m_messageQueries[index].currentFilterListIndex].count(); j++) {
       
  1253                         QMessageFilterPrivate* pf2 = QMessageFilterPrivate::implementation(pf->_filterList[m_messageQueries[index].currentFilterListIndex][j]);
       
  1254                         if (!pf2->filter(msg)) {
       
  1255                             ids.removeAt(i);
       
  1256                             i--;
       
  1257                             break;
       
  1258                         }
       
  1259                     }
       
  1260                 }
       
  1261             }
       
  1262         }
       
  1263         if (pf->_filterList.count() > 0) {
       
  1264             // Filter contains filterlist (or filterlists), not just one single filter 
       
  1265             if (m_messageQueries[index].currentFilterListIndex == 0) {
       
  1266                 m_messageQueries[index].ids << ids;
       
  1267                 m_messageQueries[index].count = ids.count(); 
       
  1268             } else {
       
  1269                 // Append new ids to resultset
       
  1270                 for (int i=0; i < ids.count(); i++) {
       
  1271                     if (!m_messageQueries[index].ids.contains(ids[i])) {
       
  1272                         m_messageQueries[index].ids.append(ids[i]);
       
  1273                         m_messageQueries[index].count++;; 
       
  1274                     }
       
  1275                 }
       
  1276             }
       
  1277             
       
  1278             m_messageQueries[index].currentFilterListIndex++;
       
  1279             if (m_messageQueries[index].currentFilterListIndex < pf->_filterList.count()) {
       
  1280                 // There are still unhandled filter lists left
       
  1281                 m_messageQueries[index].findOperation->filterAndOrderMessages(pf->_filterList[m_messageQueries[index].currentFilterListIndex],
       
  1282                                                                              m_messageQueries[index].sortOrder,
       
  1283                                                                              m_messageQueries[index].body,
       
  1284                                                                              m_messageQueries[index].matchFlags);
       
  1285                 return;
       
  1286             } else {
       
  1287                 // All filters successfully handled
       
  1288                 if (m_messageQueries[index].isQuery) {
       
  1289                     if (!m_messageQueries[index].sortOrder.isEmpty()) {
       
  1290                         // Make sure that messages are correctly ordered
       
  1291                         orderMessages(m_messageQueries[index].ids, m_messageQueries[index].sortOrder);
       
  1292                     }
       
  1293                     applyOffsetAndLimitToMsgIds(m_messageQueries[index].ids,
       
  1294                                                 m_messageQueries[index].offset,
       
  1295                                                 m_messageQueries[index].limit);
       
  1296                     m_messageQueries[index].privateService->messagesFound(m_messageQueries[index].ids, true, true);
       
  1297 
       
  1298                     //emit m_messageQueries[index].privateService->messagesFound(m_messageQueries[index].ids);
       
  1299                 } else {
       
  1300                     m_messageQueries[index].privateService->messagesCounted(m_messageQueries[index].count);
       
  1301                 }
       
  1302             }
       
  1303         } else {
       
  1304             // There was only one single filter to handle
       
  1305             if (numberOfHandledFilters == 0) {
       
  1306                 // The one and only filter was not handled
       
  1307                 // => Do filtering for all returned messages
       
  1308                 for (int i=ids.count()-1; i >= 0; i--) {
       
  1309                     QMessage msg = message(ids[i]);
       
  1310                     if (!pf->filter(msg)) {
       
  1311                         ids.removeAt(i);
       
  1312                     }
       
  1313                 }
       
  1314             }
       
  1315             // => All filters successfully handled
       
  1316             if (m_messageQueries[index].isQuery) {
       
  1317                 // Make sure that messages are correctly ordered
       
  1318                 if (!m_messageQueries[index].sortOrder.isEmpty() && !resultSetOrdered) {
       
  1319                     orderMessages(ids, m_messageQueries[index].sortOrder);
       
  1320                 }
       
  1321                 // Handle offest & limit
       
  1322                 applyOffsetAndLimitToMsgIds(ids, m_messageQueries[index].offset, m_messageQueries[index].limit);
       
  1323                 //emit m_messageQueries[index].privateService->messagesFound(ids);
       
  1324                 m_messageQueries[index].privateService->messagesFound(ids, true, true);
       
  1325             } else {
       
  1326                 m_messageQueries[index].privateService->messagesCounted(ids.count());
       
  1327             }
       
  1328         }
       
  1329     } else {
       
  1330         m_messageQueries[index].privateService->_active = false;
       
  1331         if (m_messageQueries[index].privateService->_error == QMessageManager::NoError) {
       
  1332             m_messageQueries[index].privateService->_error = QMessageManager::RequestIncomplete;
       
  1333         }
       
  1334     }
       
  1335 
       
  1336     delete m_messageQueries[index].findOperation;
       
  1337     m_messageQueries.removeAt(index);
       
  1338 }
       
  1339 
       
  1340 void CFSEngine::applyOffsetAndLimitToMsgIds(QMessageIdList& idList, int offset, int limit) const
       
  1341 {
       
  1342     if (offset > 0) {
       
  1343         if (offset > idList.count()) {
       
  1344             idList.clear();
       
  1345         } else {
       
  1346             for (int i = 0; i < offset; i++) {
       
  1347                 idList.removeFirst();
       
  1348             }
       
  1349         }
       
  1350     }
       
  1351     if (limit > 0) {
       
  1352         for (int i = idList.count()-1; i >= limit; i--) {
       
  1353             idList.removeAt(i);
       
  1354         }
       
  1355     }
       
  1356 }
       
  1357 
       
  1358 QMessageManager::NotificationFilterId CFSEngine::registerNotificationFilter(QMessageStorePrivate& aPrivateStore,
       
  1359                                                                            const QMessageFilter &filter, QMessageManager::NotificationFilterId aId)
       
  1360 {
       
  1361     ipMessageStorePrivate = &aPrivateStore;
       
  1362     iListenForNotifications = true;    
       
  1363 
       
  1364     int filterId = aId;
       
  1365     if (filterId == 0)
       
  1366         filterId = ++m_filterId;
       
  1367     m_filters.insert(filterId, filter);
       
  1368     return filterId;
       
  1369 }
       
  1370 
       
  1371 void CFSEngine::unregisterNotificationFilter(QMessageManager::NotificationFilterId notificationFilterId)
       
  1372 {
       
  1373     m_filters.remove(notificationFilterId);
       
  1374     if (m_filters.count() == 0) {
       
  1375         iListenForNotifications = false;
       
  1376     }
       
  1377 }
       
  1378 void CFSEngine::handleNestedFiltersFromFolderFilter(QMessageFolderFilter &filter) const
       
  1379 {
       
  1380     QMessageFolderFilterPrivate* pMFFilter = QMessageFolderFilterPrivate::implementation(filter);
       
  1381     if (pMFFilter->_filterList.count() > 0) {
       
  1382         int filterListCount = pMFFilter->_filterList.count();
       
  1383         for (int i=0; i < filterListCount; i++) {
       
  1384             for (int j=0; j < pMFFilter->_filterList[i].count(); j++) {
       
  1385                 QMessageFolderFilterPrivate* pMFFilter2 = QMessageFolderFilterPrivate::implementation(pMFFilter->_filterList[i][j]);
       
  1386                 if (pMFFilter2->_field == QMessageFolderFilterPrivate::ParentAccountIdFilter) {
       
  1387                     QMessageAccountIdList accountIds = queryAccounts(*pMFFilter2->_accountFilter, QMessageAccountSortOrder(), 0, 0);
       
  1388                     QMessageDataComparator::InclusionComparator cmp(static_cast<QMessageDataComparator::InclusionComparator>(pMFFilter2->_comparatorValue));
       
  1389                     if (accountIds.count() > 0) {
       
  1390                         pMFFilter->_filterList[i].removeAt(j);
       
  1391                         if (cmp == QMessageDataComparator::Includes) {
       
  1392                             for (int x = 0; x < accountIds.count(); x++) {
       
  1393                                 if (x == 0) {
       
  1394                                     if (x+1 < accountIds.count()) {
       
  1395                                         pMFFilter->_filterList.append(pMFFilter->_filterList[i]);
       
  1396                                     }
       
  1397                                     pMFFilter->_filterList[i].append(QMessageFolderFilter::byParentAccountId(accountIds[x],QMessageDataComparator::Equal));
       
  1398                                     qSort(pMFFilter->_filterList[i].begin(), pMFFilter->_filterList[i].end(), QMessageFolderFilterPrivate::lessThan);
       
  1399                                 } else {
       
  1400                                     if (x+1 < accountIds.count()) {
       
  1401                                         pMFFilter->_filterList.append(pMFFilter->_filterList[pMFFilter->_filterList.count()-1]);
       
  1402                                         pMFFilter->_filterList[pMFFilter->_filterList.count()-2].append(QMessageFolderFilter::byParentAccountId(accountIds[x],QMessageDataComparator::Equal));
       
  1403                                         qSort(pMFFilter->_filterList[pMFFilter->_filterList.count()-2].begin(), pMFFilter->_filterList[pMFFilter->_filterList.count()-2].end(), QMessageFolderFilterPrivate::lessThan);
       
  1404                                     } else {
       
  1405                                         pMFFilter->_filterList[pMFFilter->_filterList.count()-1].append(QMessageFolderFilter::byParentAccountId(accountIds[x],QMessageDataComparator::Equal));
       
  1406                                         qSort(pMFFilter->_filterList[pMFFilter->_filterList.count()-1].begin(), pMFFilter->_filterList[pMFFilter->_filterList.count()-1].end(), QMessageFolderFilterPrivate::lessThan);
       
  1407                                     }
       
  1408                                 }
       
  1409                             }
       
  1410                         } else { // Excludes
       
  1411                             for (int x = 0; x < accountIds.count(); x++) {
       
  1412                                 pMFFilter->_filterList[i].append(QMessageFolderFilter::byParentAccountId(accountIds[x],QMessageDataComparator::NotEqual));
       
  1413                             }
       
  1414                             qSort(pMFFilter->_filterList[i].begin(), pMFFilter->_filterList[i].end(), QMessageFolderFilterPrivate::lessThan);
       
  1415                         }
       
  1416                     } else {
       
  1417                         delete pMFFilter2->_accountFilter;
       
  1418                         pMFFilter2->_accountFilter = 0;
       
  1419                         pMFFilter2->_field = QMessageFolderFilterPrivate::Id;
       
  1420                         qSort(pMFFilter->_filterList[i].begin(), pMFFilter->_filterList[i].end(), QMessageFolderFilterPrivate::lessThan);
       
  1421                     }
       
  1422                 } else {
       
  1423                     break;
       
  1424                 }
       
  1425             }
       
  1426         }
       
  1427     } else {
       
  1428         if (pMFFilter->_field == QMessageFolderFilterPrivate::ParentAccountIdFilter) {
       
  1429             QMessageAccountIdList accountIds = queryAccounts(*pMFFilter->_accountFilter, QMessageAccountSortOrder(), 0, 0);
       
  1430             QMessageDataComparator::InclusionComparator cmp(static_cast<QMessageDataComparator::InclusionComparator>(pMFFilter->_comparatorValue));
       
  1431             if (accountIds.count() > 0) {
       
  1432                 for (int i=0; i < accountIds.count(); i++) {
       
  1433                     if (i == 0) {
       
  1434                         delete pMFFilter->_accountFilter;
       
  1435                         pMFFilter->_accountFilter = 0;
       
  1436                         pMFFilter->_field = QMessageFolderFilterPrivate::ParentAccountId;
       
  1437                         pMFFilter->_value = accountIds[0].toString();
       
  1438                         pMFFilter->_comparatorType = QMessageFolderFilterPrivate::Equality;
       
  1439                         if (cmp == QMessageDataComparator::Includes) {
       
  1440                             pMFFilter->_comparatorValue = static_cast<int>(QMessageDataComparator::Equal);
       
  1441                         } else { // Excludes
       
  1442                             pMFFilter->_comparatorValue = static_cast<int>(QMessageDataComparator::NotEqual);
       
  1443                         }
       
  1444                     } else {
       
  1445                         if (cmp == QMessageDataComparator::Includes) {
       
  1446                             filter |= QMessageFolderFilter::byParentAccountId(accountIds[i],QMessageDataComparator::Equal);
       
  1447                         } else { // Excludes
       
  1448                             filter &= QMessageFolderFilter::byParentAccountId(accountIds[i],QMessageDataComparator::NotEqual);
       
  1449                         }
       
  1450                     }
       
  1451                 }
       
  1452             } else {
       
  1453                 delete pMFFilter->_accountFilter;
       
  1454                 pMFFilter->_accountFilter = 0;
       
  1455                 pMFFilter->_field = QMessageFolderFilterPrivate::Id;
       
  1456             }
       
  1457         }
       
  1458     }
       
  1459 }
       
  1460 
       
  1461 QMessageFolderIdList CFSEngine::queryFolders(const QMessageFolderFilter &filter, const QMessageFolderSortOrder &sortOrder, uint limit, uint offset) const
       
  1462 {
       
  1463     QMessageFolderIdList ids;
       
  1464     
       
  1465     QMessageFolderFilter copyOfFilter = filter;
       
  1466 
       
  1467     handleNestedFiltersFromFolderFilter(copyOfFilter);
       
  1468     
       
  1469     QMessageFolderFilterPrivate* pMFFilter = QMessageFolderFilterPrivate::implementation(copyOfFilter);
       
  1470 
       
  1471     if (pMFFilter->_filterList.count() > 0) {
       
  1472         for (int i=0; i < pMFFilter->_filterList.count(); i++) {
       
  1473             bool filterHandled;
       
  1474             QMessageFolderIdList ids2 = filterMessageFolders(pMFFilter->_filterList[i][0], filterHandled);
       
  1475             for (int x=ids2.count()-1; x >= 0; x--) {
       
  1476                 QMessageFolder mf = folder(ids2[x]);
       
  1477                 int j = filterHandled ? 1 : 0;
       
  1478                 for (; j < pMFFilter->_filterList[i].count(); j++) {
       
  1479                     if (!QMessageFolderFilterPrivate::implementation(pMFFilter->_filterList[i][j])->filter(mf)) {
       
  1480                         ids2.removeAt(x);
       
  1481                         break;
       
  1482                     }
       
  1483                 }
       
  1484             }
       
  1485             for (int j=0; j < ids2.count(); j++) {
       
  1486                 if (!ids.contains(ids2[j])) {
       
  1487                    ids.append(ids2[j]);
       
  1488                 }
       
  1489             }
       
  1490         }
       
  1491     } else {
       
  1492         bool filterHandled;
       
  1493         ids = filterMessageFolders(copyOfFilter, filterHandled);
       
  1494         if (!filterHandled) {
       
  1495             for (int i=ids.count()-1; i >= 0; i--) {
       
  1496                 if (!QMessageFolderFilterPrivate::implementation(copyOfFilter)->filter(ids[i])) {
       
  1497                     ids.removeAt(i);
       
  1498                 }
       
  1499             }
       
  1500         }
       
  1501     }
       
  1502     
       
  1503     if (!sortOrder.isEmpty()) {
       
  1504         orderFolders(ids, sortOrder);
       
  1505     }
       
  1506     
       
  1507     applyOffsetAndLimitToMsgFolderIds(ids, offset, limit);
       
  1508     
       
  1509     return ids;
       
  1510 }
       
  1511 
       
  1512 void CFSEngine::applyOffsetAndLimitToMsgFolderIds(QMessageFolderIdList& idList, int offset, int limit) const
       
  1513 {
       
  1514     if (offset > 0) {
       
  1515         if (offset > idList.count()) {
       
  1516             idList.clear();
       
  1517         } else {
       
  1518             for (int i = 0; i < offset; i++) {
       
  1519                 idList.removeFirst();
       
  1520             }
       
  1521         }
       
  1522     }
       
  1523     if (limit > 0) {
       
  1524         for (int i = idList.count()-1; i >= limit; i--) {
       
  1525             idList.removeAt(i);
       
  1526         }
       
  1527     }
       
  1528 }
       
  1529 
       
  1530 int CFSEngine::countFolders(const QMessageFolderFilter &filter) const
       
  1531 {
       
  1532     return queryFolders(filter, QMessageFolderSortOrder(), 0, 0).count();
       
  1533 }
       
  1534 
       
  1535 QMessageFolder CFSEngine::folder(const QMessageFolderId &id) const
       
  1536 {
       
  1537     //return QMessageFolder();
       
  1538     
       
  1539     QMessageFolder folder;
       
  1540     TRAPD(err, folder = folderL(id));
       
  1541     Q_UNUSED(err)
       
  1542        
       
  1543     return folder;
       
  1544 }
       
  1545 
       
  1546 QMessageFolder CFSEngine::folderL(const QMessageFolderId &id) const
       
  1547 {
       
  1548     QMessageFolder folder;
       
  1549     MEmailMailbox* mailbox = NULL;
       
  1550     QMessageFolderId parentId;
       
  1551     QMessageAccountId accountId;
       
  1552 
       
  1553     // get account containing folder
       
  1554     TRAPD(err, updateEmailAccountsL());
       
  1555     Q_UNUSED(err)
       
  1556     foreach (QMessageAccount value, m_accounts) {
       
  1557         accountId = value.id();
       
  1558         QMessageFolderIdList ids = folderIdsByAccountIdL(accountId);
       
  1559         if (ids.contains(id)) {
       
  1560             TMailboxId mailboxId(stripIdPrefix(accountId.toString()).toInt());
       
  1561             mailbox = m_clientApi->MailboxL(mailboxId);
       
  1562             CleanupReleasePushL(*mailbox);
       
  1563             TFolderId folderId(stripIdPrefix(id.toString()).toInt(), mailbox->MailboxId());
       
  1564             MEmailFolder* emailFolder = mailbox->FolderL(folderId);
       
  1565             CleanupReleasePushL(*emailFolder);
       
  1566             QString name = QString::fromUtf16(emailFolder->Name().Ptr(), emailFolder->Name().Length());
       
  1567             folder = QMessageFolderPrivate::from(id, accountId, parentId, name, name);
       
  1568             CleanupStack::PopAndDestroy(emailFolder);
       
  1569             CleanupStack::PopAndDestroy(mailbox);
       
  1570             break;
       
  1571         }
       
  1572     }
       
  1573     return folder;
       
  1574 }
       
  1575 
       
  1576 QMessageFolderIdList CFSEngine::filterMessageFolders(const QMessageFolderFilter& filter, bool& filterHandled) const
       
  1577 {
       
  1578     QMessageFolderIdList ids;
       
  1579     TRAPD(err, ids = filterMessageFoldersL(filter, filterHandled));
       
  1580     Q_UNUSED(err)
       
  1581     return ids;
       
  1582 }
       
  1583 
       
  1584 QMessageFolderIdList CFSEngine::filterMessageFoldersL(const QMessageFolderFilter& filter, bool& filterHandled) const
       
  1585 {
       
  1586     filterHandled = false;
       
  1587     QMessageFolderIdList ids;
       
  1588     
       
  1589     if (filter.isEmpty()) {
       
  1590         QMessageFolderFilterPrivate* pf = QMessageFolderFilterPrivate::implementation(filter);
       
  1591         if (!pf->_notFilter) {
       
  1592             ids = allFolders();
       
  1593         }
       
  1594         filterHandled = true;
       
  1595     } else {
       
  1596         QMessageFolderFilterPrivate* pf = QMessageFolderFilterPrivate::implementation(filter);
       
  1597         if (!pf->_valid) {
       
  1598             return QMessageFolderIdList();
       
  1599         }
       
  1600     
       
  1601         switch (pf->_field) {
       
  1602         case QMessageFolderFilterPrivate::Id:
       
  1603             {
       
  1604             if (pf->_comparatorType == QMessageFolderFilterPrivate::Equality) {
       
  1605                 QMessageDataComparator::EqualityComparator cmp(static_cast<QMessageDataComparator::EqualityComparator>(pf->_comparatorValue));
       
  1606                 if (pf->_value.toString().length() > QString(SymbianHelpers::mtmPrefix).length()) {
       
  1607                     bool folderOk = false;
       
  1608                     MEmailMailbox* mailbox = NULL;
       
  1609                     MEmailFolder* folder = NULL;;
       
  1610                     if (fsFolderL(QMessageFolderId(pf->_value.toString()), mailbox, folder)) {
       
  1611                         folderOk = true;
       
  1612                         // cleanup
       
  1613                         folder->Release();
       
  1614                         mailbox->Release();
       
  1615                     }
       
  1616                     if (cmp == QMessageDataComparator::Equal) {
       
  1617                         if (folderOk) {
       
  1618                             ids.append(QMessageFolderId(pf->_value.toString()));
       
  1619                         }
       
  1620                     } else { // NotEqual
       
  1621                         ids = allFolders();
       
  1622                         if (folderOk) {
       
  1623                             ids.removeOne(QMessageFolderId(pf->_value.toString()));
       
  1624                         }
       
  1625                     }
       
  1626                 } else {
       
  1627                     if (cmp == QMessageDataComparator::NotEqual) {
       
  1628                         ids = allFolders();
       
  1629                     }
       
  1630                 }
       
  1631                 filterHandled = true;
       
  1632             } else if (pf->_comparatorType == QMessageFolderFilterPrivate::Inclusion) {
       
  1633                 QMessageDataComparator::InclusionComparator cmp(static_cast<QMessageDataComparator::InclusionComparator>(pf->_comparatorValue));
       
  1634                 if (pf->_ids.count() > 0) { // QMessageIdList
       
  1635                     QMessageFolderIdList ids2;
       
  1636                     for (int i=0; i < pf->_ids.count(); i++) {
       
  1637                         MEmailMailbox* mailbox = NULL;
       
  1638                         MEmailFolder* folder = NULL;
       
  1639                         if (fsFolderL(QMessageFolderId(pf->_ids[i]), mailbox, folder)) {
       
  1640                             ids2.append(pf->_ids[i]);
       
  1641                             // cleanup
       
  1642                             folder->Release();
       
  1643                             mailbox->Release();
       
  1644                         }
       
  1645                     }
       
  1646                     if (cmp == QMessageDataComparator::Includes) {
       
  1647                         ids << ids2;
       
  1648                     } else { // Excludes
       
  1649                         ids = allFolders();
       
  1650                         for (int i=0; i < ids2.count(); i++) {
       
  1651                             ids.removeOne(ids2[i]);
       
  1652                         }
       
  1653                     }
       
  1654                     filterHandled = true;
       
  1655                 } else {
       
  1656                     // Empty QMessageIdList as a list
       
  1657                     if (cmp == QMessageDataComparator::Excludes) {
       
  1658                         ids = allFolders();
       
  1659                     }
       
  1660                     filterHandled = true;
       
  1661                 
       
  1662                     // QMessageFilter 
       
  1663                     /*if (cmp == QMessageDataComparator::Includes) {
       
  1664                         // TODO:
       
  1665                     } else { // Excludes
       
  1666                         // TODO:
       
  1667                     }*/
       
  1668                 }
       
  1669             }
       
  1670             break;
       
  1671             }
       
  1672         case QMessageFolderFilterPrivate::Name:
       
  1673             {
       
  1674             if (pf->_comparatorType == QMessageFolderFilterPrivate::Equality) {
       
  1675                 QMessageDataComparator::EqualityComparator cmp(static_cast<QMessageDataComparator::EqualityComparator>(pf->_comparatorValue));
       
  1676                 if (cmp == QMessageDataComparator::Equal) {
       
  1677                     // TODO:
       
  1678                 } else { // NotEqual
       
  1679                     // TODO:
       
  1680                 }
       
  1681             } else if (pf->_comparatorType == QMessageFolderFilterPrivate::Inclusion) {
       
  1682                 QMessageDataComparator::InclusionComparator cmp(static_cast<QMessageDataComparator::InclusionComparator>(pf->_comparatorValue));
       
  1683                 if (cmp == QMessageDataComparator::Includes) {
       
  1684                     // TODO:
       
  1685                 } else { // Excludes
       
  1686                     if (pf->_value.toString().isEmpty() || pf->_value.toString().length() == 0) {
       
  1687                         filterHandled = true;
       
  1688                     }
       
  1689                 }
       
  1690             }
       
  1691             break;
       
  1692             }
       
  1693         case QMessageFolderFilterPrivate::Path:
       
  1694             {
       
  1695             if (pf->_comparatorType == QMessageFolderFilterPrivate::Equality) {
       
  1696                 QMessageDataComparator::EqualityComparator cmp(static_cast<QMessageDataComparator::EqualityComparator>(pf->_comparatorValue));
       
  1697                 if (cmp == QMessageDataComparator::Equal) {
       
  1698                     // TODO:
       
  1699                 } else { // NotEqual
       
  1700                     // TODO:
       
  1701                 }
       
  1702             } else if (pf->_comparatorType == QMessageFolderFilterPrivate::Inclusion) {
       
  1703                 QMessageDataComparator::InclusionComparator cmp(static_cast<QMessageDataComparator::InclusionComparator>(pf->_comparatorValue));
       
  1704                 if (cmp == QMessageDataComparator::Includes) {
       
  1705                     // TODO:
       
  1706                 } else { // Excludes
       
  1707                     if (pf->_value.toString().isEmpty() || pf->_value.toString().length() == 0) {
       
  1708                         filterHandled = true;
       
  1709                     }
       
  1710                 }
       
  1711             }
       
  1712             break;
       
  1713             }
       
  1714         case QMessageFolderFilterPrivate::ParentAccountId:
       
  1715             {
       
  1716             if (pf->_comparatorType == QMessageFolderFilterPrivate::Equality) {
       
  1717                 QMessageDataComparator::EqualityComparator cmp(static_cast<QMessageDataComparator::EqualityComparator>(pf->_comparatorValue));
       
  1718                 if (cmp == QMessageDataComparator::Equal) {
       
  1719                     if (pf->_value.toString().length() > 0) {
       
  1720                         ids = folderIdsByAccountIdL(QMessageAccountId(pf->_value.toString()));
       
  1721                     }
       
  1722                 } else { // NotEqual
       
  1723                     ids = allFolders();
       
  1724                     if (pf->_value.toString().length() > 0) {
       
  1725                         QMessageFolderIdList ids2 = folderIdsByAccountIdL(QMessageAccountId(pf->_value.toString()));
       
  1726                         for (int i = 0; i < ids2.count(); i++) {
       
  1727                             ids.removeOne(ids2[i]);
       
  1728                         }
       
  1729                     }
       
  1730                 }
       
  1731                 filterHandled = true;
       
  1732             } else if (pf->_comparatorType == QMessageFolderFilterPrivate::Inclusion) {
       
  1733                 QMessageDataComparator::InclusionComparator cmp(static_cast<QMessageDataComparator::InclusionComparator>(pf->_comparatorValue));
       
  1734                 if (cmp == QMessageDataComparator::Includes) {
       
  1735                     // TODO:
       
  1736                 } else { // Excludes
       
  1737                     // TODO:
       
  1738                 }
       
  1739             }
       
  1740             break;
       
  1741             }
       
  1742         case QMessageFolderFilterPrivate::ParentFolderId:
       
  1743             {
       
  1744             if (pf->_comparatorType == QMessageFolderFilterPrivate::Equality) {
       
  1745                 QMessageDataComparator::EqualityComparator cmp(static_cast<QMessageDataComparator::EqualityComparator>(pf->_comparatorValue));
       
  1746                 if (cmp == QMessageDataComparator::Equal) {
       
  1747                     MEmailMailbox* mailbox = NULL;
       
  1748                     MEmailFolder* parentFolder = NULL;
       
  1749                     if (fsFolderL(QMessageFolderId(pf->_value.toString()), mailbox, parentFolder)) {
       
  1750                         CleanupReleasePushL(*mailbox);
       
  1751                         CleanupReleasePushL(*parentFolder);
       
  1752 
       
  1753                         RFolderArray subfolders;
       
  1754                         
       
  1755                         parentFolder->GetSubfoldersL(subfolders);
       
  1756                         CleanupClosePushL(subfolders);
       
  1757 
       
  1758                         for(TInt i=0; i < subfolders.Count(); i++) {
       
  1759                             MEmailFolder *subFolder = subfolders[i];
       
  1760                             
       
  1761                             ids.append(QMessageFolderId(addIdPrefix(
       
  1762                                 QString::number(subFolder->FolderId().iId), 
       
  1763                                 SymbianHelpers::EngineTypeFreestyle)));
       
  1764                             
       
  1765                             subFolder->Release();
       
  1766                         }
       
  1767                         
       
  1768                         CleanupStack::PopAndDestroy(&subfolders);
       
  1769                         CleanupStack::PopAndDestroy(parentFolder);
       
  1770                         CleanupStack::PopAndDestroy(mailbox);
       
  1771                     }
       
  1772                 } else { // NotEqual
       
  1773                     // TODO:
       
  1774                 }
       
  1775             } else if (pf->_comparatorType == QMessageFolderFilterPrivate::Inclusion) {
       
  1776                 QMessageDataComparator::InclusionComparator cmp(static_cast<QMessageDataComparator::InclusionComparator>(pf->_comparatorValue));
       
  1777                 if (cmp == QMessageDataComparator::Includes) {
       
  1778                     // TODO:
       
  1779                 } else { // Excludes
       
  1780                     // TODO:
       
  1781                 }
       
  1782             }
       
  1783             break;
       
  1784             }
       
  1785         case QMessageFolderFilterPrivate::AncestorFolderIds:
       
  1786             {
       
  1787                 if (pf->_comparatorType == QMessageFolderFilterPrivate::Inclusion) {
       
  1788                     QMessageDataComparator::InclusionComparator cmp(static_cast<QMessageDataComparator::InclusionComparator>(pf->_comparatorValue));
       
  1789                     if (!pf->_value.isNull()) { // QMessageFolderId
       
  1790                         if (cmp == QMessageDataComparator::Includes) {
       
  1791                             // TODO:
       
  1792                         } else { // Excludes
       
  1793                             // TODO:
       
  1794                         }
       
  1795                     } else { // QMessageFolderFilter
       
  1796                         if (cmp == QMessageDataComparator::Includes) {
       
  1797                             // TODO:
       
  1798                         } else { // Excludes
       
  1799                             // TODO:
       
  1800                         }
       
  1801                     }
       
  1802                 }
       
  1803                 break;
       
  1804             }
       
  1805         case QMessageFolderFilterPrivate::ParentAccountIdFilter:
       
  1806         case QMessageFolderFilterPrivate::None:
       
  1807             break;        
       
  1808         }
       
  1809     }
       
  1810     
       
  1811     if (!filterHandled) {
       
  1812         ids = allFolders();
       
  1813     }
       
  1814 
       
  1815     return ids;
       
  1816 }
       
  1817 
       
  1818 
       
  1819 QMessageFolderIdList CFSEngine::allFolders() const
       
  1820 {
       
  1821     QMessageFolderIdList ids;
       
  1822     TRAPD(err, updateEmailAccountsL());
       
  1823     Q_UNUSED(err)
       
  1824     foreach (QMessageAccount value, m_accounts) {
       
  1825         QMessageFolderIdList ids2 = folderIdsByAccountId(value.id());
       
  1826         ids << ids2;
       
  1827     }
       
  1828     return ids;
       
  1829 }
       
  1830 
       
  1831 QMessageFolderIdList CFSEngine::folderIdsByAccountId(const QMessageAccountId& accountId) const
       
  1832 {
       
  1833     QMessageFolderIdList idList;
       
  1834     TRAPD(err, idList << folderIdsByAccountIdL(accountId))
       
  1835     Q_UNUSED(err);
       
  1836     return idList;
       
  1837 }
       
  1838 
       
  1839 QMessageFolderIdList CFSEngine::folderIdsByAccountIdL(const QMessageAccountId& accountId) const
       
  1840 {
       
  1841     QMessageFolderIdList folderIds;
       
  1842     
       
  1843     if (idType(accountId) != EngineTypeFreestyle)
       
  1844         return QMessageFolderIdList();
       
  1845     
       
  1846     QMessageAccount messageAccount = account(accountId);
       
  1847     
       
  1848     TMailboxId mailboxId(stripIdPrefix(accountId.toString()).toInt());
       
  1849     MEmailMailbox* mailbox = NULL;
       
  1850     mailbox = m_clientApi->MailboxL(mailboxId);
       
  1851 
       
  1852     if (mailbox == NULL)
       
  1853         return QMessageFolderIdList();
       
  1854 
       
  1855     CleanupReleasePushL(*mailbox);
       
  1856 
       
  1857     RFolderArray folders;
       
  1858     
       
  1859     mailbox->GetFoldersL(folders);
       
  1860     CleanupClosePushL(folders);
       
  1861 
       
  1862     for(TInt i=0; i < folders.Count(); i++) {
       
  1863         MEmailFolder *mailFolder = folders[i];
       
  1864         
       
  1865         QString fsIdAsString = addIdPrefix(QString::number(mailFolder->FolderId().iId), SymbianHelpers::EngineTypeFreestyle);
       
  1866         folderIds.append(QMessageFolderId(fsIdAsString));
       
  1867 
       
  1868         //TODO: Support for subfolders?
       
  1869         mailFolder->Release();
       
  1870     }
       
  1871     
       
  1872     CleanupStack::PopAndDestroy(&folders);
       
  1873     CleanupStack::PopAndDestroy(mailbox);
       
  1874     
       
  1875     return folderIds;
       
  1876 }
       
  1877 
       
  1878 bool CFSEngine::fsFolderL(const QMessageFolderId& id, MEmailMailbox* mailbox, MEmailFolder* folder) const
       
  1879 {
       
  1880     Q_UNUSED(folder);
       
  1881     MEmailFolder* fsFolder = NULL;
       
  1882     foreach (QMessageAccount account, m_accounts) {
       
  1883         TMailboxId mailboxId(stripIdPrefix(account.id().toString()).toInt());
       
  1884         mailbox = m_clientApi->MailboxL(mailboxId);
       
  1885         
       
  1886         TFolderId folderId(
       
  1887             stripIdPrefix(id.toString()).toInt(),
       
  1888             mailboxId);
       
  1889             
       
  1890         TRAPD(err, folder = mailbox->FolderL(folderId));
       
  1891         if (err == KErrNone) {               
       
  1892             CleanupReleasePushL(*fsFolder);
       
  1893             return true;
       
  1894         }
       
  1895         mailbox->Release();
       
  1896     }
       
  1897     mailbox = NULL;
       
  1898     folder = NULL;
       
  1899     return false;
       
  1900 }
       
  1901 
       
  1902 
       
  1903 QMessage CFSEngine::message(const QMessageId& id) const
       
  1904 {
       
  1905     QMessage message = QMessage();
       
  1906     TRAPD(err, message = messageL(id));
       
  1907     Q_UNUSED(err);
       
  1908     return message;
       
  1909 }
       
  1910 
       
  1911 QMessage CFSEngine::messageL(const QMessageId& id) const
       
  1912 {
       
  1913     QMessage message = QMessage();
       
  1914     foreach (QMessageAccount account, m_accounts) {
       
  1915         TMailboxId mailboxId(stripIdPrefix(account.id().toString()).toInt());
       
  1916         MEmailMailbox* mailbox = m_clientApi->MailboxL(mailboxId);
       
  1917         CleanupReleasePushL(*mailbox);
       
  1918         
       
  1919         TMessageId messageId(
       
  1920             stripIdPrefix(id.toString()).toInt(),
       
  1921             0, //stripIdPrefix(folderId.toString()).toInt(), 
       
  1922             mailboxId);
       
  1923             
       
  1924         MEmailMessage* fsMessage = NULL;
       
  1925         
       
  1926         TRAPD(err, fsMessage = mailbox->MessageL(messageId));
       
  1927         if (err == KErrNone) {
       
  1928             CleanupReleasePushL(*fsMessage);
       
  1929             message = CreateQMessageL(fsMessage);
       
  1930             
       
  1931             QMessagePrivate* privateMessage = QMessagePrivate::implementation(message);
       
  1932             privateMessage->_id = id; 
       
  1933             privateMessage->_modified = false;
       
  1934                 
       
  1935             CleanupStack::PopAndDestroy(fsMessage);
       
  1936             CleanupStack::PopAndDestroy(mailbox);
       
  1937             return message;
       
  1938         }
       
  1939         CleanupStack::PopAndDestroy(mailbox);
       
  1940     }
       
  1941     return message;
       
  1942 }
       
  1943 
       
  1944 bool CFSEngine::sendEmail(QMessage &message)
       
  1945 {
       
  1946     TMailboxId mailboxId(stripIdPrefix(message.parentAccountId().toString()).toInt());
       
  1947     MEmailMailbox* mailbox = NULL;
       
  1948     TRAPD(mailerr, mailbox = m_clientApi->MailboxL(mailboxId));
       
  1949     Q_UNUSED(mailerr);
       
  1950     
       
  1951     MEmailMessage* fsMessage = NULL;
       
  1952     TRAPD(err,
       
  1953         fsMessage = createFSMessageL(message, mailbox);
       
  1954         fsMessage->SaveChangesL();
       
  1955         fsMessage->SendL(); 
       
  1956     );
       
  1957 
       
  1958     if (fsMessage)
       
  1959         fsMessage->Release();
       
  1960     if (mailbox)
       
  1961         mailbox->Release();
       
  1962 
       
  1963     if (err != KErrNone)
       
  1964         return false;
       
  1965     else
       
  1966         return true;
       
  1967 }
       
  1968 
       
  1969 QMessage CFSEngine::CreateQMessageL(MEmailMessage* aMessage) const
       
  1970 {
       
  1971     QMessage message;
       
  1972     int size = 0;
       
  1973     message.setType(QMessage::Email);
       
  1974 
       
  1975     message.setDate(symbianTTimetoQDateTime(aMessage->Date()));
       
  1976     message.setReceivedDate(symbianTTimetoQDateTime(aMessage->Date()));
       
  1977     
       
  1978     const TFolderId& folderId = aMessage->ParentFolderId();
       
  1979     TMailboxId mailboxId = folderId.iMailboxId;
       
  1980     const QMessageAccountId accountId = QMessageAccountId(QString::number(mailboxId.iId));
       
  1981     message.setParentAccountId(accountId);
       
  1982     QMessagePrivate* privateMessage = QMessagePrivate::implementation(message);
       
  1983     privateMessage->_parentFolderId = QMessageFolderId(QString::number(folderId.iId));
       
  1984     
       
  1985     MEmailMailbox* mailbox = m_clientApi->MailboxL(mailboxId);
       
  1986     MEmailFolder* folder = mailbox->FolderL(folderId);
       
  1987     QMessagePrivate::setStandardFolder(message, QMessage::InboxFolder);
       
  1988     if (folder->FolderType() == EDrafts) {
       
  1989         QMessagePrivate::setStandardFolder(message, QMessage::DraftsFolder);
       
  1990     } else if (folder->FolderType() == EDeleted) {
       
  1991         QMessagePrivate::setStandardFolder(message, QMessage::TrashFolder);
       
  1992     } else if (folder->FolderType() == ESent) {
       
  1993         QMessagePrivate::setStandardFolder(message, QMessage::SentFolder);
       
  1994     }
       
  1995     folder->Release();
       
  1996     mailbox->Release();
       
  1997 
       
  1998     if (aMessage->Flags() & EFlag_Read) {
       
  1999         privateMessage->_status = privateMessage->_status | QMessage::Read; 
       
  2000     }
       
  2001 
       
  2002     if (aMessage->Flags() & EFlag_Important) {
       
  2003         message.setPriority(QMessage::HighPriority); 
       
  2004     } else if (aMessage->Flags() & EFlag_Low) {
       
  2005         message.setPriority(QMessage::LowPriority);
       
  2006     } else {
       
  2007         message.setPriority(QMessage::NormalPriority);
       
  2008     }
       
  2009 
       
  2010     // bodytext and attachment(s)
       
  2011     MEmailMessageContent* content = aMessage->ContentL();
       
  2012     if (content) {
       
  2013        AddContentToMessage(content, &message);
       
  2014     }
       
  2015    
       
  2016     REmailAttachmentArray attachments;                  
       
  2017     CleanupResetAndRelease<MEmailAttachment>::PushL(attachments);
       
  2018     TInt count = aMessage->GetAttachmentsL(attachments);
       
  2019     if (count > 0)
       
  2020         privateMessage->_status = privateMessage->_status | QMessage::HasAttachments;  
       
  2021     
       
  2022     for(TInt i = 0; i < count; i++) {
       
  2023         TInt availableSize = attachments[i]->AvailableSize();       
       
  2024         QByteArray name = QString::fromUtf16(attachments[i]->FileNameL().Ptr(), attachments[i]->FileNameL().Length()).toLocal8Bit();
       
  2025         QByteArray mimeType; // TODO: email client api doesn't offer information about attachment mimetype
       
  2026         QByteArray mimeSubType; // TODO;
       
  2027         int size = attachments[i]->TotalSize();
       
  2028         QMessageContentContainer attachment = QMessageContentContainerPrivate::from(
       
  2029                                                 aMessage->MessageId().iId, 
       
  2030                                                 attachments[i]->Id().iId, 
       
  2031                                                 name, mimeType, 
       
  2032                                                 mimeSubType, size);
       
  2033         addAttachmentToMessage(message, attachment);       
       
  2034     }
       
  2035     CleanupStack::PopAndDestroy();
       
  2036     attachments.Close();
       
  2037     
       
  2038     //from
       
  2039     TPtrC from = aMessage->SenderAddressL()->Address();
       
  2040     if (from.Length() > 0) {
       
  2041         message.setFrom(QMessageAddress(QMessageAddress::Email, QString::fromUtf16(from.Ptr(), from.Length())));
       
  2042         QMessagePrivate::setSenderName(message, QString::fromUtf16(from.Ptr(), from.Length()));
       
  2043     }
       
  2044     
       
  2045     //to
       
  2046     REmailAddressArray toRecipients;
       
  2047     CleanupResetAndRelease<MEmailAddress>::PushL(toRecipients);
       
  2048 
       
  2049     aMessage->GetRecipientsL(MEmailAddress::ETo, toRecipients);
       
  2050     QList<QMessageAddress> toList;
       
  2051     for(TInt i = 0; i < toRecipients.Count(); i++) {
       
  2052         TPtrC to = toRecipients[i]->Address();
       
  2053         toList.append(QMessageAddress(QMessageAddress::Email, QString::fromUtf16(to.Ptr(), to.Length())));
       
  2054     }
       
  2055     message.setTo(toList);
       
  2056     CleanupStack::PopAndDestroy(&toRecipients);
       
  2057     toRecipients.Close();
       
  2058     
       
  2059     //cc
       
  2060     REmailAddressArray ccRecipients;
       
  2061     CleanupResetAndRelease<MEmailAddress>::PushL(ccRecipients);
       
  2062     aMessage->GetRecipientsL(MEmailAddress::ECc, ccRecipients);
       
  2063     QList<QMessageAddress> ccList;
       
  2064     for(TInt i = 0; i < ccRecipients.Count(); i++) {
       
  2065         TPtrC cc = ccRecipients[i]->Address();
       
  2066         ccList.append(QMessageAddress(QMessageAddress::Email, QString::fromUtf16(cc.Ptr(), cc.Length())));
       
  2067     }
       
  2068     message.setCc(ccList); 
       
  2069     CleanupStack::PopAndDestroy(&ccRecipients);
       
  2070     ccRecipients.Close();
       
  2071     
       
  2072     //bcc
       
  2073     REmailAddressArray bccRecipients;
       
  2074     CleanupResetAndRelease<MEmailAddress>::PushL(bccRecipients);
       
  2075     aMessage->GetRecipientsL(MEmailAddress::EBcc, bccRecipients);
       
  2076     QList<QMessageAddress> bccList;
       
  2077     for(TInt i = 0; i < bccRecipients.Count(); i++) {
       
  2078         TPtrC bcc = bccRecipients[i]->Address();
       
  2079         bccList.append(QMessageAddress(QMessageAddress::Email, QString::fromUtf16(bcc.Ptr(), bcc.Length())));
       
  2080     }
       
  2081     message.setBcc(bccList);
       
  2082     CleanupStack::PopAndDestroy(&bccRecipients);
       
  2083     bccRecipients.Close();
       
  2084     
       
  2085     // Read message subject   
       
  2086     TPtrC subject = aMessage->Subject();
       
  2087     if (subject.Length() > 0) {
       
  2088         message.setSubject(QString::fromUtf16(subject.Ptr(), subject.Length()));
       
  2089     }
       
  2090     // TODO: size
       
  2091     privateMessage->_size = size;
       
  2092 
       
  2093     return message;    
       
  2094 }
       
  2095 
       
  2096 void CFSEngine::AddContentToMessage(MEmailMessageContent* aContent, QMessage* aMessage) const
       
  2097 {
       
  2098     MEmailMultipart* mPart = aContent->AsMultipartOrNull();
       
  2099     if (mPart) {
       
  2100     TInt partCount = 0;
       
  2101     TRAPD(err, partCount = mPart->PartCountL());
       
  2102         if (err == KErrNone) {
       
  2103             for (TInt i = 0; i < partCount-1; i++) {
       
  2104                 MEmailMessageContent* content = NULL;
       
  2105                 TRAPD(err2, content = mPart->PartByIndexL(i));
       
  2106                 if (err2 == KErrNone) {
       
  2107                     AddContentToMessage(content, aMessage);
       
  2108                     content->Release();
       
  2109                 }
       
  2110             }
       
  2111         }
       
  2112         return;
       
  2113     }
       
  2114  
       
  2115     MEmailTextContent* textContent = aContent->AsTextContentOrNull();
       
  2116     if (textContent) { 
       
  2117         TInt availableSize = textContent->AvailableSize();
       
  2118         TRAPD(err, 
       
  2119             TPtrC body = textContent->ContentL(); 
       
  2120             QString text = QString::fromUtf16(body.Ptr(), body.Length());
       
  2121             if (textContent->TextType() == MEmailTextContent::EPlainText) {
       
  2122                 aMessage->setBody(text, "text/plain");
       
  2123             }
       
  2124             else if (textContent->TextType() == MEmailTextContent::EHtmlText) {
       
  2125                 aMessage->setBody(text, "text/html");
       
  2126             }
       
  2127             );
       
  2128         Q_UNUSED(err);
       
  2129         return;
       
  2130     }
       
  2131 }
       
  2132 
       
  2133 void CFSEngine::addAttachmentToMessage(QMessage& message, QMessageContentContainer& attachment) const
       
  2134 {
       
  2135     QMessagePrivate* privateMessage = QMessagePrivate::implementation(message);
       
  2136     QMessageContentContainerPrivate* container = QMessagePrivate::containerImplementation(message);
       
  2137     
       
  2138     if (container->_attachments.isEmpty()) {
       
  2139         QMessageContentContainerId existingBodyId(message.bodyId());
       
  2140         if (existingBodyId == QMessageContentContainerPrivate::bodyContentId()) {
       
  2141             // The body content is in the message itself - move it to become the first attachment
       
  2142             QMessageContentContainer newBody(message);
       
  2143             QMessageContentContainerPrivate::implementation(newBody)->setDerivedMessage(0);
       
  2144     
       
  2145             container->setContentType("multipart", "mixed", "");
       
  2146             privateMessage->_bodyId = container->prependContent(newBody);
       
  2147         } else {
       
  2148             // This message is now multipart
       
  2149             container->setContentType("multipart", "mixed", "");
       
  2150         }
       
  2151     
       
  2152         container->_available = true;
       
  2153     }
       
  2154     
       
  2155     container->appendContent(attachment);
       
  2156     
       
  2157     bool haveAttachments = !container->_attachments.isEmpty();
       
  2158     message.setStatus(QMessage::HasAttachments,haveAttachments);
       
  2159     
       
  2160     privateMessage->_modified = true;
       
  2161 }
       
  2162 
       
  2163 QDateTime CFSEngine::symbianTTimetoQDateTime(const TTime& time) const
       
  2164 {
       
  2165     TDateTime dateTime = time.DateTime();
       
  2166     QDate qdate = QDate(dateTime.Year(), static_cast<int>(dateTime.Month())+1, dateTime.Day()+1);
       
  2167     QTime qtime = QTime(dateTime.Hour(), dateTime.Minute(), dateTime.Second(), dateTime.MicroSecond()/1000 );
       
  2168     return QDateTime(qdate, qtime, Qt::UTC);
       
  2169 }
       
  2170 
       
  2171 TTime CFSEngine::qDateTimeToSymbianTTime(const QDateTime& date) const
       
  2172 {
       
  2173     TDateTime dateTime;
       
  2174     dateTime.SetYear(date.date().year());
       
  2175     dateTime.SetMonth(static_cast<TMonth>(date.date().month()-1));
       
  2176     dateTime.SetDay(date.date().day()-1);
       
  2177     dateTime.SetHour(date.time().hour());
       
  2178     dateTime.SetMinute(date.time().minute());
       
  2179     dateTime.SetSecond(date.time().second());
       
  2180     dateTime.SetMicroSecond(date.time().msec()*1000);
       
  2181     return TTime(dateTime);
       
  2182 }
       
  2183 
       
  2184 TFolderType CFSEngine::standardFolderId(QMessage::StandardFolder standardFolder)
       
  2185 {
       
  2186     switch(standardFolder) {
       
  2187         case QMessage::InboxFolder: return EInbox;
       
  2188         case QMessage::OutboxFolder: return EOutbox;
       
  2189         case QMessage::DraftsFolder: return EDrafts;
       
  2190         case QMessage::SentFolder: return ESent;
       
  2191         case QMessage::TrashFolder: return EDeleted;
       
  2192         default: return EOther;
       
  2193     }
       
  2194 }
       
  2195 
       
  2196 CFSMessagesFindOperation::CFSMessagesFindOperation(CFSEngine& aOwner, int aOperationId)
       
  2197     : m_owner(aOwner), 
       
  2198       m_operationId(aOperationId),
       
  2199       m_resultCorrectlyOrdered(false),
       
  2200       m_receiveNewMessages(false),
       
  2201       m_activeSearchCount(0),
       
  2202       m_searchField(None)
       
  2203 {
       
  2204     TRAPD(err,
       
  2205             m_factory = CEmailInterfaceFactory::NewL(); 
       
  2206             m_interfacePtr = m_factory->InterfaceL(KEmailClientApiInterface); 
       
  2207             m_clientApi = static_cast<MEmailClientApi*>(m_interfacePtr); 
       
  2208         );
       
  2209     Q_UNUSED(err);
       
  2210 }
       
  2211 
       
  2212 CFSMessagesFindOperation::~CFSMessagesFindOperation()
       
  2213 {
       
  2214     foreach(FSSearchOperation operation, m_searchOperations) {
       
  2215         operation.m_search->Release();
       
  2216         operation.m_mailbox->Release();
       
  2217     }
       
  2218     
       
  2219     m_receiveNewMessages = false;
       
  2220     m_clientApi->Release();
       
  2221     delete m_factory;
       
  2222 
       
  2223 }
       
  2224 
       
  2225 void CFSMessagesFindOperation::filterAndOrderMessages(const QMessageFilter &filter, const QMessageSortOrder& sortOrder,
       
  2226                                                     QString body, QMessageDataComparator::MatchFlags matchFlags)
       
  2227 {
       
  2228     m_filterList.clear();
       
  2229     m_filterList.append(filter);
       
  2230     filterAndOrderMessages(m_filterList, sortOrder, body, matchFlags);
       
  2231 }
       
  2232 
       
  2233 void CFSMessagesFindOperation::filterAndOrderMessages(const QMessageFilterPrivate::SortedMessageFilterList& filters,
       
  2234                                                     const QMessageSortOrder& sortOrder,
       
  2235                                                     QString body,
       
  2236                                                     QMessageDataComparator::MatchFlags matchFlags)
       
  2237 {
       
  2238     TRAPD(err, filterAndOrderMessagesL(filters, sortOrder, body, matchFlags));
       
  2239     if (err != KErrNone) {
       
  2240         //something has failed -> return empty list
       
  2241         m_idList = QMessageIdList();
       
  2242         QMetaObject::invokeMethod(this, "SearchCompleted", Qt::QueuedConnection);
       
  2243     }
       
  2244 }
       
  2245 
       
  2246 void CFSMessagesFindOperation::filterAndOrderMessagesL(const QMessageFilterPrivate::SortedMessageFilterList& filters,
       
  2247                                                     const QMessageSortOrder& sortOrder,
       
  2248                                                     QString body,
       
  2249                                                     QMessageDataComparator::MatchFlags matchFlags)
       
  2250 {
       
  2251     m_numberOfHandledFilters = 0;
       
  2252     
       
  2253     TEmailSortCriteria sortCriteria = TEmailSortCriteria();
       
  2254     m_excludeIdList = QMessageIdList();
       
  2255 
       
  2256     m_matchFlags = matchFlags;
       
  2257     
       
  2258     if (filters.count() == 0) {
       
  2259         m_idList = QMessageIdList();
       
  2260         QMetaObject::invokeMethod(this, "SearchCompleted", Qt::QueuedConnection);
       
  2261         return;
       
  2262     }
       
  2263     
       
  2264     QMessageFilterPrivate* pf = QMessageFilterPrivate::implementation(filters[m_numberOfHandledFilters]);
       
  2265 
       
  2266     // Set sortOrder
       
  2267     if (!sortOrder.isEmpty() ) {
       
  2268         QMessageSortOrderPrivate* privateMessageOrdering = QMessageSortOrderPrivate::implementation(sortOrder);
       
  2269         QPair<QMessageSortOrderPrivate::Field, Qt::SortOrder> fieldOrder = privateMessageOrdering->_fieldOrderList.at(0);
       
  2270         switch (fieldOrder.first) {
       
  2271             case QMessageSortOrderPrivate::Type:
       
  2272                 break;
       
  2273             case QMessageSortOrderPrivate::Sender:
       
  2274                 sortCriteria.iField = TEmailSortCriteria::EBySender;
       
  2275                 break;
       
  2276             case QMessageSortOrderPrivate::Recipients:
       
  2277                 sortCriteria.iField = TEmailSortCriteria::EByRecipient;
       
  2278                 break;
       
  2279             case QMessageSortOrderPrivate::Subject:
       
  2280                 sortCriteria.iField = TEmailSortCriteria::EBySubject;
       
  2281                 break;
       
  2282             case QMessageSortOrderPrivate::TimeStamp:
       
  2283                 sortCriteria.iField = TEmailSortCriteria::EByDate;
       
  2284                 break;
       
  2285             case QMessageSortOrderPrivate::ReceptionTimeStamp:
       
  2286                 sortCriteria.iField = TEmailSortCriteria::EBySender;
       
  2287                 break;
       
  2288             case QMessageSortOrderPrivate::Read:
       
  2289                 sortCriteria.iField = TEmailSortCriteria::EByUnread;
       
  2290                 break;
       
  2291             case QMessageSortOrderPrivate::HasAttachments:
       
  2292                 sortCriteria.iField = TEmailSortCriteria::EByAttachment;
       
  2293                 break;
       
  2294             case QMessageSortOrderPrivate::Incoming:
       
  2295                 //TODO:
       
  2296                 break;
       
  2297             case QMessageSortOrderPrivate::Removed:
       
  2298                 //TODO:
       
  2299                 break;
       
  2300             case QMessageSortOrderPrivate::Priority:
       
  2301                 sortCriteria.iField = TEmailSortCriteria::EByPriority;
       
  2302                 break;
       
  2303             case QMessageSortOrderPrivate::Size:
       
  2304                 sortCriteria.iField = TEmailSortCriteria::EBySize;
       
  2305                 break;
       
  2306         }
       
  2307         sortCriteria.iAscending = fieldOrder.second == Qt::AscendingOrder?true:false;
       
  2308     } else {
       
  2309         // This is a workaroud for getFolderSpecificMessagesL crashing when default TEmailSortCriteria (EDontCare) is set
       
  2310         sortCriteria.iField = TEmailSortCriteria::EByDate;
       
  2311     }
       
  2312 
       
  2313     if ((filters.count() == 1) &&
       
  2314         (pf->_field == QMessageFilterPrivate::None) &&
       
  2315         (pf->_filterList.count() == 0)) {
       
  2316         if (pf->_notFilter) {
       
  2317             // There is only one filter: empty ~QMessageFilter()
       
  2318             // => return empty QMessageIdList 
       
  2319             m_idList = QMessageIdList();
       
  2320             QMetaObject::invokeMethod(this, "SearchCompleted", Qt::QueuedConnection);
       
  2321         } else {
       
  2322             // There is only one filter: empty QMessageFilter()
       
  2323             // => return all messages
       
  2324             getAllMessagesL(sortCriteria);
       
  2325         }
       
  2326         m_numberOfHandledFilters++;
       
  2327         return;
       
  2328     }
       
  2329 
       
  2330     if (!body.isEmpty()) {
       
  2331         m_searchField = Body;
       
  2332         m_searchKey = body;
       
  2333     }
       
  2334     
       
  2335     switch (pf->_field) {
       
  2336     
       
  2337         case QMessageFilterPrivate::ParentFolderId: {
       
  2338             if (idType(pf->_value.toString()) != EngineTypeFreestyle) {
       
  2339                 QMetaObject::invokeMethod(this, "SearchCompleted", Qt::QueuedConnection);
       
  2340                 return;
       
  2341             }
       
  2342             if (pf->_comparatorType == QMessageFilterPrivate::Equality) { // QMessageFolderId
       
  2343                 QMessageDataComparator::EqualityComparator cmp(static_cast<QMessageDataComparator::EqualityComparator>(pf->_comparatorValue));
       
  2344                 if (cmp == QMessageDataComparator::Equal) {
       
  2345                     m_numberOfHandledFilters++;
       
  2346                     QMessageFolder messageFolder = m_owner.folder(QMessageFolderId(pf->_value.toString()));
       
  2347                     getFolderSpecificMessagesL(messageFolder, sortCriteria);
       
  2348                     m_resultCorrectlyOrdered = true;
       
  2349                     QMetaObject::invokeMethod(this, "SearchCompleted", Qt::QueuedConnection);
       
  2350                 } else { // NotEqual
       
  2351                     // TODO:
       
  2352                 }
       
  2353             } else if (pf->_comparatorType == QMessageFilterPrivate::Inclusion) { // QMessageFolderFilter
       
  2354                 QMessageDataComparator::InclusionComparator cmp(static_cast<QMessageDataComparator::InclusionComparator>(pf->_comparatorValue));
       
  2355                 if (cmp == QMessageDataComparator::Includes) {
       
  2356                     // TODO:
       
  2357                 } else { // Excludes
       
  2358                     // TODO:
       
  2359                 }
       
  2360             }
       
  2361             break;
       
  2362         }
       
  2363         case QMessageFilterPrivate::Id: {
       
  2364             if (idType(pf->_value.toString()) != EngineTypeFreestyle) {
       
  2365                 QMetaObject::invokeMethod(this, "SearchCompleted", Qt::QueuedConnection);
       
  2366                 return;
       
  2367             }
       
  2368             m_numberOfHandledFilters++;
       
  2369             if (pf->_comparatorType == QMessageFilterPrivate::Equality) { // QMessageId
       
  2370                 QMessageDataComparator::EqualityComparator cmp(static_cast<QMessageDataComparator::EqualityComparator>(pf->_comparatorValue));
       
  2371                 if (!pf->_value.isNull() && pf->_value.toString().length() > QString(SymbianHelpers::freestylePrefix).length()) {
       
  2372                     if (cmp == QMessageDataComparator::Equal) {
       
  2373                         QMessage message = m_owner.message(QMessageId(pf->_value.toString()));
       
  2374                         m_idList.clear();
       
  2375                         m_idList.append(message.id());
       
  2376                         m_resultCorrectlyOrdered = true;
       
  2377                         QMetaObject::invokeMethod(this, "SearchCompleted", Qt::QueuedConnection);
       
  2378 
       
  2379                     } else { // NotEqual
       
  2380                         m_excludeIdList.clear();
       
  2381                         m_excludeIdList.append(QMessageId(pf->_value.toString()));
       
  2382                         getAllMessagesL(sortCriteria);
       
  2383                     }
       
  2384                 } else {
       
  2385                     if (cmp == QMessageDataComparator::NotEqual) {
       
  2386                         getAllMessagesL(sortCriteria);
       
  2387                     }
       
  2388                 }
       
  2389             } else if (pf->_comparatorType == QMessageFilterPrivate::Inclusion) {
       
  2390                 QMessageDataComparator::InclusionComparator cmp(static_cast<QMessageDataComparator::InclusionComparator>(pf->_comparatorValue));
       
  2391                 if (pf->_ids.count() > 0) { // QMessageIdList
       
  2392                     if (cmp == QMessageDataComparator::Includes) {
       
  2393                         for (int i=0; i < pf->_ids.count(); i++) {
       
  2394                             QMessage message = m_owner.message(QMessageId(pf->_ids[i].toString()));
       
  2395                             m_idList.append(message.id());
       
  2396                         }
       
  2397                         QMetaObject::invokeMethod(this, "SearchCompleted", Qt::QueuedConnection);
       
  2398                     } else { // Excludes
       
  2399                         for (int i=0; i < pf->_ids.count(); i++) {
       
  2400                             m_excludeIdList.clear();
       
  2401                             m_excludeIdList.append(QMessageId(pf->_ids[i].toString()));
       
  2402                             getAllMessagesL(sortCriteria);
       
  2403                         }
       
  2404                         getAllMessagesL(sortCriteria);
       
  2405                     }
       
  2406                 } else {
       
  2407                     //ipEntrySelection = new(ELeave)CMsvEntrySelection;
       
  2408                     if (cmp == QMessageDataComparator::Excludes) {
       
  2409                         getAllMessagesL(sortCriteria);
       
  2410                     }
       
  2411                     /*// QMessageFilter
       
  2412                     if (cmp == QMessageDataComparator::Includes) {
       
  2413                         // TODO:
       
  2414                     } else { // Excludes
       
  2415                         // TODO:
       
  2416                     }*/
       
  2417                 }
       
  2418             }
       
  2419             break;
       
  2420             }
       
  2421         case QMessageFilterPrivate::ParentAccountId: {
       
  2422             if (idType(pf->_value.toString()) != EngineTypeFreestyle) {
       
  2423                 QMetaObject::invokeMethod(this, "SearchCompleted", Qt::QueuedConnection);
       
  2424                 return;
       
  2425             }
       
  2426             if (pf->_comparatorType == QMessageFilterPrivate::Equality) { // QMessageAccountId
       
  2427                 m_numberOfHandledFilters++;
       
  2428                 QMessageDataComparator::EqualityComparator cmp(static_cast<QMessageDataComparator::EqualityComparator>(pf->_comparatorValue));
       
  2429                 if (cmp == QMessageDataComparator::Equal) {
       
  2430                     QMessageAccount messageAccount = m_owner.account(pf->_value.toString());
       
  2431                     getAccountSpecificMessagesL(messageAccount, sortCriteria);
       
  2432                     m_resultCorrectlyOrdered = true;
       
  2433                 } else { // NotEqual
       
  2434                     QStringList exludedAccounts;
       
  2435                     exludedAccounts << pf->_value.toString();
       
  2436                     
       
  2437                     QMessageFilterPrivate* privateFilter = NULL;
       
  2438                     for (int i=m_numberOfHandledFilters; i < filters.count(); i++) {
       
  2439                         privateFilter = QMessageFilterPrivate::implementation(filters[i]);
       
  2440                         if (privateFilter->_field == QMessageFilterPrivate::ParentAccountId &&
       
  2441                             privateFilter->_comparatorType == QMessageFilterPrivate::Equality) {
       
  2442                             cmp = static_cast<QMessageDataComparator::EqualityComparator>(privateFilter->_comparatorValue);
       
  2443                             if (cmp == QMessageDataComparator::NotEqual) {
       
  2444                                 exludedAccounts << privateFilter->_value.toString();
       
  2445                                 m_numberOfHandledFilters++;
       
  2446                             } else {
       
  2447                                 break;
       
  2448                             }
       
  2449                         } else {
       
  2450                             break;
       
  2451                         }
       
  2452                     }
       
  2453 
       
  2454                     privateFilter = NULL;
       
  2455                     if (filters.count() > m_numberOfHandledFilters) {
       
  2456                         privateFilter = QMessageFilterPrivate::implementation(filters[m_numberOfHandledFilters]);
       
  2457                         if (privateFilter->_field == QMessageFilterPrivate::StandardFolder &&
       
  2458                             privateFilter->_comparatorType == QMessageFilterPrivate::Equality) {
       
  2459                             cmp = static_cast<QMessageDataComparator::EqualityComparator>(privateFilter->_comparatorValue);
       
  2460                             if (cmp == QMessageDataComparator::Equal) {
       
  2461                                 m_numberOfHandledFilters++;
       
  2462                             }
       
  2463                         } else {
       
  2464                             privateFilter = NULL;
       
  2465                         }
       
  2466                     }
       
  2467                     
       
  2468                     foreach (QMessageAccount value, m_owner.m_accounts) {
       
  2469                         if (!exludedAccounts.contains(value.id().toString())) {
       
  2470                             getAccountSpecificMessagesL(value, sortCriteria);
       
  2471                         }
       
  2472                     }
       
  2473                 }
       
  2474             }
       
  2475             break;
       
  2476         }
       
  2477             
       
  2478         case QMessageFilterPrivate::AncestorFolderIds: {
       
  2479             m_numberOfHandledFilters++;
       
  2480             if (pf->_comparatorType == QMessageFilterPrivate::Inclusion) {
       
  2481                 QMessageDataComparator::InclusionComparator cmp(static_cast<QMessageDataComparator::InclusionComparator>(pf->_comparatorValue));
       
  2482                 if (!pf->_value.isNull()) { // QMessageFolderId
       
  2483                     if (cmp == QMessageDataComparator::Includes) {
       
  2484                         // TODO:
       
  2485                     } else { // Excludes
       
  2486                         // TODO:
       
  2487                     }
       
  2488                 } else { // QMessageFolderFilter
       
  2489                     if (cmp == QMessageDataComparator::Includes) {
       
  2490                         // TODO:
       
  2491                     } else { // Excludes
       
  2492                         // TODO:
       
  2493                     }
       
  2494                 }
       
  2495             }
       
  2496             break;
       
  2497             }
       
  2498         case QMessageFilterPrivate::Type: {
       
  2499             m_numberOfHandledFilters++;
       
  2500             QMessageFilterPrivate* privateFilter = NULL;
       
  2501             // Check if next filter is StandardFolder filter 
       
  2502             if (filters.count() > m_numberOfHandledFilters) {
       
  2503                 privateFilter = QMessageFilterPrivate::implementation(filters[m_numberOfHandledFilters]);
       
  2504                 if (privateFilter->_field != QMessageFilterPrivate::StandardFolder) {
       
  2505                     privateFilter = NULL;
       
  2506                 } else {
       
  2507                     m_numberOfHandledFilters++;
       
  2508                 }
       
  2509             }
       
  2510             if (pf->_comparatorType == QMessageFilterPrivate::Equality) { // QMessage::Type
       
  2511                 QMessage::Type type = static_cast<QMessage::Type>(pf->_value.toInt()); 
       
  2512                 QMessageDataComparator::EqualityComparator cmp(static_cast<QMessageDataComparator::EqualityComparator>(pf->_comparatorValue));
       
  2513                 if (cmp == QMessageDataComparator::Equal) {
       
  2514                     QMessageAccountIdList accountIds = m_owner.accountsByType(type);
       
  2515                     for (int i = 0; i < accountIds.count(); i++) {
       
  2516                         QMessageAccount messageAccount = m_owner.account(accountIds[i]);
       
  2517                         getAccountSpecificMessagesL(messageAccount, sortCriteria);
       
  2518                     }
       
  2519                 } else { // NotEqual
       
  2520                     foreach (QMessageAccount value, m_owner.m_accounts) {
       
  2521                         if (!(value.messageTypes() & type)) {
       
  2522                             getAccountSpecificMessagesL(value, sortCriteria);
       
  2523                         }
       
  2524                     }
       
  2525                 }
       
  2526             } else if (pf->_comparatorType == QMessageFilterPrivate::Inclusion) { // QMessage::TypeFlags
       
  2527                 QMessage::TypeFlags typeFlags = static_cast<QMessage::TypeFlags>(pf->_value.toInt());
       
  2528                 QMessageDataComparator::InclusionComparator cmp(static_cast<QMessageDataComparator::InclusionComparator>(pf->_comparatorValue));
       
  2529                 if (cmp == QMessageDataComparator::Includes) {
       
  2530                     foreach (QMessageAccount value, m_owner.m_accounts) {
       
  2531                         if (value.messageTypes() | typeFlags) {
       
  2532                             getAccountSpecificMessagesL(value, sortCriteria);
       
  2533                         }
       
  2534                     }
       
  2535 
       
  2536                 } else { // Excludes
       
  2537                     foreach (QMessageAccount value, m_owner.m_accounts) {
       
  2538                         if (!(value.messageTypes() & typeFlags)) {
       
  2539                             getAccountSpecificMessagesL(value, sortCriteria);
       
  2540                         }
       
  2541                     }
       
  2542                 }
       
  2543             }
       
  2544             break;
       
  2545             }
       
  2546         case QMessageFilterPrivate::StandardFolder: {
       
  2547             m_numberOfHandledFilters++;
       
  2548             QMessageDataComparator::EqualityComparator cmp(static_cast<QMessageDataComparator::EqualityComparator>(pf->_comparatorValue));
       
  2549             QMessage::StandardFolder standardFolder = static_cast<QMessage::StandardFolder>(pf->_value.toInt());
       
  2550             TFolderType stdFolder = m_owner.standardFolderId(standardFolder);
       
  2551 
       
  2552             if (cmp == QMessageDataComparator::Equal) {
       
  2553                 foreach (QMessageAccount messageAccount, m_owner.m_accounts) {
       
  2554                     TMailboxId mailboxId(stripIdPrefix(messageAccount.id().toString()).toInt());
       
  2555                     MEmailMailbox* mailbox = m_clientApi->MailboxL(mailboxId);
       
  2556                     CleanupReleasePushL(*mailbox);
       
  2557                     MEmailFolder* folder = mailbox->FolderByTypeL(stdFolder);
       
  2558                     CleanupReleasePushL(*folder);
       
  2559                     QMessageFolder standardFolder = m_owner.folder(
       
  2560                         QMessageFolderId(QString::number(folder->FolderId().iId)));
       
  2561                     getFolderSpecificMessagesL(standardFolder, sortCriteria);
       
  2562                     m_activeSearchCount++;
       
  2563                     CleanupStack::PopAndDestroy(folder);
       
  2564                     CleanupStack::PopAndDestroy(mailbox);
       
  2565                 }
       
  2566                 m_resultCorrectlyOrdered = true;
       
  2567                 QMetaObject::invokeMethod(this, "SearchCompleted", Qt::QueuedConnection);
       
  2568             } else { // NotEqual
       
  2569                 foreach (QMessageAccount messageAccount, m_owner.m_accounts) {
       
  2570                     TMailboxId mailboxId(stripIdPrefix(messageAccount.id().toString()).toInt());
       
  2571                     MEmailMailbox* mailbox = m_clientApi->MailboxL(mailboxId);
       
  2572                     CleanupReleasePushL(*mailbox);
       
  2573                     QMessage::StandardFolder i = QMessage::InboxFolder;
       
  2574                     while (i <= QMessage::TrashFolder) {
       
  2575                         if (i != standardFolder) {
       
  2576                             MEmailFolder* folder = mailbox->FolderByTypeL(m_owner.standardFolderId(i));
       
  2577                             CleanupReleasePushL(*folder);
       
  2578                             QMessageFolder standardFolder = m_owner.folder(
       
  2579                                 QMessageFolderId(QString::number(folder->FolderId().iId)));
       
  2580                             getFolderSpecificMessagesL(standardFolder, sortCriteria);
       
  2581                             CleanupStack::PopAndDestroy(folder);
       
  2582                         }
       
  2583                         i = static_cast<QMessage::StandardFolder>(static_cast<int>(i) + 1);
       
  2584                     }
       
  2585                     CleanupStack::PopAndDestroy(mailbox);    
       
  2586                 }
       
  2587                 QMetaObject::invokeMethod(this, "SearchCompleted", Qt::QueuedConnection);
       
  2588             }
       
  2589             break;
       
  2590             }
       
  2591 
       
  2592         case QMessageFilterPrivate::Sender: 
       
  2593         case QMessageFilterPrivate::Recipients: 
       
  2594         case QMessageFilterPrivate::Subject: 
       
  2595         case QMessageFilterPrivate::Status:
       
  2596         case QMessageFilterPrivate::Priority:
       
  2597         case QMessageFilterPrivate::Size:
       
  2598         case QMessageFilterPrivate::ParentAccountIdFilter:
       
  2599         case QMessageFilterPrivate::ParentFolderIdFilter: 
       
  2600         case QMessageFilterPrivate::TimeStamp:
       
  2601         case QMessageFilterPrivate::ReceptionTimeStamp:
       
  2602         case QMessageFilterPrivate::None:
       
  2603         default:
       
  2604             break;
       
  2605     
       
  2606     }
       
  2607 
       
  2608     if (body.isEmpty()) {
       
  2609         if (m_numberOfHandledFilters < filters.count()) {
       
  2610             pf = QMessageFilterPrivate::implementation(filters[m_numberOfHandledFilters]);
       
  2611             switch (pf->_field) {
       
  2612                 case QMessageFilterPrivate::Sender: {
       
  2613                     m_searchField = Sender;
       
  2614                     if (pf->_comparatorType == QMessageFilterPrivate::Equality) {
       
  2615                         QMessageDataComparator::EqualityComparator cmp(static_cast<QMessageDataComparator::EqualityComparator>(pf->_comparatorValue));
       
  2616                         if (cmp == QMessageDataComparator::Equal) {
       
  2617                             if (pf->_value.toString().length() > 0) {
       
  2618                                 m_searchKey = pf->_value.toString();
       
  2619                                 m_numberOfHandledFilters++;
       
  2620                             }
       
  2621                         } else { // NotEqual
       
  2622                             // TODO:
       
  2623                         }
       
  2624                     } else if (pf->_comparatorType == QMessageFilterPrivate::Inclusion) {
       
  2625                         QMessageDataComparator::InclusionComparator cmp(static_cast<QMessageDataComparator::InclusionComparator>(pf->_comparatorValue));
       
  2626                         if (cmp == QMessageDataComparator::Includes) {
       
  2627                             // TODO:
       
  2628                         } else { // Excludes
       
  2629                             // TODO:
       
  2630                         }
       
  2631                     }
       
  2632                     break;
       
  2633                 }
       
  2634     
       
  2635                 case QMessageFilterPrivate::Recipients: {
       
  2636                     m_searchField = Recipients;
       
  2637                     if (pf->_comparatorType == QMessageFilterPrivate::Inclusion) {
       
  2638                         QMessageDataComparator::InclusionComparator cmp(static_cast<QMessageDataComparator::InclusionComparator>(pf->_comparatorValue));
       
  2639                         if (cmp == QMessageDataComparator::Includes) {
       
  2640                             if (pf->_value.toString().length() > 0) {
       
  2641                                 m_searchKey = pf->_value.toString();
       
  2642                                 m_numberOfHandledFilters++;
       
  2643                             }
       
  2644                         } else { // Excludes
       
  2645                             //TODO:
       
  2646                         }
       
  2647                     }
       
  2648                     break;
       
  2649                 }
       
  2650     
       
  2651                 case QMessageFilterPrivate::Subject: {
       
  2652                     m_searchField = Subject;
       
  2653                     if (pf->_comparatorType == QMessageFilterPrivate::Equality) {
       
  2654                         QMessageDataComparator::EqualityComparator cmp(static_cast<QMessageDataComparator::EqualityComparator>(pf->_comparatorValue));
       
  2655                         if (cmp == QMessageDataComparator::Equal) {
       
  2656                             if (pf->_value.toString().length() > 0) {
       
  2657                                 m_searchKey = pf->_value.toString();
       
  2658                                 m_numberOfHandledFilters++;
       
  2659                             }
       
  2660                         } else { // NotEqual
       
  2661                             // TODO:
       
  2662                         }
       
  2663                     } else if (pf->_comparatorType == QMessageFilterPrivate::Inclusion) {
       
  2664                         QMessageDataComparator::InclusionComparator cmp(static_cast<QMessageDataComparator::InclusionComparator>(pf->_comparatorValue));
       
  2665                         if (cmp == QMessageDataComparator::Includes) {
       
  2666                             // TODO:
       
  2667                         } else { // Excludes
       
  2668                             // TODO:
       
  2669                         }
       
  2670                     }
       
  2671                     break;
       
  2672                 }
       
  2673                 case QMessageFilterPrivate::TimeStamp:
       
  2674                 case QMessageFilterPrivate::ReceptionTimeStamp:
       
  2675                 case QMessageFilterPrivate::Status:
       
  2676                 case QMessageFilterPrivate::Priority:
       
  2677                 case QMessageFilterPrivate::Size:
       
  2678                 case QMessageFilterPrivate::ParentAccountIdFilter:
       
  2679                 case QMessageFilterPrivate::ParentFolderIdFilter: 
       
  2680                 case QMessageFilterPrivate::Id:
       
  2681                 case QMessageFilterPrivate::ParentFolderId:
       
  2682                 case QMessageFilterPrivate::AncestorFolderIds:
       
  2683                 case QMessageFilterPrivate::ParentAccountId:
       
  2684                 case QMessageFilterPrivate::Type:
       
  2685                 case QMessageFilterPrivate::StandardFolder:
       
  2686                 case QMessageFilterPrivate::None:
       
  2687                 default:
       
  2688                     break;
       
  2689             }
       
  2690             if (m_activeSearchCount == 0)
       
  2691                 getAllMessagesL(sortCriteria);
       
  2692         }
       
  2693     }
       
  2694     if (m_activeSearchCount == 0)
       
  2695         QMetaObject::invokeMethod(this, "SearchCompleted", Qt::QueuedConnection);
       
  2696 }
       
  2697 
       
  2698 void CFSMessagesFindOperation::getAllMessagesL(TEmailSortCriteria& sortCriteria)
       
  2699 {
       
  2700     // Get all messages from every known account
       
  2701     foreach (QMessageAccount value, m_owner.m_accounts) {
       
  2702         getAccountSpecificMessagesL(value, sortCriteria);
       
  2703     }
       
  2704     if (m_activeSearchCount == 0)
       
  2705         QMetaObject::invokeMethod(this, "SearchCompleted", Qt::QueuedConnection);
       
  2706 }
       
  2707 
       
  2708 void CFSMessagesFindOperation::getAccountSpecificMessagesL(QMessageAccount& messageAccount, TEmailSortCriteria& sortCriteria)
       
  2709 {
       
  2710     TMailboxId mailboxId(stripIdPrefix(messageAccount.id().toString()).toInt());
       
  2711     FSSearchOperation operation;
       
  2712     operation.m_mailbox = m_clientApi->MailboxL(mailboxId);
       
  2713     operation.m_search = operation.m_mailbox->MessageSearchL();
       
  2714     operation.m_search->AddSearchKeyL(_L("*"));
       
  2715     operation.m_search->SetSortCriteriaL( sortCriteria );
       
  2716     operation.m_search->StartSearchL( *this ); // this implements MEmailSearchObserver
       
  2717     m_activeSearchCount++;
       
  2718     m_searchOperations.append(operation);
       
  2719 }
       
  2720 
       
  2721 
       
  2722 void CFSMessagesFindOperation::getFolderSpecificMessagesL(QMessageFolder& messageFolder, TEmailSortCriteria sortCriteria)
       
  2723 {
       
  2724     m_activeSearchCount++;
       
  2725     RSortCriteriaArray sortCriteriaArray;
       
  2726     CleanupClosePushL(sortCriteriaArray);
       
  2727     TFolderId folderId(stripIdPrefix(messageFolder.id().toString()).toInt(), 
       
  2728         stripIdPrefix(messageFolder.parentAccountId().toString()).toInt());
       
  2729     MEmailMailbox* mailbox = m_clientApi->MailboxL(stripIdPrefix(messageFolder.parentAccountId().toString()).toInt());
       
  2730     CleanupReleasePushL(*mailbox);
       
  2731     MEmailFolder *mailFolder = mailbox->FolderL(folderId);
       
  2732     CleanupReleasePushL(*mailFolder);
       
  2733         
       
  2734     sortCriteriaArray.Append(sortCriteria);
       
  2735     
       
  2736     MMessageIterator* msgIterator = mailFolder->MessagesL(sortCriteriaArray);
       
  2737     CleanupReleasePushL(*msgIterator);
       
  2738         
       
  2739     MEmailMessage* msg = NULL;
       
  2740     while ( NULL != (msg = msgIterator->NextL())) {
       
  2741         QMessageId messageId(addIdPrefix(QString::number(msg->MessageId().iId), SymbianHelpers::EngineTypeFreestyle));
       
  2742         if (!m_excludeIdList.contains(messageId)) {
       
  2743             m_idList.append(messageId);   
       
  2744         }
       
  2745         msg->Release();
       
  2746     }
       
  2747 
       
  2748     CleanupStack::PopAndDestroy(msgIterator);
       
  2749     CleanupStack::PopAndDestroy(mailFolder);
       
  2750     CleanupStack::PopAndDestroy(mailbox);
       
  2751     CleanupStack::PopAndDestroy(&sortCriteriaArray);
       
  2752 }
       
  2753 
       
  2754 void CFSMessagesFindOperation::HandleResultL(MEmailMessage* aMessage)
       
  2755 {
       
  2756     QMessageId messageId(addIdPrefix(QString::number(aMessage->MessageId().iId), SymbianHelpers::EngineTypeFreestyle));
       
  2757     if (!m_excludeIdList.contains(messageId)) {
       
  2758         m_idList.append(messageId);   
       
  2759     }
       
  2760     aMessage->Release();
       
  2761 }
       
  2762 
       
  2763 void CFSMessagesFindOperation::SearchCompletedL()
       
  2764 {
       
  2765     if (m_receiveNewMessages) {
       
  2766         m_receiveNewMessages = false;
       
  2767     } else {
       
  2768         m_activeSearchCount--;
       
  2769         if (m_activeSearchCount <= 0) {
       
  2770             QMetaObject::invokeMethod(this, "SearchCompleted", Qt::QueuedConnection);
       
  2771         }
       
  2772     }
       
  2773 }
       
  2774     
       
  2775 void CFSMessagesFindOperation::SearchCompleted()
       
  2776 {
       
  2777     if (m_searchField != None) { 
       
  2778         QMessageIdList idList;
       
  2779         foreach (QMessageId messageId, m_idList) {
       
  2780             if (fillsSearchKeyCriteria(messageId))
       
  2781                 idList.append(messageId);   
       
  2782         }
       
  2783         m_idList = idList;
       
  2784     }
       
  2785     m_owner.filterAndOrderMessagesReady(true, m_operationId, m_idList, 1, m_resultCorrectlyOrdered);
       
  2786 }
       
  2787 
       
  2788 bool CFSMessagesFindOperation::fillsSearchKeyCriteria(QMessageId& messageId)
       
  2789 {
       
  2790     QMessage message = m_owner.message(messageId);
       
  2791     
       
  2792     Qt::CaseSensitivity caseSensitivity = (m_matchFlags & QMessageDataComparator::MatchCaseSensitive) ?
       
  2793         Qt::CaseSensitive:Qt::CaseInsensitive;
       
  2794     
       
  2795     switch (m_searchField) {
       
  2796     case Sender: {
       
  2797         return message.from().addressee().contains(m_searchKey, caseSensitivity);
       
  2798     }
       
  2799     case Recipients: {
       
  2800         foreach (QMessageAddress toRecipient, message.to()) {
       
  2801             if (toRecipient.addressee().contains(m_searchKey, caseSensitivity))
       
  2802                 return true;
       
  2803         }
       
  2804         foreach (QMessageAddress ccRecipient, message.cc()) {
       
  2805             if (ccRecipient.addressee().contains(m_searchKey, caseSensitivity))
       
  2806                 return true;
       
  2807         }
       
  2808         foreach (QMessageAddress bccRecipient, message.bcc()) {
       
  2809             if (bccRecipient.addressee().contains(m_searchKey, caseSensitivity))
       
  2810                 return true;
       
  2811         }
       
  2812         return false;
       
  2813     }
       
  2814     case Subject: {
       
  2815         return message.subject().contains(m_searchKey, caseSensitivity);
       
  2816     }
       
  2817     case Body: {
       
  2818         if (message.bodyId() == QMessageContentContainerPrivate::bodyContentId()) {
       
  2819             // Message contains only body (not attachments)
       
  2820             QString messageBody = message.textContent();
       
  2821             return messageBody.contains(m_searchKey, caseSensitivity);
       
  2822         } else {
       
  2823             // Message contains body and attachments
       
  2824             QMessageContentContainerIdList contentIds = message.contentIds();
       
  2825             foreach (QMessageContentContainerId id, contentIds){
       
  2826                 QMessageContentContainer container = message.find(id);
       
  2827                 QMessageContentContainerPrivate* pPrivateContainer = QMessageContentContainerPrivate::implementation(container);
       
  2828                 if (pPrivateContainer->_id == message.bodyId()) {
       
  2829                     // ContentContainer is body
       
  2830                     return container.textContent().contains(m_searchKey, caseSensitivity);
       
  2831                 }
       
  2832             }
       
  2833         }
       
  2834         break;
       
  2835     }
       
  2836     default:
       
  2837         break;
       
  2838     }
       
  2839     return false;
       
  2840 }
       
  2841 
       
  2842 #include "..\..\build\Release\QtMessaging\moc\moc_qfsengine_symbian_p.cpp";
       
  2843 
       
  2844 QTM_END_NAMESPACE