diff -r 000000000000 -r 8466d47a6819 meetingrequest/mricalviewer/src/cesmrmrinfoicalretriever.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/meetingrequest/mricalviewer/src/cesmrmrinfoicalretriever.cpp Thu Dec 17 08:39:21 2009 +0200 @@ -0,0 +1,706 @@ +/* +* Copyright (c) 2007-2009 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: ESMR mrinfo calendar entry retriever implementation +* +*/ + + +#include "emailtrace.h" +#include "cesmrmrinfoicalretriever.h" +#include "cesmrinforecurrencehandler.h" +#include "cesmrattachmentinfo.h" +#include "mesmricalviewerobserver.h" +#include "tesmrinputparams.h" +#include "esmricalviewerutils.h" +#include "esmrconfig.hrh" + +// +#include "esmricalvieweropcodes.hrh" +#include "CFSMailClient.h" +#include "CFSMailBox.h" +#include "CFSMailMessage.h" +#include "CFSMailMessagePart.h" +#include "CFSMailCommon.h" +#include "mmrinfoprocessor.h" +#include "mmrattendee.h" +#include "mmrrecurrencerule.h" +// + +#include +#include +#include +#include +#include + +// Unnamed namespace for local definitions and functions +namespace { + +/** + * Raises system leave if parameter is different than KErrNone. + * + * @param aError Error code + */ +void LeaveIfError( TInt aError ) + { + if ( KErrNone != aError ) + { + + User::Leave( aError ); + } + } + +/** + * Tests if certain field is supported by MRINFO object. + * @param aFields Reference to MRINFO fields' + * @param aFieldType Tested fieldtype + */ +TBool IsFieldSupported( + RArray& aFields, + MMRInfoObject::TESMRInfoField aFieldType) + { + TInt fieldSupported( ETrue ); + + TInt fieldCount( aFields.Count() ); + for (TInt i=0; i < fieldCount; ++i) + { + if (aFields[i] == aFieldType) + { + fieldSupported = ETrue; + break; + } + } + return fieldSupported; + } + +/** + * Converts MRINFO method to CCalEntry method. + * @param aMRMethod MRINFO method. + * @return CCalEntry method. + */ +CCalEntry::TMethod ConverMRMethodToCalEntryMethod( + MMRInfoObject::TMRMethod aMRMethod ) + { + CCalEntry::TMethod ret(CCalEntry::EMethodNone); + switch (aMRMethod) + { + case MMRInfoObject::EMRMethodRequest: + { + ret = CCalEntry::EMethodRequest; + break; + } + case MMRInfoObject::EMRMethodCancel: + { + ret = CCalEntry::EMethodCancel; + break; + } + case MMRInfoObject::EMRMethodResponse: + { + ret = CCalEntry::EMethodReply; + break; + } + default: + break; + } + return ret; + } + +/** + * Converts MMRINFO response status to CCalEntry response status. + * @param aMRResponseStatus MRINFO response status. + * @return CCalEntry response status. + */ +CCalEntry::TStatus ConvertMRResponseToCalEntryStatus( + MMRInfoObject::TResponse aMRResponseStatus ) + { + FUNC_LOG; + CCalEntry::TStatus ret(CCalEntry::ENullStatus); + switch (aMRResponseStatus) + { + case MMRInfoObject::EMrCmdResponseAccept: + { + ret = CCalEntry::EConfirmed; + break; + } + case MMRInfoObject::EMrCmdResponseTentative: + { + ret = CCalEntry::ETentative; + break; + } + case MMRInfoObject::EMrCmdResponseDecline: + { + ret = CCalEntry::ECancelled; + break; + } + default: + break; + } + return ret; + } + +/** + * Converts MRINFO attendee role to MRINFO attendee role. + * @param aMRRole MRINFO attendee role. + * @return CCalEntry attendee role. + */ +CCalAttendee::TCalRole ConvertMRAttendeeRoleToCalEntryRole( + MMRAttendee::TAttendeeRole aMRRole) + { + CCalAttendee::TCalRole ret(CCalAttendee::ENonParticipant); + switch (aMRRole) + { + case MMRAttendee::EMRAttendeeNotSet: + { + ret = CCalAttendee::ENonParticipant; + break; + } + case MMRAttendee::EMRAttendeeChair: + { + ret = CCalAttendee::EChair; + break; + } + case MMRAttendee::EMRAttendeeParticipant: + { + ret = CCalAttendee::EReqParticipant; + break; + } + case MMRAttendee::EMRAttendeeOptionalParticipant: + { + ret = CCalAttendee::EOptParticipant; + break; + } + case MMRAttendee::EMRAttendeeNonParticipant: + { + ret = CCalAttendee::ENonParticipant; + break; + } + default: + break; + } + return ret; + } + +/** + * Converts MMRINFO response status to CCalEntry response status. + * @param aMRStatus MRINFO response status. + * @return CCalEntry response status. + */ +CCalAttendee::TCalStatus ConvertMRAttendeeStatusToCalEntryStatus( + MMRAttendee::TAttendeeStatus aMRStatus ) + { + FUNC_LOG; + CCalAttendee::TCalStatus ret(CCalAttendee::ENeedsAction); + switch (aMRStatus) + { + case MMRAttendee::EMRAttendeeActionNotSet: + { + ret = CCalAttendee::ENeedsAction; + break; + } + case MMRAttendee::EMRAttendeeActionNeeded: + { + ret = CCalAttendee::ENeedsAction; + break; + } + case MMRAttendee::EMRAttendeeActionAccepted: + { + ret = CCalAttendee::EAccepted; + break; + } + case MMRAttendee::EMRAttendeeActionTentative: + { + ret = CCalAttendee::ETentative; + break; + } + case MMRAttendee::EMRAttendeeActionConfirmed: + { + ret = CCalAttendee::EConfirmed; + break; + } + case MMRAttendee::EMRAttendeeActionDeclined: + { + ret = CCalAttendee::EDeclined; + break; + } + case MMRAttendee::EMRAttendeeActionCompleted: + { + ret = CCalAttendee::ECompleted; + break; + } + default: + break; + } + return ret; + } + +/** + * Copies attendees from MRINFO object to CCalEntry object. + * @param attendeesArray array of meeting request attendees + * @param calendar entry of the meeting request + */ +void FillAttendeesL( + RPointerArray& attendeesArray, + CCalEntry& aEntry) + { + + CCalAttendee* attendee = NULL; + TInt attendeeArrayCount( attendeesArray.Count() ); + for (TInt i=0; i < attendeeArrayCount; ++i) + { + // New attendee + address + attendee = CCalAttendee::NewL( attendeesArray[i]->Address() ); + CleanupStack::PushL(attendee); + // Common name: + if ( attendeesArray[i]->CommonName().Length() > 0 ) + { + attendee->SetCommonNameL( attendeesArray[i]->CommonName() ); + } + + // Set attendeee role: + attendee->SetRoleL( + ConvertMRAttendeeRoleToCalEntryRole( + attendeesArray[i]->AttendeeRole() ) ); + + // add attendee status: + attendee->SetStatusL( + ConvertMRAttendeeStatusToCalEntryStatus( + attendeesArray[i]->AttendeeStatus() ) ); + + // add attendee to entry + aEntry.AddAttendeeL( attendee ); + CleanupStack::Pop(attendee); + } + } + +/** + * Tests if MRINFO object is modifying entry + * @param aEntry Reference to MRINFO object. + */ +TBool IsModifyingEntryL( + MMRInfoObject& aEntry ) + { + TBool modifying( EFalse ); + TTime recurrenceId = aEntry.MRRecurrenceId(); + + if ( recurrenceId != Time::NullTTime() ) + { + modifying = ETrue; + } + + return modifying; + } + +}//namespace + +// ======== MEMBER FUNCTIONS ======== + +// --------------------------------------------------------------------------- +// CESMRInfoIcalRetrieverCmd::CESMRInfoIcalRetrieverCmd +// --------------------------------------------------------------------------- +// +CESMRInfoIcalRetrieverCmd::CESMRInfoIcalRetrieverCmd( + CCalSession& aCalSession, + TESMRInputParams& aInputParameters ) +: CESMRIcalViewerCommandBase( EESMRLoadMRInfoData, aCalSession ), + iInputParameters( aInputParameters ) + { + FUNC_LOG; + //do nothing + } + +// --------------------------------------------------------------------------- +// CESMRInfoIcalRetrieverCmd::~CESMRInfoIcalRetrieverCmd +// --------------------------------------------------------------------------- +// +CESMRInfoIcalRetrieverCmd::~CESMRInfoIcalRetrieverCmd() + { + FUNC_LOG; + iSupportedFields.Reset(); + iSupportedFields.Close(); + delete iAttachmentInfo; + delete iConvertedEntry; + } + +// --------------------------------------------------------------------------- +// CESMRInfoIcalRetriever::NewL +// --------------------------------------------------------------------------- +// +CESMRInfoIcalRetrieverCmd* CESMRInfoIcalRetrieverCmd::NewL( + CCalSession& aCalSession, + TESMRInputParams& aInputParameters ) + { + FUNC_LOG; + CESMRInfoIcalRetrieverCmd* self = + new (ELeave) CESMRInfoIcalRetrieverCmd( aCalSession, aInputParameters ); + CleanupStack::PushL( self ); + self->ConstructL(); + CleanupStack::Pop( self ); + return self; + } + +// --------------------------------------------------------------------------- +// CESMRInfoIcalRetrieverCmd::ConstructL +// --------------------------------------------------------------------------- +// +void CESMRInfoIcalRetrieverCmd::ConstructL() + { + FUNC_LOG; + //do nothing + } + +// --------------------------------------------------------------------------- +// CESMRInfoIcalRetriever::ExecuteCommandL +// --------------------------------------------------------------------------- +// +void CESMRInfoIcalRetrieverCmd::ExecuteCommandL( + CFSMailMessage& aMessage, + MESMRIcalViewerObserver& aObserver ) + { + FUNC_LOG; + SetMessage( &aMessage ); + SetObserver( &aObserver ); + + iResult.iOpType = OperationType(); + iResult.iResultCode = KErrNone; + iResult.iMessage = &aMessage; + + // Fetch MRINFO object + if ( !aMessage.IsMRInfoSet() ) + { + iResult.iResultCode = KErrNotFound; + aObserver.OperationError( iResult ); + } + else + { + iMRInfoObject = &(aMessage.GetMRInfo()); + + CreateEntryL(); + FillCommonFieldsL(); + + if ( !IsModifyingEntryL( *iMRInfoObject ) ) + { + FillRecurrenceL(); + } + + FillAttachmentInfoL(); + + // Fill input parameters + // Ownership is not trasferred + iInputParameters.iCalEntry = iConvertedEntry; + + iInputParameters.iMRInfoObject = iMRInfoObject; + iMRInfoObject = NULL; + + aObserver.OperationCompleted( iResult ); + } + } + +// --------------------------------------------------------------------------- +// CESMRInfoIcalRetrieverCmd::CancelCommand +// --------------------------------------------------------------------------- +// +void CESMRInfoIcalRetrieverCmd::CancelCommand() + { + FUNC_LOG; + // No implementation required because this is synchronous command + } + +// --------------------------------------------------------------------------- +// CESMRInfoIcalRetrieverCmd::CreateEntryL +// --------------------------------------------------------------------------- +// +void CESMRInfoIcalRetrieverCmd::CreateEntryL() + { + FUNC_LOG; + iMRInfoObject->SupportedFields( iSupportedFields ); + + HBufC8* uid8 = NULL; // buffer for UID + TInt seqNum(0); // Sequence Number + CCalEntry::TMethod method( CCalEntry::EMethodNone ); // Method + + // fetch the UID + if (IsFieldSupported(iSupportedFields, MMRInfoObject::EESMRInfoFieldId)) + { + // CnvUtfConverter + TPtrC uid16( iMRInfoObject->UidL() ); + uid8 = CnvUtfConverter::ConvertFromUnicodeToUtf8L( uid16 ); + + CleanupStack::PushL( uid8 ); + } + else + { + User::Leave( KErrCorrupt ); + } + + // Fetch the sequence nunber + if (IsFieldSupported(iSupportedFields, MMRInfoObject::EESMRInfoFieldSeqNo)) + { + seqNum = iMRInfoObject->MRSequenceNumberL(); + } + + // Fetch the method + if ( IsFieldSupported(iSupportedFields, MMRInfoObject::EESMRInfoFieldMethod) ) + { + MMRInfoObject::TMRMethod mrMethod = iMRInfoObject->MRMethodL(); + method = ConverMRMethodToCalEntryMethod(mrMethod); + if (method == CCalEntry::EMethodNone) + { + LeaveIfError( KErrCorrupt ); + } + } + else + { + LeaveIfError( KErrCorrupt ); + } + + // create new entry: + delete iConvertedEntry; iConvertedEntry = NULL; + + if ( !IsModifyingEntryL( *iMRInfoObject ) ) + { + iConvertedEntry = CCalEntry::NewL (CCalEntry::EAppt, + uid8, + method, + seqNum ); + } + else + { + TBool seqNoSupported( + IsFieldSupported( iSupportedFields, MMRInfoObject::EESMRInfoFieldSeqNo ) ); + + if( !seqNoSupported ) + { + LeaveIfError( KErrCorrupt ); + } + + TInt seqwNo( iMRInfoObject->MRSequenceNumberL() ); + TCalTime recurrenceID; + recurrenceID.SetTimeLocalL( iMRInfoObject->MRRecurrenceId() ); + + iConvertedEntry = CCalEntry::NewL( + CCalEntry::EAppt, + uid8, + method, + seqwNo, + recurrenceID, + CalCommon::EThisOnly ); + } + + CleanupStack::Pop(uid8 ); + } + +// --------------------------------------------------------------------------- +// CESMRInfoIcalRetrieverCmd::FillCommonFieldsL +// --------------------------------------------------------------------------- +// +void CESMRInfoIcalRetrieverCmd::FillCommonFieldsL() + { + FUNC_LOG; + if (IsFieldSupported( + iSupportedFields, + MMRInfoObject::EESMRInfoFieldMStatus)) + { + CCalEntry::TStatus status = + ConvertMRResponseToCalEntryStatus(iMRInfoObject->MRResponse()); + iConvertedEntry->SetStatusL(status); + } + + if (IsFieldSupported( + iSupportedFields, + MMRInfoObject::EESMRInfoFieldCreationDateTime)) + { + TTime creationTime = iMRInfoObject->CreationTimeInUtcL(); + iConvertedEntry->SetLastModifiedDateL(); + } + + if (IsFieldSupported( + iSupportedFields, + MMRInfoObject::EESMRInfoFieldOrganizer)) + { + MMROrganizer* mrOrganizer = &iMRInfoObject->MROrganizerL(); + CCalUser* organizer = CCalUser::NewL(mrOrganizer->Address()); + CleanupStack::PushL(organizer); + if ( mrOrganizer->CommonName().Length() > 0 ) + { + organizer->SetCommonNameL(mrOrganizer->CommonName()); + } + + iConvertedEntry->SetOrganizerL(organizer); + CleanupStack::Pop(organizer); + } + + if (IsFieldSupported( + iSupportedFields, MMRInfoObject::EESMRInfoFieldAttendee) || + IsFieldSupported( + iSupportedFields, MMRInfoObject::EESMRInfoFieldOptAttendee) ) + { + RPointerArray attendeesArray = iMRInfoObject->AttendeesL(); + // go through attendee array and append attendees + FillAttendeesL(attendeesArray, *iConvertedEntry ); + } + + if (IsFieldSupported(iSupportedFields, MMRInfoObject::EESMRInfoFieldStartDateTime) && + IsFieldSupported(iSupportedFields, MMRInfoObject::EESMRInfoFieldStopDateTime) ) + { + TTime start = iMRInfoObject->StartTimeInUtcL(); + TTime end = iMRInfoObject->EndTimeInUtcL(); + TCalTime calStart; + calStart.SetTimeUtcL(start); + TCalTime calEnd; + calEnd.SetTimeUtcL(end); + iConvertedEntry->SetStartAndEndTimeL(calStart, calEnd); + } + + + if (IsFieldSupported(iSupportedFields, MMRInfoObject::EESMRInfoFieldLocation)) + { + TPtrC location( iMRInfoObject->LocationL() ); + iConvertedEntry->SetLocationL( location ); + } + + if ( IsFieldSupported(iSupportedFields, MMRInfoObject::EESMRInfoFieldStartDateTime) && + IsFieldSupported(iSupportedFields, MMRInfoObject::EESMRInfoFieldAlarm)) + { + CCalAlarm* alarm = CCalAlarm::NewL(); + CleanupStack::PushL( alarm ); + + TTime start = iMRInfoObject->StartTimeInUtcL(); + TTime alarmTime = iMRInfoObject->AlarmInUtcL(); + + TDateTime startDateTime = start.DateTime(); + TDateTime alarmDateTime = alarmTime.DateTime(); + + TTimeIntervalMinutes minutesBetween; + TInt err = start.MinutesFrom(alarmTime, minutesBetween); + + if ( KErrNone == err && minutesBetween.Int() > 0 ) + { + alarm->SetTimeOffset( minutesBetween ); + // this method copies alarm details and does not take ownership + iConvertedEntry->SetAlarmL( alarm ); + } + // that's why we can destroy it here + CleanupStack::PopAndDestroy( alarm ); + } + + if (IsFieldSupported(iSupportedFields, MMRInfoObject::EESMRInfoFieldSubject)) + { + TPtrC summary( iMRInfoObject->SubjectL() ); + iConvertedEntry->SetSummaryL(summary); + } + + if (IsFieldSupported(iSupportedFields, MMRInfoObject::EESMRInfoFieldDescription)) + { + TPtrC description( iMRInfoObject->DescriptionL() ); + iConvertedEntry->SetDescriptionL(description); + } + + if (IsFieldSupported(iSupportedFields, MMRInfoObject::EESMRInfoFieldPriority)) + { + iConvertedEntry->SetPriorityL( iMRInfoObject->PriorityL() ); + } + } + +// --------------------------------------------------------------------------- +// CESMRInfoIcalRetrieverCmd::FillCommonFieldsL +// --------------------------------------------------------------------------- +// +void CESMRInfoIcalRetrieverCmd::FillRecurrenceL() + { + FUNC_LOG; + if (IsFieldSupported( + iSupportedFields, + MMRInfoObject::EESMRInfoFieldRecurrence)) + { + CESMRInfoRecurrenceHandler* recurrenceHandler = + CESMRInfoRecurrenceHandler::NewLC(); + + recurrenceHandler->ParseRecurrenceInforationL( + *iConvertedEntry, + *iMRInfoObject ); + + CleanupStack::PopAndDestroy( recurrenceHandler ); + } + } + +// --------------------------------------------------------------------------- +// CESMRInfoIcalRetrieverCmd::FillAttachmentInfoL +// --------------------------------------------------------------------------- +// +void CESMRInfoIcalRetrieverCmd::FillAttachmentInfoL() + { + FUNC_LOG; + CFSMailMessage* msg = Message(); + + if ( msg->IsFlagSet( EFSMsgFlag_Attachments ) ) + { + RPointerArray attachmentParts; + CleanupStack::PushL( + TCleanupItem( + ESMRIcalViewerUtils::MessagePartPointerArrayCleanup, + &attachmentParts ) ); + + msg->AttachmentListL( attachmentParts ); + + TInt attachmentCount( attachmentParts.Count() ); + if ( attachmentCount > 0 ) + { + delete iAttachmentInfo; + iAttachmentInfo = NULL; + + iInputParameters.iAttachmentInfo = NULL; + + CESMRAttachmentInfo* attachmentInfo = CESMRAttachmentInfo::NewL(); + CleanupStack::PushL( attachmentInfo ); + + for( TInt i(0); i < attachmentCount; ++i ) + { + CESMRAttachment::TESMRAttachmentState state( + CESMRAttachment::EAttachmentStateDownloaded ); + + if ( EFSFull != attachmentParts[i]->FetchLoadState() ) + { + state = CESMRAttachment::EAttachmentStateNotDownloaded; + } + + TInt contentSize( attachmentParts[i]->ContentSize() ); + TPtrC attachmentName( attachmentParts[i]->AttachmentNameL() ); + if ( contentSize >= 0 && attachmentName.Length() ) + { + attachmentInfo->AddAttachmentInfoL( + attachmentName, + contentSize, + state ); + } + } + + if ( attachmentInfo->AttachmentCount() ) + { + iAttachmentInfo = attachmentInfo; + CleanupStack::Pop( attachmentInfo ); + // ownership does not change + iInputParameters.iAttachmentInfo = iAttachmentInfo; + } + else + { + CleanupStack::PopAndDestroy( attachmentInfo ); + } + + attachmentInfo = NULL; + } + CleanupStack::PopAndDestroy(); // attachmentparts + } + } + +// EOF +