messagingapp/msgservices/msgserviceapp/src/msgstorehandler.cpp
changeset 72 6f657153cbc5
parent 52 12db4185673b
--- a/messagingapp/msgservices/msgserviceapp/src/msgstorehandler.cpp	Fri Sep 17 08:28:39 2010 +0300
+++ b/messagingapp/msgservices/msgserviceapp/src/msgstorehandler.cpp	Mon Oct 04 00:13:15 2010 +0300
@@ -16,99 +16,175 @@
  */
 
 #include <msvids.h>
+#include <msvstd.h>
 #include <mmsconst.h>
 #include <SendUiConsts.h>
+#include <mtclreg.h>    // for CClientMtmRegistry
+#include <mmsnotificationclient.h>
+#include <mmssettings.h>
+#include <xqconversions.h> // from xqutils
+#include <mmsconst.h>
+#include <QDateTime>
+#include <hbglobal.h>
 
 #include "msgstorehandler.h"
 #include "msgbiouids.h"
 #include "convergedmessage.h"
 
+// CONSTANTS
+_LIT(KUnixEpoch, "19700000:000000.000000");
+#define BYTES_TO_KBYTES_FACTOR 1024
+
+// LOCALIZATION
+// TODO : use dialog localizations
+#define LOC_MESSAGE_SIZE hbTrId("txt_messaging_list_size")
+#define LOC_CLASS_ADVERTISEMENT hbTrId("txt_messaging_list_advertisement")
+#define LOC_CLASS_INFORMATIONAL hbTrId("txt_messaging_list_informational")
+#define LOC_CLASS_PERSONAL hbTrId("txt_messaging_list_personal")
+#define LOC_MMS_RETRIEVAL_FAILED hbTrId("txt_messaging_dialog_mms_retrieval_failed")
+#define LOC_MMS_NOTIF_EXPIRED hbTrId("txt_messaging_list_message_expired")  
+#define LOC_MMS_WAITING hbTrId("txt_wireframe_list_multimedia_message_waiting")
+#define LOC_MMS_RETRIEVING hbTrId("txt_messaging_list_retrieving_message")   
+#define LOC_MMS_EXPIRY_DATE hbTrId("txt_messaging_list_expiry_date")
+
 //----------------------------------------------------------------------------
 // MsgStoreHandler::MsgStoreHandler
 // @see header
 //----------------------------------------------------------------------------
 MsgStoreHandler::MsgStoreHandler():
-iMsvSession(NULL)
-        {
-        InitL();
-        }
+iMsvSession(NULL), iNotificationClient(NULL), iMtmReg(NULL)
+{
+    InitL();
+}
 
 //----------------------------------------------------------------------------
 // MsgStoreHandler::~MsgStoreHandler
 // @see header
 //----------------------------------------------------------------------------
 MsgStoreHandler::~MsgStoreHandler()
+{
+    if(iNotificationClient)
     {
-    if(iMsvSession)
-        {
-        delete iMsvSession;
-        iMsvSession = NULL;
-        }
-    }
-
-//----------------------------------------------------------------------------
-// MsgStoreHandler::InitL
-// @see header
-//----------------------------------------------------------------------------
-void MsgStoreHandler::InitL( )
-    {
-    iMsvSession = CMsvSession::OpenSyncL(*this);
+        delete iNotificationClient;
+        iNotificationClient = NULL;
     }
 
-//----------------------------------------------------------------------------
-// MsgStoreHandler::markAsReadAndGetType
-// @see header
-//----------------------------------------------------------------------------
-void MsgStoreHandler::markAsReadAndGetType(int msgId,
-                                          int& msgType,
-                                          int& msgSubType)
+    if(iMtmReg)
     {
-    msgType = ConvergedMessage::None;
-    
-    CMsvEntry* cEntry = NULL;
-    TRAPD(err, cEntry = iMsvSession->GetEntryL(msgId));
-    if ( err == KErrNone)
-        {
-        TMsvEntry entry = cEntry->Entry();
-        if ( entry.Unread() ) 
-            {
-            // Mark the entry as read
-            entry.SetUnread( EFalse );
-            cEntry->ChangeL( entry );
-            }
-        // extract message type
-        extractMsgType(entry,msgType,msgSubType);
-        }
-    
-    delete cEntry;
+        delete iMtmReg;
+        iMtmReg = NULL;
     }
 
+    if(iMsvSession)
+    {
+        delete iMsvSession;
+        iMsvSession = NULL;
+    }
+}
+
 //----------------------------------------------------------------------------
 // MsgStoreHandler::HandleSessionEventL
 // @see header
 //----------------------------------------------------------------------------
 void MsgStoreHandler::HandleSessionEventL(TMsvSessionEvent /*aEvent*/,
         TAny* /*aArg1*/, TAny* /*aArg2*/, TAny* /*aArg3*/)
