mobilemessaging/mmsui/mtmsrc/MMSMTMLogData.cpp
changeset 0 72b543305e3a
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mobilemessaging/mmsui/mtmsrc/MMSMTMLogData.cpp	Thu Dec 17 08:44:11 2009 +0200
@@ -0,0 +1,474 @@
+/*
+* Copyright (c) 2005 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  
+*       Provides methods for retrieving the log db data.
+*
+*/
+
+
+
+
+// INCLUDE FILES
+#include "MMSMTMLogData.h"
+#include "CMsgDeliveryItem.h"
+#include <logview.h>
+#ifndef SYMBIAN_ENABLE_SPLIT_HEADERS
+#include <logwrap.h>        // KLogMaxRemotePartyLength
+#else
+#include <logwrap.h>        // klogmaxremotepartylength
+#include <logwraplimits.h>        // klogmaxremotepartylength
+#include <logengdurations.h>
+#endif
+#include <mmsclient.h>
+#include <mmsgenutils.h>
+#include <cntdb.h>
+#include <LogsApiConsts.h>  // klogsmsgreadtext
+
+// CONSTANTS
+
+// MACROS
+
+// LOCAL CONSTANTS AND MACROS
+
+// MODULE DATA STRUCTURES
+
+// LOCAL FUNCTION PROTOTYPES
+
+// ==================== LOCAL FUNCTIONS ====================
+
+
+// ================= MEMBER FUNCTIONS =======================
+
+
+// -----------------------------------------------------------------------------
+// CMmsMTMLogData::CMmsMTMLogData
+// C++ default constructor can NOT contain any code, that
+// might leave.
+// -----------------------------------------------------------------------------
+//
+CMmsMTMLogData::CMmsMTMLogData() : CActive( EPriorityStandard )
+    {
+    iEventStatusRead.Copy( KLogsMsgReadText );
+    CActiveScheduler::Add( this );
+    }
+
+// -----------------------------------------------------------------------------
+// CMmsMTMLogData::ConstructL
+// Symbian 2nd phase constructor can leave.
+// -----------------------------------------------------------------------------
+//
+void CMmsMTMLogData::ConstructL(MMmsMtmDeliveryDataContainer* aContainer, const TMmsMsvEntry& aEntry )
+    {
+    iFs = new (ELeave) RFs;
+    User::LeaveIfError( iFs->Connect() );
+
+    iLogClient = CLogClient::NewL( *iFs );
+    iEventView = CLogViewEvent::NewL( *iLogClient);
+    iFilterList = new ( ELeave ) CLogFilterList;
+    iParent = aContainer;
+    iLoopCounter = 0;
+    iEntry = aEntry;
+    iState = ENone;
+    iDataArray = new(ELeave) CArrayPtrFlat<CMsgDeliveryItem>(64); 
+    iLogClient->GetString( iEventStatusPendingTxt, R_LOG_DEL_PENDING );
+    iLogClient->GetString( iEventStatusSentTxt, R_LOG_DEL_SENT );
+    iLogClient->GetString( iEventStatusFailedTxt, R_LOG_DEL_FAILED );
+    iLogClient->GetString( iEventStatusNoDeliveryTxt, R_LOG_DEL_NONE );
+    iLogClient->GetString( iEventStatusDeliveredTxt, R_LOG_DEL_DONE );
+    iLogClient->GetString( iEventStatusNotSentTxt, R_LOG_DEL_NOT_SENT );
+    // See read status creation in construction
+    }
+
+// -----------------------------------------------------------------------------
+// CMmsMTMLogData::CMmsMTMLogData
+// Destructor
+// -----------------------------------------------------------------------------
+// 
+CMmsMTMLogData::~CMmsMTMLogData()
+    {
+    Cancel();
+
+    if( iFilterList )
+        {
+        iFilterList->ResetAndDestroy();
+        delete iFilterList;
+        iFilterList = NULL;
+        }
+    if (iEventView)
+        {
+        delete iEventView; 
+        iEventView = NULL;
+        }
+    if (iLogClient)
+        {
+        delete iLogClient;
+        iLogClient = NULL;
+        }
+
+    if (iFs)
+        {
+        iFs->Close();
+        delete iFs;
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CMmsMTMLogData::NewL
+// Two-phased constructor.
+// -----------------------------------------------------------------------------
+//
+CMmsMTMLogData* CMmsMTMLogData::NewL(MMmsMtmDeliveryDataContainer* aContainer, const TMmsMsvEntry& aEntry )
+    {
+    CMmsMTMLogData* self = new( ELeave ) CMmsMTMLogData( );
+
+    CleanupStack::PushL( self );
+    self->ConstructL(aContainer, aEntry);
+    CleanupStack::Pop();
+
+    return self;
+    }
+
+// ---------------------------------------------------------
+// CMmsMTMLogData::DeliveryDataL
+// Creates the necessary Log filters and starts the log db query.
+// ---------------------------------------------------------
+//
+TBool CMmsMTMLogData::DeliveryDataL(const CMmsClientMtm* aMmsClient)
+    {
+    // Check for NULL. If NULL, return false (= no data found)
+    if (!aMmsClient)
+        {
+        return EFalse;
+        }
+        
+    MtmRecipientsToArrayL( *aMmsClient );
+        
+    iState = EInit;
+    const CMsvRecipientList& recipients = aMmsClient->AddresseeList();
+    TInt recipientCount = recipients.Count();
+
+    Cancel(); 
+
+    TTime sendingDate = aMmsClient->SendingDate();
+    for (TInt i = 0; i < recipientCount ; i++)
+        {
+        TPtrC number = TMmsGenUtils::PureAddress( recipients[i] );
+
+        CLogFilter* filter = CLogFilter::NewL();
+        CleanupStack::PushL( filter );
+
+        filter->SetEventType(KLogMmsEventTypeUid);
+        filter->SetStartTime(sendingDate);
+        filter->SetDurationType(KLogDurationNone);
+        if ( TMmsGenUtils::IsValidMMSPhoneAddress( number, ETrue ) )
+            {
+            filter->SetNumber( number.Left( Min( number.Length(), KLogMaxRemotePartyLength ) ) );
+            }
+        else
+            {
+            filter->SetRemoteParty( number.Left( Min( number.Length(), KLogMaxRemotePartyLength ) ) );
+            }
+
+        iFilterList->AppendL(filter);		
+        CleanupStack::Pop( filter );
+        }
+
+    //Using SetFilterParseFilterByFilterL as it works for combination of RemoteParty and Number
+    if ( !iEventView->SetFilterParseFilterByFilterL( *iFilterList, iStatus ) ) // something found with these filters, start the active object
+        {
+        iState = EFinalize;
+        iStatus = KRequestPending;
+        TRequestStatus* pStatus = &iStatus;
+        User::RequestComplete( pStatus, KErrNone );
+        }
+    SetActive();
+    return ETrue;
+
+    }
+
+// ---------------------------------------------------------
+// CMmsMTMLogData::DoCancel
+// Cancels the active object, from CActive
+// ---------------------------------------------------------
+//  
+void CMmsMTMLogData::DoCancel()
+    {      
+    iLogClient->Cancel();
+    iEventView->Cancel();
+    }
+
+// ---------------------------------------------------------
+// CMmsMTMLogData::RunL
+// From CActive
+// ---------------------------------------------------------
+//  
+void CMmsMTMLogData::RunL()
+    {
+    Cancel();
+    if (iStatus == KErrNone)
+        {
+        if (iState == EInit) // init phase finished
+            {
+            FetchItemL();
+            }
+        else if (iState == EReading) // reading ongoing
+            {
+            CopyItemL();
+            }
+        else if (iState == EFinalize) // reading ongoing
+            {
+            SendDataL();
+            }
+        }
+
+    if (iState != EFinished)
+        {
+        SetActive();
+        }
+    }
+
+// ---------------------------------------------------------
+// CMmsMTMLogData::RunError
+// Handles the error, if necessary. From CActive
+// ---------------------------------------------------------
+//  
+ TInt CMmsMTMLogData::RunError(TInt aError)
+    {
+    return aError;
+    }
+  
+ // ---------------------------------------------------------
+// CMmsMTMLogData::SendData
+// Callback method. After finished with filling the data array,
+// sends it back to the MMmsMtmDeliveryDataContainer (implemented in laucher class)
+// ---------------------------------------------------------
+//  
+ void CMmsMTMLogData::SendDataL()
+    {
+    iState = EFinished;
+    iDataArray->Compress();
+    iParent->SetDataArrayL(iDataArray);
+    }
+
+ // ---------------------------------------------------------
+// CMmsMTMLogData::AddToArray
+// Converts the CLogEvent to CMsgDeliveryItem and adds it to the data array
+// ---------------------------------------------------------
+//  
+void CMmsMTMLogData::AddToArrayL(CLogEvent* aEvent)
+    {
+    // Check for NULL. If null, exit
+    if (!aEvent)
+    {
+        return;
+    }
+    // copy the data from the CLogEvent to CMsgDeliveryItem,
+    // which will eventually be stored into the array
+    CMsgDeliveryItem* item = CMsgDeliveryItem::NewL();
+    CleanupStack::PushL( item );
+    
+    item->SetNumberL(aEvent->Number());
+    item->SetRecipientL(aEvent->RemoteParty());
+    item->SetTime(aEvent->Time());
+
+    if (aEvent->Status().Compare(iEventStatusPendingTxt) == 0) // msg item only supports three statuses, so theres some mapping to do.
+        {
+        item->SetStatus(CMsgDeliveryItem::EPending);
+        }
+    else if (aEvent->Status().CompareF(iEventStatusSentTxt) == 0)
+        {
+        item->SetStatus(CMsgDeliveryItem::EPending);
+        }
+    else if (aEvent->Status().CompareF(iEventStatusFailedTxt) == 0)
+        {
+        item->SetStatus(CMsgDeliveryItem::EFailed);
+        }
+    else if (aEvent->Status().CompareF(iEventStatusNoDeliveryTxt) == 0)
+        {
+        item->SetStatus(CMsgDeliveryItem::EFailed);
+        }
+    else if (aEvent->Status().CompareF(iEventStatusDeliveredTxt) == 0)
+        {
+        item->SetStatus(CMsgDeliveryItem::EDelivered);
+        }
+    else if (aEvent->Status().CompareF(iEventStatusRead) == 0)
+        {
+        item->SetStatus(CMsgDeliveryItem::ERead);
+        }
+    else if (aEvent->Status().CompareF(iEventStatusNotSentTxt) == 0)
+        {
+        item->SetStatus(CMsgDeliveryItem::EFailed);
+        }
+    else 
+        {
+        item->SetStatus(CMsgDeliveryItem::ENone);
+        }
+
+    iDataArray->InsertL( iInsertedCount, item, 1 ); // add the item to the array
+    iInsertedCount++;
+    TPtrC recip = aEvent->RemoteParty();
+    DeleteRecipent( recip, EFalse, iInsertedCount ); 
+    CleanupStack::Pop( item );
+    }
+
+ // ---------------------------------------------------------
+// CMmsMTMLogData::FetchItem
+// Starts to fetch the next CLogEvent from the CLogViewEvent
+// ---------------------------------------------------------
+//
+void CMmsMTMLogData::FetchItemL()
+    {
+    iState = EReading;
+    if (iLoopCounter == 0) // the first one needs(?) to be fecthed differently
+        {
+        iEventView->FirstL(iStatus);
+        }
+    else 
+        {
+        iEventView->NextL(iStatus);				
+        }
+    }
+ // ---------------------------------------------------------
+// CMmsMTMLogData::CopyItem
+// Copies the next CLogEvent from the CLogViewEvent
+// ---------------------------------------------------------
+//  
+void CMmsMTMLogData::CopyItemL()	
+    {
+    CLogEvent* event = CLogEvent::NewL();
+    CleanupStack::PushL(event);
+    event->CopyL(iEventView->Event());
+    iLoopCounter++;
+
+    TLogLink event_id = event->Link(); 
+    TMsvId message_id = iEntry.Id();
+
+    if (event_id ==  message_id) // check the message id from the event
+        {
+        AddToArrayL(event);
+        }
+
+    CleanupStack::PopAndDestroy(event);
+
+    if (iLoopCounter >= iEventView->CountL())  // all the log events are now handled
+        {
+        iState = EFinalize;
+        iStatus = KRequestPending;
+        TRequestStatus* pStatus = &iStatus;
+        User::RequestComplete( pStatus, KErrNone );
+        } 
+
+    else  // still some log events left, continue fetching them one by one
+        {
+        FetchItemL(); 
+        }
+    }
+
+// ---------------------------------------------------------
+// CMmsMTMLogData::MtmRecipientsToArrayL
+// CLogViewEvent::SetFilterL() didn't start async operation.
+// Just copy recipients into 'destination'.
+// Calling this function means showing 'unavailable' status 
+// ---------------------------------------------------------
+//  
+void CMmsMTMLogData::MtmRecipientsToArrayL( const CMmsClientMtm& aMmsClient )
+    {
+    const CMsvRecipientList& recipients = aMmsClient.AddresseeList();
+    TInt recipientCount = recipients.Count();
+
+    TTime sendingDate = aMmsClient.SendingDate();
+    
+    HBufC* aliasBuf = HBufC::NewLC( KLogMaxRemotePartyLength );
+    TPtr aliasPtr = aliasBuf->Des();
+    
+    for (TInt i = 0; i < recipientCount ; i++)
+        {        
+        TPtrC recip = TMmsGenUtils::PureAddress( recipients[i] );
+        TBool isNumber = TMmsGenUtils::IsValidMMSPhoneAddress( recip, ETrue );
+
+        CMsgDeliveryItem* item = CMsgDeliveryItem::NewL();
+        CleanupStack::PushL( item );
+        
+        item->SetStatus( CMsgDeliveryItem::ENone );
+        item->SetTime( sendingDate );
+
+        if ( isNumber )
+            {
+            item->SetNumberL( recip );
+            item->SetRecipientL( recip );
+            
+            // get alias too
+            TInt error = TMmsGenUtils::GetAlias( 
+                recip,
+                aliasPtr,
+                KLogMaxRemotePartyLength,
+                *iFs );
+            if ( error == KErrNone && aliasPtr.Length() > 0 )
+                {            
+                item->SetRecipientL( aliasPtr );
+                aliasPtr.Zero();
+                }
+            else
+                {
+                // recipient must be there
+                }
+            }
+        else
+            {
+            item->SetRecipientL( recip );
+            }
+        
+        iDataArray->AppendL(item); // add the item to the array
+        CleanupStack::Pop( item );
+        }
+    CleanupStack::PopAndDestroy( aliasBuf );
+    }
+    
+    
+// ---------------------------------------------------------
+// CMmsMTMLogData::DeleteRecipent
+// Checks whether given recipient is already in the iDataArray
+// ---------------------------------------------------------
+//  
+void CMmsMTMLogData::DeleteRecipent(    TDesC&  aRecipient,
+                                        TBool   aType,
+                                        TInt    aInitialIndex )
+    {
+    TInt count = iDataArray->Count( );
+    for( TInt i = aInitialIndex; i < count ; i++ )
+        {
+        CMsgDeliveryItem* item = iDataArray->At(i);
+        if ( item )
+            {
+            TPtrC recip;
+            if ( aType )
+                {
+                recip.Set( item->GetNumber() );
+                }
+            else
+                {
+                recip.Set( item->GetRecipient() );
+                }
+            if ( !recip.CompareF( aRecipient ) )
+                {
+                delete item;
+                iDataArray->Delete( i );
+                break;
+                }
+            }
+        }
+    }                                       
+
+
+