/*
* Copyright (c) 2004-2007 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:
* State machine for sending a delete request to network
*
*/
// INCLUDE FILES
#include <apparc.h>
#include <msventry.h>
#include <msvids.h>
#include <logcli.h>
#include <commdb.h>
#include <in_sock.h>
#include <commdbconnpref.h>
#include <AknGlobalNote.h>
// the rest are local includes, needed always
#include "mmsconst.h"
#include "mmsdeleteoperation.h"
#include "mmssession.h"
#include "mmssettings.h"
#include "mmsservercommon.h"
#include "mmsheaders.h"
#include "mmsmmboxmessageheaders.h"
#include "mmsencode.h"
#include "mmsdecode.h"
#include "mmsscheduledentry.h"
#include "mmsgenutils.h"
#include "mmserrors.h"
#include "mmsserverentry.h"
#include "mmsconninit.h"
// EXTERNAL DATA STRUCTURES
// EXTERNAL FUNCTION PROTOTYPES
extern void gPanic( TMmsPanic aPanic );
// CONSTANTS
// MACROS
// LOCAL CONSTANTS AND MACROS
// MODULE DATA STRUCTURES
// LOCAL FUNCTION PROTOTYPES
// ==================== LOCAL FUNCTIONS ====================
// ================= MEMBER FUNCTIONS =======================
// ---------------------------------------------------------
// CMmsDeleteOperation::CMmsDeleteOperation
//
// ---------------------------------------------------------
//
CMmsDeleteOperation::CMmsDeleteOperation( RFs& aFs ):
CMmsBaseOperation( aFs )
{
//
// members that get initial value 0, need not be initialized here
//
}
// ---------------------------------------------------------
// CMmsDeleteOperation::ConstructL
//
// ---------------------------------------------------------
//
void CMmsDeleteOperation::ConstructL( CMmsSettings* aMmsSettings )
{
CMmsBaseOperation::ConstructL( aMmsSettings );
iMmsRequestHeaders = CMmsHeaders::NewL( iMmsSettings->MmsVersion() );
CActiveScheduler::Add( this );
}
// ---------------------------------------------------------
// CMmsDeleteOperation::NewL
//
// ---------------------------------------------------------
//
CMmsDeleteOperation* CMmsDeleteOperation::NewL( RFs& aFs, CMmsSettings* aMmsSettings )
{
CMmsDeleteOperation* self = new ( ELeave ) CMmsDeleteOperation( aFs );
CleanupStack::PushL( self );
self->ConstructL( aMmsSettings );
CleanupStack::Pop( self );
return self;
}
// ---------------------------------------------------------
// CMmsDeleteOperation::~CMmsDeleteOperation
//
// ---------------------------------------------------------
//
CMmsDeleteOperation::~CMmsDeleteOperation()
{
Cancel();
delete iMmsRequestHeaders;
}
// ---------------------------------------------------------
// CMmsDeleteOperation::DoCancel
//
// ---------------------------------------------------------
//
void CMmsDeleteOperation::DoCancel()
{
#ifndef _NO_MMSS_LOGGING_
TMmsLogger::Log( _L("CMmsDeleteOperation::DoCancel") );
#endif
CMmsBaseOperation::DoCancel();
// Clear possible flags
for( TInt i = iSelection->Count()-1; i >= 0; i-- )
{
// original entry
if ( iServerEntry->SetEntry( iSelection->At( i ) ) == KErrNone )
{
TMsvEntry tEntry = iServerEntry->Entry();
TMsvId parent = tEntry.Parent();
// If notification in iSelection is in mmbox folder, mark the
// possible duplicate notification in inbox too.
if ( parent == iMmsSettings->MMBoxFolder() )
{
#ifndef _NO_MMSS_LOGGING_
TMmsLogger::Log( _L("possible duplicates has to be checked") );
#endif
TInt error = KErrNone;
TRAP ( error, MarkDuplicateL( EMmsNotificationOperationFailed, *iServerEntry ) );
#ifndef _NO_MMSS_LOGGING_
TMmsLogger::Log( _L("Trap failed: error %d "), error );
#endif
}
// reload to make sure any changes are included
// (there should be no changes)
tEntry = iServerEntry->Entry();
MarkNotificationOperationFailed( tEntry );
// put to read only state after duplicates have been marked
// because MarkDuplicateL may want to edit link to related entry
tEntry.SetReadOnly( ETrue );
iServerEntry->ChangeEntry( tEntry );
}
}
}
// ---------------------------------------------------------
// CMmsDeleteOperation::StartL
//
// ---------------------------------------------------------
//
void CMmsDeleteOperation::StartL(
TMmsDeleteOperationType aDeleteType,
CMsvEntrySelection& aSelection,
CMsvServerEntry& aServerEntry,
TMsvId aService,
TRequestStatus& aStatus )
{
iDeleteType = aDeleteType;
#ifndef _NO_MMSS_LOGGING_
TMmsLogger::Log( _L("CMmsDeleteOperation::StartL") );
if( iDeleteType == EMmsDeleteNotificationOnly ) TMmsLogger::Log( _L("- EMmsDeleteNotificationOnly") );
if( iDeleteType == EMmsDeleteMMBoxOnly ) TMmsLogger::Log( _L("- EMmsDeleteMMBoxOnly") );
if( iDeleteType == EMmsDeleteBoth ) TMmsLogger::Log( _L("- EMmsDeleteBoth") );
#endif
// Make sure the version number is correctly set
CMmsBaseOperation::StartL( aSelection, aServerEntry, aService, aStatus );
iMmsRequestHeaders->Reset();
//
// Delete operation does not work as regular operations:
//
// iFailed list is emptied because retries are not used for delete
iFailed->Reset();
// iCurrentMessageNo makes no sense in case of delete
iCurrentMessageNo = 0;
}
// ---------------------------------------------------------
// CMmsDeleteOperation::StartL
// This just overrides the base class version.
// ---------------------------------------------------------
//
void CMmsDeleteOperation::StartL(
CMsvEntrySelection&,
CMsvServerEntry&,
TMsvId,
TRequestStatus& )
{
User::Leave( KErrNotSupported );
}
// ---------------------------------------------------------
// CMmsDeleteOperation::EncodePDUL
//
// ---------------------------------------------------------
//
void CMmsDeleteOperation::EncodePDUL()
{
#ifndef _NO_MMSS_LOGGING_
TMmsLogger::Log( _L("CMmsDeleteOperation::EncodePDU") );
#endif
TInt err = KErrNone; // used to trap errors that are not propagated further
// Go through iSelection and make various checks
TMsvEntry tEntry;
for( TInt i = iSelection->Count()-1; i >= 0; i-- )
{
if ( iServerEntry->SetEntry( iSelection->At( i ) ) == KErrNone )
{
tEntry = iServerEntry->Entry();
// Check that selection contains only "idle" notifications
if( ( tEntry.iMtm != KUidMsgMMSNotification ) ||
( tEntry.iMtm == KUidMsgMMSNotification &&
tEntry.iMtmData2 & KMmsNewOperationForbidden ) )
{
// Take out all non-notifications and notifications that have some operation ongoing
#ifndef _NO_MMSS_LOGGING_
TMmsLogger::Log( _L( "- notif not idle, skipping" ) );
#endif
iSelection->Delete( i );
}
else
{
// If only local delete requested, delete the entry
if( iDeleteType == EMmsDeleteNotificationOnly )
{
#ifndef _NO_MMSS_LOGGING_
TMmsLogger::Log( _L( "- just deleting the notif entry" ) );
#endif
TRAP( err, DeleteNotificationEntryL() );
#ifndef _NO_MMSS_LOGGING_
if( err != KErrNone )
{
TMmsLogger::Log( _L( "- ERROR: DeleteNotificationEntryL left" ) );
}
#endif
iSelection->Delete( i );
}
else // EMmsDeleteMMBoxOnly OR EMmsDeleteBoth
{
#ifndef _NO_MMSS_LOGGING_
TMmsLogger::Log( _L( "- mmbox deletion wanted" ) );
#endif
// Is there a message in MMBox.
if( !(tEntry.iMtmData2 & KMmsStoredInMMBox ) )
{
// No need to care about possible duplicate notification.
#ifndef _NO_MMSS_LOGGING_
TMmsLogger::Log( _L( "- accordig to mmbox flag, message is not in mmbox" ) );
#endif
// If both requested, but no message in MMBox,
// just delete the notification.
if( iDeleteType == EMmsDeleteBoth )
{
#ifndef _NO_MMSS_LOGGING_
TMmsLogger::Log( _L( "- local deletion requested, performing it" ) );
#endif
TRAP( err, DeleteNotificationEntryL() );
#ifndef _NO_MMSS_LOGGING_
if( err != KErrNone )
{
TMmsLogger::Log( _L( "- ERROR: DeleteNotificationEntryL left" ) );
}
#endif
}
else // iDeleteType == EMmsDeleteMMBoxOnly
{
#ifndef _NO_MMSS_LOGGING_
TMmsLogger::Log( _L( "- can not delete from mmbox, clearing entry flags" ) );
#endif
MarkNotificationOperationFailed( tEntry );
tEntry.SetReadOnly( ETrue );
iServerEntry->ChangeEntry( tEntry );
}
// As message not in MMBox, delete entry from selection
iSelection->Delete( i );
}
}
}
}
else
{
// take out an entry that could not be accessed
iSelection->Delete( i );
}
}
// delete from mmbox is wanted and the notifications are stored in mmbox
// Check duplicates, if the parent is in mmbox folder.
// If duplicate is found, check if the duplicate is free.
// If the duplicate is free, mark the duplicate as "deleting operation going on".
// If duplicate is not free, drop the original notification from iSelection.
for ( TInt j = iSelection->Count()-1; j >= 0; j-- )
{
if ( iServerEntry->SetEntry( iSelection->At( j ) ) == KErrNone )
{
// if original notification cannot be accessed there is no way
// to check the notification
tEntry = iServerEntry->Entry();
if ( tEntry.Parent() == iMmsSettings->MMBoxFolder() )
{
#ifndef _NO_MMSS_LOGGING_
TMmsLogger::Log( _L( "- check if duplicate is found" ) );
#endif
// parent is mmbox folder.
CMmsHeaders* mmsHeaders = CMmsHeaders::NewL( iMmsSettings->MmsVersion() );
CleanupStack::PushL( mmsHeaders );
CMsvStore* store = iServerEntry->ReadStoreL();
CleanupStack::PushL( store );
mmsHeaders->RestoreL( *store );
CleanupStack::PopAndDestroy( store );
store = NULL;
TMsvId duplicate = KMsvNullIndexEntryId;
FindDuplicateNotificationL( KMsvGlobalInBoxIndexEntryIdValue,
*mmsHeaders, duplicate );
if ( duplicate != KMsvNullIndexEntryId )
{
#ifndef _NO_MMSS_LOGGING_
TMmsLogger::Log( _L( "- duplicate found" ) );
#endif
if ( iServerEntry->SetEntry( duplicate ) == KErrNone )
{
// Mark duplicate, if it is free for a new operation
TMsvEntry dupEntry = iServerEntry->Entry();
if ( FreeNotification( dupEntry, KMmsOperationDelete ) )
{
#ifndef _NO_MMSS_LOGGING_
TMmsLogger::Log( _L( "- Marking duplicate" ) );
#endif
MarkNotificationOperationReserved( dupEntry, KMmsOperationDelete );
iServerEntry->ChangeEntry( dupEntry );
// Set duplicate as related entry to the original notification
if ( iServerEntry->SetEntry( iSelection->At( j ) ) == KErrNone )
{
tEntry = iServerEntry->Entry();
tEntry.SetReadOnly( EFalse );
iServerEntry->ChangeEntry( tEntry );
store = iServerEntry->EditStoreL();
CleanupStack::PushL( store );
mmsHeaders->RestoreL( *store );
mmsHeaders->SetRelatedEntry( duplicate );
mmsHeaders->StoreL( *store );
store->CommitL();
CleanupStack::PopAndDestroy( store );
store = NULL;
}
}
else
{
// duplicate is not free, drop the original from iSelection.
#ifndef _NO_MMSS_LOGGING_
TMmsLogger::Log( _L( "- Duplicate is not free, drop the original notification from selection" ) );
#endif
iSelection->Delete( j );
}
}
}
CleanupStack::PopAndDestroy( mmsHeaders );
}
}
}
// iSelection contains notifications that are deleted from mmbox
// Mark notifications as "deleting operation going on"
for ( TInt k = iSelection->Count()-1; k >= 0; k-- )
{
if ( iServerEntry->SetEntry( iSelection->At( k ) ) == KErrNone )
{
tEntry = iServerEntry->Entry();
#ifndef _NO_MMSS_LOGGING_
TMmsLogger::Log( _L( "- reserve notif for deletion" ) );
#endif
// Mark all remaining notifications as operation-ongoing
// operation is from now on delete
MarkNotificationOperationReserved( tEntry, KMmsOperationDelete );
tEntry.SetReadOnly( EFalse );
iServerEntry->ChangeEntry( tEntry );
}
}
//
// If remote delete is required, creating PDU to be sent
//
if( ( iDeleteType != EMmsDeleteNotificationOnly ) &&
( iSelection->Count() > 0 ) )
{
#ifndef _NO_MMSS_LOGGING_
TMmsLogger::Log( _L( "- creating PDU" ) );
#endif
//
// Create headers structure
//
// iMmsRequestHeaders is a member that has been created in the constructor
// And Reset in the StartL function
// MessageType
iMmsRequestHeaders->SetMessageType( KMmsMessageTypeMBoxDeleteReq );
// TransactionId
TBufC8<KMMSMAXTIDLENGTH> tid;
tid.Des().NumUC( AllocateTID(), EHex );
iMmsRequestHeaders->SetTidL( tid );
//
// Content-Location array
// Loop through selection and put all content locations into array
//
CMmsHeaders* mmsHeaders = CMmsHeaders::NewL( iMmsSettings->MmsVersion() );
CleanupStack::PushL( mmsHeaders ); // ***
for( TInt i = iSelection->Count() - 1; i >= 0; i-- )
{
// Get entry
if ( iServerEntry->SetEntry( iSelection->At( i ) ) == KErrNone )
{
// Get read-only message store
CMsvStore* store = iServerEntry->ReadStoreL();
CleanupStack::PushL( store ); // ***
// Restore all parts of multimedia message
mmsHeaders->RestoreL( *store );
// Add array to headers
iMmsRequestHeaders->MMBoxMessageHeadersL().ContentLocationList()
.AppendL( mmsHeaders->ContentLocation() );
CleanupStack::PopAndDestroy( store );
}
}
CleanupStack::PopAndDestroy( mmsHeaders );
//
// Encode the PDU
//
iEncoder->EncodeHeadersL( *iMmsRequestHeaders, *iEncodeBuffer );
}
iServerEntry->SetEntry( KMsvNullIndexEntryId );
FallThrough();
}
// ---------------------------------------------------------
// CMmsDeleteOperation::ConnectToIAPL
//
// ---------------------------------------------------------
//
void CMmsDeleteOperation::ConnectToIAPL()
{
#ifndef _NO_MMSS_LOGGING_
TMmsLogger::Log( _L("CMmsDeleteOperation::ConnectToIAPL") );
#endif
if( iDeleteType == EMmsDeleteNotificationOnly || iSelection->Count() == 0 )
{
FallThrough();
}
else
{
CMmsBaseOperation::ConnectToIAPL();
}
}
// ---------------------------------------------------------
// CMmsDeleteOperation::InitializeSessionL
//
// ---------------------------------------------------------
//
void CMmsDeleteOperation::InitializeSessionL()
{
#ifndef _NO_MMSS_LOGGING_
TMmsLogger::Log( _L("CMmsDeleteOperation::InitializeSessionL") );
#endif
if( iDeleteType == EMmsDeleteNotificationOnly || iSelection->Count() == 0 )
{
FallThrough();
}
else
{
CMmsBaseOperation::InitializeSessionL();
}
}
// ---------------------------------------------------------
// CMmsDeleteOperation::SubmitTransactionL
//
// ---------------------------------------------------------
//
void CMmsDeleteOperation::SubmitTransactionL()
{
#ifndef _NO_MMSS_LOGGING_
TMmsLogger::Log( _L("CMmsDeleteOperation::SubmitTransactionL"));
#endif
//
// Maybe networking not needed at all
//
if( iDeleteType == EMmsDeleteNotificationOnly || iSelection->Count() == 0 )
{
FallThrough();
return;
}
// This check is needed only when running tests in local mode
// if length of URI is 0, Symbian code will panic
if ( !iUri )
{
iError = KMmsErrorNoURI1;
}
else if ( iUri->Des().Length() == 0 )
{
iError = KMmsErrorNoURI1;
}
else
{
// keep LINT happy
}
//
// Networking is needed. Is connection open.
//
if ( !iConnected )
{
if ( iError == KErrNone )
{
iError = KErrCouldNotConnect;
}
}
//
// If something has gone wrong, just fall through
//
if ( iError != KErrNone )
{
FallThrough();
return;
}
//
// Send
//
iMmsSession->SendMessageL(
iUri->Des(),
*iEncodeBuffer,
*iEncoder,
*iDecoder,
iStatus );
SetActive();
}
// ---------------------------------------------------------
// CMmsDeleteOperation::DecodeResponseL()
//
// ---------------------------------------------------------
//
void CMmsDeleteOperation::DecodeResponseL()
{
#ifndef _NO_MMSS_LOGGING_
TMmsLogger::Log( _L( "CMmsDeleteOperation::DecodeResponseL()" ) );
#endif
if( iDeleteType != EMmsDeleteNotificationOnly && iSelection->Count() > 0 )
{
// iError is checked in base class method.
CMmsBaseOperation::DecodeResponseL();
}
else
{
FallThrough();
}
}
// ---------------------------------------------------------
// CMmsDeleteOperation::UpdateEntryStatusL
//
// ---------------------------------------------------------
//
void CMmsDeleteOperation::UpdateEntryStatusL()
{
#ifndef _NO_MMSS_LOGGING_
TMmsLogger::Log( _L( "CMmsDeleteOperation::UpdateEntryStatusL()" ) );
TMmsLogger::Log( _L( "- Number of ids in iSelection: %d" ), iSelection->Count() );
#endif
if( iDeleteType == EMmsDeleteNotificationOnly || iSelection->Count() == 0 )
{
FallThrough();
return;
}
//
// If error has occurred and there is nothing received from the network,
// just correcting the flags in the notification entries as they were before.
//
if( iError != KErrNone )
{
#ifndef _NO_MMSS_LOGGING_
TMmsLogger::Log( _L( "- error has occurred" ) );
#endif
MarkSelectionAsFailed();
FallThrough();
return;
}
//
// Following is the the default behaviour: no errors, response received
//
else
{
#ifndef _NO_MMSS_LOGGING_
TMmsLogger::Log( _L( "- no errors" ) );
#endif
//
// Get delete result array from response
//
const RPointerArray<CMmsDeleteResultArray>& resultArray
= iResponse->DeleteResultArray();
#ifndef _NO_MMSS_LOGGING_
TMmsLogger::Log( _L( "- resultarray length: %d" ), iResponse->DeleteResultArray().Count() );
#endif
//
// Make overall check for the response before checking each entry separately
// First, messagetype
//
if( iResponse->MessageType() != KMmsMessageTypeMBoxDeleteConf )
{
#ifndef _NO_MMSS_LOGGING_
TMmsLogger::Log( _L( "- ERROR: Response has wrong message type!" ) );
#endif
MarkSelectionAsFailed();
FallThrough();
return;
}
// Second, if result array contains status Unsupported-Message with no
// related Content-Location, the transaction is interpreted as failed.
for( TInt j = 0; j < resultArray.Count(); j++ )
{
if( resultArray[j]->ContentLocation().Length() == 0 &&
resultArray[j]->ResponseStatus() == KMmsErrorStatusUnsupportedMessage )
{
// If array contains item that has no Content-Location,
// something is wrong
#ifndef _NO_MMSS_LOGGING_
TMmsLogger::Log( _L( "- Response contains response-status with no corresponding ContentLocation!" ) );
TMmsLogger::Log( _L( " Interpreting this as delete failure." ) );
#endif
MarkSelectionAsFailed();
FallThrough();
return;
}
}
//
// Moving from response level checks into entry level checks...
//
// Loop through iSelection to separate failed and successful ones
// (contains notifications that were sent to network)
//
CMmsHeaders* mmsHeaders = CMmsHeaders::NewL( iMmsSettings->MmsVersion() );
CleanupStack::PushL( mmsHeaders );
for( TInt i = iSelection->Count(); i > 0; i-- )
{
#ifndef _NO_MMSS_LOGGING_
TMmsLogger::Log( _L( "- looping in iSelection[%d]" ), i-1 );
#endif
// Get Content-location of this notification
if ( iServerEntry->SetEntry( iSelection->At( i-1 ) ) == KErrNone )
{
CMsvStore* store = iServerEntry->ReadStoreL();
CleanupStack::PushL( store );
mmsHeaders->RestoreL( *store );
CleanupStack::PopAndDestroy( store );
store = NULL;
#ifndef _NO_MMSS_LOGGING_
TMmsLogger::Log( _L( "- store read" ) );
#endif
TPtrC8 pContentLocation = mmsHeaders->ContentLocation();
TMsvId duplicate = mmsHeaders->RelatedEntry();
//
// Search for the same content-location from response PDU
// (if it is found, it's mmbox delete has failed)
//
TBool bMmboxDeleteSucceeded = ETrue;
for ( TInt j = 0; j < resultArray.Count(); j++ )
{
// Check match
#ifndef _NO_MMSS_LOGGING_
TMmsLogger::Log( _L( "- looping in resultArray[%d]" ), j );
#endif
if( resultArray[j]->ContentLocation().Compare( pContentLocation ) == 0 )
{
// Get response status that will be investigated next
TInt32 responseStatus = resultArray[j]->ResponseStatus();
#ifndef _NO_MMSS_LOGGING_
TMmsLogger::Log( _L( "- Match found. X-Mms-Response-Status == %d" ), responseStatus );
#endif
// Found a match, now check the reason
if( responseStatus != KMmsStatusOk &&
responseStatus != KMmsErrorMessageNotFound && // this should not be used by the server
responseStatus != KMmsErrorPermanentMessageNotFound )
{
#ifndef _NO_MMSS_LOGGING_
TMmsLogger::Log( _L( "- delete did not succeed for this notif" ) );
#endif
// This entry failed, removing it from iSelection
iSelection->Delete( i-1 );
bMmboxDeleteSucceeded = EFalse;
// Notification will not be deleted any longer regardless of iDeleteType
// Correcting the notification entry
// StoredInMMBox flag value not changed.
#ifndef _NO_MMSS_LOGGING_
TMmsLogger::Log( _L( "- clearing entry flags" ) );
#endif
// if the original notification is in mmbox folder and a duplicate is found,
// mark the status of the duplicate notification too.
if ( duplicate != KMsvNullIndexEntryId &&
iServerEntry->Entry().Parent() == iMmsSettings->MMBoxFolder() )
{
#ifndef _NO_MMSS_LOGGING_
TMmsLogger::Log( _L(
"- duplicate exists and original notification is in mmbox folder" )
);
#endif
// Clear related entry from the original notification
// and mark the duplicate as failed
TRAP_IGNORE( MarkDuplicateL(
EMmsNotificationOperationFailed, *iServerEntry ) );
}
// Mark original notification. iServerEntry still points to it
TMsvEntry tEntry = iServerEntry->Entry();
MarkNotificationOperationFailed( tEntry );
tEntry.SetReadOnly( ETrue );
iServerEntry->ChangeEntry( tEntry );
#ifndef _NO_MMSS_LOGGING_
TMmsLogger::Log( _L( "- original marked failed" ) );
#endif
}
}
} // inner for loop (resultArray)
// Has the current entry been deleted from mmbox...
if( bMmboxDeleteSucceeded )
{
#ifndef _NO_MMSS_LOGGING_
TMmsLogger::Log( _L( "- this notification was deleted from mmbox" ) );
#endif
if ( iServerEntry->SetEntry( iSelection->At( i-1 ) ) == KErrNone )
{
// if notification is in inbox, check if a duplicate exits in mmbox folder
if ( iServerEntry->Entry().Parent() == KMsvGlobalInBoxIndexEntryIdValue )
{
TMsvId mmboxFolder = iMmsSettings->MMBoxFolder();
if ( mmboxFolder != KMsvNullIndexEntryId )
{
#ifndef _NO_MMSS_LOGGING_
TMmsLogger::Log( _L( "- original notification is in inbox" ) );
TMmsLogger::Log( _L( "- finding duplicate from mmbox inbox" ) );
#endif
FindDuplicateNotificationL( mmboxFolder, *mmsHeaders, duplicate );
}
}
// if duplicate exits, mark it as "deleted successfully from mmbox"
if ( duplicate != KMsvNullIndexEntryId )
{
#ifndef _NO_MMSS_LOGGING_
TMmsLogger::Log( _L( "- duplicate exists" ) );
#endif
// iServerEntry should still be pointing to the original notification
// Clear related entry from the original notification
// and mark the duplicate as "deleted from mmbox"
TRAP_IGNORE( MarkDuplicateL( EMmsDeletedFromMmbox, *iServerEntry ) )
}
// Should notification also be deleted...
if( iDeleteType == EMmsDeleteBoth )
{
#ifndef _NO_MMSS_LOGGING_
TMmsLogger::Log( _L( "- about to delete notif entry" ) );
#endif
DeleteNotificationEntryL();
}
else // deletetype not equal to delete-both
{
#ifndef _NO_MMSS_LOGGING_
TMmsLogger::Log( _L( "- clearing notif flags" ) );
#endif
TMsvEntry tEntry = iServerEntry->Entry();
tEntry.iMtmData2 &= ~KMmsStoredInMMBox; // not-stored-in-mmbox
tEntry.iMtmData2 &= ~KMmsNewOperationForbidden; // operations allowed
tEntry.iMtmData2 &= ~KMmsOperationOngoing; // not ongoing
tEntry.iMtmData2 |= KMmsOperationFinished; // finished
tEntry.iMtmData2 &= ~KMmsOperationResult; // OK
tEntry.SetReadOnly( ETrue );
iServerEntry->ChangeEntry( tEntry );
}
}
}
}
} // outer for loop (iSelection)
CleanupStack::PopAndDestroy( mmsHeaders );
}
iServerEntry->SetEntry( KMsvNullIndexEntryId );
FallThrough();
}
// ---------------------------------------------------------
// CMmsDeleteOperation::DeleteNotificationEntryL
//
// ---------------------------------------------------------
//
void CMmsDeleteOperation::DeleteNotificationEntryL()
{
#ifndef _NO_MMSS_LOGGING_
TMmsLogger::Log( _L( "CMmsDeleteOperation::DeleteNotificationEntryL()" ) );
#endif
// Get indexentry
TMsvEntry tEntry = iServerEntry->Entry();
TInt error = iServerEntry->SetEntry( tEntry.Parent());
if ( error == KErrNone )
{
// Can delete entry only if setting entry to parent was successful
iServerEntry->DeleteEntry( tEntry.Id() );
}
iServerEntry->SetEntry( KMsvNullIndexEntryId );
}
// ---------------------------------------------------------
// CMmsDeleteOperation::MarkSelectionAsFailed
//
// ---------------------------------------------------------
//
void CMmsDeleteOperation::MarkSelectionAsFailed()
{
#ifndef _NO_MMSS_LOGGING_
TMmsLogger::Log( _L( "CMmsDeleteOperation::MarkSelectionAsFailed()" ) );
#endif
// Loop through iSelection
for( TInt i = iSelection->Count(); i > 0; i-- )
{
TInt error = KErrNone;
error = iServerEntry->SetEntry( iSelection->At( i-1 ) );
if ( error == KErrNone )
{
// If notification in iSelection is in mmbox folder, mark the
// possible duplicate notification in inbox too.
if ( iServerEntry->Entry().Parent() == iMmsSettings->MMBoxFolder() )
{
#ifndef _NO_MMSS_LOGGING_
TMmsLogger::Log( _L( "- check possible duplicate" ) );
#endif
TRAP ( error, MarkDuplicateL( EMmsNotificationOperationFailed, *iServerEntry ) );
#ifndef _NO_MMSS_LOGGING_
TMmsLogger::Log( _L("Trap failed: error %d "), error );
#endif
}
// Mark the original notification in selection
// MarkDuplicateL does not mess up the original context of iServerEntry
TMsvEntry tEntry = iServerEntry->Entry();
MarkNotificationOperationFailed( tEntry );
tEntry.SetReadOnly( ETrue );
error = iServerEntry->ChangeEntry( tEntry );
#ifndef _NO_MMSS_LOGGING_
if( error != KErrNone )
{
TMmsLogger::Log( _L( "ERROR: ChangeEntry() failed" ) );
}
else
{
TMmsLogger::Log( _L( "- selection[%d] flags are cleared" ), i );
}
#endif
}
}
iServerEntry->SetEntry( KMsvNullIndexEntryId );
}
// ================= OTHER EXPORTED FUNCTIONS ==============
// End of File