diff -r e8e63152f320 -r 2a9601315dfc javaextensions/pim/framework/src.s60/cpimrepeatrule.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/javaextensions/pim/framework/src.s60/cpimrepeatrule.cpp Mon May 03 12:27:20 2010 +0300 @@ -0,0 +1,781 @@ +/* +* 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: PIM item repeat rule implementation. + * +*/ + + +// INCLUDE FILES +#include "cpimrepeatrule.h" +#include "pimrepeatruleconverter.h" +#include "pimjnitools.h" +#include "pimutils.h" +#include "s60commonutils.h" +#include "logger.h" + +// CONSTANTS +namespace +{ +const TInt KPIMRepeatRuleMaskWeekInMonth = 1023; // All week bits set +const TInt KPIMRepeatRuleMaskDayInWeek = 131071; // All day bits set +const TInt KPIMRepeatRuleMaskMonthInYear = 536870911; // All month bits set +} + +// ============================ MEMBER FUNCTIONS =============================== + +// ----------------------------------------------------------------------------- +// CPIMRepeatRule::CPIMRepeatRule +// C++ default constructor can NOT contain any code, that +// might leave. +// ----------------------------------------------------------------------------- +// +CPIMRepeatRule::CPIMRepeatRule() : + iRepeatRuleFrequency(0), iRepeatRuleInterval(0), iRepeatRuleEndDate( + Time::NullTTime()), iRepeatRuleDayInMonth(0), iRepeatRuleDayInWeek(0), + iRepeatRuleDayInYear(0), iRepeatRuleMonthInYear(0), + iRepeatRuleWeekInMonth(0), iRepeatRuleCount(0) +{ + JELOG2(EPim); +} + +// ----------------------------------------------------------------------------- +// CPIMRepeatRule::ConstructL +// Symbian 2nd phase constructor can leave. +// ----------------------------------------------------------------------------- +// +void CPIMRepeatRule::ConstructL() +{ + JELOG2(EPim); + iExceptDates = new(ELeave) CArrayFixFlat (1); + // Create here also the array to store the original exception dates + iOriginalExceptDates = new(ELeave) CArrayFixFlat (1); +} + +// ----------------------------------------------------------------------------- +// CPIMRepeatRule::NewL +// Two-phased constructor. +// ----------------------------------------------------------------------------- +// +CPIMRepeatRule* CPIMRepeatRule::NewL() +{ + JELOG2(EPim); + CPIMRepeatRule* self = new(ELeave) CPIMRepeatRule; + + CleanupStack::PushL(self); + self->ConstructL(); + CleanupStack::Pop(self); + + return self; +} + +pimbaserepeatrule* pimbaserepeatrule::getInstance() +{ + JELOG2(EPim); + CPIMRepeatRule* repeatRule = NULL; + TInt error = KErrNone; + TRAP(error, repeatRule = CPIMRepeatRule::NewL()); + if (error != KErrNone) + throw KErrGeneral; + return repeatRule; +} + +// Destructor +CPIMRepeatRule::~CPIMRepeatRule() +{ + JELOG2(EPim); + delete iExceptDates; + delete iOriginalExceptDates; +} + +// ----------------------------------------------------------------------------- +// CPIMRepeatRule::DatesL +// Returns the repeat dates. +// Returns: An array of repeat dates without the exception dates. +// The ownership of the array is transferred to the caller. +// ----------------------------------------------------------------------------- +// +CArrayFixFlat* CPIMRepeatRule::DatesL(const TPIMDate& aStartDate, + const TPIMDate& aSubsetBeginning, const TPIMDate& aSubsetEnding) const +{ + JELOG2(EPim); + return PIMRepeatRuleConverter::DatesL(*this, aStartDate, aSubsetBeginning, + aSubsetEnding, *iExceptDates, iRepeatRuleEndDate, iRepeatRuleCount); +} + +jintArray CPIMRepeatRule::dates(jlong aStartDate, jlong aSubsetBeginning, + jlong aSubsetEnding, JNIEnv* aJniEnv) +{ + JELOG2(EPim); + CArrayFix* repeatDates = NULL; + + TPIMDate nativeStartDate(java::util::S60CommonUtils::JavaTimeToTTime( + aStartDate)); + TPIMDate nativeSubsetBeginning(java::util::S60CommonUtils::JavaTimeToTTime( + aSubsetBeginning)); + TPIMDate nativeSubsetEnding(java::util::S60CommonUtils::JavaTimeToTTime( + aSubsetEnding)); + TInt error = KErrNone; + TRAP(error, repeatDates = DatesL(nativeStartDate, nativeSubsetBeginning, + nativeSubsetEnding)); + + if (error != KErrNone || repeatDates == NULL) + { + // major error + return NULL; + } + + jintArray repeatDatesIntArray = NativeDatesToJavaInts(*aJniEnv, + *repeatDates); + + delete repeatDates; + return repeatDatesIntArray; + +} + +// ----------------------------------------------------------------------------- +// CPIMRepeatRule::AddExceptDateL +// Adds an exception date into the repeat rule. +// ----------------------------------------------------------------------------- +// +void CPIMRepeatRule::AddExceptDateL(TPIMDate aDate) +{ + JELOG2(EPim); + TInt exceptionDateFinder; + TInt fetchIndex = 0; + TKeyArrayFix key(0, ECmpTInt64); + exceptionDateFinder = iExceptDates->Find(aDate, key, fetchIndex); + if (exceptionDateFinder != 0) // 0 would mean that the element was found + { + iExceptDates->AppendL(aDate); + } +} + +void CPIMRepeatRule::addExceptDate(jlong aValue) +{ + JELOG2(EPim); + TPIMDate nativeValue(java::util::S60CommonUtils::JavaTimeToTTime(aValue)); + TInt error = KErrNone; + TRAP(error, AddExceptDateL(nativeValue)); +} + +// ----------------------------------------------------------------------------- +// CPIMRepeatRule::RemoveExceptDate +// Removes an exception date given as a parameter. +// ----------------------------------------------------------------------------- +// +void CPIMRepeatRule::RemoveExceptDate(TPIMDate aDate) +{ + JELOG2(EPim); + TInt exceptionDateFinder; + TInt fetchIndex = 0; + TKeyArrayFix key(0, ECmpTInt64); + exceptionDateFinder = iExceptDates->Find(aDate, key, fetchIndex); + if (exceptionDateFinder == 0) // 0 means that the element was found + { + iExceptDates->Delete(fetchIndex); + // Deleting elements from the array does not cause the + // array buffer to be automatically compressed. + // Compress() method returns excess space to the heap. + iExceptDates->Compress(); + } +} + +void CPIMRepeatRule::removeExceptDate(jlong aValue) +{ + JELOG2(EPim); + TPIMDate nativeValue(java::util::S60CommonUtils::JavaTimeToTTime(aValue)); + RemoveExceptDate(nativeValue); +} + +// ----------------------------------------------------------------------------- +// CPIMRepeatRule::GetExceptDatesL +// Returns the exception dates. +// Returns: An array of exceptiond dates. +// The ownership of the array stays with the repeat rule. +// ----------------------------------------------------------------------------- +// +const CArrayFix& CPIMRepeatRule::GetExceptDatesL() const +{ + JELOG2(EPim); + return *iExceptDates; +} + +jintArray CPIMRepeatRule::getExceptDates(JNIEnv* aJniEnv) +{ + JELOG2(EPim); + // The ownership of the except dates array stays with the repeat rule. + const CArrayFix* exceptDates = NULL; + TInt error = KErrNone; + TRAP(error, exceptDates = &(GetExceptDatesL())); + if (error != KErrNone || exceptDates == NULL) + { + // major error + return NULL; + } + jintArray exceptDatesIntArray = NativeDatesToJavaInts(*aJniEnv, + *exceptDates); + return exceptDatesIntArray; +} + +// ----------------------------------------------------------------------------- +// CPIMRepeatRule::GetIntL +// Returns an integer value. +// Returns: An integer value based on the parameter field. +// ----------------------------------------------------------------------------- +// +TInt CPIMRepeatRule::GetIntL(TPIMField aField) const +{ + JELOG2(EPim); + switch (aField) + { + // First the two supported repeat rule int fields + case EPIMRepeatRuleFrequency: + { + if (iRepeatRuleFrequency == 0) + { + User::Leave(KErrNotFound); + } + return iRepeatRuleFrequency; + } + case EPIMRepeatRuleInterval: + { + if (iRepeatRuleInterval == 0) + { + User::Leave(KErrNotFound); + } + return iRepeatRuleInterval; + } + + // Then the rest of the repeat rule fields (not supported by Nokia.) + case EPIMRepeatRuleDayInMonth: + { + if (iRepeatRuleDayInMonth == 0) + { + User::Leave(KErrNotFound); + } + return iRepeatRuleDayInMonth; + } + case EPIMRepeatRuleDayInWeek: + { + if (iRepeatRuleDayInWeek == 0) + { + User::Leave(KErrNotFound); + } + return iRepeatRuleDayInWeek; + } + case EPIMRepeatRuleDayInYear: + { + if (iRepeatRuleDayInYear == 0) + { + User::Leave(KErrNotFound); + } + return iRepeatRuleDayInYear; + } + case EPIMRepeatRuleMonthInYear: + { + if (iRepeatRuleMonthInYear == 0) + { + User::Leave(KErrNotFound); + } + return iRepeatRuleMonthInYear; + } + case EPIMRepeatRuleWeekInMonth: + { + if (iRepeatRuleWeekInMonth == 0) + { + User::Leave(KErrNotFound); + } + return iRepeatRuleWeekInMonth; + } + case EPIMRepeatRuleCount: + { + if (iRepeatRuleCount == 0) + { + User::Leave(KErrNotFound); + } + return iRepeatRuleCount; + } + default: + { + User::Leave(KErrArgument); + // Even the method leaves here, the compiler requires it to return + // an integer value. The next line is only because of that. + return 0; + } + } +} + +int CPIMRepeatRule::getRepeatInt(TPIMField aField) +{ + JELOG2(EPim); + TInt error = KErrNone; + int retVal = 0; + TRAP(error, retVal = GetIntL(aField)); + if (error != KErrNone) + throw error; + return retVal; +} + +// ----------------------------------------------------------------------------- +// CPIMRepeatRule::SetIntL +// Sets an integer value for the given field. +// ----------------------------------------------------------------------------- +// +void CPIMRepeatRule::SetIntL(TPIMField aField, TInt aValue) +{ + JELOG2(EPim); + switch (aField) + { + // First the two supported repeat rule int fields + case EPIMRepeatRuleFrequency: + { + if (aValue == EPIMRepeatRuleDaily || aValue == EPIMRepeatRuleWeekly + || aValue == EPIMRepeatRuleMonthly || aValue + == EPIMRepeatRuleYearly) + { + iRepeatRuleFrequency = aValue; + } + else + { + User::Leave(KErrTooBig); + } + break; + } + case EPIMRepeatRuleInterval: + { + if (aValue > 0) + { + iRepeatRuleInterval = aValue; + } + else + { + User::Leave(KErrTooBig); + } + break; + } + + // Then the rest of the repeat rule fields (not supported by Nokia.) + case EPIMRepeatRuleDayInMonth: + { + if (0 < aValue && aValue < 32) // Valid values are 1-31 + { + iRepeatRuleDayInMonth = aValue; + } + else + { + User::Leave(KErrTooBig); + } + break; + } + case EPIMRepeatRuleDayInWeek: + { + if (aValue > 0 && aValue <= KPIMRepeatRuleMaskDayInWeek && (aValue + & KPIMRepeatRuleMaskWeekInMonth) == 0) + { + // Value does consist of 1 or more weekdays only + iRepeatRuleDayInWeek = aValue; + } + else + { + User::Leave(KErrTooBig); + } + break; + } + case EPIMRepeatRuleDayInYear: + { + if (0 < aValue && aValue < 367) // Valid values are 1-366 + { + iRepeatRuleDayInYear = aValue; + } + else + { + User::Leave(KErrTooBig); + } + break; + } + case EPIMRepeatRuleMonthInYear: + { + if (aValue > 0 && aValue <= KPIMRepeatRuleMaskMonthInYear && (aValue + & KPIMRepeatRuleMaskDayInWeek) == 0) + { + // Value does consist of 1 or more months only + iRepeatRuleMonthInYear = aValue; + } + else + { + User::Leave(KErrTooBig); + } + break; + } + case EPIMRepeatRuleWeekInMonth: + { + if (aValue > 0 && aValue <= KPIMRepeatRuleMaskWeekInMonth) + { + // Value does consist of 1 or more weeks in month only + iRepeatRuleWeekInMonth = aValue; + } + else + { + User::Leave(KErrTooBig); + } + break; + } + case EPIMRepeatRuleCount: + { + if (aValue > 0) + { + iRepeatRuleCount = aValue; + } + else + { + User::Leave(KErrTooBig); + } + break; + } + default: + { + User::Leave(KErrArgument); + } + } +} + +void CPIMRepeatRule::setRepeatInt(TPIMField aField, int aValue) +{ + JELOG2(EPim); + TInt error = KErrNone; + TRAP(error, SetIntL(aField, aValue)); + if (error != KErrNone) + throw error; + +} + +// ----------------------------------------------------------------------------- +// CPIMRepeatRule::GetDateL +// Returns a date value. +// Returns: A date value based on the parameter field. +// ----------------------------------------------------------------------------- +// +TPIMDate CPIMRepeatRule::GetDateL(TPIMField aField) const +{ + JELOG2(EPim); + if (aField != EPIMRepeatRuleEnd) + { + User::Leave(KErrArgument); + } + + if (iRepeatRuleEndDate == Time::NullTTime()) + { + User::Leave(KErrNotFound); + } + + return iRepeatRuleEndDate; +} + +jlong CPIMRepeatRule::getRepeatDate(TPIMField aField) +{ + JELOG2(EPim); + TInt error = KErrNone; + TPIMDate value; + TRAP(error, value = GetDateL(aField)); + if (error != KErrNone) + throw error; + jlong retVal = java::util::S60CommonUtils::TTimeToJavaTime(value); + return retVal; +} + +// ----------------------------------------------------------------------------- +// CPIMRepeatRule::SetDateL +// Sets a date value for the given field. +// ----------------------------------------------------------------------------- +// +void CPIMRepeatRule::SetDateL(TPIMField aField, TPIMDate aDate) +{ + JELOG2(EPim); + if (aField == EPIMRepeatRuleEnd) + { + if (!PIMRepeatRuleConverter::IsValidAgendaDate(aDate)) + { + User::Leave(KErrTooBig); + } + iRepeatRuleEndDate = aDate; + } + else + { + User::Leave(KErrArgument); + } +} + +void CPIMRepeatRule::setDate(TPIMField aField, jlong aValue) +{ + JELOG2(EPim); + TPIMDate nativeValue(java::util::S60CommonUtils::JavaTimeToTTime(aValue)); + TInt error = KErrNone; + TRAP(error, SetDateL(aField, nativeValue)); + if (error != KErrNone) + throw error; +} + +// ----------------------------------------------------------------------------- +// CPIMRepeatRule::GetFieldsL +// Returns the fields that are in use. +// Returns: An array of repeat rule fields that are in use. +// The ownership of the array is transferred to the caller. +// ----------------------------------------------------------------------------- +// +CArrayFix* CPIMRepeatRule::GetFieldsL() const +{ + JELOG2(EPim); + CArrayFixFlat* repeatRuleFields = new(ELeave) CArrayFixFlat< + TPIMField> (1); + CleanupStack::PushL(repeatRuleFields); + + // First the three supported repeat rule fields + if (iRepeatRuleFrequency != 0) + { + repeatRuleFields->AppendL(EPIMRepeatRuleFrequency); + } + if (iRepeatRuleInterval != 0) + { + repeatRuleFields->AppendL(EPIMRepeatRuleInterval); + } + if (iRepeatRuleEndDate != Time::NullTTime()) + { + repeatRuleFields->AppendL(EPIMRepeatRuleEnd); + } + + // Then the rest of the repeat rule fields (not supported by Nokia.) + if (iRepeatRuleDayInMonth != 0) + { + repeatRuleFields->AppendL(EPIMRepeatRuleDayInMonth); + } + if (iRepeatRuleDayInWeek != 0) + { + repeatRuleFields->AppendL(EPIMRepeatRuleDayInWeek); + } + if (iRepeatRuleDayInYear != 0) + { + repeatRuleFields->AppendL(EPIMRepeatRuleDayInYear); + } + if (iRepeatRuleMonthInYear != 0) + { + repeatRuleFields->AppendL(EPIMRepeatRuleMonthInYear); + } + if (iRepeatRuleWeekInMonth != 0) + { + repeatRuleFields->AppendL(EPIMRepeatRuleWeekInMonth); + } + if (iRepeatRuleCount != 0) + { + repeatRuleFields->AppendL(EPIMRepeatRuleCount); + } + + CleanupStack::Pop(repeatRuleFields); + return repeatRuleFields; +} + +jintArray CPIMRepeatRule::getFields(JNIEnv* aJniEnv) +{ + JELOG2(EPim); + CArrayFix* fields = NULL; + TInt error = KErrNone; + TRAP(error, fields = GetFieldsL()); + // We now own the field array + + if (error != KErrNone || fields == NULL) + { + delete fields; + return NULL; + } + + const TInt numFields = fields->Count(); + + jintArray javaFields = aJniEnv->NewIntArray(numFields); + + if (javaFields == NULL) + { + delete fields; + return NULL; + } + + if (numFields > 0) + { + aJniEnv->SetIntArrayRegion(javaFields, 0, numFields, fields->Back(0)); + } + + delete fields; + return javaFields; +} + +// ----------------------------------------------------------------------------- +// CPIMRepeatRule::ClearFieldL +// Clears the value of the field given as a parameter. +// ----------------------------------------------------------------------------- +// +void CPIMRepeatRule::ClearFieldL(TPIMField aField) +{ + JELOG2(EPim); + switch (aField) + { + // First the three supported repeat rule fields + case EPIMRepeatRuleFrequency: + { + iRepeatRuleFrequency = 0; + break; + } + case EPIMRepeatRuleInterval: + { + iRepeatRuleInterval = 0; + break; + } + case EPIMRepeatRuleEnd: + { + iRepeatRuleEndDate = Time::NullTTime(); + break; + } + + // Then the rest of the repeat rule fields (not supported by Nokia.) + case EPIMRepeatRuleDayInMonth: + { + iRepeatRuleDayInMonth = 0; + break; + } + case EPIMRepeatRuleDayInWeek: + { + iRepeatRuleDayInWeek = 0; + break; + } + case EPIMRepeatRuleDayInYear: + { + iRepeatRuleDayInYear = 0; + break; + } + case EPIMRepeatRuleMonthInYear: + { + iRepeatRuleMonthInYear = 0; + break; + } + case EPIMRepeatRuleWeekInMonth: + { + iRepeatRuleWeekInMonth = 0; + break; + } + case EPIMRepeatRuleCount: + { + iRepeatRuleCount = 0; + break; + } + default: + { + User::Leave(KErrArgument); + } + } +} + +// ----------------------------------------------------------------------------- +// CPIMRepeatRule::Clear +// Clears all values of the repeat rule. +// ----------------------------------------------------------------------------- +// +void CPIMRepeatRule::clear() +{ + JELOG2(EPim); + iExceptDates->Reset(); + iRepeatRuleFrequency = 0; + iRepeatRuleInterval = 0; + iRepeatRuleEndDate = Time::NullTTime(); + iRepeatRuleDayInMonth = 0; + iRepeatRuleDayInWeek = 0; + iRepeatRuleDayInYear = 0; + iRepeatRuleMonthInYear = 0; + iRepeatRuleWeekInMonth = 0; + iRepeatRuleCount = 0; +} + +// ----------------------------------------------------------------------------- +// CPIMRepeatRule::BackupRepeatL +// Copies all the fields from the Agenda model's Repeat definition. +// ----------------------------------------------------------------------------- +// +void CPIMRepeatRule::BackupRepeatL() +{ + JELOG2(EPim); + for (TInt i = 0; i < iExceptDates->Count(); i++) + { + iOriginalExceptDates->AppendL(iExceptDates->At(i)); + } + iOriginalRepeatRuleFrequency = iRepeatRuleFrequency; + iOriginalRepeatRuleInterval = iRepeatRuleInterval; + iOriginalRepeatRuleEndDate = iRepeatRuleEndDate; + iOriginalRepeatRuleDayInMonth = iRepeatRuleDayInMonth; + iOriginalRepeatRuleDayInWeek = iRepeatRuleDayInWeek; + iOriginalRepeatRuleDayInYear = iRepeatRuleDayInYear; + iOriginalRepeatRuleMonthInYear = iRepeatRuleMonthInYear; + iOriginalRepeatRuleWeekInMonth = iRepeatRuleWeekInMonth; + iOriginalRepeatRuleCount = iRepeatRuleCount; +} + +// ----------------------------------------------------------------------------- +// CPIMRepeatRule::IsModified +// Checks if the repeat rule has been changed or not. +// ----------------------------------------------------------------------------- +// +TBool CPIMRepeatRule::IsModified() const +{ + JELOG2(EPim); + // First check that has the exception dates amount changed + if (iExceptDates->Count() != iOriginalExceptDates->Count()) + { + return ETrue; + } + + // If original repeat had same amount of exception dates, compare all dates + if (iExceptDates->Count() > 0 && iOriginalExceptDates->Count() > 0) + { + TInt exceptionDateFinder; + TInt fetchIndex = 0; + TKeyArrayFix key(0, ECmpTInt64); + for (TInt i = 0; i < iExceptDates->Count(); i++) + { + const TPIMDate& exceptDate = iExceptDates->At(i); + exceptionDateFinder = iOriginalExceptDates->Find(exceptDate, key, + fetchIndex); + if (exceptionDateFinder != 0) // 0 would mean that date was found + { + return ETrue; + } + } + } + + // Exception dates comparison passed, continue with the rest of the fields + if (iOriginalRepeatRuleFrequency == iRepeatRuleFrequency + && iOriginalRepeatRuleInterval == iRepeatRuleInterval + && iOriginalRepeatRuleEndDate == iRepeatRuleEndDate + && iOriginalRepeatRuleDayInMonth == iRepeatRuleDayInMonth + && iOriginalRepeatRuleDayInWeek == iRepeatRuleDayInWeek + && iOriginalRepeatRuleDayInYear == iRepeatRuleDayInYear + && iOriginalRepeatRuleMonthInYear == iRepeatRuleMonthInYear + && iOriginalRepeatRuleWeekInMonth == iRepeatRuleWeekInMonth + && iOriginalRepeatRuleCount == iRepeatRuleCount) + { + // All the fields are identical, the repeat has not been changed + return EFalse; + } + else + { + // At least one of the fields was different, the repeat has been changed + return ETrue; + } +} + +// End of File