--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/emailservices/emailstore/base_plugin/src/baseplugintranslator.cpp Thu Dec 17 08:39:21 2009 +0200
@@ -0,0 +1,1331 @@
+/*
+* Copyright (c) 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: Email interface implementation, translator utilities.
+*
+*/
+
+
+
+#include "BasePlugin.h"
+#include "baseplugincommonutils.h"
+#include "CFSMailCommon.h"
+
+
+static void TranslateMsgStoreAttendeeL(
+ CMsgStorePropertyContainer& aSrc,
+ TUint aIdx,
+ MMROrganizer& aAttendee );
+
+static void TranslateMsgStoreAttendeesL(
+ CMsgStorePropertyContainer& aMessage,
+ CBaseMrInfoObject& aMrInfo,
+ const TDesC8& aProperty,
+ MMRAttendee::TAttendeeRole aRole );
+
+
+/**@ the info object's description field is mapped to the message body which can be
+of arbitrary size; at the moment cap the max description size to avoid memory problems.*/
+const TInt KMaxDescription = 512*1024;
+
+/**
+ *
+ */
+class TDayOfWeekFtor
+ {
+ public:
+ virtual void operator () ( MRRecurrenceRule::TMRRecurrentDay aDay ) = 0;
+ };
+
+/**
+ *
+ */
+class TWeekDayTranslator : public TDayOfWeekFtor
+ {
+ public:
+ TWeekDayTranslator( RArray<MRRecurrenceRule::TMRRecurrentDay>& aDays )
+ : iDays( aDays )
+ {
+ };
+
+ virtual void operator () ( MRRecurrenceRule::TMRRecurrentDay aDay )
+ {
+ iDays.AppendL( aDay );
+ };
+
+ private:
+ RArray<MRRecurrenceRule::TMRRecurrentDay>& iDays;
+ };
+
+/**
+ *
+ */
+class TMonthDayTranslator : public TDayOfWeekFtor
+ {
+ public:
+ TMonthDayTranslator( MRRecurrenceRule::TMRRecurrentDay& aDayOfWeek )
+ : iDayOfWeek( aDayOfWeek )
+ {
+ };
+
+ virtual void operator () ( MRRecurrenceRule::TMRRecurrentDay aDay )
+ {
+ /**@ the contract with IMS/Outlook is that there is a single day
+ set in a monthly by day of week rule; asserts ?*/
+ iDayOfWeek = aDay;
+ };
+
+ private:
+ MRRecurrenceRule::TMRRecurrentDay& iDayOfWeek;
+ };
+
+
+/**
+ *
+ */
+EXPORT_C void CBasePlugin::TranslateMsgStorePropsL(
+ const TFSMailMsgId& aMailBoxId,
+ CMsgStorePropertyContainer& aMessage,
+ CFSMailMessagePart& aFsMsg,
+ const TFSMailDetails aDetails )
+
+ {
+ __LOG_ENTER( "TranslateMsgStorePropsL" )
+
+ __LOG_WRITE_FORMAT1_INFO( "aDetails = 0x%X.", aDetails )
+
+ TFSMailMsgId fsId( GetPluginId(), aMessage.ParentId() );
+ aFsMsg.SetFolderId( fsId );
+
+ TUint idx = 0;
+ //subject.
+ if ( ( EFSMsgDataEnvelope & aDetails || EFSMsgDataStructure & aDetails
+ || EFSMsgDataSubject & aDetails )
+ && aMessage.FindProperty( KMsgStorePropertySubject, idx ) )
+ {
+ const TDesC& subject = aMessage.PropertyValueDesL( idx );
+ aFsMsg.SetSubject( subject );
+ idx = 0;
+
+ __LOG_WRITE_FORMAT1_INFO( "Subject: %S.", &subject );
+ }
+
+ //from.
+ if ( ( EFSMsgDataEnvelope & aDetails|| EFSMsgDataStructure & aDetails
+ || EFSMsgDataSender & aDetails )
+ && aMessage.FindProperty( KMsgStorePropertyFrom, idx ) )
+ {
+ CFSMailAddress* address = FetchEmailAddressL( aMessage, idx );
+ aFsMsg.SetSender( address );
+ idx = 0;
+ }
+
+ //received.
+ if ( ( EFSMsgDataEnvelope & aDetails || EFSMsgDataStructure & aDetails
+ || EFSMsgDataDate & aDetails )
+ && aMessage.FindProperty( KMsgStorePropertyReceivedAt, idx ) )
+ {
+ TTime time;
+ aMessage.PropertyValueTimeL( idx, time );
+ aFsMsg.SetDate( time );
+ idx = 0;
+
+ __LOG_WRITE8_FORMAT1_INFO( "Received: %ld.", time.Int64() );
+ }
+
+ //sent.
+ if ( ( EFSMsgDataEnvelope & aDetails || EFSMsgDataStructure & aDetails
+ || EFSMsgDataDate & aDetails )
+ && aMessage.FindProperty( KMsgStorePropertySent, idx ) )
+ {
+ TTime time;
+ aMessage.PropertyValueTimeL( idx, time );
+ aFsMsg.SetDate( time );
+ idx = 0;
+
+ __LOG_WRITE8_FORMAT1_INFO( "Sent: %ld.", time.Int64() );
+ }
+
+ if ( EFSMsgDataEnvelope & aDetails || EFSMsgDataStructure & aDetails )
+ {
+ //to recipients.
+ while ( aMessage.FindProperty( KMsgStorePropertyTo, idx, idx ) )
+ {
+ CFSMailAddress* address = FetchEmailAddressL( aMessage, idx );
+ aFsMsg.AppendToRecipient( address );
+ ++idx;
+ }
+ idx = 0;
+
+ //cc recipients.
+ while ( aMessage.FindProperty( KMsgStorePropertyCc, idx, idx ) )
+ {
+ CFSMailAddress* address = FetchEmailAddressL( aMessage, idx );
+ aFsMsg.AppendCCRecipient( address );
+ ++idx;
+ }
+ idx = 0;
+
+ //bcc recipients.
+ while ( aMessage.FindProperty( KMsgStorePropertyBcc, idx, idx ) )
+ {
+ CFSMailAddress* address = FetchEmailAddressL( aMessage, idx );
+ aFsMsg.AppendBCCRecipient( address );
+ ++idx;
+ }
+ idx = 0;
+
+ //flags.
+ if ( aMessage.FindProperty( KMsgStorePropertyFlags, idx ) )
+ {
+ TUint32 i = aMessage.PropertyValueUint32L( idx );
+ aFsMsg.SetFlag( i );
+ idx = 0;
+
+ __LOG_WRITE_FORMAT1_INFO( "Flags: 0x%X.", i )
+ }
+
+ //content-size.
+ if ( aMessage.FindProperty( KMsgStorePropertySize, idx ) )
+ {
+ TUint32 i = aMessage.PropertyValueUint32L( idx );
+ aFsMsg.SetContentSize( i );
+ idx = 0;
+
+ __LOG_WRITE_FORMAT1_INFO( "Content-size: %d.", i )
+ }
+
+ //content-type.
+ if ( aMessage.FindProperty( KMsgStorePropertyContentType, idx ) )
+ {
+
+ const TDesC& contentType = aMessage.PropertyValueDesL( idx );
+
+ idx = 0;
+ if ( aMessage.FindProperty( KMsgStorePropertyCharset, idx ) )
+ {
+ _LIT( KCharSemicolon, ";" );
+ const TDesC& charSet = aMessage.PropertyValueDesL( idx );
+
+ TInt maxLength = contentType.Length() + KFSMailContentTypeParamCharset().Length() +
+ KCharSemicolon().Length() + charSet.Length();
+
+ HBufC* buf = HBufC::NewLC( maxLength );
+ TPtr bufPtr( buf->Des() );
+
+ bufPtr.Append( contentType );
+ bufPtr.Append( KCharSemicolon );
+ bufPtr.Append( KFSMailContentTypeParamCharset );
+ bufPtr.Append( charSet );
+ aFsMsg.SetContentType( bufPtr );
+ __LOG_WRITE_FORMAT1_INFO( "Content-type: %S.", &bufPtr );
+ CleanupStack::PopAndDestroy( buf );
+ }
+ else
+ {
+ aFsMsg.SetContentType( contentType );
+ __LOG_WRITE_FORMAT1_INFO( "Content-type: %S.", &contentType );
+ }
+
+ idx = 0;
+ }
+
+ //content-id.
+ if ( aMessage.FindProperty( KMsgStorePropertyContentId, idx ) )
+ {
+ const TDesC& contentId = aMessage.PropertyValueDesL( idx );
+ aFsMsg.SetContentIDL( contentId );
+ idx = 0;
+
+ __LOG_WRITE_FORMAT1_INFO( "Content-id: %S.", &contentId );
+ }
+
+ //content-description.
+ if ( aMessage.FindProperty( KMsgStorePropertyContentDescription, idx ) )
+ {
+ const TDesC& contentDescription = aMessage.PropertyValueDesL( idx );
+ aFsMsg.SetContentDescription( contentDescription );
+ idx = 0;
+
+ __LOG_WRITE_FORMAT1_INFO(
+ "Content-description: %S.", &contentDescription );
+ }
+
+ //content-class.
+ if ( aMessage.FindProperty( KMsgStorePropertyContentClass, idx ) )
+ {
+ const TDesC& contentClass = aMessage.PropertyValueDesL( idx );
+ aFsMsg.SetContentClass( contentClass );
+ idx = 0;
+ }
+
+ //fetched content size.
+ if ( aMessage.FindProperty( KMsgStorePropertyRetrievedSize, idx ) )
+ {
+ TUint32 retrievedSize = aMessage.PropertyValueUint32L( idx );
+ aFsMsg.SetFetchedContentSize( retrievedSize );
+ idx = 0;
+ }
+
+ //content-disposition.
+ if ( aMessage.FindProperty( KMsgStorePropertyContentDisposition, idx ) )
+ {
+ const TDesC& contentDisposition = aMessage.PropertyValueDesL( idx );
+ aFsMsg.SetContentDisposition( contentDisposition );
+ idx = 0;
+
+ __LOG_WRITE_FORMAT1_INFO(
+ "Content-desposition: %S.", &contentDisposition );
+ }
+
+ //meeting request info.
+ if ( aMessage.FindProperty( KMsgStorePropertyMeetingRequest, idx ) )
+ {
+ CMsgStorePropertyContainer* mrInfo
+ = aMessage.PropertyValueContainerL( idx );
+ CleanupStack::PushL( mrInfo );
+ TranslateMsgStoreMrL( aMailBoxId, aMessage, *mrInfo, aFsMsg );
+ CleanupStack::PopAndDestroy( mrInfo );
+ idx = 0;
+ }
+
+ //read-only size
+ if ( aMessage.FindProperty( KMsgStorePropertyReadOnlySize, idx ) )
+ {
+ TUint readOnlySize = aMessage.PropertyValueUint32L(idx);
+ aFsMsg.SetReadOnlyPartSize(readOnlySize);
+ idx = 0;
+ }
+ }
+
+ __LOG_EXIT
+ } //TranslateMsgStorePropsL.
+
+
+/**
+ * Common msgstore meeting request fields translation to Freestyle.
+ *
+ * @param aMessage
+ * @param aFsMsg
+ */
+EXPORT_C void CBasePlugin::TranslateMsgStoreMrL(
+ const TFSMailMsgId& aMailBoxId,
+ CMsgStorePropertyContainer& aMessage,
+ CMsgStorePropertyContainer& aCalendar,
+ CFSMailMessagePart& aFsMsg )
+
+ {
+ __LOG_ENTER( "TranslateMsgStoreMrL" )
+
+ CBaseMrInfoObject* mmrInfo = CBaseMrInfoObject::NewL();
+ CleanupStack::PushL( mmrInfo );
+
+ TUint idx;
+
+ //uid.
+ idx = 0;
+ if ( aCalendar.FindProperty( KMsgStorePropertyMrGuid, idx ) )
+ {
+ const TDesC8& uid8 = aCalendar.PropertyValueDes8L( idx );
+
+ HBufC* uid = HBufC::NewLC( uid8.Length() );
+ //uid not utf8-encoded.
+ uid->Des().Copy( uid8 );
+ mmrInfo->SetUidL( uid );
+
+ CleanupStack::Pop( uid );
+ }
+
+ //subject.
+ idx = 0;
+ if ( aMessage.FindProperty( KMsgStorePropertySubject, idx ) )
+ {
+ const TDesC& subject = aMessage.PropertyValueDesL( idx );
+ mmrInfo->SetSubjectL( subject );
+
+ __LOG_WRITE_FORMAT1_INFO( "MR Subject: %S.", &subject );
+ }
+
+ //description - the plain/text email body.
+ __LOG_WRITE_INFO( "About to translate the description field." );
+ idx = 0;
+ TMsgStoreId msgId = aMessage.Id();
+
+ CMailboxInfo& mailBox = GetMailboxInfoL( aMailBoxId.Id() );
+ CMsgStoreMessage* theMessage = mailBox().FetchMessageL( msgId, KMsgStoreInvalidId );
+ CleanupStack::PushL( theMessage );
+
+ CMsgStoreMessagePart* plainText = GetBodyPartL( *theMessage );
+ if ( NULL != plainText )
+ {
+ CleanupStack::PushL( plainText );
+
+ TUint length = plainText->ContentLengthL();
+ //the body can be of arbitrary size - taking precautions until resolved.
+ length = length < KMaxDescription ? length : KMaxDescription;
+ HBufC* description = HBufC::NewLC( length );
+
+ RBuf8 buf8;
+ CleanupClosePushL( buf8 );
+ buf8.CreateL( length );
+
+ plainText->FetchContentToBufferL( buf8 );
+
+ //replace the cr with the lf per iCal spec otherwise the Symbian iCal importer would leave with -20;
+ //see ANN0001 for more info.
+
+ _LIT8( KCrLf, "\r\x00\n\x00" );
+ _LIT8( KLf, "\n\x00" );
+ const TUint crLfSize = KCrLf().Size();
+
+ TInt idx = KErrNotFound;
+ while ( KErrNotFound != ( idx = buf8.Find( KCrLf ) ) )
+ {
+ buf8.Replace( idx, crLfSize, KLf );
+ }
+
+ TPtrC ptr( KNullDesC );
+ ptr.Set( reinterpret_cast<const TUint16*>( buf8.Ptr() ), buf8.Length() / 2 );
+
+ mmrInfo->SetDescriptionL( ptr );
+
+ //CleanupStack::PopAndDestroy( body );
+ CleanupStack::PopAndDestroy( &buf8 );
+ CleanupStack::PopAndDestroy( description );
+ CleanupStack::PopAndDestroy( plainText );
+ }
+ CleanupStack::PopAndDestroy( theMessage );
+
+ //creation date.
+ idx = 0;
+ if ( aCalendar.FindProperty( KMsgStorePropertyMrCreationDate, idx ) )
+ {
+ TTime time;
+ aCalendar.PropertyValueTimeL( idx, time );
+ mmrInfo->SetCreationTimeInUtcL( time );
+ }
+
+ //start date.
+ idx = 0;
+ if ( aCalendar.FindProperty( KMsgStorePropertyMrStartDate, idx ) )
+ {
+ TTime time;
+ aCalendar.PropertyValueTimeL( idx, time );
+ mmrInfo->SetStartTimeInUtcL( time );
+ }
+
+ //end date.
+ idx = 0;
+ if ( aCalendar.FindProperty( KMsgStorePropertyMrEndDate, idx ) )
+ {
+ TTime time;
+ aCalendar.PropertyValueTimeL( idx, time );
+ mmrInfo->SetEndTimeInUtcL( time );
+ }
+
+ //location.
+ idx = 0;
+ if ( aCalendar.FindProperty( KMsgStorePropertyMrLocation, idx ) )
+ {
+ const TDesC& location = aCalendar.PropertyValueDesL( idx );
+ mmrInfo->SetLocationL( location );
+ }
+
+ //organizer / from.
+ idx = 0;
+ if ( aMessage.FindProperty( KMsgStorePropertyFrom, idx ) )
+ {
+ TranslateMsgStoreAttendeeL( aMessage, idx, mmrInfo->MROrganizerL() );
+ }
+
+ //attendees / to.
+ TranslateMsgStoreAttendeesL(
+ aMessage, *mmrInfo, KMsgStorePropertyTo, MMRAttendee::EMRAttendeeParticipant );
+
+ //attendees / cc.
+ TranslateMsgStoreAttendeesL(
+ aMessage, *mmrInfo, KMsgStorePropertyCc, MMRAttendee::EMRAttendeeOptionalParticipant );
+
+ //recurrence info.
+ __LOG_WRITE_INFO( "About to start translating the recurrence rule." )
+
+ CBaseMrRecurrenceRule* recurrenceRule = CBaseMrRecurrenceRule::NewL();
+ CleanupStack::PushL( recurrenceRule );
+
+ //start date.
+ /**@ dupes the infoobject one ?*/
+ idx = 0;
+ if ( aCalendar.FindProperty( KMsgStorePropertyMrStartDate, idx ) )
+ {
+ TTime time;
+ aCalendar.PropertyValueTimeL( idx, time );
+ recurrenceRule->SetRecurrenceStartTimeL( time );
+ }
+
+ //end date.
+ idx = 0;
+ if ( aCalendar.FindProperty( KMsgStorePropertyMrRecurEndDate, idx ) )
+ {
+ TTime time;
+ aCalendar.PropertyValueTimeL( idx, time );
+ recurrenceRule->SetRecurrenceUntilL( time );
+ }
+
+ //frequency.
+ idx = 0;
+ if ( aCalendar.FindProperty( KMsgStorePropertyMrFrequency, idx ) )
+ {
+ TUint32 imsFreq = aCalendar.PropertyValueUint32L( idx );
+ recurrenceRule->SetRecurrentInterval( imsFreq );
+ }
+
+ //priority.
+ idx = 0;
+ if ( aCalendar.FindProperty( KMsgStorePropertyMrPriority, idx ) )
+ {
+ TUint32 priority = aCalendar.PropertyValueUint32L( idx );
+ mmrInfo->SetPriorityL( priority );
+ }
+
+ /**@ privacy/sensitivity missing ? */
+ /*idx = 0;
+ if ( aCalendar.FindProperty( KMsgStorePropertyMrPrivate, idx ) )
+ {
+ TBool private = aCalendar.PropertyValueBoolL( idx );
+ }*/
+
+ //method.
+ idx = 0;
+ if ( aCalendar.FindProperty( KMsgStorePropertyMrMethod, idx ) )
+ {
+ TUint32 method = aCalendar.PropertyValueUint32L( idx );
+ mmrInfo->SetMethod( static_cast<MMRInfoObject::TMRMethod>( method ) );
+ }
+
+ //status.
+ idx = 0;
+ if ( aCalendar.FindProperty( KMsgStorePropertyMrStatus, idx ) )
+ {
+ TUint32 status = aCalendar.PropertyValueUint32L( idx );
+ mmrInfo->SetMRResponseL( static_cast<MMRInfoObject::TResponse>( status ) );
+ }
+
+ //alarm/reminder time.
+ idx = 0;
+ if ( aCalendar.FindProperty( KMsgStorePropertyMrReminder, idx ) )
+ {
+ TBool hasReminder = aCalendar.PropertyValueBoolL( idx );
+ if ( hasReminder )
+ {
+ idx = 0;
+ if ( aCalendar.FindProperty( KMsgStorePropertyMrReminderTime, idx ) )
+ {
+ if ( Time::NullTTime() != mmrInfo->StartTimeInUtcL() )
+ {
+ TUint32 offsetMinutes;
+ offsetMinutes = aCalendar.PropertyValueUint32L( idx );
+
+ TTime time = mmrInfo->StartTimeInUtcL();
+ time -= TTimeIntervalMinutes( offsetMinutes );
+ mmrInfo->SetAlarmInUtcL( time );
+ }
+ else
+ {
+ __LOG_WRITE_INFO(
+ "Could not find a start date/time so can't set the reminder time." )
+ }
+ }
+ }
+ }
+
+ //recurrent count.
+ idx = 0;
+ if ( aCalendar.FindProperty( KMsgStorePropertyMrRecurCount, idx ) )
+ {
+ TUint32 count = aCalendar.PropertyValueUint32L( idx );
+ recurrenceRule->SetRecurrentCountL( count );
+ }
+
+ //recurrence rule type.
+ idx = 0;
+ MRRecurrenceRule::TMRRecurrenceType recurrenceType
+ = MRRecurrenceRule::EMRRecurrenceInvalid;
+ if ( aCalendar.FindProperty( KMsgStorePropertyMrRecurType, idx ) )
+ {
+ TUint32 fsType = aCalendar.PropertyValueUint32L( idx );
+ recurrenceType = static_cast<MRRecurrenceRule::TMRRecurrenceType>( fsType );
+ recurrenceRule->SetRecurrenceTypeL( recurrenceType );
+ }
+
+ //monthly-by-day-of-week.
+ if ( MRRecurrenceRule::EMRRecurrenceMonthly == recurrenceType )
+ {
+ MRRecurrenceRule::TRecurrentDaysofMonth dayOfMonth;
+
+ //week number.
+ idx = 0;
+ if ( aCalendar.FindProperty( KMsgStorePropertyMrWeekNo, idx ) )
+ {
+ TUint32 weekNo = aCalendar.PropertyValueUint32L( idx );
+ /**@ double check that when testing starts.*/
+ dayOfMonth.iWeekOfMonth =
+ static_cast<MRRecurrenceRule::TMRRecurrenceWeek>( weekNo );
+ }
+
+ //day of week mask.
+ idx = 0 ;
+ if ( aCalendar.FindProperty( KMsgStorePropertyMrDayOfWeekMask, idx ) )
+ {
+ TUint32 dowMask = aCalendar.PropertyValueUint32L( idx );
+
+ TMonthDayTranslator mdt( dayOfMonth.iDayOfWeek );
+ TranslateMsgStoreDayOfWeek( dowMask, mdt );
+ }
+
+ /** IMS, Outlook support a single day, intellisync-specific.*/
+ RArray<MRRecurrenceRule::TRecurrentDaysofMonth> days;
+ CleanupClosePushL( days );
+
+ days.AppendL( dayOfMonth );
+ recurrenceRule->SetRecurrentDaysofMonthL( days );
+
+ CleanupStack::PopAndDestroy( &days );
+
+ }
+ //monthly-by-monthday.
+ if ( MRRecurrenceRule::EMRRecurrenceMonthlyByDay == recurrenceType )
+ {
+ //Day number.
+ idx = 0;
+ RArray<TInt> days;
+ CleanupClosePushL( days );
+
+ if ( aCalendar.FindProperty( KMsgStorePropertyMrMonthDay, idx ) )
+ {
+ TUint32 monthDayNo = aCalendar.PropertyValueUint32L( idx );
+ days.Append(monthDayNo);
+ /**@ double check that when testing starts.*/
+ }
+
+ recurrenceRule->SetRecurrentMonthDaysL( days );
+
+ CleanupStack::PopAndDestroy( &days );
+
+ }
+ //weekly.
+ else if ( MRRecurrenceRule::EMRRecurrenceWeekly == recurrenceType )
+ {
+ //day of week mask.
+ idx = 0 ;
+ if ( aCalendar.FindProperty( KMsgStorePropertyMrDayOfWeekMask, idx ) )
+ {
+ TUint32 dowMask = aCalendar.PropertyValueUint32L( idx );
+
+ RArray<MRRecurrenceRule::TMRRecurrentDay> days;
+ CleanupClosePushL( days );
+
+ TWeekDayTranslator wdt( days );
+ TranslateMsgStoreDayOfWeek( dowMask, wdt );
+ recurrenceRule->SetRecurrentWeekDaysL( days );
+
+ CleanupStack::PopAndDestroy( &days );
+ }
+ }
+ //yearly.
+ else if ( MRRecurrenceRule::EMRRecurrenceYearly == recurrenceType )
+ {
+ //week number.
+ idx = 0;
+ if ( aCalendar.FindProperty( KMsgStorePropertyMrWeekNo, idx ) )
+ {
+ /**@ needs redoing after the latest changes to the MMR ifaces
+ by activesync.*/
+ /*TUint32 weekNo = aCalendar.PropertyValueUint32L( idx );
+
+ MRRecurrenceRule::TRecurrentDaysofMonth dayOfMonth;*/
+ /**@ double check that when testing starts.*/
+ /*dayOfMonth.iWeekOfMonth =
+ static_cast<MRRecurrenceRule::TMRRecurrenceWeek>( weekNo );
+
+ //add to mmr info object.
+ RArray<TInt> days;
+ CleanupClosePushL( days );
+
+ days.AppendL( dayOfMonth );
+ recurrenceRule->SetRecurrentMonthDaysL( days );
+
+ CleanupStack::PopAndDestroy( &days );*/
+ }
+
+ //day of week mask.
+ idx = 0;
+ if ( aCalendar.FindProperty( KMsgStorePropertyMrDayOfWeekMask, idx ) )
+ {
+ TUint32 dowMask = aCalendar.PropertyValueUint32L( idx );
+
+ RArray<MRRecurrenceRule::TMRRecurrentDay> days;
+ CleanupClosePushL( days );
+
+ TWeekDayTranslator wdt( days );
+ TranslateMsgStoreDayOfWeek( dowMask, wdt );
+ recurrenceRule->SetRecurrentWeekDaysL( days );
+
+ CleanupStack::PopAndDestroy( &days );
+ }
+ }
+
+ mmrInfo->SetRecurrenceRuleL( *recurrenceRule );
+ CleanupStack::Pop( recurrenceRule );
+
+ //recurrence id.
+ idx = 0;
+ if ( aCalendar.FindProperty( KMsgStorePropertyMrRRID, idx ) )
+ {
+ TTime time;
+ aCalendar.PropertyValueTimeL( idx, time );
+ mmrInfo->SetMRRecurrenceIdL( time );
+ }
+
+ //sequence number.
+ idx = 0;
+ if ( aCalendar.FindProperty( KMsgStorePropertyMrSeqNo, idx ) )
+ {
+ TUint32 seqNo = aCalendar.PropertyValueUint32L( idx );
+ mmrInfo->SetMRSequenceNumber( static_cast<TInt>( seqNo ) );
+ }
+
+ aFsMsg.SetMRInfo( mmrInfo );
+ CleanupStack::Pop( mmrInfo );
+
+ __LOG_EXIT
+ } //TranslateMsgStoreMrL.
+
+
+/**
+ *
+ */
+EXPORT_C void CBasePlugin::TranslateEmailFwMessageL(
+ CFSMailMessagePart& aSrc,
+ CMsgStoreMessagePart& aDst,
+ TBool aInInbox )
+
+ {
+ __LOG_ENTER( "TranslateEmailFwMessageL" )
+
+ //subject.
+ TDesC& value = aSrc.GetSubject();
+ if ( NULL != &value && KNullDesC() != value )
+ {
+ aDst.AddOrUpdatePropertyL( KMsgStorePropertySubject, value );
+ }
+
+ RMsgStoreAddress msgStoreAddress;
+ CleanupClosePushL( msgStoreAddress ); //+msgStoreAddress
+
+ //from.
+ CFSMailAddress* address = aSrc.GetSender();
+ if ( NULL != address )
+ {
+ CBasePlugin::RemoveAllPropertiesL( aDst, KMsgStorePropertyFrom );
+
+ if ( address->GetEmailAddress().Length() )
+ {
+ msgStoreAddress.iEmailAddress.Create( address->GetEmailAddress() );
+ }
+
+ if ( address->GetDisplayName().Length() )
+ {
+ msgStoreAddress.iDisplayName.Create( address->GetDisplayName() );
+ }
+
+ aDst.AddOrUpdatePropertyL( KMsgStorePropertyFrom, msgStoreAddress );
+ msgStoreAddress.Close();
+ }
+
+ CleanupStack::PopAndDestroy( &msgStoreAddress ); //-msgStoreAddress
+
+ //received or sent, depending on the folder.
+ if ( aInInbox )
+ {
+ if ( aSrc.GetDate() != 0 )
+ {
+ aDst.AddOrUpdatePropertyL( KMsgStorePropertyReceivedAt, aSrc.GetDate() );
+ }
+ }
+ else
+ {
+ //set the sent stamp.
+ TTime sentTime;
+ sentTime.UniversalTime();
+ aDst.AddOrUpdatePropertyL( KMsgStorePropertySent, sentTime );
+ aSrc.SetDate( sentTime );
+ }
+
+ //to recipients.
+ RPointerArray<CFSMailAddress>& toRecipients = aSrc.GetToRecipients();
+ TranslateEmailFwRecipientsL( aDst, KMsgStorePropertyTo, toRecipients );
+
+ //cc recipients.
+ RPointerArray<CFSMailAddress>& ccRecipients = aSrc.GetCCRecipients();
+ TranslateEmailFwRecipientsL( aDst, KMsgStorePropertyCc, ccRecipients );
+
+ //bcc recipients.
+ RPointerArray<CFSMailAddress>& bccRecipients = aSrc.GetBCCRecipients();
+ TranslateEmailFwRecipientsL( aDst, KMsgStorePropertyBcc, bccRecipients );
+
+ //flags.
+ //the cast is important otherwise the TBool overload gets called.
+ TUint32 flag = static_cast<TUint32>( aSrc.GetFlags() );
+ aDst.AddOrUpdatePropertyL(
+ KMsgStorePropertyFlags, flag );
+
+ //content type.
+ const TPtrC& contentType = aSrc.GetContentType();
+ if ( 0 < contentType.Length() )
+ {
+ aDst.AddOrUpdatePropertyL( KMsgStorePropertyContentType, contentType );
+ }
+
+ //content id.
+ const TPtrC& contentId = aSrc.ContentID();
+ if ( 0 < contentId.Length() )
+ {
+ aDst.AddOrUpdatePropertyL( KMsgStorePropertyContentId, contentId );
+ }
+
+ //content description.
+ const TPtrC& contentDescription = aSrc.ContentDescription();
+ if ( 0 < contentDescription.Length() )
+ {
+ aDst.AddOrUpdatePropertyL(
+ KMsgStorePropertyContentDescription, contentDescription );
+ }
+
+ //content disposition.
+ const TPtrC& contentDisposition = aSrc.ContentDisposition();
+ if ( 0 < contentDisposition.Length() )
+ {
+ aDst.AddOrUpdatePropertyL(
+ KMsgStorePropertyContentDisposition, contentDisposition );
+ }
+
+ //content class.
+ const TDesC& contentClass = aSrc.GetContentClass();
+ if ( 0 < contentClass.Length() )
+ {
+ aDst.AddOrUpdatePropertyL(
+ KMsgStorePropertyContentClass, contentClass );
+ }
+
+ //attachment name.
+ const TDesC& attachmentName = aSrc.AttachmentNameL();
+ if ( 0 < attachmentName.Length() )
+ {
+ aDst.AddOrUpdatePropertyL( KMsgStorePropertyName, attachmentName );
+ }
+
+ //meeting request info.
+ if ( aSrc.IsMRInfoSet() )
+ {
+ MMRInfoObject& mmrInfo = aSrc.GetMRInfo(); //no ownership transfer.
+ TranslateEmailFwMrL( mmrInfo, aDst );
+ }
+ else
+ {
+ //in the case of a MR origination the MRInfo object is not used thus is never set but still
+ //the calendar property container is present and necessary.
+ TUint index = 0;
+ if ( !( flag & EFSMsgFlag_CalendarMsg )
+ && aDst.FindProperty( KMsgStorePropertyMeetingRequest, index ) )
+ {
+ aDst.RemovePropertyL( index );
+ }
+ }
+
+ //read-only size
+ if (aSrc.ReadOnlyPartSize() > 0)
+ {
+ aDst.AddOrUpdatePropertyL(KMsgStorePropertyReadOnlySize, (TUint32)aSrc.ReadOnlyPartSize());
+ }
+
+ __LOG_EXIT
+ } //TranslateEmailFwMessageL.
+
+
+/**
+ *
+ */
+EXPORT_C void CBasePlugin::TranslateEmailFwMrL(
+ MMRInfoObject& aSrc,
+ CMsgStorePropertyContainer& aDst )
+
+ {
+ __LOG_ENTER( "TranslateEmailFwMrL" )
+
+ TUint index;
+ CMsgStorePropertyContainer* calendar = aDst.FindProperty(
+ KMsgStorePropertyMeetingRequest, index ) ?
+ aDst.PropertyValueContainerL( index )
+ : CMsgStorePropertyContainer::NewL();
+ CleanupStack::PushL( calendar );
+
+ //response code.
+ calendar->AddOrUpdatePropertyL(
+ KMsgStorePropertyMrMethod, static_cast<TUint32>( aSrc.MRMethodL() ) );
+
+ calendar->AddOrUpdatePropertyL(
+ KMsgStorePropertyMrStatus, static_cast<TUint32>( aSrc.MRResponse() ) );
+
+ //uid.
+ const TDesC& uid = aSrc.UidL();
+ if ( uid != KNullDesC )
+ {
+ HBufC8* uid8 = HBufC8::NewLC( uid.Length() );
+ //uid not utf8-encoded.
+ uid8->Des().Copy( uid );
+ calendar->AddOrUpdatePropertyL( KMsgStorePropertyMrGuid, *uid8 );
+ CleanupStack::PopAndDestroy( uid8 );
+ }
+
+ //description.
+ const TDesC& description = aSrc.DescriptionL();
+ if ( description != KNullDesC )
+ {
+ /**@ set the body of the plain text part instead ?*/
+ calendar->AddOrUpdatePropertyL( KMsgStorePropertyMrCalBody, description );
+ }
+
+ //creation date.
+ TTime time = aSrc.CreationTimeInUtcL();
+ if ( Time::NullTTime() != time )
+ {
+ calendar->AddOrUpdatePropertyL( KMsgStorePropertyMrCreationDate, time );
+ }
+
+ //start date.
+ time = aSrc.StartTimeInUtcL();
+ if ( Time::NullTTime() != time )
+ {
+ calendar->AddOrUpdatePropertyL( KMsgStorePropertyMrStartDate, time );
+ }
+
+ //end date.
+ time = aSrc.EndTimeInUtcL();
+ if ( Time::NullTTime() != time )
+ {
+ calendar->AddOrUpdatePropertyL( KMsgStorePropertyMrEndDate, time );
+ }
+
+ //alarm/reminder time.
+ time = aSrc.AlarmInUtcL();
+ if ( Time::NullTTime() != time )
+ {
+ if ( Time::NullTTime() != aSrc.StartTimeInUtcL() )
+ {
+ TTimeIntervalMinutes offsetMinutes;
+ TInt error = aSrc.StartTimeInUtcL().MinutesFrom( time, offsetMinutes );
+
+ if ( KErrNone != error )
+ {
+ calendar->AddOrUpdatePropertyL( KMsgStorePropertyMrReminderTime,
+ static_cast<TUint32>( offsetMinutes.Int() ) );
+ calendar->AddOrUpdatePropertyL( KMsgStorePropertyMrReminder, ETrue );
+ }
+ else
+ {
+ __LOG_WRITE_FORMAT1_INFO(
+ "Failed to compute the reminder time, error %d.", error )
+ }
+ }
+ }
+
+ //location.
+ const TDesC& location = aSrc.LocationL();
+ if ( location != KNullDesC )
+ {
+ calendar->AddOrUpdatePropertyL( KMsgStorePropertyMrLocation, location );
+ }
+
+ const TDesC& summary = aSrc.SubjectL();
+ if ( summary != KNullDesC )
+ {
+ calendar->AddOrUpdatePropertyL( KMsgStorePropertyMrSubject, summary );
+ }
+
+ //organizer / from.
+ RMsgStoreAddress msgStoreAddress;
+ CleanupClosePushL( msgStoreAddress );
+
+ /*TranslateEmailFwAttendeeL( aSrc.MROrganizerL(), msgStoreAddress );
+ aDst.AddOrUpdatePropertyL( KMsgStorePropertyFrom, msgStoreAddress );*/
+
+ //attendees / to.
+ /*RPointerArray<MMRAttendee>& attendees = aSrc.AttendeesL();
+ TInt count = attendees.Count();
+
+ for ( TInt i = 0; i < count; i++ )
+ {
+ msgStoreAddress.Close();
+
+ TranslateEmailFwAttendeeL( *(attendees[i]), msgStoreAddress );
+ aDst.AddPropertyL( KMsgStorePropertyTo, msgStoreAddress );
+ }*/
+
+ CleanupStack::PopAndDestroy( &msgStoreAddress );
+
+ //recurrence info.
+ __LOG_WRITE_INFO( "Translating MMR info object recurrence rule to MsgStore." )
+ const MRRecurrenceRule& rRule = aSrc.RecurrenceRuleL();
+
+ //start date.
+ time = rRule.RecurrenceStartTime();
+ if ( Time::NullTTime() != time )
+ {
+ calendar->AddOrUpdatePropertyL( KMsgStorePropertyMrStartDate, time );
+ }
+
+ //end date.
+ time = rRule.RecurrentUntil();
+ if ( Time::NullTTime() != time )
+ {
+ calendar->AddOrUpdatePropertyL( KMsgStorePropertyMrRecurEndDate, time );
+ }
+
+ //frequency.
+ TInt frequency = rRule.RecurrentInterval();
+ if ( 0 != frequency )
+ {
+ calendar->AddOrUpdatePropertyL(
+ KMsgStorePropertyMrFrequency, static_cast<TUint32>( rRule.RecurrentInterval() ) );
+ }
+ else
+ {
+ TUint index = 0;
+ if ( calendar->FindProperty( KMsgStorePropertyMrFrequency, index ) )
+ {
+ calendar->RemovePropertyL( index );
+ }
+ }
+
+ //priority.
+ calendar->AddOrUpdatePropertyL(
+ KMsgStorePropertyMrPriority, static_cast<TUint32>( aSrc.PriorityL() ) );
+
+ /**@ privacy/sensitivity missing ? */
+ /*idx = 0;
+ if ( aCalendar.FindProperty( KMsgStorePropertyMrPrivate, idx ) )
+ {
+ TBool private = aCalendar.PropertyValueBoolL( idx );
+ }*/
+
+ //recurrent count.
+ calendar->AddOrUpdatePropertyL(
+ KMsgStorePropertyMrRecurCount, static_cast<TUint32>( rRule.RecurrentCount() ) );
+
+ //recurrence rule type.
+ MRRecurrenceRule::TMRRecurrenceType rType = rRule.Type();
+ calendar->AddOrUpdatePropertyL(
+ KMsgStorePropertyMrRecurType, static_cast<TUint32>( rType ) );
+
+ //monthly-by-day-of-week.
+ if ( MRRecurrenceRule::EMRRecurrenceMonthly == rType )
+ {
+ /**@ needs redoing after the latest MMR iface changes by activesync.*/
+ /*const RArray<TInt>& monthDays = rRule.RecurrentMonthDays();
+ if ( monthDays.Count() )
+ {
+ //week number.
+ calendar->AddOrUpdatePropertyL(
+ KMsgStorePropertyMrWeekNo, static_cast<TUint32>( monthDays[0].iWeekOfMonth ) );
+
+ //day of week mask.
+ TUint32 dowMask = 0;
+ TranslateEmailFwDayOfWeek( monthDays[0].iDayOfWeek, dowMask );
+ calendar->AddOrUpdatePropertyL(
+ KMsgStorePropertyMrDayOfWeekMask, static_cast<TUint32>( dowMask ) );
+ }*/
+ }
+ //weekly.
+ else if ( MRRecurrenceRule::EMRRecurrenceWeekly == rType )
+ {
+ const RArray<MRRecurrenceRule::TMRRecurrentDay>& days = rRule.RecurrentWeekDays();
+
+ //day of week mask.
+ if ( days.Count() )
+ {
+ TUint32 dowMask = 0;
+
+ for ( TInt i = 0; i < days.Count(); i++ )
+ {
+ TranslateEmailFwDayOfWeek( days[i], dowMask );
+ }
+
+ calendar->AddOrUpdatePropertyL(
+ KMsgStorePropertyMrDayOfWeekMask, static_cast<TUint32>( dowMask ) );
+ }
+ }
+ //yearly.
+ else if ( MRRecurrenceRule::EMRRecurrenceYearly == rType )
+ {
+ /**@ needs redoing after the latest MMR iface changes by activesync.*/
+ /*const RArray<MRRecurrenceRule::TRecurrentDaysofMonth>& monthDays = rRule.RecurrentMonthDays();
+ if ( monthDays.Count() )
+ {
+ //week number.
+ calendar->AddOrUpdatePropertyL(
+ KMsgStorePropertyMrWeekNo, static_cast<TUint32>( monthDays[0].iWeekOfMonth ) );
+
+ //day of week mask.
+ TUint32 dowMask = 0;
+ TranslateEmailFwDayOfWeek( monthDays[0].iDayOfWeek, dowMask );
+ calendar->AddOrUpdatePropertyL(
+ KMsgStorePropertyMrDayOfWeekMask, static_cast<TUint32>( dowMask ) );
+ }*/
+ }
+
+ //recurrence id.
+ calendar->AddOrUpdatePropertyL( KMsgStorePropertyMrRRID, aSrc.MRRecurrenceId() );
+
+ //sequence number.
+ calendar->AddOrUpdatePropertyL( KMsgStorePropertyMrSeqNo, static_cast<TUint32>( aSrc.MRSequenceNumberL() ) );
+
+ aDst.AddOrUpdatePropertyL( KMsgStorePropertyMeetingRequest, *calendar );
+ CleanupStack::PopAndDestroy( calendar );
+ __LOG_EXIT
+ } //TranslateEmailFwMrL.
+
+
+/**
+ * Day of week translator from the MsgStore to the FS format. The actual translation
+ * step is supplied via the day of week ftor. See CDayOfWeekFtor for further
+ * information. Although not strictly necessary this avoids duplicating all the if's
+ * when dealing with rule translation.
+ *
+ * @param aDayOfWeekMask day of week mask in the MsgStore format, see
+ * MsgStorePropertyKeys.h for information.
+ * @param aFtor translation ftor.
+ */
+void CBasePlugin::TranslateMsgStoreDayOfWeek(
+ TUint32 aDayOfWeekMask,
+ TDayOfWeekFtor& aFtor )
+
+ {
+ if ( KMsgStoreDaySunday & aDayOfWeekMask )
+ {
+ aFtor( MRRecurrenceRule::EMRRecurrenceSunday );
+ }
+ if ( KMsgStoreDayMonday & aDayOfWeekMask )
+ {
+ aFtor( MRRecurrenceRule::EMRRecurrenceMonday );
+ }
+ if ( KMsgStoreDayTuesday & aDayOfWeekMask )
+ {
+ aFtor( MRRecurrenceRule::EMRRecurrenceTuesday );
+ }
+ if ( KMsgStoreDayWednesday & aDayOfWeekMask )
+ {
+ aFtor( MRRecurrenceRule::EMRRecurrenceWednesday );
+ }
+ if ( KMsgStoreDayThursday & aDayOfWeekMask )
+ {
+ aFtor( MRRecurrenceRule::EMRRecurrenceThursday );
+ }
+ if ( KMsgStoreDayFriday & aDayOfWeekMask )
+ {
+ aFtor( MRRecurrenceRule::EMRRecurrenceFriday );
+ }
+ if ( KMsgStoreDaySaturday & aDayOfWeekMask )
+ {
+ aFtor( MRRecurrenceRule::EMRRecurrenceSaturday );
+ }
+ }
+
+
+/**
+ *
+ */
+void CBasePlugin::TranslateEmailFwDayOfWeek(
+ MRRecurrenceRule::TMRRecurrentDay aSrc,
+ TUint32& aDst )
+
+ {
+ if ( MRRecurrenceRule::EMRRecurrenceSunday == aSrc )
+ {
+ aDst |= KMsgStoreDaySunday;
+ }
+ if ( MRRecurrenceRule::EMRRecurrenceMonday == aSrc )
+ {
+ aDst |= KMsgStoreDayMonday;
+ }
+ if ( MRRecurrenceRule::EMRRecurrenceTuesday == aSrc )
+ {
+ aDst |= KMsgStoreDayTuesday;
+ }
+ if ( MRRecurrenceRule::EMRRecurrenceWednesday == aSrc )
+ {
+ aDst |= KMsgStoreDayWednesday;
+ }
+ if ( MRRecurrenceRule::EMRRecurrenceThursday == aSrc )
+ {
+ aDst |= KMsgStoreDayThursday;
+ }
+ if ( MRRecurrenceRule::EMRRecurrenceFriday == aSrc )
+ {
+ aDst |= KMsgStoreDayFriday;
+ }
+ if ( MRRecurrenceRule::EMRRecurrenceSaturday == aSrc )
+ {
+ aDst |= KMsgStoreDaySaturday;
+ }
+ }
+
+
+/**
+ *
+ */
+/*static*/ void TranslateMsgStoreAttendeeL(
+ CMsgStorePropertyContainer& aSrc,
+ TUint aIdx,
+ MMROrganizer& aAttendee )
+
+ {
+ RMsgStoreAddress address;
+ CleanupClosePushL( address );
+
+ aSrc.PropertyValueAddressL( aIdx, address );
+
+ if ( address.iEmailAddress.Length() )
+ {
+ aAttendee.SetAddressL( address.iEmailAddress );
+ }
+
+ if ( address.iDisplayName.Length() )
+ {
+ aAttendee.SetCommonNameL( address.iDisplayName );
+ }
+
+ CleanupStack::PopAndDestroy( &address );
+ }
+
+
+/**
+ *
+ */
+EXPORT_C void CBasePlugin::TranslateEmailFwAttendeeL(
+ MMROrganizer& aSrc,
+ RMsgStoreAddress& aDst )
+
+ {
+ const TDesC& address = aSrc.Address();
+ if ( address != KNullDesC )
+ {
+ aDst.iEmailAddress.Create( address );
+ }
+
+ const TDesC& commonName = aSrc.CommonName();
+ if ( commonName != KNullDesC )
+ {
+ aDst.iDisplayName.Create( commonName );
+ }
+ }
+
+
+/**
+ *
+ */
+EXPORT_C inline void CBasePlugin::RemoveAllPropertiesL(
+ CMsgStorePropertyContainer& aContainer,
+ const TDesC8& aName )
+
+ {
+ TUint index = 0;
+ while ( aContainer.FindProperty( aName, index ) )
+ {
+ aContainer.RemovePropertyL( index );
+ }
+ }
+
+
+/**
+ *
+ */
+void CBasePlugin::TranslateEmailFwRecipientsL(
+ CMsgStoreMessagePart& aDst,
+ const TDesC8& aDstProperty,
+ RPointerArray<CFSMailAddress>& aRecipients )
+
+ {
+ CBasePlugin::RemoveAllPropertiesL( aDst, aDstProperty );
+
+ TInt count = aRecipients.Count();
+ if ( 0 < count )
+ {
+ RMsgStoreAddress msgStoreAddress;
+ CleanupClosePushL( msgStoreAddress );
+
+ for ( TUint i = 0; i < count; i++ )
+ {
+ if ( aRecipients[i]->GetEmailAddress().Length() )
+ {
+ msgStoreAddress.iEmailAddress.Create( aRecipients[i]->GetEmailAddress() );
+ }
+ if ( aRecipients[i]->GetDisplayName().Length() )
+ {
+ msgStoreAddress.iDisplayName.Create( aRecipients[i]->GetDisplayName() );
+ }
+
+ aDst.AddPropertyL( aDstProperty, msgStoreAddress );
+ msgStoreAddress.Close();
+ }
+
+ CleanupStack::PopAndDestroy( &msgStoreAddress );
+ }
+ }
+
+
+/**
+ *
+ */
+/*static*/ void TranslateMsgStoreAttendeesL(
+ CMsgStorePropertyContainer& aMessage,
+ CBaseMrInfoObject& aMrInfo,
+ const TDesC8& aProperty,
+ MMRAttendee::TAttendeeRole aRole )
+ {
+
+ TUint idx = 0;
+ while ( aMessage.FindProperty( aProperty, idx, idx ) )
+ {
+ MMRAttendee* attendee = CBaseMrAttendee::NewL();
+ CleanupStack::PushL( attendee );
+
+ TranslateMsgStoreAttendeeL( aMessage, idx, *attendee );
+ attendee->SetAttendeeRoleL( aRole );
+
+ aMrInfo.AddAttendeeL( attendee );
+ CleanupStack::Pop( attendee );
+
+ ++idx;
+ }
+ }
+
+
+/* ANN0001
+An intentional formatted text line break MUST only be included in a
+"TEXT" property value by representing the line break with the
+character sequence of BACKSLASH (US-ASCII decimal 92), followed by a
+LATIN SMALL LETTER N (US-ASCII decimal 110) or a LATIN CAPITAL LETTER
+N (US-ASCII decimal 78), that is "\n" or "\N".
+
+http://www.kanzaki.com/docs/ical/text.html
+ */