diff -r 000000000000 -r f979ecb2b13e calendarengines/agnversit2/src/AgnParseRRule.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/calendarengines/agnversit2/src/AgnParseRRule.cpp Tue Feb 02 10:12:19 2010 +0200 @@ -0,0 +1,365 @@ +/* +* Copyright (c) 2007-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: This file contains implementation of iCal parser which parses +* the recurrence rule of iCal entry. +* +*/ + + + + +#include "AgnParseRRule.h" + +#include "calendarengines_debug.h" + +#include +#include "ICalValue.h" // For CICalValue + +/** +Constructor + +@param aAgnImpUtil AgnVersit2Importer utility functions +*/ +CAgnParseRRule::CAgnParseRRule( MAgnImpUtil& aAgnImpUtil ) : + iAgnImpUtil( aAgnImpUtil ), + iSetSegs( 0 ) + { + TRACE_ENTRY_POINT; + TRACE_EXIT_POINT; + } + + +/** +Destructor +*/ +CAgnParseRRule::~CAgnParseRRule() + { + TRACE_ENTRY_POINT; + TRACE_EXIT_POINT; + } + + +//========================================================================================= +// Parsing functions +//========================================================================================= + +/** +Parse the keywords and update RRule +@param aRule recurrence rules +@param aRecRules array of recurrence rule value segments. +@param aStartTime The DTSTART of the parent component. +@param aUid Entry Uid +@param aRulevalues array of CICalValues +@return True if parsed the keyword successfully +*/ +TBool CAgnParseRRule::ParseL( TCalRRule& aRule, RPointerArray& aRecRules, + const TCalTime& aStartTime, const TDesC8& aUid, + const RPointerArray& aRulevalues ) + { + TRACE_ENTRY_POINT; + + aRule.SetDtStart( aStartTime ); + + TInt recCount = aRecRules.Count(); + TBool parsed = EFalse; + + //Loop through the CICalRuleSegments + for (TInt rnum = 0; rnum < aRecRules.Count(); ++rnum) + { + parsed = EFalse; + + CICalRuleSegment* segment = aRecRules[rnum]; + + if (segment->Values().Count() < 1) + { + iAgnImpUtil.ReportErrorL( MAgnImportObserver::EImpErrorMissingData, aUid, + aRulevalues[0]->TextL() ); + + // On continue, all we have is FREQ=DAILY. + } + + //Try to parse it with specific parser + TRAPD( error, parsed = DoParseL( *segment, aRule ) ); + + //if the keyword was not parsed, try to parse it + if( error == KErrNone && !parsed ) + { + //Update aRule with CICalRuleSegment + switch (segment->Type()) + { + case CICalRuleSegment::ESegFreq : + break; + + //Set Until + case CICalRuleSegment::ESegUntil : + { + SetRRuleUntilL( *segment, aRule ); + break; + } + + //Set Count + case CICalRuleSegment::ESegCount : + { + aRule.SetCount(segment->Values()[0]->IntegerL()); + break; + } + + //Set Interval + case CICalRuleSegment::ESegInterval : + { + aRule.SetInterval(segment->Values()[0]->IntegerL()); + break; + } + + //Not supported keywords by freq, report error + case CICalRuleSegment::ESegByPos : // not supported by freq, fall through + case CICalRuleSegment::ESegBySecond : // not supported by freq, fall through + case CICalRuleSegment::ESegByMinute : // not supported by freq, fall through + case CICalRuleSegment::ESegByHour : // not supported by freq, fall through + case CICalRuleSegment::ESegByYearDay : // not supported by freq, fall through + case CICalRuleSegment::ESegByWeekNo : // not supported by freq, fall through + case CICalRuleSegment::ESegExtension : // not supported by freq, fall through + case CICalRuleSegment::ESegWkSt : // not supported by freq, fall through + case CICalRuleSegment::ESegByDay : // not supported by freq, fall through + case CICalRuleSegment::ESegByMonthDay : // not supported by freq, fall through + case CICalRuleSegment::ESegByMonth : // not supported by freq, fall through + default: + { + iAgnImpUtil.ReportErrorL( MAgnImportObserver::EImpErrorNotSupported, aUid, + aRulevalues[0]->TextL() ); + } + } + } + + //TRAP returned error + else if( error != KErrNone ) + { + if( error == KErrAbort )//KErrAbort, report error and stop parsing + { + TRACE_EXIT_POINT; + iAgnImpUtil.ReportErrorL( MAgnImportObserver::EImpErrorNotSupported, aUid, + aRulevalues[0]->TextL(), EFalse ); + } + else //Otherwise leave with error + { + TRACE_EXIT_POINT; + User::Leave( error ); + } + } + + }//for end + + + //Finalize parsing + parsed = FinalizeParsingL( aRule, aStartTime ); + + TRACE_EXIT_POINT; + return parsed; + } + + +/** +Parse the keywords and update RRule +@param aSegment recurrence rule value segment. +@param aRule recurrence rules +@return true if parsed the keyword successfully +*/ +TBool CAgnParseRRule::DoParseL( CICalRuleSegment& /*aSegment*/, TCalRRule& /*aRule*/ ) + { + TRACE_ENTRY_POINT; + + return EFalse; + TRACE_EXIT_POINT; + } + +/** +Finalize the parsing +@param aRule recurrence rules +@param aStartTime The DTSTART of the parent component. +@return true if finalized parsing successfully +*/ +TBool CAgnParseRRule::FinalizeParsingL( TCalRRule& aRule, const TCalTime& /*aStartTime*/ ) + { + TRACE_ENTRY_POINT; + + TBool finalized = ETrue; + + // Agenda requires that all RRULES have an interval of some sort. + // An interval of 1 is the default. + if (aRule.Interval() < 1) + { + aRule.SetInterval(1); + } + + TRACE_EXIT_POINT; + return finalized; + } + + + +//========================================================================================= +// Following functions updates the TCalRRule +//========================================================================================= + +/** +Update TCalRRule with Until value +@param aSegment recurrence rule value segment. +@param aRule recurrence rules +@return true if aRule updated successfully +*/ +TBool CAgnParseRRule::SetRRuleUntilL( const CICalRuleSegment& aSegment, TCalRRule& aRule ) + { + TRACE_ENTRY_POINT; + + TTime time; + TCalTime calTime; + + // adding time and date information to the Repeat Until field + CICalValue::TTimeZoneType type = CICalValue::EUtcTime; + aSegment.Values()[0]->GetDateTimeL(time, type); + + calTime.SetTimeUtcL(time); + aRule.SetUntil(calTime); + + TRACE_EXIT_POINT; + return ETrue; + } + +/** +Update TCalRRule with week start value +@param aSegment recurrence rule value segment. +@param aRule recurrence rules +@return true if aRule updated successfully +*/ +TBool CAgnParseRRule::SetRRuleWkStL( const CICalRuleSegment& aSegment, TCalRRule& aRule ) + { + TRACE_ENTRY_POINT; + + TDay dayval; + TInt daypos; + aSegment.Values()[0]->GetDayL(dayval, daypos); + aRule.SetWkSt(dayval); + //iSetSegs |= ESegFlagByWkSt; <-- Does not exist, a bug? + + TRACE_EXIT_POINT; + return ETrue; + } + +/** +Update TCalRRule with by days +@param aSegment recurrence rule value segment. +@param aRule recurrence rules +@return true if aRule updated successfully +*/ +TBool CAgnParseRRule::SetRRuleByDayL( const CICalRuleSegment& aSegment, TCalRRule& aRule ) + { + TRACE_ENTRY_POINT; + + RArray daysOfMonth; + CleanupClosePushL(daysOfMonth); + + const RPointerArray& values = aSegment.Values(); + + TInt valCount = values.Count(); + TDay dayval = EMonday; + TInt daypos = 0; + + for (TInt day = 0; day < valCount; ++day) + { + values[day]->GetDayL(dayval, daypos); + if ((daypos == -1) || ((daypos >= 1) && (daypos <= KMaxWeekDayNum))) + { + User::LeaveIfError(daysOfMonth.Append(TCalRRule::TDayOfMonth(dayval, daypos))); + } + else if (daypos == 0) + //BYDAY applies to every day in month + { + User::LeaveIfError(daysOfMonth.Append(TCalRRule::TDayOfMonth(dayval, 1))); + User::LeaveIfError(daysOfMonth.Append(TCalRRule::TDayOfMonth(dayval, 2))); + User::LeaveIfError(daysOfMonth.Append(TCalRRule::TDayOfMonth(dayval, 3))); + User::LeaveIfError(daysOfMonth.Append(TCalRRule::TDayOfMonth(dayval, 4))); + User::LeaveIfError(daysOfMonth.Append(TCalRRule::TDayOfMonth(dayval, -1))); + } + else + { + //Invalid day - unrecoverable + User::Leave( KErrAbort ); + } + } + + aRule.SetByDay(daysOfMonth); + CleanupStack::PopAndDestroy(&daysOfMonth); + iSetSegs |= ESegFlagByDay; + + TRACE_EXIT_POINT; + return ETrue; + } + +/** +Update TCalRRule with by month +@param aSegment recurrence rule value segment. +@param aRule recurrence rules +@return true if aRule updated successfully +*/ +TBool CAgnParseRRule::SetRRuleByMonthL( const CICalRuleSegment& aSegment, TCalRRule& aRule ) + { + TRACE_ENTRY_POINT; + + RArray theMonths; + CleanupClosePushL(theMonths); + const RPointerArray& values = aSegment.Values(); + TInt valCount = values.Count(); + + for (TInt month = 0; month < valCount; ++month) + { + User::LeaveIfError(theMonths.Append(values[month]->MonthL())); + } + + iSetSegs |= ESegFlagByMonth; + aRule.SetByMonth(theMonths); + CleanupStack::PopAndDestroy(&theMonths); + + TRACE_EXIT_POINT; + return ETrue; + } + + +/** +Update TCalRRule with by month day +@param aSegment recurrence rule value segment. +@param aRule recurrence rules +@return true if aRule updated successfully +*/ +TBool CAgnParseRRule::SetRRuleByMonthDayL( const CICalRuleSegment& aSegment, TCalRRule& aRule ) + { + TRACE_ENTRY_POINT; + + RArray days; + CleanupClosePushL(days); + const RPointerArray& values = aSegment.Values(); + TInt valCount = values.Count(); + + for (TInt day = 0; day < valCount; ++day) + { + //dates are represented as day - 1 (0 = 1) in TDateTime + User::LeaveIfError(days.Append(values[day]->IntegerL() - 1 )); + } + + aRule.SetByMonthDay(days); + CleanupStack::PopAndDestroy(&days); + iSetSegs |= ESegFlagByMonthDay; + + TRACE_EXIT_POINT; + return ETrue; + }