-    {
+{
     // Nothing to do
+}
+
+//----------------------------------------------------------------------------
+// MsgStoreHandler::InitL
+// @see header
+//----------------------------------------------------------------------------
+void MsgStoreHandler::InitL()
+{
+    TInt err = KErrNone;
+    TRAP(err,iMsvSession = CMsvSession::OpenSyncL(*this));
+    if(err != KErrNone)
+    {
+        iMsvSession = NULL;
+        return;
     }
 
+    TRAP(err,iMtmReg = CClientMtmRegistry::NewL(*iMsvSession));
+    if(err != KErrNone)
+    {
+        iMtmReg = NULL;
+        return;
+    }
+}
+
 //----------------------------------------------------------------------------
-// MsgStoreHandler::extractMsgType
+// MsgStoreHandler::MessageLocation
+// @see header
+//----------------------------------------------------------------------------
+TMsvId MsgStoreHandler::MessageLocation( TMsvId aMsgId ) const
+{
+    TMsvId parent = NULL;
+    CMsvEntry* cEntry = NULL;
+    TRAPD(err, cEntry = iMsvSession->GetEntryL(aMsgId));
+    if(err == KErrNone)
+    {
+        TMsvEntry msvEntry = cEntry->Entry();
+        parent = msvEntry.Parent();
+    }
+    delete cEntry;
+    return parent;
+}
+
+//----------------------------------------------------------------------------
+// MsgStoreHandler::markAsRead
 // @see header
 //----------------------------------------------------------------------------
-void MsgStoreHandler::extractMsgType(const TMsvEntry& entry,
-                                    int& msgType,
-                                    int& msgSubType)
+void MsgStoreHandler::markAsRead(int msgId)
+{
+    CMsvEntry* cEntry = NULL;
+    TRAPD(err, cEntry = iMsvSession->GetEntryL(msgId));
+    if(err == KErrNone)
     {
+        TMsvEntry entry = cEntry->Entry();
+        if ( entry.Unread() ) 
+        {
+            // Mark the entry as read
+            entry.SetUnread( EFalse );
+            cEntry->ChangeL( entry );
+        }
+    }
+    delete cEntry;
+}
+
+//----------------------------------------------------------------------------
+// MsgStoreHandler::getMsgTypeInfo
+// @see header
+//----------------------------------------------------------------------------
+void MsgStoreHandler::getMsgTypeInfo(int msgId,
+                                     int& msgType,
+                                     int& msgSubType)
+{
     msgType = ConvergedMessage::None;
     msgSubType = ConvergedMessage::None;
 
+    CMsvEntry* cEntry = NULL;
+    TRAPD(err, cEntry = iMsvSession->GetEntryL(msgId));
+    if(err != KErrNone)
+    {
+        // error in getting the entry, return back
+        delete cEntry;
+        return;
+    }
+
+    TMsvEntry entry = cEntry->Entry();
     switch(entry.iMtm.iUid)   
+    {
+        case KSenduiMtmSmsUidValue:
         {
-        case KSenduiMtmSmsUidValue:            
             msgType = ConvergedMessage::Sms;
+            if (entry.iBioType == KMsgBioUidVCard.iUid)
+            {
+                msgSubType = ConvergedMessage::VCard;
+            }
             break;
+        }
         case KSenduiMtmBtUidValue:
             msgType = ConvergedMessage::BT;
             break;
@@ -119,78 +195,426 @@
             msgType = ConvergedMessage::MmsNotification;
             break;
         case KSenduiMtmBioUidValue:
-            { 
-        if (entry.iMtmData1 == KSenduiMtmBtUidValue) 
-		{
-            msgType = ConvergedMessage::BT;
+        {
+            if (entry.iMtmData1 == KSenduiMtmBtUidValue) 
+            {
+                msgType = ConvergedMessage::BT;
+                if (entry.iBioType == KMsgBioUidVCard.iUid) 
+                {
+                    msgSubType = ConvergedMessage::VCard;
+                }
+                else if (entry.iBioType == KMsgBioUidVCalendar.iUid) 
+                {
+                    msgSubType = ConvergedMessage::VCal;
+                }
+                break;
+            }
 
-            if (entry.iBioType == KMsgBioUidVCard.iUid) 
-			{
+            msgType = ConvergedMessage::BioMsg;
+            // based on the biotype uid set message type
+            if(entry.iBioType == KMsgBioUidRingingTone.iUid)
+            {
+                msgSubType = ConvergedMessage::RingingTone;
+            }
+            else if(entry.iBioType == KMsgBioProvisioningMessage.iUid)
+            {
+                msgSubType = ConvergedMessage::Provisioning;
+            }     
+            else if (entry.iBioType == KMsgBioUidVCard.iUid)
+            {
                 msgSubType = ConvergedMessage::VCard;
             }
-            else if (entry.iBioType == KMsgBioUidVCalendar.iUid) 
-			{
+            else if (entry.iBioType == KMsgBioUidVCalendar.iUid)
+            {
                 msgSubType = ConvergedMessage::VCal;
-            }
-
+            }        
             break;
         }
-            msgType = ConvergedMessage::BioMsg; 
-
-            // based on the biotype uid set message type
-            if(entry.iBioType == KMsgBioUidRingingTone.iUid)
-                {
-                msgSubType = ConvergedMessage::RingingTone;
-                }
-            else if(entry.iBioType == KMsgBioProvisioningMessage.iUid)
-                {
-                msgSubType = ConvergedMessage::Provisioning;
-                }     
-            else if (entry.iBioType == KMsgBioUidVCard.iUid)
-                {
-                msgSubType = ConvergedMessage::VCard;
-                }
-            else if (entry.iBioType == KMsgBioUidVCalendar.iUid)
-                {
-                msgSubType = ConvergedMessage::VCal;
-                }        
-            }
-            break;
         default:
             msgType = ConvergedMessage::None;       
             break;
-        }
     }
+    delete cEntry;
+}
 
 //----------------------------------------------------------------------------
 // MsgStoreHandler::deleteMessage
 // @see header
 //----------------------------------------------------------------------------
 void MsgStoreHandler::deleteMessage(int msgId)
-    {
+{
     iMsvSession->RemoveEntry(msgId);
-    }
+}
 
 //----------------------------------------------------------------------------
 // MsgStoreHandler::isDraftMessage
 // @see header
 //----------------------------------------------------------------------------
 bool MsgStoreHandler::isDraftMessage(int msgId)
-{       
-    bool draftmsg = false;
+{
+    return (KMsvDraftEntryIdValue == MessageLocation(msgId));
+}
+
+//----------------------------------------------------------------------------
+// MsgStoreHandler::locked
+// @see header
+//----------------------------------------------------------------------------
+bool MsgStoreHandler::locked(int msgId)
+{
+    bool msglocked = false;
+    CMsvEntry* cEntry = NULL;
+    TRAPD(err, cEntry = iMsvSession->GetEntryL(msgId));
+    if(err != KErrNone)
+    {
+        // error in getting the entry e.g. already deleted message
+        msglocked = true;
+    }
+    else
+    {
+        // Outbox messages are locked and hence cann't be viewed.
+        // However, make an exception for failed messages.
+        TMsvEntry entry = cEntry->Entry();
+        if( (KMsvGlobalOutBoxIndexEntryIdValue == entry.Parent()) && 
+            (KMsvSendStateFailed != entry.SendingState()) )
+        {
+            msglocked = true;
+        }
+    }
+    delete cEntry;
+    return msglocked;
+}
+
+//----------------------------------------------------------------------------
+// MsgStoreHandler::exists
+// @see header
+//----------------------------------------------------------------------------
+bool MsgStoreHandler::exists(int msgId)
+{
+    bool msgexists = true;
     CMsvEntry* cEntry = NULL;
     TRAPD(err, cEntry = iMsvSession->GetEntryL(msgId));
-    if ( err == KErrNone)
+    if(err != KErrNone)
+    {
+        // error in getting the entry e.g. already deleted message
+        msgexists = false;
+    }
+    delete cEntry;
+    return msgexists;
+}
+
+//----------------------------------------------------------------------------
+// MsgStoreHandler::setNotificationMessageId
+// @see header
+//----------------------------------------------------------------------------
+int MsgStoreHandler::setNotificationMessageId(int msgId)
+{
+    TRAPD(err, SetNotificationMessageIdL(msgId));
+    return err;
+}
+
+//----------------------------------------------------------------------------
+// MsgStoreHandler::SetNotificationMessageIdL
+// @see header
+//----------------------------------------------------------------------------
+void MsgStoreHandler::SetNotificationMessageIdL( TMsvId aMsgId )
+{
+    // get MMS Notification client mtm & set the content to current entry
+    if(iNotificationClient)
+    {
+        delete iNotificationClient;
+        iNotificationClient = NULL;
+    }
+    iNotificationClient = static_cast<CMmsNotificationClientMtm*>( 
+                    iMtmReg->NewMtmL( KUidMsgMMSNotification ));
+    iNotificationClient->SwitchCurrentEntryL(aMsgId);
+    iNotificationClient->LoadMessageL();
+}
+
+//----------------------------------------------------------------------------
+// MsgStoreHandler::MaxReceiveSizeLimitL
+// @see header
+//----------------------------------------------------------------------------
+TInt MsgStoreHandler::MaxReceiveSizeLimitL()
+{
+    CMmsSettings* settings = CMmsSettings::NewL();
+    CleanupStack::PushL( settings );
+    iNotificationClient->RestoreSettingsL();
+    settings->CopyL( iNotificationClient->MmsSettings() );
+    TInt maxSize = static_cast<TInt>(settings->MaximumReceiveSize() );
+    CleanupStack::PopAndDestroy( settings );
+    return maxSize;
+}
+
+// ---------------------------------------------------------
+// MsgStoreHandler::MmsNotificationStatus
+// @see header
+// ---------------------------------------------------------
+TCsMmsNotificationMsgState 
+MsgStoreHandler::MmsNotificationStatus( TInt aMsvId )
+{
+    TMsvId dummy = 0x0;
+
+    TMsvEntry entry;
+    iMsvSession->GetEntry(aMsvId, dummy, entry);
+
+    TCsMmsNotificationMsgState status = EMsgStatusNull;
+
+    TTime currentTime;
+    currentTime.HomeTime( );
+    TTime expiryTime = iNotificationClient->ExpiryDate( );
+    TLocale locale;
+    expiryTime += locale.UniversalTimeOffset();
+    if (locale.QueryHomeHasDaylightSavingOn())          
     {
-        TMsvEntry msvEntry = cEntry->Entry();
-        TMsvId parent = msvEntry.Parent();
-        if(parent == KMsvDraftEntryIdValue)
+        TTimeIntervalHours daylightSaving(1);          
+        expiryTime += daylightSaving;
+    }
+
+    // operationMask includes operation type. It is not bitmap but ordinal number. 
+    // It does not include operation status and result
+    TInt operationMask = (entry.iMtmData2 & KMmsOperationIdentifier) ;
+
+    // Note! Ongoing operation resets every bit of operation type, operation status
+    // and result. E.g. If message has been forwarded and then fetching starts, 
+    // information about forwarding is lost
+
+    if( ( entry.iMtmData1 & KMmsMessageTypeMask ) == KMmsMessageMNotificationInd )
         {
-            draftmsg = true;  
+        if(     operationMask == KMmsOperationFetch 
+                &&  OperationOngoing( entry ) )
+            { 
+            // It's in retrieving state
+            status = EMsgStatusRetrieving;
+            }
+        else if(    operationMask == KMmsOperationForward
+                &&  OperationOngoing( entry ) )
+            { 
+            // It's in forwarding state
+            status = EMsgStatusForwarding;
+            }
+        else if(    operationMask == KMmsOperationForward
+                &&  OperationFinished( entry )
+                &&  !( entry.iMtmData2 & KMmsOperationResult ) )
+            { 
+            // It's been forwarded succesfully
+            status = EMsgStatusForwarded;
+            }
+        else if(    operationMask == KMmsOperationFetch 
+                &&  OperationFinished( entry )
+                &&   (  entry.iMtmData2 & KMmsOperationResult 
+                ||  entry.iError ) )
+            { 
+            // Fetch has been failed
+            status = EMsgStatusFailed;
+            }
+        else if(    operationMask == KMmsOperationDelete
+                &&  OperationFinished( entry )
+                &&  !( entry.iMtmData2 & KMmsOperationResult ) )
+            { 
+            // It's been deleted succesfully
+            status = EMsgStatusDeleted;
+            }
+        else if( currentTime > expiryTime )
+            {
+            status = EMsgStatusExpired;
+            }
+        else 
+            {   // Normal waiting state
+            status = EMsgStatusReadyForFetching;
+            }
+        }
+
+    return status;
+}
+
+// ---------------------------------------------------------
+// MsgStoreHandler::OperationOngoing
+// @see header
+// ---------------------------------------------------------
+TBool MsgStoreHandler::OperationOngoing( 
+        const TMsvEntry& aEntry ) const
+    {
+    return (    aEntry.iMtmData2 & KMmsOperationOngoing 
+            &&  !( aEntry.iMtmData2 & KMmsOperationFinished ) );
+    }
+
+// ---------------------------------------------------------
+// MsgStoreHandler::OperationFinished
+// @see header
+// ---------------------------------------------------------
+TBool MsgStoreHandler::OperationFinished( 
+    const TMsvEntry& aEntry ) const
+    {
+    return (    aEntry.iMtmData2 & KMmsOperationFinished
+            &&  !( aEntry.iMtmData2 & KMmsOperationOngoing ) );
+    }
+
+//---------------------------------------------------------------
+// MsgStoreHandler::notificationSubject
+// @see header
+//---------------------------------------------------------------
+QString MsgStoreHandler::notificationSubject()
+{
+    QString subject;
+    if(iNotificationClient)
+    {
+        TPtrC sub =  iNotificationClient->SubjectL();
+        subject = XQConversions::s60DescToQString(sub);
+    }
+    return subject;
+}
+//---------------------------------------------------------------
+// MsgStoreHandler::notificationMsgSize
+// @see header
+//---------------------------------------------------------------
+QString MsgStoreHandler::notificationMsgSize()
+{
+    // Null check
+    if(!iNotificationClient)
+    {
+        return LOC_MESSAGE_SIZE.arg(0);
+    }
+
+    // Size of message.
+    TInt size = iNotificationClient->MessageTransferSize();
+
+    // read max receive size limit from settings
+    TInt maxSize = 0;
+    TRAP_IGNORE(maxSize = MaxReceiveSizeLimitL());
+
+    // apply max size limit rule
+    if( maxSize > 0 )
+    {
+        if( size > maxSize )
+        {
+            size = maxSize;
         }
     }
 
-    delete cEntry;
-    return draftmsg;
+    TInt fileSize = size / BYTES_TO_KBYTES_FACTOR;
+    if ( size % BYTES_TO_KBYTES_FACTOR )
+    {
+        fileSize++;
+    }
+
+    return LOC_MESSAGE_SIZE.arg(fileSize);
+}
+
+//---------------------------------------------------------------
+// MsgStoreHandler::notificationClass
+// @see header
+//---------------------------------------------------------------
+QString MsgStoreHandler::notificationClass()
+{
+    QString notificationClass;
+    // Null Check
+    if(!iNotificationClient)
+    {
+        return notificationClass;
+    }
+
+    TInt msgClass = iNotificationClient->MessageClass( );
+    switch( msgClass )
+    {
+        case EMmsClassPersonal:
+        {
+            notificationClass = LOC_CLASS_PERSONAL;
+            break;
+        }
+        case EMmsClassAdvertisement:
+        {
+            notificationClass = LOC_CLASS_ADVERTISEMENT;
+            break;
+        }
+        case EMmsClassInformational:
+        {
+            notificationClass = LOC_CLASS_INFORMATIONAL;
+            break;
+        }
+        default:
+        {   // In case no class is returned (0), don't add the field
+            break;
+        }
+    }
+    return notificationClass;
 }
+
+//---------------------------------------------------------------
+// MsgStoreHandler::notificationStatus
+// @see header
+//---------------------------------------------------------------
+void MsgStoreHandler::notificationStatus(
+        int& status,
+        QString& statusStr)
+{
+    // Null Check
+    if(!iNotificationClient)
+    {
+        return;
+    }
+
+    // fetch mms notification status from store handler
+    // and map as per our UI requirements
+    TMsvEntry entry = iNotificationClient->Entry().Entry();
+    status = MmsNotificationStatus(entry.Id());
+    switch(status)
+    {
+        case ConvergedMessage::NotifFailed:
+        {
+            statusStr = LOC_MMS_RETRIEVAL_FAILED;
+            break;
+        }
+        case ConvergedMessage::NotifExpired:
+        {
+            statusStr = LOC_MMS_NOTIF_EXPIRED;
+            break;
+        }
+        case ConvergedMessage::NotifReadyForFetching:
+        {
+            statusStr = LOC_MMS_WAITING;
+            break;
+        }
+        case ConvergedMessage::NotifWaiting:
+        case ConvergedMessage::NotifRetrieving:
+        {
+            statusStr = LOC_MMS_RETRIEVING;
+            break;
+        }
+        default:
+        {
+            // not handled, do nothing
+            break;
+        }
+    }
+}
+
+//---------------------------------------------------------------
+// MsgStoreHandler::notificationExpiryDate
+// @see header
+//---------------------------------------------------------------
+QString MsgStoreHandler::notificationExpiryDate()
+{
+    // Null Check
+    if(!iNotificationClient)
+    {
+        return QString();
+    }
+
+    // get expiry time from entry
+    TTime expiryTime = iNotificationClient->ExpiryDate( );
+    TLocale locale;
+    expiryTime += locale.UniversalTimeOffset();
+    if (locale.QueryHomeHasDaylightSavingOn())          
+    {
+        TTimeIntervalHours daylightSaving(1);          
+        expiryTime += daylightSaving;
+    }
+    
+    // create formatted string for the expiry time
+    TTime unixEpoch(KUnixEpoch);
+    TTimeIntervalSeconds seconds;
+    expiryTime.SecondsFrom(unixEpoch, seconds);
+    return LOC_MMS_EXPIRY_DATE.arg(seconds.Int());
+}
+
 // End of file