/*
* Copyright (c) 2002-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: Static helper methods for analyzing entries
*
*/
// INCLUDE FILES
#include "emailtrace.h"
#include "esmrentryhelper.h"
#include "esmrhelper.h"
#include "esmrdef.h"
// From System
#include <calentry.h>
#include <caltime.h>
#include <calrrule.h>
#include <caluser.h>
#include <msvids.h>
#include <MsgMailUIDs.h>
#include <cmrmailboxutils.h>
#include <CalenInterimUtils2.h>
// unnamed naespace for local definitions
namespace { // codescanner::namespace
// Definition for zero interval
const TInt KZeroInterval( 0 );
}
// ======== MEMBER FUNCTIONS ========
// ----------------------------------------------------------------------------
// ESMREntryHelper::SendingMailBoxL
// ----------------------------------------------------------------------------
//
EXPORT_C TMsvId ESMREntryHelper::SendingMailBoxL(
const MAgnEntryUi::TAgnEntryUiInParams& aInParams,
CMRMailboxUtils& aUtils )
{
FUNC_LOG;
TMsvId result(0);
if ( aInParams.iCallingApp.iUid == KUidMsgMailViewer )
{
result = aInParams.iMailBoxId;
}
else
{
CMRMailboxUtils::TMailboxInfo info;
// returns KMsvNullIndexEntryId if default box cannot be resolved:
aUtils.GetDefaultMRMailBoxL( info );
result = info.iEntryId;
}
return result;
}
// ----------------------------------------------------------------------------
// ESMREntryHelper::IsRepeatingMeetingL
// ----------------------------------------------------------------------------
//
EXPORT_C TBool ESMREntryHelper::IsRepeatingMeetingL(
const CCalEntry& aEntry )
{
FUNC_LOG;
TBool retVal( EFalse );
if ( IsModifyingEntryL( aEntry ) )
{
retVal = ETrue;
}
else
{
TCalRRule dummyRule;
if ( aEntry.GetRRuleL( dummyRule ) )
{
retVal = ETrue;
}
else
{
RArray<TCalTime> dummyRDateList;
CleanupClosePushL( dummyRDateList );
aEntry.GetRDatesL( dummyRDateList );
if ( dummyRDateList.Count() > 0 )
{
retVal = ETrue;
}
CleanupStack::PopAndDestroy( &dummyRDateList );
}
}
return retVal;
}
// ----------------------------------------------------------------------------
// ESMREntryHelper::IsModifyingEntryL
// ----------------------------------------------------------------------------
//
EXPORT_C TBool ESMREntryHelper::IsModifyingEntryL( const CCalEntry& aEntry )
{
FUNC_LOG;
return ( aEntry.RecurrenceIdL().TimeUtcL() !=
Time::NullTTime() ) ? ETrue : EFalse;
}
// ----------------------------------------------------------------------------
// ESMREntryHelper::IsLatestSavedSentL
// ----------------------------------------------------------------------------
//
EXPORT_C TBool ESMREntryHelper::IsLatestSavedSentL(
const CCalEntry& aEntry )
{
FUNC_LOG;
TBool retVal( EFalse );
if ( aEntry.DTStampL().TimeUtcL() == Time::NullTTime() )
{
// If entries are synchronized to phone we must always assume that
// they have been sent already. In case of our own requests we keep the
// DTSTAMP as null until sending.
retVal = ETrue;
}
return retVal;
}
// ----------------------------------------------------------------------------
// ESMREntryHelper::IsCancelledL
// ----------------------------------------------------------------------------
//
EXPORT_C TBool ESMREntryHelper::IsCancelledL(
const CCalEntry& aEntry,
CMRMailboxUtils& aUtils )
{
FUNC_LOG;
TBool retVal( EFalse );
// Check if either entire meeting is cancelled, or this attendee
// has been removed from the participant list. According to RFC2446
// in that case entry doesn't have status field set.
if ( aEntry.StatusL() == CCalEntry::ECancelled ||
( aEntry.MethodL() == CCalEntry::EMethodCancel &&
!aUtils.ThisAttendeeL( aEntry ) ) )
{
retVal = ETrue;
}
return retVal;
}
// ----------------------------------------------------------------------------
// ESMREntryHelper::IsAllDayEventL
// ----------------------------------------------------------------------------
//
EXPORT_C TBool ESMREntryHelper::IsAllDayEventL( const CCalEntry& aEntry )
{
FUNC_LOG;
TBool retVal( EFalse );
TDateTime start = aEntry.StartTimeL().TimeLocalL().DateTime();
TDateTime end = aEntry.EndTimeL().TimeLocalL().DateTime();
// All-day events:
// From one days 00:00:00 to at least next days 00:00:00.
// Start times hour, minute and second need to be the same.
// Start and end time days need to be different
if( start.Hour() == end.Hour() &&
start.Minute() == end.Minute() &&
start.Second() == end.Second() &&
start.Day() != end.Day() )
{
if( start.Hour() == 0 &&
start.Minute() == 0 &&
start.Second() == 0 )
{
retVal = ETrue;
}
}
return retVal;
}
// ----------------------------------------------------------------------------
// ESMREntryHelper::OccursInPastL
// ----------------------------------------------------------------------------
//
EXPORT_C TBool ESMREntryHelper::OccursInPastL( const CCalEntry& aEntry )
{
FUNC_LOG;
TBool retVal( EFalse );
TTime universalTime;
universalTime.UniversalTime();
TTime meetingUniversalTime = aEntry.StartTimeL().TimeUtcL();
if ( universalTime > meetingUniversalTime )
{
retVal = ETrue;
}
return retVal;
}
// ----------------------------------------------------------------------------
// ESMREntryHelper::PhoneOwnerAddrL
// ----------------------------------------------------------------------------
//
EXPORT_C const TDesC& ESMREntryHelper::PhoneOwnerAddrL(
const CCalEntry& aEntry,
CMRMailboxUtils& aUtils )
{
FUNC_LOG;
if ( aUtils.IsOrganizerL( aEntry ) )
{
return aEntry.OrganizerL()->Address();
}
else
{
CCalAttendee* thisAttendee = aUtils.ThisAttendeeL( aEntry );
if ( thisAttendee )
{
return thisAttendee->Address();
}
else
{
return KNullDesC;
}
}
}
// ----------------------------------------------------------------------------
// ESMREntryHelper::EqualAttendeeL
// ----------------------------------------------------------------------------
//
EXPORT_C CCalAttendee* ESMREntryHelper::EqualAttendeeL(
const CCalAttendee& aAttendee,
const CCalEntry& aEntry )
{
FUNC_LOG;
TPtrC addr = ESMRHelper::AddressWithoutMailtoPrefix(
aAttendee.Address() );
RPointerArray<CCalAttendee>& attendees = aEntry.AttendeesL();
TInt count( attendees.Count() );
for ( TInt i ( 0 ); i < count; ++i )
{
TPtrC testAddr =
ESMRHelper::AddressWithoutMailtoPrefix(
attendees[i]->Address() );
if ( addr.CompareF( testAddr ) == 0 )
{
return attendees[i];
}
}
return NULL;
}
// ----------------------------------------------------------------------------
// ESMREntryHelper::SpansManyDaysL
// ----------------------------------------------------------------------------
//
EXPORT_C TBool ESMREntryHelper::SpansManyDaysL(
const TCalTime& aStartTime,
const TCalTime& aEndTime )
{
FUNC_LOG;
TBool retVal( EFalse );
// mustn't use UTC time here, local time specifies if the midnight
// is crossed
TTime localStartTime = aStartTime.TimeLocalL();
TTime localEndTime = aEndTime.TimeLocalL();
TTimeIntervalDays days = localEndTime.DaysFrom( localStartTime );
if ( days.Int() > 0 )
{
retVal = ETrue;
}
return retVal;
}
// ----------------------------------------------------------------------------
// ESMREntryHelper::EventTypeL
// ----------------------------------------------------------------------------
//
EXPORT_C TESMRCalendarEventType ESMREntryHelper::EventTypeL(
const CCalEntry& aCalEntry )
{
FUNC_LOG;
TESMRCalendarEventType type( EESMREventTypeNone );
switch ( aCalEntry.EntryTypeL() )
{
case CCalEntry::EAppt:
if ( CCalenInterimUtils2::IsMeetingRequestL(
const_cast< CCalEntry& >( aCalEntry ) ) )
{
type = EESMREventTypeMeetingRequest;
}
else
{
type = EESMREventTypeAppt;
}
break;
case CCalEntry::ETodo:
type = EESMREventTypeETodo;
break;
case CCalEntry::EEvent:
type = EESMREventTypeEEvent;
break;
case CCalEntry::EReminder:
type = EESMREventTypeEReminder;
break;
case CCalEntry::EAnniv:
type = EESMREventTypeEAnniv;
break;
}
return type;
}
// ----------------------------------------------------------------------------
// ESMREntryHelper::SetInstanceStartAndEndL
// ----------------------------------------------------------------------------
//
EXPORT_C void ESMREntryHelper::SetInstanceStartAndEndL(
CCalEntry& aChild,
const CCalEntry& aParent,
const TCalTime& aChildStart )
{
TTime parentStart( aParent.StartTimeL().TimeUtcL() );
TTime parentEnd( aParent.EndTimeL().TimeUtcL() );
const TTime KNullTime( Time::NullTTime() );
if ( KNullTime == parentStart ||
KNullTime == parentEnd ||
KNullTime == aChildStart.TimeUtcL() )
{
// Invalid time --> Leaving
User::Leave( KErrArgument );
}
TTimeIntervalMicroSeconds duration( KZeroInterval );
duration = parentEnd.MicroSecondsFrom( parentStart );
TCalTime childStart;
TCalTime childEnd;
// Meeting time mode is Fixed Utc
if( aChild.EntryTypeL() == CCalEntry::EAppt )
{
const TTime startTime = aChildStart.TimeUtcL();
childStart.SetTimeUtcL( startTime );
childEnd.SetTimeUtcL( startTime + duration );
}
// Anniversary time mode is local floating
if( aChild.EntryTypeL() == CCalEntry::EAnniv )
{
const TTime startTime = aChildStart.TimeLocalL();
childStart.SetTimeLocalFloatingL( startTime );
childEnd.SetTimeLocalFloatingL( startTime + duration );
}
aChild.SetStartAndEndTimeL( childStart, childEnd );
}
// ----------------------------------------------------------------------------
// ESMREntryHelper::CheckRepeatUntilValidityL
// ----------------------------------------------------------------------------
//
EXPORT_C void ESMREntryHelper::CheckRepeatUntilValidityL(
CCalEntry& aEntry,
const TCalTime& aInstanceTime )
{
if ( ESMREntryHelper::IsRepeatingMeetingL(aEntry) &&
!ESMREntryHelper::IsModifyingEntryL(aEntry) )
{
TCalRRule originalRRule;
if ( aEntry.GetRRuleL( originalRRule ) )
{
TCalTime endTime = aEntry.EndTimeL();
TCalTime startTime = aEntry.StartTimeL();
TTimeIntervalMicroSeconds duration =
endTime.TimeLocalL().MicroSecondsFrom(
startTime.TimeLocalL() );
TTime instanceEndTime( aInstanceTime.TimeLocalL() );
instanceEndTime += duration;
TCalTime repeatUntilTime = originalRRule.Until();
TDateTime repeat = repeatUntilTime.TimeLocalL().DateTime();
TDateTime instanceEndDatetime = instanceEndTime.DateTime();
if ( repeatUntilTime.TimeLocalL() < instanceEndTime )
{
// reset the recurrence so, that the repeat until
// time is included in repeat range. This is done,
// because when setting the instance start and end
// time, the CCalEntry implementation clears the
// recurrence information if the end time is
// after repeat until end time.
// CCalEntry forces the repeat until time to be
// same than last entry's start time when storing the
// entry to db. Reason uknown.
TCalRRule rRule = originalRRule;
TCalTime newUntil;
newUntil.SetTimeLocalL( instanceEndTime );
rRule.SetUntil( newUntil );
aEntry.SetRRuleL( rRule );
}
}
}
}
// End of File