messagingapp/msgui/appengine/src/conversationmsgstorehandler.cpp
branchRCL_3
changeset 26 ebe688cedc25
equal deleted inserted replaced
25:fa1df4b99609 26:ebe688cedc25
       
     1 /*
       
     2 * Copyright (c) 2008 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 <hbglobal.h>
       
    19 #include <textresolver.h> // from CommonEngine
       
    20 #include <mtclreg.h>
       
    21 #include <mmsnotificationclient.h>
       
    22 #include <mmssettings.h>
       
    23 #include <xqconversions.h> // from xqutils
       
    24 #include <mmsconst.h>
       
    25 #include <QDateTime>
       
    26 
       
    27 #include "conversationmsgstorehandler.h"
       
    28 #include "draftsmodel.h"
       
    29 #include "MuiuOperationWait.h"
       
    30 #include "msgbiouids.h"
       
    31 #include "UniEditorGenUtils.h"
       
    32 
       
    33 // SYSTEM INCLUDES
       
    34 #include <StringLoader.h>
       
    35 #include <ccsdefs.h> 
       
    36 #include <msvids.h>
       
    37 #include <mmserrors.h>
       
    38 #include <msvuids.h>
       
    39 #include <smut.h>
       
    40 #include <SendUiConsts.h>
       
    41 #include <featmgr.h>
       
    42 #include <gsmerror.h> 
       
    43 
       
    44 // CONSTANTS
       
    45 const TUid KSmsMtmUid ={KSenduiMtmSmsUidValue};
       
    46 const TUid KMmsMtmUid ={KSenduiMtmMmsUidValue};
       
    47 _LIT(KUnixEpoch, "19700000:000000.000000");
       
    48 #define BYTES_TO_KBYTES_FACTOR 1024
       
    49 
       
    50 // LOCALIZATION
       
    51 #define LOC_MESSAGE_SIZE hbTrId("txt_messaging_list_size")
       
    52 #define LOC_CLASS_ADVERTISEMENT hbTrId("txt_messaging_list_advertisement")
       
    53 #define LOC_CLASS_INFORMATIONAL hbTrId("txt_messaging_list_informational")
       
    54 #define LOC_CLASS_PERSONAL hbTrId("txt_messaging_list_personal")
       
    55 #define LOC_MMS_RETRIEVAL_FAILED hbTrId("txt_messaging_dialog_mms_retrieval_failed")
       
    56 #define LOC_MMS_NOTIF_EXPIRED hbTrId("Message Expired !")   //TODO: localization
       
    57 #define LOC_MMS_WAITING hbTrId("txt_wireframe_list_multimedia_message_waiting")
       
    58 #define LOC_MMS_RETRIEVING hbTrId("Retrieving message...")   //TODO: localization
       
    59 #define LOC_MMS_EXPIRY_DATE hbTrId("txt_messaging_list_expiry_date")
       
    60 
       
    61 // ================= MEMBER FUNCTIONS =======================
       
    62 
       
    63 // ---------------------------------------------------------
       
    64 // Default constructor.
       
    65 // ---------------------------------------------------------
       
    66 //
       
    67 ConversationMsgStoreHandler::ConversationMsgStoreHandler():
       
    68     iMsvSession(NULL),iDraftEntry(NULL),iDraftMessages(NULL),mDraftsModel(NULL),
       
    69     iMtmReg(NULL),iMmsClient(NULL),iNotificationClient(NULL)
       
    70     {
       
    71     TRAP_IGNORE(InitL());
       
    72     }
       
    73 
       
    74 // ---------------------------------------------------------
       
    75 // Destructor.
       
    76 // ---------------------------------------------------------
       
    77 //
       
    78 ConversationMsgStoreHandler::~ConversationMsgStoreHandler()
       
    79     {
       
    80     if ( iDraftEntry )
       
    81         {
       
    82         delete iDraftEntry;
       
    83         iDraftEntry = NULL;
       
    84         }
       
    85 
       
    86     if ( iDraftMessages )
       
    87         {
       
    88         iDraftMessages->Reset();
       
    89         delete iDraftMessages;
       
    90         iDraftMessages = NULL;
       
    91     }
       
    92 
       
    93     if (iMmsClient)
       
    94     {
       
    95         delete iMmsClient;
       
    96         iMmsClient = NULL;
       
    97     }
       
    98     if (iNotificationClient)
       
    99     {
       
   100         delete iNotificationClient;
       
   101         iNotificationClient = NULL;
       
   102     }
       
   103     if (iMtmReg)
       
   104     {
       
   105         delete iMtmReg;
       
   106         iMtmReg = NULL;
       
   107     }
       
   108     if (iMsvSession)
       
   109     {
       
   110         delete iMsvSession;
       
   111         iMsvSession = NULL;
       
   112         }
       
   113     }
       
   114 
       
   115 // ---------------------------------------------------------
       
   116 // 
       
   117 // ---------------------------------------------------------
       
   118 //
       
   119 void ConversationMsgStoreHandler::InitL( )
       
   120     {
       
   121     TInt err = KErrNone;
       
   122     TRAP(err,iMsvSession = CMsvSession::OpenSyncL(*this));
       
   123     if(err != KErrNone)
       
   124         {
       
   125         iMsvSession = NULL;
       
   126         return;
       
   127         }
       
   128     
       
   129     TRAP(err,iMtmReg = CClientMtmRegistry::NewL(*iMsvSession));
       
   130     if(err != KErrNone)
       
   131         {
       
   132         iMtmReg = NULL;
       
   133         return;
       
   134         }
       
   135 	
       
   136 	 // Get if offline is supported
       
   137     FeatureManager::InitializeLibL();
       
   138     if (FeatureManager::FeatureSupported(KFeatureIdOfflineMode))
       
   139     {
       
   140         iOfflineSupported = ETrue;
       
   141     }
       
   142     else
       
   143     {
       
   144         iOfflineSupported = EFalse;
       
   145     }
       
   146     FeatureManager::UnInitializeLib();
       
   147 		
       
   148     }
       
   149 
       
   150 // ---------------------------------------------------------
       
   151 // ConversationMsgStoreHandler::HandleSessionEventL()
       
   152 // ---------------------------------------------------------
       
   153 //
       
   154 void ConversationMsgStoreHandler::HandleSessionEventL(TMsvSessionEvent aEvent,
       
   155         TAny* aArg1, TAny* aArg2, TAny* aArg3)
       
   156     {   
       
   157     //args
       
   158     if(aArg1 == NULL || aArg2 == NULL)
       
   159         {   
       
   160         return;
       
   161         }
       
   162 
       
   163     //start, processing the event
       
   164     CMsvEntrySelection* selection=NULL;
       
   165     TMsvId target = 0;
       
   166     TMsvId source = 0;
       
   167     selection= (CMsvEntrySelection*)aArg1;
       
   168     target = *(TMsvId*)aArg2; // target (current) parent
       
   169     if(aArg3 != NULL)
       
   170         {
       
   171         source = *(TMsvId*)aArg3; // source parent
       
   172         }
       
   173     //process for draft messages only
       
   174     if ( target == KMsvDraftEntryIdValue)
       
   175         {
       
   176         switch( aEvent )
       
   177             {
       
   178             //case EMsvEntriesCreated:
       
   179             case EMsvEntriesChanged:
       
   180             case EMsvEntriesMoved:
       
   181                 {
       
   182                 TMsvEntry entry;
       
   183                 TMsvId service;
       
   184                 TInt error= KErrNone;
       
   185 
       
   186                 for( TInt i=0 ; i < selection->Count() ; ++i )
       
   187                     {
       
   188                     error = iMsvSession->GetEntry(selection->At(i),service,entry);
       
   189                     if (KErrNone == error)
       
   190                         {
       
   191                         // process only visible entries
       
   192                         if (entry.Visible() && IsMtmSupported(entry.iMtm.iUid))
       
   193                             {
       
   194                                 if(mDraftsModel && mDraftsModel->isReady())
       
   195                                 {
       
   196                                     mDraftsModel->addRow(entry);
       
   197                                 }
       
   198                             }
       
   199                         }
       
   200                     }
       
   201                 }
       
   202                 break;
       
   203 
       
   204             case EMsvEntriesDeleted:
       
   205                 {
       
   206                 for( TInt i=0 ; i < selection->Count() ; ++i )
       
   207                     {
       
   208                     TMsvId id = selection->At( i );
       
   209                     if(mDraftsModel && mDraftsModel->isReady())
       
   210                         {
       
   211                         mDraftsModel->deleteRow(id);
       
   212                         }
       
   213                     }
       
   214                 }
       
   215                 break;
       
   216             }//end switch 
       
   217         }
       
   218     else if(KMsvDraftEntryIdValue == source)
       
   219         {
       
   220         //if message is moved from drafts to other folder
       
   221         // it needs to be removed.
       
   222         if(aEvent == EMsvEntriesMoved)
       
   223             {
       
   224             for( TInt i=0 ; i < selection->Count() ; ++i )
       
   225                 {
       
   226                 TMsvId id = selection->At( i );
       
   227                 if(mDraftsModel && mDraftsModel->isReady())
       
   228                     {
       
   229                     mDraftsModel->deleteRow(id);
       
   230                     }
       
   231                 }
       
   232             }
       
   233         }
       
   234     }
       
   235 
       
   236 // ---------------------------------------------------------
       
   237 // ConversationMsgStoreHandler::MsgStatus
       
   238 // ---------------------------------------------------------
       
   239 //
       
   240 TCsMmsNotificationMsgState ConversationMsgStoreHandler::
       
   241 MmsNotificationStatus( TInt aMsvId )
       
   242     {
       
   243     TMsvId dummy = 0x0;
       
   244     
       
   245     TMsvEntry entry;
       
   246     iMsvSession->GetEntry(aMsvId, dummy, entry);
       
   247     
       
   248     TCsMmsNotificationMsgState status = EMsgStatusNull;
       
   249 
       
   250     TTime currentTime;
       
   251     currentTime.HomeTime( );
       
   252     TTime expiryTime = iNotificationClient->ExpiryDate( );
       
   253     TLocale locale;
       
   254     expiryTime += locale.UniversalTimeOffset();
       
   255     if (locale.QueryHomeHasDaylightSavingOn())          
       
   256     {
       
   257         TTimeIntervalHours daylightSaving(1);          
       
   258         expiryTime += daylightSaving;
       
   259     }
       
   260 
       
   261     // operationMask includes operation type. It is not bitmap but ordinal number. 
       
   262     // It does not include operation status and result
       
   263     TInt operationMask = (entry.iMtmData2 & KMmsOperationIdentifier) ;
       
   264 
       
   265     // Note! Ongoing operation resets every bit of operation type, operation status
       
   266     // and result. E.g. If message has been forwarded and then fetching starts, 
       
   267     // information about forwarding is lost
       
   268 
       
   269     if( ( entry.iMtmData1 & KMmsMessageTypeMask ) == KMmsMessageMNotificationInd )
       
   270         {
       
   271         if(     operationMask == KMmsOperationFetch 
       
   272                 &&  OperationOngoing( entry ) )
       
   273             { 
       
   274             // It's in retrieving state
       
   275             status = EMsgStatusRetrieving;
       
   276             }
       
   277         else if(    operationMask == KMmsOperationForward
       
   278                 &&  OperationOngoing( entry ) )
       
   279             { 
       
   280             // It's in forwarding state
       
   281             status = EMsgStatusForwarding;
       
   282             }
       
   283         else if(    operationMask == KMmsOperationForward
       
   284                 &&  OperationFinished( entry )
       
   285                 &&  !( entry.iMtmData2 & KMmsOperationResult ) )
       
   286             { 
       
   287             // It's been forwarded succesfully
       
   288             status = EMsgStatusForwarded;
       
   289             }
       
   290         else if(    operationMask == KMmsOperationFetch 
       
   291                 &&  OperationFinished( entry )
       
   292                 &&   (  entry.iMtmData2 & KMmsOperationResult 
       
   293                 ||  entry.iError ) )
       
   294             { 
       
   295             // Fetch has been failed
       
   296             status = EMsgStatusFailed;
       
   297             }
       
   298         else if(    operationMask == KMmsOperationDelete
       
   299                 &&  OperationFinished( entry )
       
   300                 &&  !( entry.iMtmData2 & KMmsOperationResult ) )
       
   301             { 
       
   302             // It's been deleted succesfully
       
   303             status = EMsgStatusDeleted;
       
   304             }
       
   305         else if( currentTime > expiryTime )
       
   306             {
       
   307             status = EMsgStatusExpired;
       
   308             }
       
   309         else 
       
   310             {   // Normal waiting state
       
   311             status = EMsgStatusReadyForFetching;
       
   312             }
       
   313         }
       
   314 
       
   315     return status;
       
   316     }
       
   317 
       
   318 // ---------------------------------------------------------
       
   319 // ConversationMsgStoreHandler::OperationOngoing
       
   320 // ---------------------------------------------------------
       
   321 //
       
   322 TBool ConversationMsgStoreHandler::OperationOngoing( const TMsvEntry& aEntry ) const
       
   323     {
       
   324     return (    aEntry.iMtmData2 & KMmsOperationOngoing 
       
   325             &&  !( aEntry.iMtmData2 & KMmsOperationFinished ) );
       
   326     }
       
   327 
       
   328 // ---------------------------------------------------------
       
   329 // ConversationMsgStoreHandler::OperationFinished
       
   330 // ---------------------------------------------------------
       
   331 //
       
   332 TBool ConversationMsgStoreHandler::OperationFinished( 
       
   333     const TMsvEntry& aEntry ) const
       
   334     {
       
   335     return (    aEntry.iMtmData2 & KMmsOperationFinished
       
   336             &&  !( aEntry.iMtmData2 & KMmsOperationOngoing ) );
       
   337     }
       
   338 
       
   339 // ---------------------------------------------------------
       
   340 // ConversationMsgStoreHandler::MarkMessagesReadL
       
   341 // ---------------------------------------------------------
       
   342 //
       
   343 void ConversationMsgStoreHandler::MarkMessagesReadL(RArray<TInt>& aIdArray)
       
   344     {    
       
   345     for ( int index = 0; index < aIdArray.Count(); index++ )
       
   346         {
       
   347         TMsvId id = aIdArray[index];
       
   348         CMsvEntry* cEntry = NULL;
       
   349         TRAPD(err, cEntry = iMsvSession->GetEntryL(id));
       
   350         if ( err == KErrNotFound )
       
   351             continue; // Entry is already deleted.
       
   352         TMsvEntry entry = cEntry->Entry();
       
   353         if ( entry.Unread() ) 
       
   354             {
       
   355             // Mark the entry as read
       
   356             entry.SetUnread( EFalse );
       
   357             cEntry->ChangeL( entry );
       
   358             }
       
   359         delete cEntry;
       
   360         }
       
   361     }
       
   362 
       
   363 // ---------------------------------------------------------
       
   364 // ConversationMsgStoreHandler::DeleteMessages
       
   365 // ---------------------------------------------------------
       
   366 //
       
   367 void ConversationMsgStoreHandler::DeleteMessages(RArray<TInt>& aIdArray)
       
   368 {
       
   369     for(int index=0;index < aIdArray.Count() ;++index)
       
   370     {
       
   371         TMsvId id = aIdArray[index];
       
   372         iMsvSession->RemoveEntry(id);
       
   373     }   
       
   374 }
       
   375 
       
   376 // ---------------------------------------------------------
       
   377 // ConversationMsgStoreHandler::DeleteAllDraftMessages
       
   378 // ---------------------------------------------------------
       
   379 //
       
   380 void ConversationMsgStoreHandler::DeleteAllDraftMessagesL()
       
   381 {
       
   382     // Cancel the processing of draft messages.
       
   383     iIdle->Cancel();
       
   384 
       
   385     CMsvEntry *draftsEntry = iMsvSession->GetEntryL(KMsvDraftEntryIdValue);
       
   386     CleanupStack::PushL(draftsEntry);
       
   387     CMsvEntrySelection *draftsSelection = draftsEntry->ChildrenL();
       
   388     CleanupStack::PushL(draftsSelection);
       
   389     if ( draftsSelection->Count() > 0 )
       
   390         {
       
   391         CMuiuOperationWait* wait = CMuiuOperationWait::NewLC();
       
   392         CMsvOperation *operation = draftsEntry->DeleteL(*draftsSelection, wait->iStatus);
       
   393         wait->Start();
       
   394         CleanupStack::PopAndDestroy(wait);
       
   395         delete operation;
       
   396         }
       
   397     CleanupStack::PopAndDestroy(2, draftsEntry);
       
   398 }
       
   399 
       
   400 // ---------------------------------------------------------
       
   401 // ConversationMsgStoreHandler::DeleteMessagesL
       
   402 // ---------------------------------------------------------
       
   403 //
       
   404 CMsvSession& ConversationMsgStoreHandler::GetMsvSession()
       
   405 {
       
   406     return *iMsvSession;
       
   407 }
       
   408 
       
   409 // ---------------------------------------------------------
       
   410 // ConversationMsgStoreHandler::FetchDraftsMessages
       
   411 // ---------------------------------------------------------
       
   412 //
       
   413 void ConversationMsgStoreHandler::FetchDraftMessages(DraftsModel* draftsModel)
       
   414     {
       
   415     mDraftsModel = draftsModel;
       
   416     iState = EReadDrafts;
       
   417     TCallBack callback = TCallBack(ProcessDraftMessages, (TAny*) this);
       
   418     TRAPD(err, iIdle = CIdle::NewL(CActive::EPriorityStandard));
       
   419     if(err == KErrNone)
       
   420         {
       
   421         iIdle->Start(callback);    
       
   422         }
       
   423     }
       
   424 
       
   425 // -----------------------------------------------------------------------------
       
   426 // ConversationMsgStoreHandler::ProcessDraftMessages
       
   427 // CIdle callback 
       
   428 // -----------------------------------------------------------------------------
       
   429 //
       
   430 TInt ConversationMsgStoreHandler::ProcessDraftMessages(TAny* aArg)
       
   431     {
       
   432     ConversationMsgStoreHandler* handler = (ConversationMsgStoreHandler*) aArg; 
       
   433     TInt ok = 0;
       
   434     TRAPD(err, ok = handler->ProcessDraftMessagesL());
       
   435     return ((err == KErrNone) && ok);
       
   436     }
       
   437 
       
   438 // ---------------------------------------------------------
       
   439 // ConversationMsgStoreHandler::ProcessDraftMessagesL
       
   440 // ---------------------------------------------------------
       
   441 //
       
   442 TInt ConversationMsgStoreHandler::ProcessDraftMessagesL()
       
   443     {
       
   444     switch(iState)
       
   445         {
       
   446         case EReadDrafts:
       
   447             {
       
   448             iDraftEntry = iMsvSession->GetEntryL(KMsvDraftEntryIdValue);
       
   449            
       
   450             iDraftMessages = iDraftEntry->ChildrenL();
       
   451             iDraftMessageCount = iDraftEntry->Count();
       
   452 
       
   453             if ( iDraftMessageCount ) 
       
   454                 {
       
   455                 iState = EProcessDrafts;
       
   456                 }
       
   457             else
       
   458                 {
       
   459                 iState = EComplete; // no draft messages
       
   460                 mDraftsModel->setReady(); //ready to handle dynamic events
       
   461                 CleanupL();
       
   462                 return 0; //DONE
       
   463                 }
       
   464             return 1;
       
   465             }
       
   466         case EProcessDrafts:
       
   467             {
       
   468             if ( iDraftMessageCount ) 
       
   469                 {
       
   470                 iDraftMessageCount--;
       
   471                 TMsvEntry entry = iDraftEntry->ChildDataL(
       
   472                         iDraftMessages->At(iDraftMessageCount));
       
   473                 
       
   474                 // process only visible entries
       
   475                 if (entry.Visible() && IsMtmSupported(entry.iMtm.iUid))
       
   476                 {
       
   477                 //add message to model
       
   478                 mDraftsModel->addRow(entry);
       
   479                 }
       
   480                 //continue to process other draft messages
       
   481                 iState = EProcessDrafts;
       
   482                 }
       
   483             else
       
   484                 {
       
   485                 iState = EComplete;
       
   486                 mDraftsModel->setReady(); //ready to handle dynamic events
       
   487                 CleanupL();
       
   488                 return 0; // DONE
       
   489                 }
       
   490             return 1; 
       
   491             }
       
   492         }
       
   493 
       
   494     return 0;
       
   495     }
       
   496 
       
   497 // -----------------------------------------------------------------------------
       
   498 // ConversationMsgStoreHandler::CleanupL()
       
   499 // Helper function for state machine cleanup
       
   500 // -----------------------------------------------------------------------------
       
   501 //
       
   502 void ConversationMsgStoreHandler::CleanupL()
       
   503     {
       
   504     if ( iDraftEntry )
       
   505         {
       
   506         delete iDraftEntry;
       
   507         iDraftEntry = NULL;
       
   508         }
       
   509 
       
   510     if ( iDraftMessages )
       
   511         {
       
   512         iDraftMessages->Reset();
       
   513         delete iDraftMessages;
       
   514         iDraftMessages = NULL;
       
   515         }
       
   516 
       
   517     iDraftMessageCount = 0;
       
   518     }
       
   519 
       
   520 // -----------------------------------------------------------------------------
       
   521 // ConversationMsgStoreHandler::IsMtmSupported()
       
   522 // 
       
   523 // -----------------------------------------------------------------------------
       
   524 //
       
   525 TBool ConversationMsgStoreHandler::IsMtmSupported(long uid)	
       
   526     {
       
   527     if ( KSenduiMtmSmsUidValue == uid || KSenduiMtmMmsUidValue == uid )
       
   528         {
       
   529         return ETrue;
       
   530         }	
       
   531     return EFalse;
       
   532     }
       
   533 	
       
   534 //-----------------------------------------------------------------------------
       
   535 // ConversationMsgStoreHandler::ResendMessage(TMsvId aId)
       
   536 // 
       
   537 // -----------------------------------------------------------------------------
       
   538 //	
       
   539 	
       
   540 bool ConversationMsgStoreHandler::ResendMessageL(TMsvId aId)
       
   541 {
       
   542     bool retval = true;
       
   543 	TMsvId serviceId;
       
   544 	TMsvEntry msgEntry;
       
   545 	  
       
   546 	if(iMsvSession == NULL)
       
   547 	    {
       
   548         return false;
       
   549    		}
       
   550   TInt err = iMsvSession->GetEntry(aId, serviceId, msgEntry);
       
   551     
       
   552   if (KErrNone == err)
       
   553   {
       
   554        TUid mtmUid = msgEntry.iMtm;
       
   555 
       
   556        CMsvEntry* entry = iMsvSession->GetEntryL(KMsvGlobalOutBoxIndexEntryId);
       
   557        CleanupStack::PushL(entry);
       
   558 
       
   559        CMuiuOperationWait* wait = CMuiuOperationWait::NewLC();
       
   560 
       
   561        if (mtmUid == KSmsMtmUid)
       
   562        {
       
   563            UniEditorGenUtils* genUtils = new UniEditorGenUtils();
       
   564            CleanupStack::PushL(genUtils);
       
   565 
       
   566            // if phone is in offline mode set sending state to suspended
       
   567            // so that mtm does not try to send it.
       
   568            if (iOfflineSupported && genUtils->IsPhoneOfflineL())
       
   569            {
       
   570                msgEntry.SetSendingState(KMsvSendStateSuspended);
       
   571                msgEntry.iError = KErrGsmOfflineOpNotAllowed;
       
   572            }
       
   573            else
       
   574            {
       
   575                msgEntry.SetSendingState(KMsvSendStateWaiting);
       
   576            }
       
   577            CleanupStack::PopAndDestroy(genUtils);
       
   578 
       
   579            // Update message entry with sending state.
       
   580            entry->SetEntryL(msgEntry.Id());
       
   581            entry->ChangeL(msgEntry);
       
   582 
       
   583            TMsvId firstId;
       
   584            TSmsUtilities::ServiceIdL(*iMsvSession, firstId);
       
   585 
       
   586            entry->SetEntryL(KMsvGlobalOutBoxIndexEntryId);
       
   587            //send the message
       
   588            entry->CopyL(aId, firstId, wait->iStatus);
       
   589            wait->Start();
       
   590        }
       
   591        else if (mtmUid == KMmsMtmUid)
       
   592        {
       
   593            //send the message
       
   594            entry->CopyL(aId, msgEntry.iServiceId, wait->iStatus);
       
   595            wait->Start();
       
   596        }
       
   597        CleanupStack::PopAndDestroy(2, entry);
       
   598    }
       
   599    else
       
   600    {
       
   601        User::LeaveIfError(err);
       
   602    }
       
   603    return retval;
       
   604 }
       
   605 
       
   606 //-----------------------------------------------------------------------------
       
   607 // ConversationMsgStoreHandler::DownloadOperationSupported
       
   608 // -----------------------------------------------------------------------------
       
   609 bool ConversationMsgStoreHandler::DownloadOperationSupported(
       
   610         const TMsvId& aId)
       
   611 {
       
   612     TMsvId serviceId;
       
   613     TMsvEntry msgEntry;
       
   614     TInt err = iMsvSession->GetEntry(aId,serviceId,msgEntry);
       
   615     
       
   616     TCsMmsNotificationMsgState msgstatus = 
       
   617             MmsNotificationStatus( aId );
       
   618 
       
   619     if ( msgEntry.iType == KUidMsvMessageEntry  )
       
   620         {
       
   621 
       
   622         if( msgEntry.iMtmData2 & KMmsNewOperationForbidden ) // New Forbidden
       
   623             {
       
   624             return false;
       
   625             }
       
   626         // If notification is succesfully routed to app 
       
   627         // aContext.iMtmData2 & KMmsMessageRoutedToApplication is ETrue and
       
   628         // if notification is NOT succesfully routed to app 
       
   629         // aContext.iError is KMmsErrorUnregisteredApplication.
       
   630         if(    ( msgEntry.iError == KMmsErrorUnregisteredApplication ) // To unregistered application
       
   631             || ( msgEntry.iMtmData2 & KMmsMessageRoutedToApplication ) )
       
   632             {
       
   633             return false;
       
   634             }
       
   635 
       
   636         if( msgstatus == EMsgStatusDeleted )
       
   637             { // Msg already been deleted from server
       
   638             return false;
       
   639             }
       
   640 
       
   641         if( msgstatus == EMsgStatusReadyForFetching 
       
   642             || msgstatus == EMsgStatusFailed )
       
   643             {   // Fetch is supported if the msg is waiting or something has been failed
       
   644             return true;
       
   645             }
       
   646 
       
   647         if (    msgstatus == EMsgStatusForwarded 
       
   648             &&  msgEntry.iMtmData2 & KMmsStoredInMMBox )
       
   649             { // Fetch is supported if it's forwarded and multiple forward is supported
       
   650             return true;
       
   651             }
       
   652         
       
   653         if( msgstatus == EMsgStatusExpired )
       
   654             {
       
   655             return false;
       
   656             }
       
   657         }
       
   658     return false;
       
   659 }
       
   660 
       
   661 //---------------------------------------------------------------
       
   662 // ConversationMsgStoreHandler::setNotificationMessageIdL
       
   663 // @see header
       
   664 //---------------------------------------------------------------
       
   665 void ConversationMsgStoreHandler::setNotificationMessageIdL(int messageId)
       
   666 {
       
   667     // get MMS Notification client mtm & set the content to current entry
       
   668     if(iNotificationClient)
       
   669     {
       
   670         delete iNotificationClient;
       
   671         iNotificationClient = NULL;
       
   672     }
       
   673     CClientMtmRegistry* mtmRegistry = 
       
   674             CClientMtmRegistry::NewL( *iMsvSession );
       
   675     iNotificationClient = static_cast<CMmsNotificationClientMtm*>( 
       
   676                     mtmRegistry->NewMtmL( KUidMsgMMSNotification ));
       
   677     iNotificationClient->SwitchCurrentEntryL(messageId);
       
   678     iNotificationClient->LoadMessageL();
       
   679 }
       
   680 
       
   681 //---------------------------------------------------------------
       
   682 // ConversationMsgStoreHandler::NotificationMsgSizeL
       
   683 // @see header
       
   684 //---------------------------------------------------------------
       
   685 QString ConversationMsgStoreHandler::NotificationMsgSize()
       
   686 {
       
   687     // Size of message.
       
   688     TInt size = iNotificationClient->MessageTransferSize( );
       
   689 
       
   690     // read max receive size limit from settings
       
   691     TInt maxSize = 0;
       
   692     TRAP_IGNORE(maxSize = MaxReceiveSizeLimitL());
       
   693 
       
   694     // apply max size limit rule
       
   695     if( maxSize > 0 )
       
   696     {
       
   697         if( size > maxSize )
       
   698         {
       
   699             size = maxSize;
       
   700         }
       
   701     }
       
   702 
       
   703     TInt fileSize = size / BYTES_TO_KBYTES_FACTOR;
       
   704     if ( size % BYTES_TO_KBYTES_FACTOR )
       
   705     {
       
   706         fileSize++;
       
   707     }
       
   708 
       
   709     return LOC_MESSAGE_SIZE.arg(fileSize);
       
   710 }
       
   711 
       
   712 //---------------------------------------------------------------
       
   713 // ConversationMsgStoreHandler::NotificationClass
       
   714 // @see header
       
   715 //---------------------------------------------------------------
       
   716 QString ConversationMsgStoreHandler::NotificationClass()
       
   717 {
       
   718     QString notificationClass;
       
   719     TInt msgClass = iNotificationClient->MessageClass( );
       
   720     switch( msgClass )
       
   721     {
       
   722         case EMmsClassPersonal:
       
   723         {
       
   724             notificationClass = LOC_CLASS_PERSONAL;
       
   725             break;
       
   726         }
       
   727         case EMmsClassAdvertisement:
       
   728         {
       
   729             notificationClass = LOC_CLASS_ADVERTISEMENT;
       
   730             break;
       
   731         }
       
   732         case EMmsClassInformational:
       
   733         {
       
   734             notificationClass = LOC_CLASS_INFORMATIONAL;
       
   735             break;
       
   736         }
       
   737         default:
       
   738         {   // In case no class is returned (0), don't add the field
       
   739             break;
       
   740         }
       
   741     }
       
   742     return notificationClass;
       
   743 }
       
   744 
       
   745 //---------------------------------------------------------------
       
   746 // ConversationMsgStoreHandler::NotificationStatus
       
   747 // @see header
       
   748 //---------------------------------------------------------------
       
   749 void ConversationMsgStoreHandler::NotificationStatus(
       
   750         int& status,
       
   751         QString& statusStr)
       
   752 {
       
   753     // fetch mms notification status from store handler
       
   754     // and map as per our UI requirements
       
   755     TMsvEntry entry = iNotificationClient->Entry().Entry();
       
   756     status = MmsNotificationStatus(entry.Id());
       
   757     switch(status)
       
   758     {
       
   759         case ConvergedMessage::NotifFailed:
       
   760         {
       
   761             statusStr = LOC_MMS_RETRIEVAL_FAILED;
       
   762             break;
       
   763         }
       
   764         case ConvergedMessage::NotifExpired:
       
   765         {
       
   766             statusStr = LOC_MMS_NOTIF_EXPIRED;
       
   767             break;
       
   768         }
       
   769         case ConvergedMessage::NotifReadyForFetching:
       
   770         {
       
   771             statusStr = LOC_MMS_WAITING;
       
   772             break;
       
   773         }
       
   774         case ConvergedMessage::NotifWaiting:
       
   775         case ConvergedMessage::NotifRetrieving:
       
   776         {
       
   777             statusStr = LOC_MMS_RETRIEVING;
       
   778             break;
       
   779         }
       
   780         default:
       
   781         {
       
   782             // not handled, do nothing
       
   783             break;
       
   784         }
       
   785     }
       
   786 }
       
   787 
       
   788 //---------------------------------------------------------------
       
   789 // ConversationMsgStoreHandler::NotificationExpiryDate
       
   790 // @see header
       
   791 //---------------------------------------------------------------
       
   792 QString ConversationMsgStoreHandler::NotificationExpiryDate()
       
   793 {
       
   794     TTime expiryTime = 0;
       
   795     QString expiryTimeStr;
       
   796 
       
   797     // get expiry time from entry
       
   798     expiryTime = iNotificationClient->ExpiryDate( );
       
   799     TLocale locale;
       
   800     expiryTime += locale.UniversalTimeOffset();
       
   801     if (locale.QueryHomeHasDaylightSavingOn())          
       
   802     {
       
   803         TTimeIntervalHours daylightSaving(1);          
       
   804         expiryTime += daylightSaving;
       
   805     }
       
   806     
       
   807     // create formatted string for the expiry time
       
   808     TTime unixEpoch(KUnixEpoch);
       
   809     TTimeIntervalSeconds seconds;
       
   810     expiryTime.SecondsFrom(unixEpoch, seconds);
       
   811     return LOC_MMS_EXPIRY_DATE.arg(seconds.Int());
       
   812 }
       
   813 
       
   814 //-----------------------------------------------------------------------------
       
   815 // ConversationMsgStoreHandler::DownloadMessageL
       
   816 // 
       
   817 // -----------------------------------------------------------------------------
       
   818 //  
       
   819     
       
   820 TInt ConversationMsgStoreHandler::DownloadMessageL(TMsvId aId)
       
   821 {
       
   822     TMsvId serviceId;
       
   823     TMsvEntry msgEntry;
       
   824 
       
   825     TInt err = iMsvSession->GetEntry(aId,serviceId,msgEntry);
       
   826 
       
   827     if(err!= KErrNone || msgEntry.iMtm!= KUidMsgMMSNotification)
       
   828     {
       
   829         return KErrGeneral;
       
   830     }
       
   831 
       
   832     /*if(!iNotificationClient)
       
   833     {
       
   834         iNotificationClient = static_cast<CMmsNotificationClientMtm*> 
       
   835         (iMtmReg->NewMtmL(KUidMsgMMSNotification));
       
   836     }
       
   837     iNotificationClient->SwitchCurrentEntryL(aId);    */ 
       
   838     
       
   839     // set context to current entry
       
   840     setNotificationMessageIdL(aId);
       
   841 
       
   842     TTime currentTime;
       
   843     currentTime.HomeTime( );
       
   844     TTime expiryTime = iNotificationClient->ExpiryDate( );
       
   845     TLocale locale;
       
   846     expiryTime += locale.UniversalTimeOffset();
       
   847     if (locale.QueryHomeHasDaylightSavingOn())          
       
   848     {
       
   849         TTimeIntervalHours daylightSaving(1);          
       
   850         expiryTime += daylightSaving;
       
   851     }
       
   852 
       
   853     if( currentTime > expiryTime )
       
   854     {   // Message is expired
       
   855         return KErrGeneral;
       
   856     }
       
   857 
       
   858     //Check if the mms client mtm object is already created or not
       
   859     if( iMmsClient )
       
   860     {
       
   861         // If mms client mtm object is already created restore the settings
       
   862         iMmsClient->RestoreSettingsL();
       
   863     }
       
   864     else
       
   865     {
       
   866         iMmsClient = static_cast<CMmsClientMtm*> (iMtmReg->NewMtmL(KMmsMtmUid));
       
   867     }        
       
   868 
       
   869     //TODO chk if only AP check is sufficient
       
   870     TMsvId service = iMmsClient->DefaultServiceL();
       
   871     TBool valid( iMmsClient->ValidateService( service ) == KErrNone );
       
   872     if(!valid)
       
   873     {
       
   874         return KErrNotFound;
       
   875     }
       
   876 
       
   877     CMuiuOperationWait* wait =CMuiuOperationWait::NewLC();;
       
   878 
       
   879     CMsvEntrySelection* sel = new ( ELeave ) CMsvEntrySelection;
       
   880     CleanupStack::PushL( sel );
       
   881     sel->AppendL( aId );    
       
   882 
       
   883     CMsvOperation* op = 
       
   884             iNotificationClient->FetchMessagesL( *sel, wait->iStatus );
       
   885 
       
   886     if( !op )
       
   887     {  
       
   888         CleanupStack::PopAndDestroy( sel ); // selection
       
   889         CleanupStack::PopAndDestroy( wait ); // wait
       
   890         return KErrGeneral; 
       
   891     }
       
   892 
       
   893     CleanupStack::PushL( op );
       
   894     wait->Start();
       
   895     // Lets ignore the return value of wait
       
   896 
       
   897     CleanupStack::PopAndDestroy( op ); // op 
       
   898     CleanupStack::PopAndDestroy( sel ); // selection
       
   899     CleanupStack::PopAndDestroy( wait ); // wait
       
   900 
       
   901     return KErrNone;
       
   902 }
       
   903 
       
   904 //----------------------------------------------------------------------------
       
   905 // ConversationMsgStoreHandler::markAsReadAndGetType
       
   906 // @see header
       
   907 //----------------------------------------------------------------------------
       
   908 void ConversationMsgStoreHandler::markAsReadAndGetType(int msgId,
       
   909                                                       int& msgType,
       
   910                                                       int& msgSubType)
       
   911     {
       
   912     msgType = ConvergedMessage::None;
       
   913     msgSubType = ConvergedMessage::None;
       
   914     
       
   915     CMsvEntry* cEntry = NULL;
       
   916     TRAPD(err, cEntry = iMsvSession->GetEntryL(msgId));
       
   917     if ( err == KErrNone)
       
   918         {
       
   919         TMsvEntry entry = cEntry->Entry();
       
   920         if ( entry.Unread() ) 
       
   921             {
       
   922             // Mark the entry as read
       
   923             entry.SetUnread( EFalse );
       
   924             TRAP_IGNORE(cEntry->ChangeL( entry ));
       
   925             }
       
   926         // extract message type
       
   927         extractMsgType(entry,msgType,msgSubType);
       
   928         }
       
   929     
       
   930     delete cEntry;
       
   931     }
       
   932 
       
   933 //----------------------------------------------------------------------------
       
   934 // ConversationMsgStoreHandler::extractMsgType
       
   935 // @see header
       
   936 //----------------------------------------------------------------------------
       
   937 void ConversationMsgStoreHandler::extractMsgType(const TMsvEntry& entry,
       
   938                                     int& msgType,
       
   939                                     int& msgSubType)
       
   940     {
       
   941     msgType = ConvergedMessage::None;
       
   942     msgSubType = ConvergedMessage::None;
       
   943 
       
   944     switch(entry.iMtm.iUid)   
       
   945         {
       
   946         case KSenduiMtmSmsUidValue:            
       
   947             msgType = ConvergedMessage::Sms;
       
   948             if (entry.iBioType == KMsgBioNokiaServiceSentMessage.iUid) {
       
   949                 msgSubType = ConvergedMessage::NokiaService;
       
   950             }
       
   951             break;
       
   952         case KSenduiMtmBtUidValue:
       
   953             msgType = ConvergedMessage::BT;
       
   954             break;
       
   955         case KSenduiMtmMmsUidValue:        
       
   956             msgType = ConvergedMessage::Mms;
       
   957             break;
       
   958         case KSenduiMMSNotificationUidValue:            
       
   959             msgType = ConvergedMessage::MmsNotification;
       
   960             break;
       
   961         case KSenduiMtmBioUidValue:
       
   962             { 
       
   963  			if (entry.iMtmData1 == KSenduiMtmBtUidValue) 
       
   964 				{
       
   965             	msgType = ConvergedMessage::BT;
       
   966 
       
   967             	if (entry.iBioType == KMsgBioUidVCard.iUid) 
       
   968 					{	
       
   969                		 msgSubType = ConvergedMessage::VCard;
       
   970             		}
       
   971             	else if (entry.iBioType == KMsgBioUidVCalendar.iUid) 
       
   972 					{
       
   973 			
       
   974                		 msgSubType = ConvergedMessage::VCal;
       
   975             		}
       
   976 
       
   977            	 break;
       
   978        		 }
       
   979             msgType = ConvergedMessage::BioMsg; 
       
   980 
       
   981             // based on the biotype uid set message type
       
   982             if(entry.iBioType == KMsgBioUidRingingTone.iUid)
       
   983                 {
       
   984                 msgSubType = ConvergedMessage::RingingTone;
       
   985                 }
       
   986             else if(entry.iBioType == KMsgBioProvisioningMessage.iUid)
       
   987                 {
       
   988                 msgSubType = ConvergedMessage::Provisioning;
       
   989                 }     
       
   990             else if (entry.iBioType == KMsgBioUidVCard.iUid)
       
   991                 {
       
   992                 msgSubType = ConvergedMessage::VCard;
       
   993                 }
       
   994             else if (entry.iBioType == KMsgBioUidVCalendar.iUid)
       
   995                 {
       
   996                 msgSubType = ConvergedMessage::VCal;
       
   997                 }
       
   998             else if (entry.iBioType == KMsgBioNokiaServiceSentMessage.iUid) {
       
   999                 msgSubType = ConvergedMessage::NokiaService;
       
  1000                 }
       
  1001             }
       
  1002         break;
       
  1003     default:
       
  1004         msgType = ConvergedMessage::None;
       
  1005         break;
       
  1006     }
       
  1007 }
       
  1008 
       
  1009 //----------------------------------------------------------------------------
       
  1010 // ConversationMsgStoreHandler::getMsgSubType
       
  1011 // @see header
       
  1012 //----------------------------------------------------------------------------
       
  1013 int ConversationMsgStoreHandler::getMsgSubType(int msgId)
       
  1014 {
       
  1015     int msgType = ConvergedMessage::None;
       
  1016     int msgSubType = ConvergedMessage::None;
       
  1017     CMsvEntry* cEntry = NULL;
       
  1018     TRAPD(err, cEntry = iMsvSession->GetEntryL(msgId));
       
  1019     if (err == KErrNone) {
       
  1020         TMsvEntry entry = cEntry->Entry();
       
  1021         extractMsgType(entry, msgType, msgSubType);
       
  1022     }
       
  1023     return msgSubType;
       
  1024 }
       
  1025 
       
  1026 //----------------------------------------------------------------------------
       
  1027 // ConversationMsgStoreHandler::MaxReceiveSizeLimitL
       
  1028 // @see header
       
  1029 //----------------------------------------------------------------------------
       
  1030 TInt ConversationMsgStoreHandler::MaxReceiveSizeLimitL()
       
  1031 {
       
  1032     CMmsSettings* settings = CMmsSettings::NewL();
       
  1033     CleanupStack::PushL( settings );
       
  1034     iNotificationClient->RestoreSettingsL();
       
  1035     settings->CopyL( iNotificationClient->MmsSettings() );
       
  1036     TInt maxSize = static_cast<TInt>(settings->MaximumReceiveSize() );
       
  1037     CleanupStack::PopAndDestroy( settings );
       
  1038     return maxSize;
       
  1039 }
       
  1040 
       
  1041 // End of file