--- a/ipsservices/ipssosplugin/src/ipsplgnewchildpartfromfileoperation.cpp Fri Apr 16 14:51:52 2010 +0300
+++ b/ipsservices/ipssosplugin/src/ipsplgnewchildpartfromfileoperation.cpp Mon May 03 12:23:15 2010 +0300
@@ -26,6 +26,7 @@
_LIT( KMimeTextCalRequest, "text/calendar; method=REQUEST;" );
_LIT( KMimeTextCalResponse, "text/calendar; method=RESPONSE;" );
_LIT( KMimeTextCalCancel, "text/calendar; method=CANCEL;" );
+_LIT( KFileExtensionICS, ".ics" );
_LIT8( KMethod, "method" );
_LIT8( KRequest, "REQUEST" );
@@ -35,10 +36,10 @@
// ================= MEMBER FUNCTIONS =======================
// ----------------------------------------------------------------------------
-// CCIpsPlgNewChildPartFromFileOperation::CCIpsPlgNewChildPartFromFileOperation
+// CIpsPlgNewChildPartFromFileOperation::CIpsPlgNewChildPartFromFileOperation
// ----------------------------------------------------------------------------
//
-CCIpsPlgNewChildPartFromFileOperation::CCIpsPlgNewChildPartFromFileOperation(
+CIpsPlgNewChildPartFromFileOperation::CIpsPlgNewChildPartFromFileOperation(
CMsvSession& aMsvSession,
TRequestStatus& aObserverRequestStatus,
const TFSMailMsgId& aMailBoxId,
@@ -46,24 +47,23 @@
MFSMailRequestObserver& aOperationObserver,
const TInt aRequestId)
:
- CMsvOperation(
- aMsvSession,
- CActive::EPriorityStandard,
- aObserverRequestStatus),
- iMailBoxId(aMailBoxId),
+ CIpsPlgBaseOperation(
+ aMsvSession,
+ aObserverRequestStatus,
+ aRequestId,
+ aMailBoxId),
iMessageId(aMessageId),
- iOperationObserver(aOperationObserver),
- iRequestId(aRequestId)
+ iOperationObserver(aOperationObserver)
{
FUNC_LOG;
CActiveScheduler::Add( this );
}
// ----------------------------------------------------------------------------
-// CCIpsPlgNewChildPartFromFileOperation::NewL
+// CIpsPlgNewChildPartFromFileOperation::NewL
// ----------------------------------------------------------------------------
//
-CCIpsPlgNewChildPartFromFileOperation* CCIpsPlgNewChildPartFromFileOperation::NewL(
+CIpsPlgNewChildPartFromFileOperation* CIpsPlgNewChildPartFromFileOperation::NewL(
CMsvSession& aMsvSession,
TRequestStatus& aObserverRequestStatus,
const TFSMailMsgId& aMailBoxId,
@@ -75,8 +75,8 @@
CIpsPlgMsgMapper *aMsgMapper)
{
FUNC_LOG;
- CCIpsPlgNewChildPartFromFileOperation* self =
- new (ELeave) CCIpsPlgNewChildPartFromFileOperation(
+ CIpsPlgNewChildPartFromFileOperation* self =
+ new (ELeave) CIpsPlgNewChildPartFromFileOperation(
aMsvSession,
aObserverRequestStatus,
aMailBoxId,
@@ -90,55 +90,61 @@
}
// ----------------------------------------------------------------------------
-// CCIpsPlgNewChildPartFromFileOperation::ConstructL
+// CIpsPlgNewChildPartFromFileOperation::ConstructL
// ----------------------------------------------------------------------------
//
-void CCIpsPlgNewChildPartFromFileOperation::ConstructL(CIpsPlgMsgMapper *aMsgMapper,
+void CIpsPlgNewChildPartFromFileOperation::ConstructL(CIpsPlgMsgMapper *aMsgMapper,
const TDesC& aContentType,
const TDesC& aFilePath)
{
FUNC_LOG;
iMsgMapper = aMsgMapper;
- iStatus = KRequestPending;
iContentType = aContentType.AllocL();
iFilePath = aFilePath.AllocL();
- // Start async request in RunL
- iStep = EStep1; // First step
- SetActive();
- iStatus = KRequestPending;
- TRequestStatus* status = &iStatus;
- User::RequestComplete(status,KErrNone);
+ // Start from attachment manager initialization
+ InitAttachmentManagerL();
}
// ----------------------------------------------------------------------------
-// CCIpsPlgNewChildPartFromFileOperation::~CCIpsPlgNewChildPartFromFileOperation
+// CIpsPlgNewChildPartFromFileOperation::~CIpsPlgNewChildPartFromFileOperation
// ----------------------------------------------------------------------------
//
-CCIpsPlgNewChildPartFromFileOperation::~CCIpsPlgNewChildPartFromFileOperation()
+CIpsPlgNewChildPartFromFileOperation::~CIpsPlgNewChildPartFromFileOperation()
{
FUNC_LOG;
Cancel(); // Cancel any request, if outstanding
delete iOperation;
+ iOperation = NULL;
delete iContentType;
+ iContentType = NULL;
delete iFilePath;
+ iFilePath = NULL;
}
// ----------------------------------------------------------------------------
-// CCIpsPlgNewChildPartFromFileOperation::DoCancel
+// CIpsPlgNewChildPartFromFileOperation::DoCancel
// ----------------------------------------------------------------------------
//
-void CCIpsPlgNewChildPartFromFileOperation::DoCancel()
+void CIpsPlgNewChildPartFromFileOperation::DoCancel()
{
FUNC_LOG;
+
if (iOperation)
{
iOperation->Cancel();
}
+
+ if (iMessage)
+ {
+ iMessage->AttachmentManager().CancelRequest();
+ iMessage->Cancel();
+ }
+
TRequestStatus* status = &iObserverRequestStatus;
if ( status && status->Int() == KRequestPending )
{
- SignalFSObserver( iStatus.Int(), NULL );
+ SignalFSObserver(iStatus.Int(),NULL);
User::RequestComplete( status, iStatus.Int() );
}
}
@@ -148,7 +154,7 @@
// Checks whether the requested message is already cached. If not, the cached
// objects are deleted and new objects are created.
// ----------------------------------------------------------------------------
-void CCIpsPlgNewChildPartFromFileOperation::GetMessageEntryL(
+void CIpsPlgNewChildPartFromFileOperation::GetMessageEntryL(
TMsvId aId,
CMsvEntry*& aMessageEntry,
CImEmailMessage*& aImEmailMessage )
@@ -172,7 +178,7 @@
// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
//
-void CCIpsPlgNewChildPartFromFileOperation::CleanCachedMessageEntries()
+void CIpsPlgNewChildPartFromFileOperation::CleanCachedMessageEntries()
{
FUNC_LOG;
delete iCachedEmailMessage;
@@ -182,183 +188,218 @@
}
// ----------------------------------------------------------------------------
-// CCIpsPlgNewChildPartFromFileOperation::RunL
+// CIpsPlgNewChildPartFromFileOperation::RunL
// ----------------------------------------------------------------------------
//
-void CCIpsPlgNewChildPartFromFileOperation::RunL()
+void CIpsPlgNewChildPartFromFileOperation::RunL()
{
if( iStatus.Int() == KErrNone )
- // divided to 4 steps, run asunchronously from 1 to 4
- switch (iStep)
{
- case EStep1:
- {
- iEntry = NULL;
- iMessage = NULL;
- RFile file;
- TInt fileSize( 0 );
-
- // Read attachment size
- TRAPD(err,file.Open( iMsvSession.FileSession(), iFilePath->Des(), EFileShareReadersOnly ));
- if (err != KErrNone)
- {
- RunError(err);
- }
-
- //in rare case that file has disappeared while sending
- //we just won't get the size for it
- file.Size( fileSize );
- file.Close();
-
- // Initialize CMsvAttachment instance for the attachment creation
- CMsvAttachment* info = CMsvAttachment::NewL( CMsvAttachment::EMsvFile );
- CleanupStack::PushL( info );
-
- info->SetAttachmentNameL( iFilePath->Des() );
- info->SetSize( fileSize );
-
- // Create/acquire Symbian message entry objects
- GetMessageEntryL( iMessageId.Id(), iEntry, iMessage );
-
- // Start attachment creation
- iStatus = KRequestPending;
- iMessage->AttachmentManager().AddAttachmentL(
- iFilePath->Des(), info, iStatus );
- CleanupStack::Pop( info ); // attachment manager takes ownership
- iStep = EStep2; // Next step
- SetActive();
+ // Divided to 3 steps. Run asunchronously after InitAttachmentManagerL.
+ // PrepareMsvEntryL, PrepareStoreL and StoreMessagePartL respectively
+ switch (iStep)
+ {
+ case EPrepareMsvEntry:
+ PrepareMsvEntryL();
break;
- }
- case EStep2:
- {
- // Dig out the entry ID of the new attachment (unbelievable that
- // there seems to be no better way to do this)
- iMessage->GetAttachmentsListL( iEntry->Entry().Id( ),
- CImEmailMessage::EAllAttachments, CImEmailMessage::EThisMessageOnly );
- TKeyArrayFix key( 0, ECmpTInt32 );
- CMsvEntrySelection* attachmentIds = iMessage->Selection().CopyLC();
- attachmentIds->Sort( key );
- if ( !attachmentIds->Count() )
- {
- User::Leave( KErrGeneral );
- }
- iNewAttachmentId = (*attachmentIds)[ attachmentIds->Count()-1 ];
- CleanupStack::PopAndDestroy( attachmentIds );
-
- CMsvEntry* cAtta = iMsvSession.GetEntryL( iNewAttachmentId );
- CleanupStack::PushL( cAtta );
-
- // Set filename to iDetails
- TMsvEntry tEntry = cAtta->Entry();
- tEntry.iDetails.Set(iFilePath->Des());
-
- // Do async
- iStatus = KRequestPending;
- cAtta->ChangeL( tEntry, iStatus );
- CleanupStack::PopAndDestroy( cAtta );
- iStep = EStep3; // Next step
- SetActive();
+ case EPrepareStore:
+ PrepareStoreL();
break;
- }
- case EStep3:
- {
- CMsvEntry* cAtta = iMsvSession.GetEntryL( iNewAttachmentId );
- CleanupStack::PushL( cAtta );
- TBool parentToMultipartAlternative( EFalse );
- if( cAtta->HasStoreL() )
- {
- CMsvStore* store = cAtta->EditStoreL();
- CleanupStack::PushL( store );
- CImMimeHeader* mimeHeader = CImMimeHeader::NewLC();
-
- if( store->IsPresentL( KUidMsgFileMimeHeader ) )
- {
- mimeHeader->RestoreL( *store );
- CDesC8Array& array = mimeHeader->ContentTypeParams();
- array.AppendL( KMethod );
- parentToMultipartAlternative = ETrue;
-
- if( iContentType->Des().Find( KMimeTextCalRequest ) != KErrNotFound )
- {
- array.AppendL( KRequest );
- }
- else if( iContentType->Des().Find( KMimeTextCalResponse ) != KErrNotFound )
- {
- array.AppendL( KResponse );
- }
- else if( iContentType->Des().Find( KMimeTextCalCancel ) != KErrNotFound )
- {
- array.AppendL( KCancel );
- }
- else
- {
- parentToMultipartAlternative = EFalse;
- }
- mimeHeader->StoreWithoutCommitL( *store );
- store->CommitL();
- }
-
- CleanupStack::PopAndDestroy( 2, store );
- }
-
- if( parentToMultipartAlternative &&
- iFilePath->Find( _L(".ics")) != KErrNotFound )
- {
- TMsvEntry tAttaEntry = cAtta->Entry();
- TMsvId id = tAttaEntry.Parent();
- CMsvEntry* cParent = iMsvSession.GetEntryL( id );
- CleanupStack::PushL( cParent );
-
- TMsvEmailEntry tEntry = cParent->Entry();
- tEntry.SetMessageFolderType( EFolderTypeAlternative );
-
- // Do async again if needed
- iStatus = KRequestPending;
- cParent->ChangeL( tEntry, iStatus );
- CleanupStack::PopAndDestroy( cParent );
- CleanupStack::PopAndDestroy( cAtta );
- iStep = EStep4; // Next step
- SetActive();
- break;
- }
- CleanupStack::PopAndDestroy( cAtta );
- iStep = EStep4; // Next step
- // Continue to next step wihout break;
- }
- case EStep4:
- {
- // Delete the message entries to get all the changes to disk and
- // possible store locks released
- CleanCachedMessageEntries();
-
- CFSMailMessagePart* result ( NULL );
- // Create the FS message part object
- result = iMsgMapper->GetMessagePartL( iNewAttachmentId, iMailBoxId,
- iMessageId );
-
- // Set attachment name
- result->SetAttachmentNameL(iFilePath->Des());
-
- // store message part
- result->SaveL();
-
- // set flag
- result->SetFlag(EFSMsgFlag_Attachments);
-
- SignalFSObserver(iStatus.Int(),result);
- // nothing left to process, so complete the observer
- TRequestStatus* status = &iObserverRequestStatus;
- User::RequestComplete( status, iStatus.Int() );
+ case EStoreMessagePart:
+ StoreMessagePartL();
break;
- }
+ }
+ }
+ else if (iStatus.Int() == KErrCancel)
+ {
+ // Do Nothing
+ }
+ else
+ {
+ User::Leave(iStatus.Int());
}
}
// ----------------------------------------------------------------------------
-// CCIpsPlgNewChildPartFromFileOperation::RunError
+// CIpsPlgNewChildPartFromFileOperation::InitAttachmentManagerL
+// ----------------------------------------------------------------------------
+//
+void CIpsPlgNewChildPartFromFileOperation::InitAttachmentManagerL()
+ {
+ iEntry = NULL;
+ iMessage = NULL;
+ RFile file;
+ TInt fileSize( 0 );
+
+ // Read attachment size
+ User::LeaveIfError(
+ file.Open( iMsvSession.FileSession(), iFilePath->Des(), EFileShareReadersOnly )
+ );
+
+ //in rare case that file has disappeared while sending
+ //we just won't get the size for it
+ file.Size( fileSize );
+ file.Close();
+
+ // Initialize CMsvAttachment instance for the attachment creation
+ CMsvAttachment* info = CMsvAttachment::NewL( CMsvAttachment::EMsvFile );
+ CleanupStack::PushL( info );
+
+ info->SetAttachmentNameL( iFilePath->Des() );
+ info->SetSize( fileSize );
+
+ // Create/acquire Symbian message entry objects
+ GetMessageEntryL( iMessageId.Id(), iEntry, iMessage );
+
+ // Start attachment creation
+ iMessage->AttachmentManager().AddAttachmentL(
+ iFilePath->Des(), info, iStatus );
+ CleanupStack::Pop( info ); // attachment manager takes ownership
+ iStep = EPrepareMsvEntry; // Next step
+ SetActive();
+ }
+
+// ----------------------------------------------------------------------------
+// CIpsPlgNewChildPartFromFileOperation::PrepareMsvEntryL
+// ----------------------------------------------------------------------------
+//
+void CIpsPlgNewChildPartFromFileOperation::PrepareMsvEntryL()
+ {
+ // Dig out the entry ID of the new attachment
+ iMessage->GetAttachmentsListL( iEntry->Entry().Id( ),
+ CImEmailMessage::EAllAttachments, CImEmailMessage::EThisMessageOnly );
+ TKeyArrayFix key( 0, ECmpTInt32 );
+ CMsvEntrySelection* attachmentIds = iMessage->Selection().CopyLC();
+ attachmentIds->Sort( key );
+ if ( !attachmentIds->Count() )
+ {
+ User::Leave( KErrGeneral );
+ }
+ iNewAttachmentId = (*attachmentIds)[ attachmentIds->Count()-1 ];
+ CleanupStack::PopAndDestroy( attachmentIds );
+
+ CMsvEntry* cAtta = iMsvSession.GetEntryL( iNewAttachmentId );
+ CleanupStack::PushL( cAtta );
+
+ // Set filename to iDetails
+ TMsvEntry tEntry = cAtta->Entry();
+ tEntry.iDetails.Set(iFilePath->Des());
+
+ // Do async
+ iOperation = cAtta->ChangeL( tEntry, iStatus );
+ CleanupStack::PopAndDestroy( cAtta );
+ iStep = EPrepareStore; // Next step
+ SetActive();
+ }
+
+// ----------------------------------------------------------------------------
+// CIpsPlgNewChildPartFromFileOperation::PrepareStoreL
// ----------------------------------------------------------------------------
//
-TInt CCIpsPlgNewChildPartFromFileOperation::RunError(TInt aError)
+void CIpsPlgNewChildPartFromFileOperation::PrepareStoreL()
+ {
+ CMsvEntry* cAtta = iMsvSession.GetEntryL( iNewAttachmentId );
+ CleanupStack::PushL( cAtta );
+ TBool parentToMultipartAlternative( EFalse );
+ if( cAtta->HasStoreL() )
+ {
+ CMsvStore* store = cAtta->EditStoreL();
+ CleanupStack::PushL( store );
+ CImMimeHeader* mimeHeader = CImMimeHeader::NewLC();
+
+ if( store->IsPresentL( KUidMsgFileMimeHeader ) )
+ {
+ mimeHeader->RestoreL( *store );
+ CDesC8Array& array = mimeHeader->ContentTypeParams();
+ array.AppendL( KMethod );
+ parentToMultipartAlternative = ETrue;
+
+ if( iContentType->Des().Find( KMimeTextCalRequest ) != KErrNotFound )
+ {
+ array.AppendL( KRequest );
+ }
+ else if( iContentType->Des().Find( KMimeTextCalResponse ) != KErrNotFound )
+ {
+ array.AppendL( KResponse );
+ }
+ else if( iContentType->Des().Find( KMimeTextCalCancel ) != KErrNotFound )
+ {
+ array.AppendL( KCancel );
+ }
+ else
+ {
+ parentToMultipartAlternative = EFalse;
+ }
+ mimeHeader->StoreWithoutCommitL( *store );
+ store->CommitL();
+ }
+
+ CleanupStack::PopAndDestroy( 2, store );
+ }
+
+ if( parentToMultipartAlternative &&
+ iFilePath->Find( KFileExtensionICS ) != KErrNotFound )
+ {
+ TMsvEntry tAttaEntry = cAtta->Entry();
+ TMsvId id = tAttaEntry.Parent();
+ CMsvEntry* cParent = iMsvSession.GetEntryL( id );
+ CleanupStack::PushL( cParent );
+
+ TMsvEmailEntry tEntry = cParent->Entry();
+ tEntry.SetMessageFolderType( EFolderTypeAlternative );
+
+ // Do async again if needed
+
+ iOperation = cParent->ChangeL( tEntry, iStatus );
+ CleanupStack::PopAndDestroy( cParent );
+ CleanupStack::PopAndDestroy( cAtta );
+ }
+ else
+ {
+ CleanupStack::PopAndDestroy( cAtta );
+ iStatus = KRequestPending;
+ TRequestStatus* status = &iStatus;
+ User::RequestComplete(status,KErrNone);
+ }
+ iStep = EStoreMessagePart; // Next step
+ SetActive();
+ }
+
+// ----------------------------------------------------------------------------
+// CIpsPlgNewChildPartFromFileOperation::StoreMessagePartL
+// ----------------------------------------------------------------------------
+//
+void CIpsPlgNewChildPartFromFileOperation::StoreMessagePartL()
+ {
+ // Delete the message entries to get all the changes to disk and
+ // possible store locks released
+ CleanCachedMessageEntries();
+
+ CFSMailMessagePart* result ( NULL );
+ // Create the FS message part object
+ result = iMsgMapper->GetMessagePartL( iNewAttachmentId, iFSMailboxId,
+ iMessageId );
+
+ // Set attachment name
+ result->SetAttachmentNameL(iFilePath->Des());
+
+ // store message part
+ result->SaveL();
+
+ // set flag
+ result->SetFlag(EFSMsgFlag_Attachments);
+
+ SignalFSObserver(iStatus.Int(),result);
+ // nothing left to process, so complete the observer
+ TRequestStatus* status = &iObserverRequestStatus;
+ User::RequestComplete( status, iStatus.Int() );
+ }
+
+// ----------------------------------------------------------------------------
+// CIpsPlgNewChildPartFromFileOperation::RunError
+// ----------------------------------------------------------------------------
+//
+TInt CIpsPlgNewChildPartFromFileOperation::RunError(TInt aError)
{
FUNC_LOG;
SignalFSObserver( aError, NULL );
@@ -369,47 +410,68 @@
}
// ----------------------------------------------------------------------------
-// CCIpsPlgNewChildPartFromFileOperation::SignalFSObserver
+// CIpsPlgNewChildPartFromFileOperation::SignalFSObserver
// ----------------------------------------------------------------------------
//
-void CCIpsPlgNewChildPartFromFileOperation::SignalFSObserver(
+void CIpsPlgNewChildPartFromFileOperation::SignalFSObserver(
TInt aStatus, CFSMailMessagePart* aMessagePart )
{
FUNC_LOG;
- TFSProgress result =
- { TFSProgress::EFSStatus_Waiting, 0, 0, KErrNone, aMessagePart };
-
if ( aStatus == KErrCancel )
{
- result.iProgressStatus = TFSProgress::EFSStatus_RequestCancelled;
- result.iError = KErrCancel;
+ iFSProgress.iProgressStatus = TFSProgress::EFSStatus_RequestCancelled;
+ iFSProgress.iError = KErrCancel;
+ iFSProgress.iParam = NULL;
}
else
{
- result.iProgressStatus = TFSProgress::EFSStatus_RequestComplete;
- result.iError = aStatus;
+ iFSProgress.iProgressStatus = TFSProgress::EFSStatus_RequestComplete;
+ iFSProgress.iError = aStatus;
+ iFSProgress.iParam = aMessagePart;
}
- TRAP_IGNORE( iOperationObserver.RequestResponseL( result, iRequestId ) );
+ TRAP_IGNORE( iOperationObserver.RequestResponseL( iFSProgress, iFSRequestId ) );
}
// ----------------------------------------------------------------------------
-// CCIpsPlgNewChildPartFromFileOperation::ProgressL
+// CIpsPlgNewChildPartFromFileOperation::ProgressL
// ----------------------------------------------------------------------------
//
-const TDesC8& CCIpsPlgNewChildPartFromFileOperation::ProgressL()
+const TDesC8& CIpsPlgNewChildPartFromFileOperation::ProgressL()
{
FUNC_LOG;
// Make sure that operation is active
- if ( IsActive() )
- {
- // Get progress
- if ( iOperation )
- {
- return iOperation->ProgressL();
- }
- }
- return iBlank;
+ return (IsActive() && iOperation) ?
+ iOperation->ProgressL() : KNullDesC8;
+ }
+
+// ---------------------------------------------------------------------------
+// CIpsPlgNewChildPartFromFileOperation::GetErrorProgressL
+// ---------------------------------------------------------------------------
+//
+const TDesC8& CIpsPlgNewChildPartFromFileOperation::GetErrorProgressL( TInt /*aError*/ )
+ {
+ FUNC_LOG;
+ return KNullDesC8; // error progress info not supported
+ }
+
+// ---------------------------------------------------------------------------
+// CIpsPlgNewChildPartFromFileOperation::GetFSProgressL
+// ---------------------------------------------------------------------------
+//
+TFSProgress CIpsPlgNewChildPartFromFileOperation::GetFSProgressL() const
+ {
+ FUNC_LOG;
+ return iFSProgress;
+ }
+
+// ----------------------------------------------------------------------------
+// CIpsPlgNewChildPartFromFileOperation::IpsOpType
+// ----------------------------------------------------------------------------
+TIpsOpType CIpsPlgNewChildPartFromFileOperation::IpsOpType() const
+ {
+ FUNC_LOG;
+ return EIpsOpTypeNewChildPartFromFile;
}
// End of File