calendarengines/versit2/src/ICalRuleSegment.cpp
changeset 0 f979ecb2b13e
equal deleted inserted replaced
-1:000000000000 0:f979ecb2b13e
       
     1 /*
       
     2 * Copyright (c) 2002-2004 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:   Implements the definition of CICalRuleSegment.It deals with recurrence rule property of a claendar event.
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 
       
    20 // Class include.
       
    21 #include "ICalRuleSegment.h"	// CICalRuleSegment
       
    22 
       
    23 //debug
       
    24 #include "calendarengines_debug.h"
       
    25 
       
    26 // User includes.
       
    27 #include "ICalKeyWords.h"	// Literals
       
    28 #include "ICalErrors.h"		// Error codes
       
    29 #include "ICalValue.h"		// CICalValue
       
    30 
       
    31 /**
       
    32 Static factory construction. Not exported as this class is only provided as a
       
    33 utility for breaking down recurrence rules into segments - it is only ever
       
    34 created by the CICalValue class.
       
    35 @param aSource TDesC containing the rule segment information
       
    36 @return A new rule segment
       
    37 @internalTechnology
       
    38 */
       
    39 CICalRuleSegment* CICalRuleSegment::NewL(const TDesC& aSource)
       
    40 	{
       
    41 	TRACE_ENTRY_POINT;
       
    42 	
       
    43 	CICalRuleSegment* self = CICalRuleSegment::NewLC(aSource);
       
    44 	CleanupStack::Pop(self);
       
    45 	
       
    46 	TRACE_EXIT_POINT;
       
    47 	return self;
       
    48 	}
       
    49 
       
    50 /**
       
    51 Static factory construction. Not exported as this class is only provided as a
       
    52 utility for breaking down recurrence rules into segments - it is only ever
       
    53 created by the CICalValue class.
       
    54 @param aSource TDesC containing the rule segment information
       
    55 @return A new rule segment
       
    56 @internalTechnology
       
    57 */
       
    58 CICalRuleSegment* CICalRuleSegment::NewLC(const TDesC& aSource)
       
    59 	{
       
    60 	TRACE_ENTRY_POINT;
       
    61 	
       
    62 	CICalRuleSegment* self = new (ELeave) CICalRuleSegment;
       
    63 	CleanupStack::PushL(self);
       
    64 	self->ConstructL(aSource);
       
    65 	
       
    66 	TRACE_EXIT_POINT;
       
    67 	return self;
       
    68 	}
       
    69 
       
    70 /**
       
    71 Destructor
       
    72 @internalTechnology
       
    73 */
       
    74 CICalRuleSegment::~CICalRuleSegment()
       
    75 	{
       
    76 	TRACE_ENTRY_POINT;
       
    77 	
       
    78 	iValues.ResetAndDestroy();
       
    79 	delete iTypeString;
       
    80 	}
       
    81 
       
    82 /**
       
    83 Access method for the segment type as a descriptor.
       
    84 @return The segment type as a descriptor or an empty descriptor if no type is
       
    85 set.
       
    86 @publishedPartner
       
    87 */
       
    88 EXPORT_C const TDesC& CICalRuleSegment::TypeName() const
       
    89 	{
       
    90 	TRACE_ENTRY_POINT;
       
    91 	
       
    92 	if (iTypeString)
       
    93 		{
       
    94 		TRACE_EXIT_POINT;
       
    95 		return *iTypeString;
       
    96 		}
       
    97 		
       
    98 	// Else type is not set due to SetTypeL() leaving.
       
    99 	TRACE_EXIT_POINT;
       
   100 	return KNullDesC;
       
   101 	}
       
   102 
       
   103 /**
       
   104 Access method for the value array.
       
   105 @return The value array.
       
   106 @publishedPartner
       
   107 */
       
   108 EXPORT_C const RPointerArray<CICalValue>& CICalRuleSegment::Values() const
       
   109 	{
       
   110 	TRACE_ENTRY_POINT;
       
   111 	TRACE_EXIT_POINT;
       
   112 	return iValues;
       
   113 	}
       
   114 	
       
   115 /**
       
   116 Access method for the segment type as an enumeration.
       
   117 @return The segment type as an enumeration.
       
   118 @publishedPartner
       
   119 */
       
   120 EXPORT_C CICalRuleSegment::TSegmentType CICalRuleSegment::Type() const
       
   121 	{
       
   122 	TRACE_ENTRY_POINT;
       
   123 	TRACE_EXIT_POINT;
       
   124 	return iType;
       
   125 	}
       
   126 
       
   127 /**
       
   128 Access method for the segment value as a frequency enumeration. Only the first
       
   129 value is used.
       
   130 @return The segment value as a frequency.
       
   131 @leave Leaves with KErrRuleTypeNotFrequency if this rule segment does not
       
   132 contain a frequency.
       
   133 @leave Leaves with KErrRuleFrequencyUnknown if the frequency cannot be
       
   134 determined.
       
   135 @publishedPartner
       
   136 */
       
   137 EXPORT_C CICalRuleSegment::TFreq CICalRuleSegment::FreqL() const
       
   138 	{
       
   139 	TRACE_ENTRY_POINT;
       
   140 	
       
   141 	// Type MUST be frequency if this method is called.
       
   142 	
       
   143 	if (iType != ESegFreq)
       
   144 		{
       
   145 		User::Leave(KErrRuleTypeNotFrequency);
       
   146 		}
       
   147 	
       
   148 	// The rule must have at least one value.
       
   149 	// If it has more than one then the first value is taken (for recoverability).
       
   150 	if (iValues.Count() == 0)
       
   151 		{
       
   152 		User::Leave(KErrRuleFrequencyUnknown);
       
   153 		}
       
   154 	
       
   155 	// Compare the first value.
       
   156 	const TDesC& firstValue = iValues[0]->TextL();
       
   157 	
       
   158 	if (firstValue.CompareF(KICalYearly) == 0)
       
   159 		{
       
   160 		TRACE_EXIT_POINT;
       
   161 		return EFreqYearly;
       
   162 		}
       
   163 	else if (firstValue.CompareF(KICalMonthly) == 0)
       
   164 		{
       
   165 		TRACE_EXIT_POINT;
       
   166 		return EFreqMonthly;
       
   167 		}
       
   168 	else if (firstValue.CompareF(KICalWeekly) == 0)
       
   169 		{
       
   170 		TRACE_EXIT_POINT;
       
   171 		return EFreqWeekly;
       
   172 		}
       
   173 	else if (firstValue.CompareF(KICalDaily) == 0)
       
   174 		{
       
   175 		TRACE_EXIT_POINT;
       
   176 		return EFreqDaily;
       
   177 		}
       
   178 	else if (firstValue.CompareF(KICalHourly) == 0)
       
   179 		{
       
   180 		TRACE_EXIT_POINT;
       
   181 		return EFreqHourly;
       
   182 		}
       
   183 	else if (firstValue.CompareF(KICalMinutely) == 0)
       
   184 		{
       
   185 		TRACE_EXIT_POINT;
       
   186 		return EFreqMinutely;
       
   187 		}
       
   188 	else if (firstValue.CompareF(KICalSecondly) == 0)
       
   189 		{
       
   190 		TRACE_EXIT_POINT;
       
   191 		return EFreqSecondly;
       
   192 		}
       
   193 	
       
   194 	// Else...
       
   195 	User::Leave(KErrRuleFrequencyUnknown);
       
   196 	
       
   197 	TRACE_EXIT_POINT;
       
   198 	return EFreqDaily;	// Never reached.
       
   199 	}
       
   200 	
       
   201 /**
       
   202 Constructor
       
   203 @internalTechnology
       
   204 */
       
   205 CICalRuleSegment::CICalRuleSegment()
       
   206 	{
       
   207 	TRACE_ENTRY_POINT;
       
   208 	TRACE_EXIT_POINT;
       
   209 	}
       
   210 
       
   211 /**
       
   212 Internal construction.
       
   213 @param aSource Descriptor containing details of the segment.
       
   214 @leave Leaves with KErrInvalidRuleSegment if the rule segment has no "type".
       
   215 @leave Leaves with KErrRuleSegmentHasNoValue if the rule segment has no value.
       
   216 @leave Leaves if there is an error adding a value to this rule segment.
       
   217 @internalTechnology
       
   218 */
       
   219 void CICalRuleSegment::ConstructL(const TDesC& aSource)
       
   220 	{
       
   221 	TRACE_ENTRY_POINT;
       
   222 	
       
   223 	// We've been passed a descriptor containing the type string followed
       
   224 	// by an equals sign followed by (one or more) comma separated values.
       
   225 	// All escaping is assumed to have been previously removed.
       
   226 	
       
   227 	// Get the position of the equals sign.
       
   228 	const TInt equalsSignPos = aSource.Locate(KICalEqualsChar);
       
   229 	
       
   230 	if (equalsSignPos < 1)	// "Type" must be at least one character long.
       
   231 		{
       
   232 		User::Leave(KErrInvalidRuleSegment);
       
   233 		}
       
   234 
       
   235 	if ((equalsSignPos + 1) >= aSource.Length())	// Value must be at least one character long.
       
   236 		{
       
   237 		User::Leave(KErrRuleSegmentHasNoValue);
       
   238 		}
       
   239 
       
   240 	// Any text before this point is the type string.
       
   241 	SetTypeL(aSource.Left(equalsSignPos));
       
   242 	
       
   243 	// Any text after this point contains value information
       
   244 	TPtrC aRemainder(aSource.Mid(equalsSignPos + 1));
       
   245 	
       
   246 	while (aRemainder.Length() > 0)
       
   247 		{
       
   248 		// Find the next comma.
       
   249 		TInt endOfValue(aRemainder.Locate(KICalCommaChar));
       
   250 		
       
   251 		if (endOfValue == KErrNotFound)
       
   252 			{
       
   253 			endOfValue = aRemainder.Length();
       
   254 			}
       
   255 		
       
   256 		// Add value.
       
   257 		if (endOfValue > 0)
       
   258 			{
       
   259 			CICalValue* val = CICalValue::NewLC();
       
   260 			val->SetTextL(aRemainder.Left(endOfValue));
       
   261 			User::LeaveIfError(iValues.Append(val));
       
   262 			CleanupStack::Pop(val);
       
   263 			}
       
   264 		
       
   265 		// Set the remainder.
       
   266 		if (endOfValue < (aRemainder.Length() - 1))	// Value must be at least one character long.
       
   267 			{
       
   268 			aRemainder.Set(aRemainder.Mid(endOfValue + 1));
       
   269 			}
       
   270 		else
       
   271 			{
       
   272 			break;
       
   273 			}
       
   274 		}
       
   275 	
       
   276 	TRACE_EXIT_POINT;
       
   277 	}
       
   278 
       
   279 /**
       
   280 Sets the type of a rule segment.
       
   281 @param aType The type as a descriptor.
       
   282 @internalTechnology
       
   283 */
       
   284 void CICalRuleSegment::SetTypeL(const TDesC& aType)
       
   285 	{
       
   286 	TRACE_ENTRY_POINT;
       
   287 
       
   288 	// Set the type.
       
   289 	
       
   290 	if (aType.CompareF(KICalFreq) == 0)
       
   291 		{
       
   292 		iType = ESegFreq;
       
   293 		}
       
   294 	else if (aType.CompareF(KICalUntil) == 0)
       
   295 		{
       
   296 		iType = ESegUntil;
       
   297 		}
       
   298 	else if (aType.CompareF(KICalCount) == 0)
       
   299 		{
       
   300 		iType = ESegCount;
       
   301 		}
       
   302 	else if (aType.CompareF(KICalInterval) == 0)
       
   303 		{
       
   304 		iType = ESegInterval;
       
   305 		}
       
   306 	else if (aType.CompareF(KICalBySecond) == 0)
       
   307 		{
       
   308 		iType = ESegBySecond;
       
   309 		}
       
   310 	else if (aType.CompareF(KICalByMinute) == 0)
       
   311 		{
       
   312 		iType = ESegByMinute;
       
   313 		}
       
   314 	else if (aType.CompareF(KICalByHour) == 0)
       
   315 		{
       
   316 		iType = ESegByHour;
       
   317 		}
       
   318 	else if (aType.CompareF(KICalByDay) == 0)
       
   319 		{
       
   320 		iType = ESegByDay;
       
   321 		}
       
   322 	else if (aType.CompareF(KICalByMonthDay) == 0)
       
   323 		{
       
   324 		iType = ESegByMonthDay;
       
   325 		}
       
   326 	else if (aType.CompareF(KICalByYearDay) == 0)
       
   327 		{
       
   328 		iType = ESegByYearDay;
       
   329 		}
       
   330 	else if (aType.CompareF(KICalByWeekNo) == 0)
       
   331 		{
       
   332 		iType = ESegByWeekNo;
       
   333 		}
       
   334 	else if (aType.CompareF(KICalByMonth) == 0)
       
   335 		{
       
   336 		iType = ESegByMonth;
       
   337 		}
       
   338 	else if (aType.CompareF(KICalBySetPos) == 0)
       
   339 		{
       
   340 		iType = ESegByPos;
       
   341 		}
       
   342 	else if (aType.CompareF(KICalWkSt) == 0)
       
   343 		{
       
   344 		iType = ESegWkSt;
       
   345 		}
       
   346 	else
       
   347 		{
       
   348 		iType = ESegExtension;
       
   349 		}
       
   350 	
       
   351 	// Set the type string.
       
   352 	delete iTypeString;
       
   353 	iTypeString = NULL;
       
   354 	iTypeString = aType.AllocL();
       
   355 	
       
   356 	TRACE_EXIT_POINT;
       
   357 	}
       
   358 
       
   359 // End of File
       
   360