/*
* Copyright (c) 2002-2006 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:
* A Client MTM to access MMS notifications in a manual fetch mode.
* All this is needed to support new mtm type for Symbian OS messaging
* UI components.
*
*/
// INCLUDE FILES
#include <msvids.h>
#include "mmsheaders.h"
#include "mmsnotificationclient.h"
#include "mmscmds.h"
#include "mmsmessageoperation.h"
#include "mmsmmboxviewheaders.h"
#include "mmssettings.h"
// EXTERNAL DATA STRUCTURES
// EXTERNAL FUNCTION PROTOTYPES
// CONSTANTS
// MACROS
// LOCAL CONSTANTS AND MACROS
const TInt KMmsAttributeArrayGranularity = 8;
// MODULE DATA STRUCTURES
// LOCAL FUNCTION PROTOTYPES
// ==================== LOCAL FUNCTIONS ====================
// ================= MEMBER FUNCTIONS =======================
// ---------------------------------------------------------
// CMmsClientNotificationMtm::NewL
// ---------------------------------------------------------
//
EXPORT_C CMmsNotificationClientMtm* CMmsNotificationClientMtm::NewL(
CRegisteredMtmDll& aRegisteredMtmDll,
CMsvSession& aSession )
{
CMmsNotificationClientMtm* self = new ( ELeave ) CMmsNotificationClientMtm(
aRegisteredMtmDll, aSession );
CleanupStack::PushL( self );
self->ConstructL();
CleanupStack::Pop( self );
return self;
}
// ---------------------------------------------------------
// CMmsClientNotificationMtm::CMmsNotificationClientMtm
// ---------------------------------------------------------
//
CMmsNotificationClientMtm::CMmsNotificationClientMtm(
CRegisteredMtmDll& aRegisteredMtmDll,
CMsvSession& aSession )
: CMmsClientMtm( aRegisteredMtmDll, aSession )
{
__ASSERT_DEBUG( Type() == KUidMsgMMSNotification, gPanic( EMmsBadMtmTypeUid ) );
}
// ---------------------------------------------------------
// CMmsClientNotificationMtm::~CMmsNotificationClientMtm
// ---------------------------------------------------------
//
CMmsNotificationClientMtm::~CMmsNotificationClientMtm()
{
}
// ---------------------------------------------------------
// CMmsClientNotificationMtm::ConstructL
//
// ---------------------------------------------------------
//
void CMmsNotificationClientMtm::ConstructL()
{
// First loading settings
iMmsSettings = CMmsSettings::NewL();
iMmsSettings->LoadSettingsL();
// Get the base values to detect changes
iHomeMode = iMmsSettings->ReceivingModeHome();
iRoamingMode = iMmsSettings->ReceivingModeForeign();
iAccessPointCount = iMmsSettings->AccessPointCount();
iMessageDrive = EDriveC;
TInt error = KErrNone;
TRAP ( error, { iMessageDrive = Session().CurrentDriveL(); } );
if ( error != KErrNone )
{
// if cannot ask, use default
iMessageDrive = EDriveC;
}
// Notification client mtm does not create new service
iServiceId = iMmsSettings->Service();
iMmsHeaders = CMmsHeaders::NewL( iMmsSettings->MmsVersion() );
iAttributes = new( ELeave ) CDesCArrayFlat( KMmsAttributeArrayGranularity );
// Set the original context to the service entry
SwitchCurrentEntryL( iServiceId );
}
// ---------------------------------------------------------
// CMmsClientMtm::QueryCapability
// ---------------------------------------------------------
//
TInt CMmsNotificationClientMtm::QueryCapability(
TUid /*aCapability*/,
TInt& /*aResponse*/ )
{
// Nothing Supported at the moment
return KErrNotSupported;
}
// ---------------------------------------------------------
// CMmsNotificationClientMtm::ForwardL
// ---------------------------------------------------------
//
CMsvOperation* CMmsNotificationClientMtm::ForwardL(
TMsvId aDestination,
TMsvPartList /*aPartList*/,
TRequestStatus& aCompletionStatus )
{
//
// Actual creation is done synchronously below
//
TMsvId id = CreateForwardEntryL( aDestination );
//
// This method has to be asynchronous..
//
TPckgC < TMsvId > progress = id;
return CMsvCompletedOperation::NewL( Session(), Type(), progress,
KMsvLocalServiceIndexEntryId, aCompletionStatus );
}
// ---------------------------------------------------------
// CMmsClientNotificationMtm::CreateForwardEntryL
// ---------------------------------------------------------
//
TMsvId CMmsNotificationClientMtm::CreateForwardEntryL( TMsvId aDestination )
{
//
// Check that current context is valid
//
if( iMsvEntry->Entry().iType != KUidMsvMessageEntry
|| iMsvEntry->Entry().iMtm != KUidMsgMMSNotification )
{
User::Leave( KErrUnknown );
}
// It is assumed that a created forward entry can not be saved to drafts.
// I.e. the application calling this, is responsible to take care that
// the entry is either SENT or DESTROYED.
//
// Load entry to local cache if necessary
//
if( iMmsHeaders->ContentLocation() == TPtrC8() )
{
LoadMessageL();
}
//
// Create new Mms message object into aDestination folder
//
TMsvId forwardId = CMmsMessageOperation::CreateForwardWithoutRetrievalL(
Session(),
*iMmsHeaders,
iMsvEntry->EntryId(),
aDestination,
iServiceId );
return forwardId;
}
// ---------------------------------------------------------
// CMmsClientNotificationMtm::SendL
// ---------------------------------------------------------
//
CMsvOperation* CMmsNotificationClientMtm::SendL(
TRequestStatus& aCompletionStatus,
const TTime aSendingTime )
{
//
// Is it possible to proceed with the operation...
// If yes, the notification is marked as "further-operations-not-allowed"
//
TMsvId relatedNotificationId = iMmsHeaders->RelatedEntry();
TInt retval = ReserveNotificationOperationL( relatedNotificationId, KMmsOperationForward );
if( retval != KErrNone )
{
TPckgC < TMsvId > progress = relatedNotificationId;
return CMsvCompletedOperation::NewL(
Session(),
KUidMsgMMSNotification,
progress, // progress contains the related entry id
iServiceId,
aCompletionStatus,
KErrInUse);
}
//
// Create the selection to be sent
//
CMsvEntrySelection* selection = new( ELeave ) CMsvEntrySelection;
CleanupStack::PushL( selection ); // ***
selection->AppendL( iMsvEntry->Entry().Id() );
//
// Make sure the message is in OUTBOX
//
TMsvId currentParent = iMsvEntry->Entry().Parent();
if ( currentParent != KMsvGlobalOutBoxIndexEntryId )
{
CMsvEntry* cEntry = NULL;
cEntry = Session().GetEntryL( currentParent );
CleanupStack::PushL( cEntry );
cEntry->MoveL( iMsvEntry->Entry().Id(), KMsvGlobalOutBoxIndexEntryId );
CleanupStack::PopAndDestroy( cEntry );
}
//
// Create parameters structure
//
TCommandParameters parameters;
TTime now;
now.UniversalTime();
if ( aSendingTime > now )
{
aSendingTime.SecondsFrom( now, parameters.iInitialDelay );
}
TCommandParametersBuf paramPack( parameters );
//
// Call Server MTM
//
CMsvOperation* op = InvokeAsyncFunctionL(
EMmsScheduledForward,
*selection,
paramPack,
aCompletionStatus );
//
// Cleanup and return
//
CleanupStack::PopAndDestroy( selection );
return op;
}
// ---------------------------------------------------------
// CMmsClientNotificationMtm::SendL
// ---------------------------------------------------------
//
CMsvOperation* CMmsNotificationClientMtm::SendL(
CMsvEntrySelection& /*aSelection*/,
TRequestStatus& /*aCompletionStatus*/,
TTime /*aSendingTime*/ )
{
User::Leave( KErrNotSupported );
return NULL; // makes the compiler happy
}
// ---------------------------------------------------------
// CMmsClientNotificationMtm::ReserveNotificationOperationL
// ---------------------------------------------------------
//
TInt CMmsNotificationClientMtm::ReserveNotificationOperationL(
TMsvId aNotifId,
const TUint32 aOperation )
{
//
// Get hands on index entry based on entryId
//
CMsvEntry* cEntry = NULL;
cEntry = Session().GetEntryL( aNotifId );
CleanupStack::PushL( cEntry ); // ***
TMsvEntry tEntry = cEntry->Entry();
//
// Check that entry is a notification
//
if( cEntry->Entry().iType != KUidMsvMessageEntry
|| cEntry->Entry().iMtm != KUidMsgMMSNotification )
{
CleanupStack::PopAndDestroy( cEntry );
return KErrNotSupported;
}
//
// Make some checks concerning the current status of notification and
// return with error if reservation is not possible
//
// if operation is forbidden OR
// if ( (the aOperation is fetch or forward) and notification is deleted successfully from mmbox)
if( tEntry.iMtmData2 & KMmsNewOperationForbidden ||
( ( aOperation == KMmsOperationFetch || aOperation == KMmsOperationForward ) &&
tEntry.iMtmData2 & KMmsOperationFinished &&
! ( tEntry.iMtmData2 & KMmsOperationResult ) &&
! ( tEntry.iMtmData2 & KMmsStoredInMMBox ) &&
tEntry.iMtmData2 & KMmsOperationDelete ) )
{
CleanupStack::PopAndDestroy( cEntry );
return KErrInUse;
}
//
// Set the flags
//
// reserve the operation
MarkNotificationOperationReserved( tEntry, aOperation );
tEntry.SetReadOnly( EFalse );
//
// Save the entry
//
cEntry->ChangeL( tEntry );
CleanupStack::PopAndDestroy( cEntry );
return KErrNone;
}
// ---------------------------------------------------------
// CMmsNotificationClientMtm::MarkFreeNotificationsReservedL
// ---------------------------------------------------------
//
void CMmsNotificationClientMtm::MarkFreeNotificationsReservedL(
CMsvEntrySelection& aNotifications, const TUint32 aOperation )
{
TInt count = aNotifications.Count();
if ( count == 0 )
{
return;
}
CMsvEntry* clientEntry = Session().GetEntryL( aNotifications.At( 0 ));
CleanupStack::PushL( clientEntry );
for ( TInt i = aNotifications.Count() - 1 ; i >= 0 ; i-- )
{
TBool drop = EFalse;
TBool alreadyMarked = EFalse;
clientEntry->SetEntryL( aNotifications.At( i ) );
TMsvEntry entry = clientEntry->Entry();
TMsvId duplicate = KMsvNullIndexEntryId;
if ( FreeNotification( entry, aOperation ) )
{
// Check possible duplicate, if mmbox folder even exists
TMsvId mmboxFolder = iMmsSettings->MMBoxFolder();
if ( mmboxFolder != KMsvNullIndexEntryId )
{
TMsvId parent = entry.Parent();
CMmsHeaders* mmsHeaders = CMmsHeaders::NewL( iMmsSettings->MmsVersion() );
CleanupStack::PushL( mmsHeaders );
CMsvStore* store = clientEntry->ReadStoreL();
CleanupStack::PushL( store );
mmsHeaders->RestoreL( *store );
CleanupStack::PopAndDestroy( store );
store = NULL;
if ( parent == KMsvGlobalInBoxIndexEntryId )
{
FindDuplicateNotificationL( mmboxFolder,
*mmsHeaders, duplicate );
}
else if ( parent == mmboxFolder )
{
FindDuplicateNotificationL( KMsvGlobalInBoxIndexEntryId,
*mmsHeaders, duplicate );
}
else
{
// keep LINT happy
}
if ( duplicate != KMsvNullIndexEntryId )
{
// check if duplicate is free for a operation
clientEntry->SetEntryL( duplicate );
TMsvEntry dupEntry = clientEntry->Entry();
if ( FreeNotification( dupEntry, aOperation ))
{
// if original notification is in mmbox folder
// mark the duplicate reserved too.
if ( parent == mmboxFolder )
{
MarkNotificationOperationReserved( dupEntry, aOperation );
clientEntry->ChangeL( dupEntry );
clientEntry->SetEntryL( aNotifications.At( i ) );
entry = clientEntry->Entry();
MarkNotificationOperationReserved( entry, aOperation );
entry.SetReadOnly( EFalse );
clientEntry->ChangeL( entry );
alreadyMarked = ETrue;
store = clientEntry->EditStoreL();
CleanupStack::PushL( store );
mmsHeaders->RestoreL( *store );
mmsHeaders->SetRelatedEntry( duplicate );
mmsHeaders->StoreL( *store );
store->CommitL();
CleanupStack::PopAndDestroy( store );
store = NULL;
}
clientEntry->SetEntryL( aNotifications.At( i ) );
}
else // duplicate is not free-> original notification has to be dropped
{
drop = ETrue;
}
}
CleanupStack::PopAndDestroy( mmsHeaders );
}
}
else // original notification is not free
{
drop = ETrue;
}
if ( drop )
{
// Remove the entry from selection
aNotifications.Delete( i );
}
else // mark original notification reserved, unless it is already marked
{
if ( !alreadyMarked)
{
clientEntry->SetEntryL( aNotifications.At( i ) );
entry = clientEntry->Entry();
MarkNotificationOperationReserved( entry, aOperation );
entry.SetReadOnly( EFalse );
clientEntry->ChangeL( entry );
}
}
}
aNotifications.Compress();
CleanupStack::PopAndDestroy( clientEntry );
}
// ---------------------------------------------------------
// CMmsNotificationClientMtm::FreeNotification
// ---------------------------------------------------------
//
TBool CMmsNotificationClientMtm::FreeNotification( TMsvEntry& aEntry, const TUint32 aOperation )
{
if ( aEntry.iMtm != KUidMsgMMSNotification)
{
return EFalse;
}
if ( aEntry.iMtmData2 & KMmsNewOperationForbidden ||
( aEntry.iMtmData2 & KMmsOperationFinished &&
!( aEntry.iMtmData2 & KMmsOperationResult ) &&
!( aEntry.iMtmData2 & KMmsStoredInMMBox ) &&
( aOperation == KMmsOperationFetch || aOperation == KMmsOperationForward )))
{
return EFalse;
}
return ETrue;
}
// ---------------------------------------------------------
// CMmsNotificationClientMtm::MarkNotificationOperationReserved
// ---------------------------------------------------------
//
void CMmsNotificationClientMtm::MarkNotificationOperationReserved( TMsvEntry& aEntry,
const TUint32 aOperation )
{
aEntry.iMtmData2 &= ~KMmsOperationIdentifier; // clear possible old operation
aEntry.iMtmData2 |= KMmsNewOperationForbidden; // forbidden
aEntry.iMtmData2 |= KMmsOperationOngoing; // operation is active
aEntry.iMtmData2 |= aOperation; // operation
aEntry.iMtmData2 &= ~KMmsOperationFinished; // not finished
aEntry.iMtmData2 &= ~KMmsOperationResult; // not failed
}
// ---------------------------------------------------------
// CMmsNotificationClientMtm::FindDuplicateNotificationL
// ---------------------------------------------------------
//
void CMmsNotificationClientMtm::FindDuplicateNotificationL( TMsvId aParent,
CMmsHeaders& aHeaders,
TMsvId& aDuplicate )
{
aDuplicate = KMsvNullIndexEntryId;
if ( aParent == KMsvNullIndexEntryId )
{
return;
}
CMsvEntry* cEntry = Session().GetEntryL( aParent );
CleanupStack::PushL( cEntry );
CMsvEntrySelection* selection = cEntry->ChildrenWithMtmL( KUidMsgMMSNotification );
CleanupStack::PushL( selection );
TInt count = selection->Count();
if ( count == 0 )
{
CleanupStack::PopAndDestroy( selection );
CleanupStack::PopAndDestroy( cEntry );
return;
}
CMmsHeaders* mmsHeaders = CMmsHeaders::NewL( iMmsSettings->MmsVersion() );
CleanupStack::PushL( mmsHeaders );
for ( TInt i = count; i > 0 && ( aDuplicate == KMsvNullIndexEntryId ); i-- )
{
cEntry->SetEntryL( selection->At( i - 1 ) );
CMsvStore* store = cEntry->ReadStoreL();
CleanupStack::PushL( store );
mmsHeaders->RestoreL( *store );
CleanupStack::PopAndDestroy( store );
// content location must match
if ( mmsHeaders->ContentLocation().Compare( aHeaders.ContentLocation() ) == 0 )
{
aDuplicate = selection->At( i - 1 );
}
}
CleanupStack::PopAndDestroy( mmsHeaders );
CleanupStack::PopAndDestroy( selection );
CleanupStack::PopAndDestroy( cEntry );
}
// ---------------------------------------------------------
// CMmsClientNotificationMtm::GetExtendedText
// ---------------------------------------------------------
//
const TPtrC CMmsNotificationClientMtm::GetExtendedText() const
{
return iMmsHeaders->ExtendedNotification();
}
// ---------------------------------------------------------
// CMmsNotificationClientMtm::FetchMessagesL
// ---------------------------------------------------------
//
CMsvOperation* CMmsNotificationClientMtm::FetchMessagesL(
const CMsvEntrySelection& aSelection,
TRequestStatus& aCompletionStatus )
{
if ( aSelection.Count() == 0 )
{
User::Leave( KErrNotFound );
}
CMsvEntrySelection* notifications = aSelection.CopyLC();
// mark free notifications reserved. Others are dropped out.
MarkFreeNotificationsReservedL( *notifications, KMmsOperationFetch );
// check if none of the entries are allowed to start fetch
if ( notifications->Count() == 0 )
{
// leave will destroy reserved items from cleanupstack
User::Leave( KErrNotSupported );
}
TCommandParameters parameters; // initialized to zero
TCommandParametersBuf paramPack( parameters );
// Fetch messages
CMsvOperation* op = InvokeAsyncFunctionL(
EMmsScheduledReceiveForced,
*notifications,
paramPack,
aCompletionStatus );
CleanupStack::PopAndDestroy( notifications );
return op;
}
// ---------------------------------------------------------
// CMmsNotificationClientMtm::FetchMessageL
// ---------------------------------------------------------
//
CMsvOperation* CMmsNotificationClientMtm::FetchMessageL(
TMsvId aUid,
TRequestStatus& aCompletionStatus )
{
CMsvEntrySelection* selection = new ( ELeave ) CMsvEntrySelection;
CleanupStack::PushL( selection );
selection->AppendL( aUid );
// Mark the notification reserved for fetching is possible
MarkFreeNotificationsReservedL( *selection, KMmsOperationFetch );
// if notification is not allowed to be fetched,
// the notification is dropped from selection.
if ( selection->Count() == 0 )
{
CleanupStack::PopAndDestroy( selection );
return NULL;
}
TCommandParameters parameters; // initialized to zero
TCommandParametersBuf paramPack( parameters );
// Fetch the message
CMsvOperation* op = InvokeAsyncFunctionL(
EMmsScheduledReceiveForced,
*selection,
paramPack,
aCompletionStatus );
CleanupStack::PopAndDestroy( selection );
return op;
}
// ---------------------------------------------------------
// CMmsNotificationClientMtm::FetchAllL
// ---------------------------------------------------------
//
CMsvOperation* CMmsNotificationClientMtm::FetchAllL( TRequestStatus& aCompletionStatus,
TBool aForced )
{
// List notifications that have no active operation
CMsvEntrySelection* notifications = ListNotificationsL();
if ( notifications->Count() == 0 )
{
delete notifications;
notifications = NULL;
User::Leave( KErrNotFound );
}
CleanupStack::PushL( notifications );
// Loop through the notifications and reserve them for the operation
TInt retval = KErrNone;
TInt count = notifications->Count();
for ( TInt i = count; i > 0; i-- )
{
retval = ReserveNotificationOperationL( notifications->At( i - 1 ), KMmsOperationFetch );
if( retval != KErrNone )
{
// Remove the entry from selection
notifications->Delete( i - 1 );
}
}
TCommandParameters parameters; // initialized to zero
TCommandParametersBuf paramPack( parameters );
// Fetch the message
CMsvOperation* op = NULL;
if ( aForced )
{
op = InvokeAsyncFunctionL(
EMmsScheduledReceiveForced,
*notifications,
paramPack,
aCompletionStatus );
}
else
{
op = InvokeAsyncFunctionL(
EMmsScheduledReceive,
*notifications,
paramPack,
aCompletionStatus );
}
CleanupStack::PopAndDestroy( notifications );
return op;
}
// ---------------------------------------------------------
// CMmsNotificationClientMtm::NotificationCount
// ---------------------------------------------------------
//
TInt CMmsNotificationClientMtm::NotificationCount()
{
TInt numberOfNotifications = -1;
TInt error = KErrNone;
CMsvEntrySelection* notifications = NULL;
TRAP( error,
{ notifications = ListNotificationsL();
});
if ( error == KErrNone )
{
numberOfNotifications = notifications->Count();
}
delete notifications;
notifications = NULL;
return numberOfNotifications;
}
// ---------------------------------------------------------
// CMmsNotificationClientMtm::ListNotificationsL
// ---------------------------------------------------------
//
CMsvEntrySelection* CMmsNotificationClientMtm::ListNotificationsL()
{
return CMmsClientMtm::ListNotificationsInInboxL();
}
// ---------------------------------------------------------
// CMmsNotificationClientMtm::DeleteNotificationL
// ---------------------------------------------------------
//
CMsvOperation* CMmsNotificationClientMtm::DeleteNotificationL(
const CMsvEntrySelection& aSelection,
TMmsDeleteOperationType aDeleteType,
TRequestStatus& aCompletionStatus )
{
if ( aSelection.Count() == 0 )
{
// if nothing to delete, operation is complete
TPckgC < TMsvId > progress = 0;
return CMsvCompletedOperation::NewL( Session(), Type(), progress,
KMsvLocalServiceIndexEntryId, aCompletionStatus, KErrNone );
}
//
// aDeleteType has to be delivered to server side.
// Using TCommandParameters.iError for it on purpose.
//
TCommandParameters parameters;
parameters.iError = aDeleteType;
TCommandParametersBuf paramPack( parameters );
//
// Modifying indexentries
//
CMsvEntry* cEntry = NULL;
cEntry = Session().GetEntryL( aSelection.At( 0 ) );
CleanupStack::PushL( cEntry ); // ***
for ( TInt i = 0; i < aSelection.Count(); i++ )
{
cEntry->SetEntryL( aSelection.At( i ) );
TMsvEntry tEntry = cEntry->Entry();
tEntry.SetReadOnly( EFalse );
cEntry->ChangeL( tEntry );
}
CleanupStack::PopAndDestroy( cEntry );
//
// NOTE: Notification delete operations perform majority of the work in
// the server side. This includes also notification reservation for the operation.
//
//
// Calling server side
//
CMsvOperation* op = InvokeAsyncFunctionL(
EMmsScheduledNotificationDelete,
aSelection,
paramPack,
aCompletionStatus );
return op;
}
// ---------------------------------------------------------
// CMmsNotificationClientMtm::UnscheduledDeleteNotificationL
// ---------------------------------------------------------
//
CMsvOperation* CMmsNotificationClientMtm::UnscheduledDeleteNotificationL(
const CMsvEntrySelection& aSelection,
TMmsDeleteOperationType aDeleteType,
TRequestStatus& aCompletionStatus )
{
if ( aSelection.Count() == 0 )
{
// if nothing to delete, operation is complete
TPckgC < TMsvId > progress = 0;
return CMsvCompletedOperation::NewL( Session(), Type(), progress,
KMsvLocalServiceIndexEntryId, aCompletionStatus, KErrNone );
}
//
// aDeleteType has to be delivered to server side.
// Using TCommandParameters.iError for it on purpose.
//
TCommandParameters parameters;
parameters.iError = aDeleteType;
TCommandParametersBuf paramPack( parameters );
//
// NOTE: Notification delete operations perform majority of the work in
// the server side. This includes also notification reservation for the operation.
//
//
// Calling server side
//
CMsvOperation* op = InvokeAsyncFunctionL(
EMmsNotificationDelete,
aSelection,
paramPack,
aCompletionStatus );
return op;
}
// ---------------------------------------------------------
// CMmsNotificationClientMtm::DeleteAllNotificationsL
// ---------------------------------------------------------
//
CMsvOperation* CMmsNotificationClientMtm::DeleteAllNotificationsL(
TMmsDeleteOperationType aDeleteType,
TRequestStatus& aCompletionStatus )
{
//
// Get selection of all the notifications in Inbox
// (operations that do not have ongoing operations)
//
CMsvEntrySelection* selection = ListNotificationsL();
if ( selection->Count() == 0 )
{
delete selection;
selection = NULL;
// if nothing to delete, operation is complete
TPckgC < TMsvId > progress = 0;
return CMsvCompletedOperation::NewL( Session(), Type(), progress,
KMsvLocalServiceIndexEntryId, aCompletionStatus, KErrNone );
}
CleanupStack::PushL( selection );
//
// Call DeleteNotificationL with the selection just created
//
CMsvOperation* op = DeleteNotificationL(
*selection,
aDeleteType,
aCompletionStatus );
CleanupStack::PopAndDestroy( selection );
return op;
}
// ---------------------------------------------------------
// CMmsNotificationClientMtm::DeleteForwardEntryL
// ---------------------------------------------------------
//
void CMmsNotificationClientMtm::DeleteForwardEntryL( const CMsvEntrySelection& aSelection )
{
//
// Loop through the selection of forward entries
//
TInt count = aSelection.Count();
for( TInt index = 0; index < count; index++ )
{
iMsvEntry->SetEntryL( aSelection.At( index ) );
TMsvEntry tEntry = iMsvEntry->Entry();
// Test entry type
if( tEntry.iType != KUidMsvMessageEntry ||
tEntry.iMtm != KUidMsgMMSNotification ||
!( tEntry.iMtmData1 & KMmsMessageForwardReq ) )
{
continue;
}
// Test entry location
TMsvId parentId = tEntry.Parent();
if( ( parentId != KMsvGlobalOutBoxIndexEntryId ) &&
( parentId != KMsvSentEntryId ) )
{
continue;
}
// Test that entry is not in a middle of some other action
if( tEntry.SendingState() == KMsvSendStateSending )
{
// Too late to delete
continue;
}
else
{
// Quickly "reserve" the entry for deletion
tEntry.SetSendingState( KMsvSendStateSuspended );
iMsvEntry->ChangeL( tEntry );
}
//
// Entry will do; it will be deleted.
//
// But first clearing possible related notification
CMsvStore* store = iMsvEntry->ReadStoreL();
CleanupStack::PushL( store ); // ***
CMmsHeaders* mmsHeaders = CMmsHeaders::NewL( iMmsSettings->MmsVersion() );
CleanupStack::PushL( mmsHeaders );
mmsHeaders->RestoreL( *store );
TMsvId relatedId = mmsHeaders->RelatedEntry();
CleanupStack::PopAndDestroy( mmsHeaders );
CleanupStack::PopAndDestroy( store );
// If forward entry has a "related id" (i.e. id of the notification),
// context is changed to it and it will be cleared.
if( relatedId != KMsvNullIndexEntryId )
{
// Change to related notification
iMsvEntry->SetEntryL( relatedId );
tEntry = iMsvEntry->Entry();
// "Clear" the flags
tEntry.iMtmData2 &= ~KMmsOperationIdentifier; // clear possible old operations
tEntry.iMtmData2 &= ~KMmsNewOperationForbidden; // not forbidden
tEntry.iMtmData2 &= ~KMmsOperationOngoing; // not ongoing
tEntry.iMtmData2 &= ~KMmsOperationFinished; // not finished (this is notification's initial state)
tEntry.iMtmData2 &= ~KMmsOperationResult; // clear also the result flag ("assuming OK")
tEntry.SetReadOnly( ETrue );
iMsvEntry->ChangeL( tEntry );
}
// Activating parent entry of the forward entry
iMsvEntry->SetEntryL( parentId );
// Delete forward entry
iMsvEntry->DeleteL( aSelection.At( index ) );
} // for loop
}
// ---------------------------------------------------------
// CMmsNotificationClientMtm::MmboxInfoL
// ---------------------------------------------------------
//
TBool CMmsNotificationClientMtm::MmboxInfoL( TMmboxInfo& aMmboxInfo )
{
// check first, if quota information is available.
TMsvId mmboxFolder = iMmsSettings->MMBoxFolder();
CMsvEntry* cEntry = Session().GetEntryL( KMsvLocalServiceIndexEntryId );
CleanupStack::PushL( cEntry );
TInt pushedToStack = 1;
cEntry->SetEntryL( mmboxFolder );
// Show invisible entries
cEntry->SetSortTypeL( TMsvSelectionOrdering( KMsvNoGrouping, EMsvSortByIdReverse, ETrue ) );
CMsvEntrySelection* selection = cEntry->ChildrenWithMtmL( KUidMsgTypeMultimedia );
CleanupStack::PushL( selection );
pushedToStack++;
TBool quotaInfoAvailable = EFalse;
if ( selection->Count() > 0 )
{
cEntry->SetEntryL( selection->At( 0 ));
CMsvStore* store = cEntry->ReadStoreL();
CleanupStack::PushL( store );
pushedToStack++;
CMmsHeaders* mmsHeaders = CMmsHeaders::NewL( iMmsSettings->MmsVersion() );
CleanupStack::PushL( mmsHeaders );
pushedToStack++;
mmsHeaders->RestoreL( *store );
// Get quota info
CMmsMMBoxViewHeaders& viewHeaders = mmsHeaders->MMBoxViewHeadersL();
aMmboxInfo.mmboxTotalInBytes = viewHeaders.MMBoxTotalSize();
aMmboxInfo.mmboxTotalInMessageCount = viewHeaders.MMBoxTotalNumber();
aMmboxInfo.mmboxQuotaInBytes = viewHeaders.MMBoxQuotaSize();
aMmboxInfo.mmboxQuotaInMessageCount = viewHeaders.MMBoxQuotaNumber();
// get Date info
TMsvEntry tEntry = cEntry->Entry();
aMmboxInfo.date = tEntry.iDate;
// error
aMmboxInfo.error = tEntry.iError;
quotaInfoAvailable = ETrue;
}
CleanupStack::PopAndDestroy( pushedToStack );
return quotaInfoAvailable;
}
// ---------------------------------------------------------
// CMmsNotificationClientMtm::UpdateMmBoxListL
// ---------------------------------------------------------
//
CMsvOperation* CMmsNotificationClientMtm::UpdateMmBoxListL(
TRequestStatus& aCompletionStatus )
{
TCommandParameters parameters; // initialized to zero
TCommandParametersBuf paramPack( parameters );
CMsvEntrySelection* selection = new ( ELeave ) CMsvEntrySelection;
CleanupStack::PushL( selection );
selection->AppendL( iServiceId );
// Update mmbox list
CMsvOperation* op = InvokeAsyncFunctionL(
EMmsUpdateMmboxList,
*selection,
paramPack,
aCompletionStatus );
CleanupStack::PopAndDestroy( selection );
return op;
}
// ---------------------------------------------------------
// CMmsNotificationClientMtm::GetMmboxFolderL
// ---------------------------------------------------------
//
TMsvId CMmsNotificationClientMtm::GetMmboxFolderL()
{
return iMmsSettings->MMBoxFolder();
}
// ---------------------------------------------------------
// CMmsNotificationClientMtm
// ---------------------------------------------------------
//
const TPtrC CMmsNotificationClientMtm::GetApplicationId() const
{
return iMmsHeaders->ApplicId();
}
// ================= OTHER EXPORTED FUNCTIONS ==============
// End of File