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