diff -r f5050f1da672 -r 04becd199f91 javaextensions/pim/framework/src.s60/cpimeventmatcher.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/javaextensions/pim/framework/src.s60/cpimeventmatcher.cpp Tue Apr 27 16:30:29 2010 +0300 @@ -0,0 +1,335 @@ +/* +* Copyright (c) 2008 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: An event occurrence matcher. + * +*/ + + +// INCLUDE FILES +#include "cpimeventmatcher.h" +#include "cpimeventitem.h" +#include "cpimrepeatrule.h" +#include "pimpanics.h" +#include "logger.h" + +CPIMEventMatcher::CPIMEventMatcher(const TPIMEventSearchType aSearchType, + const TPIMDate& aStartDate, const TPIMDate& aEndDate, + TBool aInitialEventOnly) : + iSearchType(aSearchType), iStartDate(aStartDate), iEndDate(aEndDate), + iInitialEventOnly(aInitialEventOnly) +{ + JELOG2(EPim); +} + +CPIMEventMatcher::~CPIMEventMatcher() +{ + JELOG2(EPim); +} + +TBool CPIMEventMatcher::SaneOptions() +{ + JELOG2(EPim); + if (iSearchType != EPIMEventSearchStarting && iSearchType + != EPIMEventSearchEnding && iSearchType != EPIMEventSearchOccurring) + { + return EFalse; + } + + if (iStartDate > iEndDate) + { + return EFalse; + } + + return ETrue; +} + +TBool CPIMEventMatcher::MatchL(const CPIMEventItem& aTestedEvent, + TPIMDate& aOccurrenceStart) const +{ + JELOG2(EPim); + TBool eventMatches = EFalse; + + switch (iSearchType) + { + case EPIMEventSearchStarting: + { + eventMatches = MatchStartingL(aTestedEvent, aOccurrenceStart); + break; + } + case EPIMEventSearchEnding: + { + eventMatches = MatchEndingL(aTestedEvent, aOccurrenceStart); + break; + } + case EPIMEventSearchOccurring: + { + eventMatches = MatchOccurringL(aTestedEvent, aOccurrenceStart); + break; + } + default: + { + // Error + User::Panic(KPIMPanicCategory, EPIMPanicEventItemsSearchType); + break; + } + } + + return eventMatches; +} + +TBool CPIMEventMatcher::MatchStartingL(const CPIMEventItem& aTestedEvent, + TPIMDate& aOccurrenceStart) const +{ + JELOG2(EPim); + // If the Event, regardless of repeating, starts between the given + // range (inclusive), it matches. If we didn't get direct match, + // we'll check if any of the repeating occurrences of the item + // starts between the given range (if repeating occurrences are + // taken into account and the Event is repeating). + + TPIMDate eventStart(0); // For matching and occurrence start + TPIMDate dummyEnd(0); // Not used + TBool match = EFalse; + + if (ExtractStartAndEndDateL(aTestedEvent, eventStart, dummyEnd) == KErrNone) + { + if (eventStart >= iStartDate && eventStart <= iEndDate) + { + aOccurrenceStart = eventStart; + match = ETrue; + } + else if (!iInitialEventOnly && aTestedEvent.IsRepeating()) + { + match = MatchStartingRepeatingL(eventStart, aTestedEvent, + aOccurrenceStart); + } + } + + return match; +} + +TBool CPIMEventMatcher::MatchStartingRepeatingL(const TPIMDate& aEventStart, + const CPIMEventItem& aTestedEvent, TPIMDate& aOccurrenceStart) const +{ + JELOG2(EPim); + TBool match = EFalse; + + const CPIMRepeatRule* repeatRule = + static_cast(aTestedEvent.GetRepeat()); + + CArrayFixFlat* occurrences = repeatRule->DatesL(aEventStart, + iStartDate, iEndDate); + + const TInt numOccs = occurrences->Count(); + for (TInt occIndex = 0; occIndex < numOccs; occIndex++) + { + // Occurrence start date + TPIMDate occ = occurrences->At(occIndex); + + if ((occ >= iStartDate) && (occ <= iEndDate)) + { + aOccurrenceStart = occ; + match = ETrue; + break; + } + } + + delete occurrences; + return match; +} + +TBool CPIMEventMatcher::MatchEndingL(const CPIMEventItem& aTestedEvent, + TPIMDate& aOccurrenceStart) const +{ + JELOG2(EPim); + // If the Event, regardless of repeating, ends between the given + // range (inclusive), it matches. If we didn't get direct match, + // we'll check if any of the repeating occurrences of the item + // ends between the given range (if repeating occurrences are + // taken into account and the Event is repeating). + + TPIMDate eventStart(0); // For occurrence start + TPIMDate eventEnd(0); // For matching + TBool match = EFalse; + + if (ExtractStartAndEndDateL(aTestedEvent, eventStart, eventEnd) == KErrNone) + { + if (eventEnd >= iStartDate && eventEnd <= iEndDate) + { + aOccurrenceStart = eventStart; + match = ETrue; + } + else if (!iInitialEventOnly && aTestedEvent.IsRepeating()) + { + match = MatchEndingRepeatingL(eventEnd, aTestedEvent, + aOccurrenceStart); + } + } + + return match; +} + +TBool CPIMEventMatcher::MatchEndingRepeatingL(const TPIMDate& aEventEnd, + const CPIMEventItem& aTestedEvent, TPIMDate& aOccurrenceStart) const +{ + JELOG2(EPim); + TBool match = EFalse; + + // We need the start date for getting the repeating + // occurrences of the event. Skip if not present. + TPIMDate eventStart(0); + if (aTestedEvent.CountValuesL(EPIMEventStart) != 0) + { + // And again we just use the first start value + eventStart = aTestedEvent.GetDateL(EPIMEventStart, 0); + + const CPIMRepeatRule* repeatRule = + static_cast(aTestedEvent.GetRepeat()); + + TTimeIntervalMicroSeconds eventLen = aEventEnd.MicroSecondsFrom( + eventStart); + + // We expand the subset of retrieved occurrences a bit + // from the start so that the first possible end date is + // included. + CArrayFixFlat* occurrences = repeatRule->DatesL(eventStart, + iStartDate - eventLen, iEndDate); + + const TInt numOccs = occurrences->Count(); + for (TInt occIndex = 0; occIndex < numOccs; occIndex++) + { + // Occurrence start date + TPIMDate occ = occurrences->At(occIndex); + + if (((occ + eventLen) >= iStartDate) && ((occ + eventLen) + <= iEndDate)) + { + aOccurrenceStart = occ; + match = ETrue; + break; + } + } + + delete occurrences; + } + + return match; +} + +TBool CPIMEventMatcher::MatchOccurringL(const CPIMEventItem& aTestedEvent, + TPIMDate& aOccurrenceStart) const +{ + JELOG2(EPim); + // If the Event, regardless of repeating, either starts or ends + // between the given range (inclusive) or the start date is before + // range start and the end date is after range end, it matches. + // If we didn't get direct match, we'll check the same for any + // possible repeating occurrences of the item. + + TPIMDate eventStart(0); // For matching and occurrence start + TPIMDate eventEnd(0); // For matching + TBool match = EFalse; + + if (ExtractStartAndEndDateL(aTestedEvent, eventStart, eventEnd) == KErrNone) + { + if (eventStart <= iEndDate && eventEnd >= iStartDate) + { + aOccurrenceStart = eventStart; + match = ETrue; + } + else if (!iInitialEventOnly && aTestedEvent.IsRepeating()) + { + match = MatchOccurringRepeatingL(eventStart, eventEnd, + aTestedEvent, aOccurrenceStart); + } + } + + return match; +} + +TBool CPIMEventMatcher::MatchOccurringRepeatingL(const TPIMDate& aEventStart, + const TPIMDate& aEventEnd, const CPIMEventItem& aTestedEvent, + TPIMDate& aOccurrenceStart) const +{ + JELOG2(EPim); + TBool match = EFalse; + + const CPIMRepeatRule* repeatRule = + static_cast(aTestedEvent.GetRepeat()); + + TTimeIntervalMicroSeconds eventLen = + aEventEnd.MicroSecondsFrom(aEventStart); + + // We expand the subset of retrieved occurrences a bit from the start + // so that the first possible end date is included and a matching + // event may start before the given range. + CArrayFixFlat* occurrences = repeatRule->DatesL(aEventStart, + iStartDate - eventLen, iEndDate); + + const TInt numOccs = occurrences->Count(); + for (TInt occIndex = 0; occIndex < numOccs; occIndex++) + { + // Occurrence start date + TPIMDate occ = occurrences->At(occIndex); + + if (occ <= iEndDate && occ + eventLen >= iStartDate) + { + aOccurrenceStart = occ; + match = ETrue; + break; + } + } + + delete occurrences; + return match; +} + +TInt CPIMEventMatcher::ExtractStartAndEndDateL(const CPIMEventItem& aEvent, + TPIMDate& aEventStart, TPIMDate& aEventEnd) const +{ + JELOG2(EPim); + TInt retVal = KErrNone; + + if (aEvent.CountValuesL(EPIMEventStart) != 0) + { + // Start date is present. + aEventStart = aEvent.GetDateL(EPIMEventStart, 0); + if (aEvent.CountValuesL(EPIMEventEnd) != 0) + { + // End date is also present. + aEventEnd = aEvent.GetDateL(EPIMEventEnd, 0); + } + else + { + // End date is not present - use start date also as end date. + aEventEnd = aEventStart; + } + } + else if (aEvent.CountValuesL(EPIMEventEnd) != 0) + { + // Start date is not present, but end date is present. + // Use end date also as start date. + aEventEnd = aEvent.GetDateL(EPIMEventEnd, 0); + aEventStart = aEventEnd; + } + else + { + // Neither start or end date is present. + retVal = KErrNotFound; + } + + return retVal; +} + +// End of File