emailuis/nmframeworkadapter/src/nmframeworkadapter.cpp
changeset 18 578830873419
child 20 ecc8def7944a
equal deleted inserted replaced
4:e7aa27f58ae1 18:578830873419
       
     1 /*
       
     2 * Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:
       
    15 *
       
    16 */
       
    17 
       
    18 #include "nmframeworkadapterheaders.h"
       
    19 
       
    20 /*!
       
    21     \class NmFrameworkAdapter
       
    22 
       
    23     \brief The NmFrameworkAdapter works as an adapter between emailframework which is (legacy)
       
    24     Symbian code and emailuis which is done using QT.
       
    25 
       
    26     The NmFrameworkAdapter works as an adapter between emailframework which is (legacy)
       
    27     Symbian code and emailuis which is done using QT. Most functions in the adapter merely do d
       
    28     ata type conversions and forward function calls to emailframework implementation.
       
    29     Also events coming from emailframework are converted and emitted as signals.
       
    30  */
       
    31 
       
    32 static const int nmListMessagesBlock = 100;
       
    33 static const int nmMaxItemsInMessageList = 1000;
       
    34 
       
    35 
       
    36 /*!
       
    37     Constructor
       
    38 */
       
    39 NmFrameworkAdapter::NmFrameworkAdapter( ) : mFSfw(NULL)
       
    40 {
       
    41     NMLOG("NmFrameworkAdapter::NmFrameworkAdapter() <---");
       
    42     // get s60email framework
       
    43     TRAP_IGNORE(mFSfw = CFSMailClient::NewL());
       
    44     if(mFSfw){
       
    45         TRAP_IGNORE(mFSfw->AddObserverL(*this));
       
    46         }
       
    47     NMLOG("NmFrameworkAdapter::NmFrameworkAdapter() --->");
       
    48 }
       
    49 
       
    50 /*!
       
    51     Destructor
       
    52 */
       
    53 NmFrameworkAdapter::~NmFrameworkAdapter()
       
    54 {
       
    55     if(mFSfw){
       
    56         mFSfw->RemoveObserver(*this);
       
    57         mFSfw->Close();
       
    58         }
       
    59 
       
    60     mFSfw = NULL;
       
    61 }
       
    62 
       
    63 /*!
       
    64     Add ids of all existing mailboxes to list given as reference.
       
    65 
       
    66     \param mailboxIdList The list to receive the mailbox ids.
       
    67 
       
    68     \return Error code.
       
    69  */
       
    70 int NmFrameworkAdapter::listMailboxIds(QList<NmId>& mailboxIdList)
       
    71 {
       
    72     QList<NmMailbox*> mailboxList;
       
    73     int ret = listMailboxes(mailboxList);
       
    74 
       
    75     if ( ret == NmNoError ) {
       
    76         QListIterator<NmMailbox*> iterator(mailboxList);
       
    77         while (iterator.hasNext()) {
       
    78             NmMailbox *box = iterator.next();
       
    79             mailboxIdList.append(box->id());
       
    80             delete box;
       
    81             box = NULL;
       
    82         }
       
    83     }
       
    84     return ret;
       
    85 }
       
    86 
       
    87 /*!
       
    88     Fill array given as reference with new mailbox objects, one for each existing mailbox.
       
    89 
       
    90     \param mailboxList The list to receive the mailbox object pointers, ownership of which is transferred to caller.
       
    91 
       
    92     \return Error code.
       
    93  */
       
    94 int NmFrameworkAdapter::listMailboxes(QList<NmMailbox*>& mailboxList)
       
    95 {
       
    96     // get list of mailboxes from all plugins
       
    97     TFSMailMsgId id;
       
    98     id.SetNullId();
       
    99     RPointerArray<CFSMailBox> mailBoxes;
       
   100 
       
   101     //if id.IsNullId(), mailboxes are listed from all plugins.
       
   102     //otherwise, only from the given one.
       
   103     TInt rcode = mFSfw->ListMailBoxes(id,mailBoxes);
       
   104 
       
   105     if ( rcode == NmNoError ) {
       
   106         // convert mailbox data to QT classes
       
   107         NmMailbox* box(0);
       
   108         for(TInt i=0;i<mailBoxes.Count();i++) {
       
   109             box = NULL;
       
   110             if (mailBoxes[i]) {
       
   111                 box = mailBoxes[i]->GetNmMailbox();
       
   112                 }
       
   113             if (box) {
       
   114                 mailboxList.append(box);
       
   115                 }
       
   116             }
       
   117         }
       
   118 	mailBoxes.ResetAndDestroy();
       
   119     return rcode;
       
   120 }
       
   121 
       
   122 /*!
       
   123     Get a pointer to a new mailbox object for the mailbox identified by id.
       
   124 
       
   125     \param id Id of the mailbox.
       
   126     \param mailbox Pointer reference to receive the mailbox object, ownership of which is transferred to caller.
       
   127 
       
   128     \return Error code.
       
   129  */
       
   130 int NmFrameworkAdapter::getMailboxById(const NmId& id, NmMailbox*& mailbox)
       
   131 {
       
   132     const TFSMailMsgId mailMsgId(id.pluginId32(), id.id32());
       
   133     CFSMailBox *box(NULL);
       
   134     TRAPD(err, box = mFSfw->GetMailBoxByUidL(mailMsgId));
       
   135     if (err == KErrNone && box) {
       
   136         mailbox = box->GetNmMailbox();
       
   137         delete box;
       
   138         box = NULL;
       
   139     }
       
   140     return err;
       
   141 }
       
   142 
       
   143 /*!
       
   144     Delete the mailbox with the given id. Not implemented yet.
       
   145 
       
   146     \param id Id of the mailbox to be deleted.
       
   147 
       
   148     \return Error code.
       
   149  */
       
   150 int NmFrameworkAdapter::deleteMailboxById(const NmId& /*id*/)
       
   151 {
       
   152     return 0;
       
   153 }
       
   154 
       
   155 /*!
       
   156     Returns message from the store together with whole message part structure
       
   157 
       
   158     \param mailboxId Id of the mailbox containing the folder.
       
   159     \param folderId Id of the folder containing the message.
       
   160     \param messageId Id of the message.
       
   161     \param message Pointer reference to receive a message object containing requested message,
       
   162      ownership is transferred.
       
   163 
       
   164     \return Error code.
       
   165  */
       
   166 int NmFrameworkAdapter::getMessageById(
       
   167     const NmId& mailboxId,
       
   168     const NmId& folderId,
       
   169     const NmId& messageId,
       
   170     NmMessage*& message)
       
   171 {
       
   172     TRAPD(err, getMessageByIdL(mailboxId,folderId,messageId,message));
       
   173     return err;
       
   174 }
       
   175 
       
   176 /*!
       
   177     Leaving version of getMessageById function
       
   178  */
       
   179 void NmFrameworkAdapter::getMessageByIdL(
       
   180     const NmId& mailboxId,
       
   181     const NmId& folderId,
       
   182     const NmId& messageId,
       
   183     NmMessage*& message)
       
   184 {
       
   185     // select message details to be listed
       
   186     TFSMailDetails details(EFSMsgDataStructure);
       
   187 
       
   188     CFSMailMessage* newMessage(NULL);
       
   189     newMessage = mFSfw->GetMessageByUidL(TFSMailMsgId(mailboxId), TFSMailMsgId(folderId),
       
   190         TFSMailMsgId(messageId), details);
       
   191 
       
   192     // GetMessageByUidL can return NULL pointer
       
   193     if (newMessage) {
       
   194         message = newMessage->GetNmMessage();
       
   195         //assign all children found by mail plugin to NmMessage
       
   196 
       
   197         message->removeAllChildParts();
       
   198         childrenToNmMessagePartL(newMessage, message);
       
   199     }
       
   200     else {
       
   201         User::Leave(KErrNotFound);
       
   202     }
       
   203 }
       
   204 
       
   205 /*!
       
   206     Returns list of folders in a mailbox.
       
   207 	
       
   208 	\param mailboxId Id of the mailbox containing the folder.
       
   209 	\param folderList Reference to a pointer list to receive pointers to the folders.
       
   210 	
       
   211 	\return Error code.
       
   212  */
       
   213 int NmFrameworkAdapter::listFolders(
       
   214     const NmId& mailboxId,
       
   215     QList<NmFolder*>& folderList)
       
   216 {
       
   217     CFSMailBox* currentMailbox = NULL;
       
   218     TRAPD (err, currentMailbox = mFSfw->GetMailBoxByUidL(mailboxId));
       
   219     if (KErrNone == err) {
       
   220         RPointerArray<CFSMailFolder> folders = currentMailbox->ListFolders();
       
   221         for (int i = 0; i < folders.Count(); i++) {
       
   222             folderList.append(folders[i]->GetNmFolder());
       
   223         }
       
   224         return KErrNone;
       
   225     }
       
   226     else {
       
   227         return err;
       
   228     }
       
   229 }
       
   230 
       
   231 /*!
       
   232     Returns list of envelopes from the backend for specific mailbox and folder.
       
   233 
       
   234     \param mailboxId Id of the mailbox containing the folder.
       
   235     \param folderId Folder id.
       
   236     \param messageMetaDataList Reference to pointer list to receive the envelope objects,
       
   237      ownership is transferred.
       
   238 
       
   239     \return Error code.
       
   240  */
       
   241 int NmFrameworkAdapter::listMessages(
       
   242 	const NmId &mailboxId,
       
   243     const NmId &folderId,
       
   244     QList<NmMessageEnvelope*> &messageEnvelopeList)
       
   245 {
       
   246     TRAPD(err, listMessagesL(mailboxId,folderId,messageEnvelopeList));
       
   247     return err;
       
   248 }
       
   249 
       
   250 /*!
       
   251     Leaving version of list messages
       
   252  */
       
   253 void NmFrameworkAdapter::listMessagesL(
       
   254         const NmId &mailboxId,
       
   255         const NmId &folderId,
       
   256         QList<NmMessageEnvelope*> &messageEnvelopeList)
       
   257 {
       
   258     CFSMailBox * currentMailbox(NULL);
       
   259     CFSMailFolder* folder(NULL);
       
   260 
       
   261     currentMailbox = mFSfw->GetMailBoxByUidL(mailboxId);
       
   262     if (!currentMailbox) {
       
   263         User::Leave(KErrNotFound);
       
   264     }
       
   265     CleanupStack::PushL(currentMailbox);
       
   266     folder = mFSfw->GetFolderByUidL(currentMailbox->GetId(), TFSMailMsgId(folderId));
       
   267 
       
   268     if (folder) {
       
   269         CleanupStack::PushL(folder);
       
   270         // First prepare all the parameters
       
   271         // select message details to be listed
       
   272         TFSMailDetails details(EFSMsgDataEnvelope);
       
   273 
       
   274         // set sorting criteria
       
   275         TFSMailSortCriteria criteria;
       
   276         criteria.iField = EFSMailSortByDate;
       
   277         criteria.iOrder = EFSMailDescending;
       
   278         RArray<TFSMailSortCriteria> sorting;
       
   279         CleanupClosePushL(sorting);
       
   280         sorting.Append(criteria);
       
   281 
       
   282         TFSMailMsgId currentMessageId; // first call contains NULL id as begin id
       
   283         // get messages list from the backend
       
   284         MFSMailIterator* iterator(NULL);
       
   285 
       
   286         iterator = folder->ListMessagesL(details, sorting);
       
   287         if (iterator) {
       
   288             CleanupStack::PushL(iterator);
       
   289             RPointerArray<CFSMailMessage> messages;
       
   290             CleanupResetAndDestroy<CFSMailMessage>::PushL(messages);
       
   291 
       
   292             //Message list is fetched in blocks to prevent OOM in protocol plugin side
       
   293             bool moreMessagesToFollow(false);
       
   294             moreMessagesToFollow = iterator->NextL(
       
   295                 TFSMailMsgId(), nmListMessagesBlock, messages);
       
   296             for ( int i = nmListMessagesBlock;
       
   297                   i < nmMaxItemsInMessageList && moreMessagesToFollow ;
       
   298                   i += nmListMessagesBlock ) {
       
   299                 moreMessagesToFollow = iterator->NextL(
       
   300                     messages[i-1]->GetMessageId(), nmListMessagesBlock, messages);
       
   301             }
       
   302 
       
   303             //Add all found emails to the result list
       
   304             for(TInt i=0; i<messages.Count(); i++) {
       
   305                 NmMessageEnvelope* newEnvelope(NULL);
       
   306                 newEnvelope = messages[i]->GetNmMessageEnvelope();
       
   307                 if (newEnvelope) {
       
   308                     messageEnvelopeList.append(newEnvelope);
       
   309                 }
       
   310             }
       
   311             CleanupStack::PopAndDestroy( &messages );
       
   312             CleanupStack::Pop(iterator);
       
   313             delete iterator;
       
   314            	iterator = NULL;
       
   315         }
       
   316         CleanupStack::PopAndDestroy(); // sorting
       
   317         CleanupStack::PopAndDestroy(folder);
       
   318     }
       
   319     CleanupStack::PopAndDestroy(currentMailbox);
       
   320 }
       
   321 
       
   322 /*!
       
   323     Starts a message fetching operation.
       
   324 
       
   325     \param mailboxId Id of the mailbox containing the folder.
       
   326     \param folderId Id of the folder containing the message.
       
   327     \param messageId Id of the message to fetch.
       
   328 
       
   329     \return An NmOperation object for the operation, ownership is transferred to caller
       
   330  */
       
   331 NmOperation *NmFrameworkAdapter::fetchMessage(
       
   332     const NmId &mailboxId,
       
   333     const NmId &folderId,
       
   334     const NmId &messageId )
       
   335 {
       
   336     NmOperation *oper = new NmFwaMessageFetchingOperation(mailboxId, folderId, messageId, *mFSfw);
       
   337     return oper;
       
   338 }
       
   339 
       
   340 /*!
       
   341     Starts a message part fetching operation.
       
   342 
       
   343     \param mailboxId Id of the mailbox containing the folder.
       
   344     \param folderId Id of the folder containing the message.
       
   345     \param messageId Id of message containing the message parts
       
   346     \param messagePartIds array of ids to be fetched
       
   347 
       
   348     \return An NmOperation object for the operation, ownership is transferred to caller
       
   349  */
       
   350 NmOperation *NmFrameworkAdapter::fetchMessagePart( 
       
   351     const NmId &mailboxId,
       
   352     const NmId &folderId,
       
   353     const NmId &messageId,
       
   354     const NmId &messagePartId)
       
   355 {
       
   356     NmOperation *oper = new NmFwaMessagePartFetchingOperation(
       
   357             mailboxId, folderId, messageId, messagePartId, *mFSfw);
       
   358     return oper;
       
   359 }
       
   360 
       
   361 /*!
       
   362     Get the id of a standard folder.
       
   363 
       
   364     \param mailboxId Id of the mailbox containing the folder.
       
   365     \param folderType Type of standard folder to get the id of.
       
   366 
       
   367     \return Id of the standard folder, or NmId for which NmId.getId() == 0 if not found.
       
   368  */
       
   369 NmId NmFrameworkAdapter::getStandardFolderId(
       
   370     const NmId& mailboxId,
       
   371     NmFolderType folderType )
       
   372 {
       
   373     TFSMailMsgId folderId;
       
   374     NmId resultId(0);
       
   375     CFSMailBox * currentMailbox(NULL);
       
   376 
       
   377     TRAPD(error, currentMailbox = mFSfw->GetMailBoxByUidL(mailboxId) );
       
   378 
       
   379     if( !currentMailbox || error != KErrNone ) {
       
   380     	return resultId;
       
   381     }
       
   382 
       
   383     switch(folderType) {
       
   384     	case NmFolderInbox:
       
   385     		folderId = currentMailbox->GetStandardFolderId( EFSInbox );
       
   386     		break;
       
   387     	case NmFolderOutbox:
       
   388     		folderId = currentMailbox->GetStandardFolderId( EFSOutbox );
       
   389     		break;
       
   390     	case NmFolderDrafts:
       
   391     		folderId = currentMailbox->GetStandardFolderId( EFSDraftsFolder );
       
   392     		break;
       
   393     	case NmFolderSent:
       
   394     		folderId = currentMailbox->GetStandardFolderId( EFSSentFolder );
       
   395     		break;
       
   396     	case NmFolderDeleted:
       
   397     		folderId = currentMailbox->GetStandardFolderId( EFSDeleted );
       
   398     		break;
       
   399     	case NmFolderOther:
       
   400     	default:
       
   401     		folderId = currentMailbox->GetStandardFolderId( EFSOther );
       
   402     		break;
       
   403     }
       
   404 
       
   405     delete currentMailbox;
       
   406     currentMailbox = NULL;
       
   407 
       
   408     resultId.setPluginId32(static_cast<quint32>(folderId.PluginId().iUid));
       
   409     resultId.setId32(folderId.Id());
       
   410 
       
   411     return resultId;
       
   412 }
       
   413 
       
   414 /*!
       
   415     Connect to mailbox if not already connected and refresh.
       
   416 
       
   417     \param mailboxId Id of the mailbox.
       
   418     \return Async request id or error code.
       
   419  */
       
   420 int NmFrameworkAdapter::refreshMailbox(NmId mailboxId)
       
   421 {
       
   422     TRAPD(err, RefreshMailboxL(mailboxId)); // return value not used
       
   423     return ( err == KErrNone ) ? NmNoError : NmGeneralError;
       
   424 }
       
   425 
       
   426 /*!
       
   427     Sets content for the given message part. Client shouldn't create
       
   428     message part on its own. Instead it should be requested by calling
       
   429     e.g. getMessageById.
       
   430 
       
   431     \param mailboxId Id of the mailbox containing the folder (Unused).
       
   432     \param folderId Id of the folder containing the message (Unused).
       
   433     \param messageId Id of the message (Unused).
       
   434     \param messagePart Part of a message for which content is going to be requested.
       
   435 
       
   436     \return Error code.
       
   437  */
       
   438 int NmFrameworkAdapter::contentToMessagePart(
       
   439     const NmId &mailboxId,
       
   440     const NmId &folderId,
       
   441     const NmId &messageId,
       
   442     NmMessagePart &messagePart)
       
   443 {
       
   444     TRAPD(err, contentToMessagePartL(mailboxId,folderId,messageId,messagePart));
       
   445     return err;
       
   446 }
       
   447 
       
   448 /*!
       
   449     Leaving version of contentToMessagePart function
       
   450  */
       
   451 void NmFrameworkAdapter::contentToMessagePartL(
       
   452     const NmId &mailboxId,
       
   453     const NmId &folderId,
       
   454     const NmId &messageId,
       
   455     NmMessagePart &messagePart)
       
   456 {
       
   457     CFSMailMessagePart* cfsPart = CFSMailMessagePart::NewLC(messageId,messagePart);
       
   458     cfsPart->SetMailBoxId(TFSMailMsgId(mailboxId));
       
   459     cfsPart->SetFolderId(TFSMailMsgId(folderId));
       
   460     QString contentType = messagePart.contentType();
       
   461 
       
   462     if (cfsPart && contentType.startsWith(NmContentTypeTextPlain)) {
       
   463         // add 1 for max size for zero termination and prevend 0 size hbufc
       
   464         HBufC* data = HBufC::NewLC(cfsPart->FetchedContentSize()+1);
       
   465         TPtr dataPtr = data->Des();
       
   466         TInt startOffset = 0;
       
   467 
       
   468         cfsPart->GetContentToBufferL(dataPtr, startOffset);
       
   469         messagePart.setTextContent(NmConverter::toQString(dataPtr), contentType);
       
   470         CleanupStack::PopAndDestroy(data);
       
   471     }
       
   472     else if (cfsPart){
       
   473         RFile file = cfsPart->GetContentFileL();
       
   474         TInt fileSize = 0;
       
   475         file.Size(fileSize);
       
   476         if (fileSize != 0) {
       
   477             HBufC8* data = HBufC8::NewLC(fileSize);
       
   478             TPtr8 dataPtr = data->Des();
       
   479 
       
   480             if (fileSize != 0) {
       
   481                 TInt dummyPos = 0;
       
   482                 file.Seek(ESeekStart, dummyPos);
       
   483                 User::LeaveIfError(file.Read(dataPtr));
       
   484             }
       
   485 
       
   486             if (contentType.startsWith(NmContentTypeTextHtml) || contentType.contains( NmContentDescrAttachmentHtml )) {
       
   487                 messagePart.setTextContent( QString::fromUtf8(reinterpret_cast<const char*>(
       
   488                         dataPtr.Ptr()), fileSize), contentType);
       
   489             }
       
   490             else {
       
   491                 messagePart.setBinaryContent(QByteArray(
       
   492                         reinterpret_cast<const char*>(dataPtr.Ptr()), fileSize), contentType);
       
   493             }
       
   494             CleanupStack::PopAndDestroy(data);
       
   495         }
       
   496         file.Close();
       
   497     }
       
   498     else {
       
   499         // null cfsPart
       
   500         User::Leave(KErrNotFound);
       
   501     }
       
   502 
       
   503     CleanupStack::PopAndDestroy(cfsPart);
       
   504 }
       
   505 
       
   506 /*!
       
   507     Deletes the listed messages from specific mailbox and folder.
       
   508 
       
   509     \param mailboxId Id of the mailbox containing the folder.
       
   510     \param folderId Id of the folder containing the messages.
       
   511     \param messageIdList List of ids of the messages to be deleted.
       
   512 
       
   513     \return Error code.
       
   514  */
       
   515 int NmFrameworkAdapter::deleteMessages(
       
   516 	const NmId &mailboxId,
       
   517 	const NmId &folderId,
       
   518 	const QList<NmId> &messageIdList)
       
   519 {
       
   520     TInt err = NmNoError;
       
   521     RArray<TFSMailMsgId> messageIds;
       
   522     for (TInt i=0; i<messageIdList.size(); i++) {
       
   523         err = messageIds.Append(TFSMailMsgId(messageIdList[i]));
       
   524         if (err!=NmNoError) {
       
   525             break;
       
   526         }
       
   527     }
       
   528     if (NmNoError == err) {
       
   529         TRAP(err, mFSfw->DeleteMessagesByUidL(TFSMailMsgId(mailboxId), TFSMailMsgId(folderId), messageIds));
       
   530     }
       
   531     messageIds.Close();
       
   532 
       
   533     return ( err == NmNoError ) ? NmNoError : NmGeneralError;
       
   534 }
       
   535 
       
   536 /*!
       
   537     Starts an async operation to store listed message envelopes to the given mailbox
       
   538 
       
   539     \param mailboxId Id of the mailbox.
       
   540     \param folderId Unused.
       
   541     \param envelopeList List of the envelope objects to store.
       
   542 
       
   543     \return NmStoreEnvelopesOperation
       
   544  */
       
   545 NmStoreEnvelopesOperation *NmFrameworkAdapter::storeEnvelopes(
       
   546 	const NmId &mailboxId,
       
   547 	const NmId &folderId,
       
   548 	const QList<const NmMessageEnvelope*> &envelopeList)
       
   549 {
       
   550     Q_UNUSED(folderId);
       
   551     NMLOG("NmFrameworkAdapter::storeEnvelopes() <---");
       
   552 
       
   553     NmStoreEnvelopesOperation* operation(NULL);
       
   554     RPointerArray<CFSMailMessage> envelopeMessages;
       
   555 
       
   556     int count = envelopeList.count();
       
   557     for(int i=0;i<count;i++) {
       
   558         TRAP_IGNORE( envelopeMessages.AppendL(mailMessageFromEnvelopeL( *envelopeList.at(i)) ));
       
   559     }
       
   560 
       
   561     if ( envelopeMessages.Count() ) {
       
   562         operation = new NmFwaStoreEnvelopesOperation(
       
   563                 mailboxId,
       
   564                 envelopeMessages,
       
   565                 *mFSfw);
       
   566         }
       
   567 
       
   568     NMLOG("NmFrameworkAdapter::storeEnvelopes() --->");
       
   569     return operation;
       
   570 }
       
   571 
       
   572 /*!
       
   573     Creates a new message into the drafts folder a mailbox.
       
   574 
       
   575     \param mailboxId Id of the mailbox.
       
   576 
       
   577     \return NmMessageCreationOperation
       
   578  */
       
   579 NmMessageCreationOperation *NmFrameworkAdapter::createNewMessage(const NmId &mailboxId)
       
   580 {
       
   581     NmMessageCreationOperation *oper =
       
   582         new NmFwaMessageCreationOperation(mailboxId, *mFSfw);
       
   583     return oper;
       
   584 }
       
   585 
       
   586 /*!
       
   587     Creates a new forward message into the drafts folder of a mailbox.
       
   588 
       
   589     \param mailboxId Id of the mailbox.
       
   590     \param originalMessageId Id of the original message. Original message must be in the given mailbox.
       
   591 
       
   592     \return NmMessageCreationOperation
       
   593  */
       
   594 NmMessageCreationOperation *NmFrameworkAdapter::createForwardMessage(
       
   595     const NmId &mailboxId,
       
   596     const NmId &originalMessageId)
       
   597 {
       
   598     NmMessageCreationOperation *oper =
       
   599         new NmFwaForwardMessageCreationOperation(mailboxId, originalMessageId, *mFSfw);
       
   600     return oper;
       
   601 }
       
   602 
       
   603 /*!
       
   604     Creates a new reply message into the drafts folder of a mailbox.
       
   605 
       
   606     \param mailboxId Id of the mailbox.
       
   607     \param originalMessageId Id of the original message. Original message must be in the given mailbox.
       
   608     \param replyAll Is reply for all recipients?
       
   609 
       
   610     \return NmMessageCreationOperation
       
   611  */
       
   612 NmMessageCreationOperation *NmFrameworkAdapter::createReplyMessage(
       
   613     const NmId &mailboxId,
       
   614     const NmId &originalMessageId,
       
   615     const bool replyAll)
       
   616 {
       
   617     NmMessageCreationOperation *oper =
       
   618         new NmFwaReplyMessageCreationOperation(mailboxId, originalMessageId, replyAll, *mFSfw);
       
   619     return oper;
       
   620 }
       
   621 
       
   622 /*!
       
   623     Not implemented yet.
       
   624  */
       
   625 int NmFrameworkAdapter::saveMessage(const NmMessage &message)
       
   626 {
       
   627     Q_UNUSED(message);
       
   628     return NmNoError;
       
   629 }
       
   630 
       
   631 /*!
       
   632     Store asynchronously message with its parts.
       
   633  */
       
   634 NmOperation* NmFrameworkAdapter::saveMessageWithSubparts(const NmMessage &message)
       
   635 {
       
   636     CFSMailMessage * cfsMessage = NULL;
       
   637     NmOperation *oper = NULL;
       
   638 
       
   639     int err = KErrNone;
       
   640     TRAP(err, cfsMessage = CFSMailMessage::NewL(message));
       
   641     if (err == KErrNone) {
       
   642         //transfers ownership of cfsMessage
       
   643         oper = new NmFwaStoreMessageOperation(cfsMessage, *mFSfw);
       
   644     }
       
   645 
       
   646     return oper;
       
   647 }
       
   648 
       
   649 /*!
       
   650     From MFSMailEventObserver
       
   651 
       
   652     \sa MFSMailEventObserver
       
   653  */
       
   654 void NmFrameworkAdapter::EventL(
       
   655     TFSMailEvent aEvent,
       
   656     TFSMailMsgId mailbox,
       
   657     TAny* param1,
       
   658     TAny* param2,
       
   659     TAny* param3)
       
   660 {
       
   661     switch (aEvent) {
       
   662         // Mailbox related events:
       
   663         case TFSEventNewMailbox:
       
   664             handleMailboxEvent(mailbox, NmMailboxCreated);
       
   665             break;
       
   666         case TFSEventMailboxDeleted:
       
   667             handleMailboxEvent(mailbox, NmMailboxDeleted);
       
   668             break;
       
   669         case TFSEventMailboxRenamed:
       
   670             handleMailboxEvent(mailbox, NmMailboxChanged);
       
   671             break;
       
   672 
       
   673         //
       
   674         // Mail related events:
       
   675         // signal:
       
   676         // void messageEvent(
       
   677         //      NmMessageEvent event,
       
   678         //      const NmId &folderId,
       
   679         //      QList<NmId> &messageIds);
       
   680         //
       
   681         // enum NmMessageEvent
       
   682         //   NmMessageCreated,
       
   683         //   NmMessageChanged,
       
   684         //   NmMessageDeleted
       
   685         //
       
   686 
       
   687         // New mails created
       
   688         // param1: RArray<TFSMailMsgId>* aNewEntries
       
   689         // param2: TFSMailMsgId* aParentFolder
       
   690         // param3: NULL
       
   691         case TFSEventNewMail:
       
   692             handleMessageEvent(param1, param2, NmMessageCreated, mailbox);
       
   693             break;
       
   694         // Mails changed
       
   695         // param1: RArray<TFSMailMsgId>* aEntries
       
   696         // param2: TFSMailMsgId* aParentFolder
       
   697         // param3: NULL
       
   698         case TFSEventMailChanged:
       
   699             handleMessageEvent(param1, param2, NmMessageChanged, mailbox);
       
   700             break;
       
   701         // Mails deleted
       
   702         // param1: RArray<TFSMailMsgId>* aEntries
       
   703         // param2: TFSMailMsgId* aParentFolder
       
   704         // param3: NULL
       
   705         case TFSEventMailDeleted:
       
   706             handleMessageEvent(param1, param2, NmMessageDeleted, mailbox);
       
   707             break;
       
   708 
       
   709 
       
   710         // Mails moved
       
   711         // param1: RArray<TFSMailMsgId>* aEntries
       
   712         // param2: TFSMailMsgId* aNewParentFolder
       
   713         // param3: TFSMailMsgId* aOldParentFolder
       
   714         case TFSEventMailMoved:
       
   715             handleMailMoved(param1, param2, param3, mailbox);
       
   716             break;
       
   717 
       
   718         // Mails copied
       
   719         // param1: RArray<TFSMailMsgId>* aNewEntries
       
   720         // param2: TFSMailMsgId* aNewParentFolder
       
   721         // param3: TFSMailMsgId* aOldParentFolder
       
   722         case TFSEventMailCopied:
       
   723             handleMailCopied(param1, param2, mailbox);
       
   724             break;
       
   725 
       
   726 
       
   727         //sync state related events
       
   728         case TFSEventMailboxSyncStateChanged:
       
   729             handleSyncstateEvent(param1, mailbox);
       
   730             break;
       
   731 
       
   732         case TFSEventMailboxOnline:{
       
   733             NmId id = NmConverter::mailMsgIdToNmId(mailbox);
       
   734             emit connectionEvent(Connected, id);
       
   735             }
       
   736             break;
       
   737         case TFSEventMailboxOffline:{
       
   738             NmId id = NmConverter::mailMsgIdToNmId(mailbox);
       
   739             emit connectionEvent(Disconnected, id);
       
   740             }
       
   741             break;
       
   742 
       
   743         default:
       
   744             break;
       
   745     }
       
   746 }
       
   747 
       
   748 /*!
       
   749     Delete the message from specific mailbox and folder.
       
   750 
       
   751     \param mailboxId Id of the mailbox containing the folder.
       
   752     \param folderId Id of the folder containing the message.
       
   753     \param messageId Id of the message.
       
   754 
       
   755     \return Error code.
       
   756  */
       
   757 int NmFrameworkAdapter::removeMessage(
       
   758     const NmId& mailboxId,
       
   759     const NmId& folderId,
       
   760     const NmId& messageId)
       
   761 {
       
   762     TRAPD(error, removeMessageL(mailboxId, folderId, messageId));
       
   763     return error;
       
   764 }
       
   765 
       
   766 /*!
       
   767     Subscribe to events from a mailbox.
       
   768 
       
   769     \param mailboxId Id of the mailbox.
       
   770 */
       
   771 void NmFrameworkAdapter::subscribeMailboxEvents(const NmId& mailboxId)
       
   772 {
       
   773     TRAP_IGNORE(mFSfw->SubscribeMailboxEventsL(mailboxId, *this));
       
   774 }
       
   775 
       
   776 /*!
       
   777     Unsubscribe to events from a mailbox.
       
   778 
       
   779     \param mailboxId Id of the mailbox.
       
   780 */
       
   781 void NmFrameworkAdapter::unsubscribeMailboxEvents(const NmId& mailboxId)
       
   782 {
       
   783     mFSfw->UnsubscribeMailboxEvents(mailboxId, *this);
       
   784 }
       
   785 
       
   786 NmId NmFrameworkAdapter::getMailboxIdByMailMsgId(TFSMailMsgId mailbox)
       
   787 {
       
   788     NmId nmId(0);
       
   789 
       
   790     QList<NmId> mailboxIds;
       
   791     listMailboxIds(mailboxIds);
       
   792 
       
   793     QListIterator<NmId> iterator(mailboxIds);
       
   794     while (iterator.hasNext()) {
       
   795         nmId = iterator.next();
       
   796         if (nmId.id32() == mailbox.Id()) {
       
   797             break;
       
   798         }
       
   799     }
       
   800     mailboxIds.clear();
       
   801     return nmId;
       
   802 }
       
   803 
       
   804 /*!
       
   805     Leaving version of removeMessage
       
   806 */
       
   807 void NmFrameworkAdapter::removeMessageL(
       
   808     const NmId& mailboxId,
       
   809     const NmId& folderId,
       
   810     const NmId& messageId)
       
   811 {
       
   812     CFSMailFolder* folder = mFSfw->GetFolderByUidL( TFSMailMsgId(mailboxId), TFSMailMsgId(folderId));
       
   813     CleanupStack::PushL(folder);
       
   814     if ( folder ) {
       
   815         folder->RemoveMessageL(TFSMailMsgId(messageId));
       
   816     }
       
   817     CleanupStack::PopAndDestroy(folder);
       
   818 }
       
   819 
       
   820 
       
   821 /*!
       
   822    Sends the given message.
       
   823  */
       
   824 NmMessageSendingOperation *NmFrameworkAdapter::sendMessage(
       
   825     NmMessage *message)
       
   826 {
       
   827     NmFwaMessageSendingOperation *oper = new NmFwaMessageSendingOperation(message, *mFSfw);
       
   828 	return oper;
       
   829 }
       
   830 
       
   831 /*!
       
   832    Add attachment into the given message.
       
   833  */
       
   834 NmAddAttachmentsOperation *NmFrameworkAdapter::addAttachments(
       
   835     const NmMessage &message,
       
   836     const QList<QString> &fileList)
       
   837 {
       
   838     NmAddAttachmentsOperation *oper = new NmFwaAddAttachmentsOperation(message, fileList, *mFSfw);
       
   839     return oper;
       
   840 }
       
   841 
       
   842 /*!
       
   843    Remove attachment from the given message.
       
   844  */
       
   845 NmOperation *NmFrameworkAdapter::removeAttachment(
       
   846     const NmMessage &message,
       
   847     const NmId &attachmentPartId)
       
   848 {
       
   849     NmOperation *oper = new NmFwaRemoveAttachmentOperation(message, attachmentPartId, *mFSfw);
       
   850     return oper;
       
   851 }
       
   852 
       
   853 /*!
       
   854    Checks outbox for messages
       
   855  */
       
   856 NmCheckOutboxOperation *NmFrameworkAdapter::checkOutbox(const NmId& mailboxId)
       
   857 {
       
   858     NmCheckOutboxOperation *oper =
       
   859         new NmFwaCheckOutboxOperation(mailboxId, *mFSfw);
       
   860 
       
   861     return oper;
       
   862 }
       
   863 
       
   864 /*!
       
   865     Returns the current sync state of the given mailbox
       
   866  */
       
   867 NmSyncState NmFrameworkAdapter::syncState(const NmId& mailboxId) const
       
   868 {
       
   869    CFSMailBox* mailBox = NULL;
       
   870    TRAPD(err, mailBox = mFSfw->GetMailBoxByUidL(TFSMailMsgId(mailboxId)) );
       
   871    if (KErrNone == err && mailBox) {
       
   872        TSSMailSyncState syncState = mailBox->CurrentSyncState();
       
   873        delete mailBox;
       
   874        if (EmailSyncing == syncState) {
       
   875            return Synchronizing;
       
   876        }
       
   877        else {
       
   878            return SyncComplete;
       
   879        }
       
   880    }
       
   881    else {
       
   882        return SyncComplete;
       
   883    }
       
   884 }
       
   885 
       
   886 /*!
       
   887     Returns the current connection state of the given mailbox
       
   888  */
       
   889 NmConnectState NmFrameworkAdapter::connectionState(const NmId& mailboxId) const
       
   890 {
       
   891     CFSMailBox* mailBox = NULL;
       
   892     TRAPD(err, mailBox = mFSfw->GetMailBoxByUidL(TFSMailMsgId(mailboxId)) );
       
   893     if (KErrNone == err && mailBox) {
       
   894         TFSMailBoxStatus status = mailBox->GetMailBoxStatus();
       
   895         delete mailBox;
       
   896         if (status == EFSMailBoxOnline) {
       
   897             return Connected;
       
   898         }
       
   899         else {
       
   900             return Disconnected;
       
   901         }
       
   902     }
       
   903     else {
       
   904        return Disconnected;
       
   905     }
       
   906 }
       
   907 
       
   908 /*!
       
   909    creates CFSMailMessage based on envelope
       
   910    Call to this must be trapped
       
   911  */
       
   912 CFSMailMessage* NmFrameworkAdapter::mailMessageFromEnvelopeL(
       
   913     const NmMessageEnvelope& envelope)
       
   914 {
       
   915     NmMessage* nmMessage = new(ELeave) NmMessage( envelope );
       
   916     CFSMailMessage* message = CFSMailMessage::NewL( *nmMessage );
       
   917     delete nmMessage;
       
   918     nmMessage = NULL;
       
   919     return message;
       
   920 }
       
   921 
       
   922 
       
   923 /*!
       
   924    Assigns recursively all children to NmMessagePart object.
       
   925  */
       
   926 void NmFrameworkAdapter::childrenToNmMessagePartL(
       
   927         CFSMailMessagePart *cfsParent,
       
   928         NmMessagePart *nmParent)
       
   929 {
       
   930     User::LeaveIfNull(cfsParent);
       
   931     User::LeaveIfNull(nmParent);
       
   932 
       
   933     RPointerArray<CFSMailMessagePart> parts;
       
   934     cfsParent->ChildPartsL(parts);
       
   935     CleanupResetAndDestroy<CFSMailMessagePart>::PushL(parts);
       
   936 
       
   937     NmMessagePart *nmPart = NULL;
       
   938     if(parts.Count()){
       
   939         for(int i=0; i<parts.Count(); i++){
       
   940             nmPart = parts[i]->GetNmMessagePart();
       
   941             nmParent->addChildPart(nmPart);
       
   942             childrenToNmMessagePartL(parts[i], nmPart);
       
   943         }
       
   944     }
       
   945     CleanupStack::PopAndDestroy(1, &parts);
       
   946 }
       
   947 
       
   948 /*!
       
   949    Leaving Refresh function
       
   950  */
       
   951 int NmFrameworkAdapter::RefreshMailboxL(NmId mailboxId)
       
   952 {
       
   953     int result(KErrNotFound);
       
   954     CFSMailBox *currentMailbox(NULL);
       
   955     currentMailbox = mFSfw->GetMailBoxByUidL(mailboxId);
       
   956     if(currentMailbox) {
       
   957         CleanupStack::PushL(currentMailbox);
       
   958         result = currentMailbox->RefreshNowL();
       
   959         CleanupStack::PopAndDestroy(currentMailbox);
       
   960         currentMailbox = NULL;
       
   961     }
       
   962     return result;
       
   963 }
       
   964 
       
   965 /*!
       
   966    handles mailbox related events
       
   967  */
       
   968 void NmFrameworkAdapter::handleMailboxEvent( TFSMailMsgId mailbox, NmMailboxEvent event)
       
   969 {
       
   970     QList<NmId> mailboxIds;
       
   971     NmId nmId;
       
   972     if (event == NmMailboxDeleted) {
       
   973 		nmId = mailbox.GetNmId();
       
   974     } else {
       
   975 		nmId = getMailboxIdByMailMsgId(mailbox);
       
   976     }
       
   977     mailboxIds.append(nmId);
       
   978     emit mailboxEvent(event, mailboxIds);
       
   979     }
       
   980 
       
   981 /*!
       
   982    handles new, changed, deleted events
       
   983  */
       
   984 void NmFrameworkAdapter::handleMessageEvent(
       
   985     TAny* param1,
       
   986     TAny* param2,
       
   987     NmMessageEvent event,
       
   988     TFSMailMsgId mailbox)
       
   989 {
       
   990     NmId nmMsgId(0);
       
   991     QList<NmId> messageIds;
       
   992     RArray<TFSMailMsgId>* newFsEntries = reinterpret_cast<RArray<TFSMailMsgId>*> (param1);
       
   993     TFSMailMsgId* fsFolderId = reinterpret_cast<TFSMailMsgId*> (param2);
       
   994     NmId folderId = fsFolderId->GetNmId();
       
   995 
       
   996     TFSMailMsgId fsMsgId;
       
   997     for(TInt i = 0; i < newFsEntries->Count(); i++){
       
   998         fsMsgId = (*newFsEntries)[i];
       
   999         nmMsgId = fsMsgId.GetNmId();
       
  1000         messageIds.append(nmMsgId);
       
  1001     }
       
  1002     emit messageEvent(event, folderId, messageIds, mailbox.GetNmId());
       
  1003 }
       
  1004 
       
  1005 /*!
       
  1006    function to handle mailmoved event
       
  1007  */
       
  1008 void NmFrameworkAdapter::handleMailMoved(TAny* param1,TAny* param2,TAny* param3, TFSMailMsgId mailbox)
       
  1009 {
       
  1010     NmId nmMsgId(0);
       
  1011     QList<NmId> messageIds;
       
  1012     RArray<TFSMailMsgId>* newFsEntries = reinterpret_cast<RArray<TFSMailMsgId>*> (param1);
       
  1013     TFSMailMsgId* fsFromFolderId = reinterpret_cast<TFSMailMsgId*> (param3);
       
  1014     NmId fromFolderId = fsFromFolderId->GetNmId();
       
  1015     TFSMailMsgId* fsToFolderId = reinterpret_cast<TFSMailMsgId*> (param2);
       
  1016     NmId toFolderId = fsToFolderId->GetNmId();
       
  1017 
       
  1018     TFSMailMsgId fsMsgId;
       
  1019     for(TInt i = 0; i < newFsEntries->Count(); i++){
       
  1020         fsMsgId = (*newFsEntries)[i];
       
  1021         nmMsgId = fsMsgId.GetNmId();
       
  1022         messageIds.append(nmMsgId);
       
  1023     }
       
  1024     // Yes, this is supposed to emit two signals from single incoming
       
  1025     // event. Design decison was to create separate signals.
       
  1026     emit messageEvent(NmMessageDeleted, fromFolderId, messageIds, mailbox.GetNmId());
       
  1027     emit messageEvent(NmMessageCreated, toFolderId, messageIds, mailbox.GetNmId());
       
  1028 }
       
  1029 
       
  1030 /*!
       
  1031    function to handle mailcopied event
       
  1032  */
       
  1033 void NmFrameworkAdapter::handleMailCopied(TAny* param1,TAny* param2, TFSMailMsgId mailbox)
       
  1034 {
       
  1035     NmId nmMsgId(0);
       
  1036     QList<NmId> messageIds;
       
  1037     RArray<TFSMailMsgId>* newFsEntries = reinterpret_cast<RArray<TFSMailMsgId>*> (param1);
       
  1038     TFSMailMsgId* fsToFolderId = reinterpret_cast<TFSMailMsgId*> (param2);
       
  1039     NmId toFolderId = fsToFolderId->GetNmId();
       
  1040 
       
  1041     TFSMailMsgId fsMsgId;
       
  1042     for(TInt i = 0; i < newFsEntries->Count(); i++){
       
  1043         fsMsgId = (*newFsEntries)[i];
       
  1044         nmMsgId = fsMsgId.GetNmId();
       
  1045         messageIds.append(nmMsgId);
       
  1046     }
       
  1047     // Not interested in param3 (aOldParentFolder)
       
  1048     emit messageEvent(NmMessageCreated, toFolderId, messageIds, mailbox.GetNmId());
       
  1049 }
       
  1050 
       
  1051 void NmFrameworkAdapter::handleSyncstateEvent(TAny* param1, TFSMailMsgId mailbox)
       
  1052 {
       
  1053     TSSMailSyncState* state = static_cast<TSSMailSyncState*>( param1 );
       
  1054 
       
  1055     NmId id = NmConverter::mailMsgIdToNmId(mailbox);
       
  1056     switch(*state)
       
  1057         {
       
  1058         case StartingSync:
       
  1059             {
       
  1060             emit syncStateEvent(Synchronizing, id);
       
  1061             }
       
  1062             break;
       
  1063         case FinishedSuccessfully:
       
  1064             {
       
  1065             emit syncStateEvent(SyncComplete, id);
       
  1066             }
       
  1067             break;
       
  1068         case SyncError:
       
  1069         default:
       
  1070             {
       
  1071             emit syncStateEvent(SyncComplete,id);
       
  1072             }
       
  1073             break;
       
  1074         };
       
  1075 }
       
  1076 Q_EXPORT_PLUGIN(NmFrameworkAdapter)
       
  1077