This topic introduces Calender iterator classes and describes how device implementers can use instance iterators for searching and sorting.
General knowledge of searching and sorting as well as Calendar.
The following terms are referred to within this topic
An object that allows a program to move through each element within a range of data.
For the Calendar component an instance is an occurence of a Calendar entry. Therefore, an instance iterator points to each occurence of a Calendar entry.
Rules that decide the order in which Calendar instances are arranged.
Instance iteration is a function of the Calendar component within the PIM Application Services collection. This document describes the classes within Calendar that enable searching and sorting of Calendar instances. The iterators used for searching and sorting are created using three distinct factory methods of the CCalInstanceView class. Each iterator has a different behaviour which is described in the following sections
CCalInstanceIterator
The instance iterator class CCalInstanceIterator provides standard functions for iterating through a set of Calendar instances
CCalInstance* CCalInstanceIterator::NextL(); CCalInstance* CCalInstanceIterator::PreviousL(); TBool CCalInstanceIterator::HasMore() const; TInt CCalInstanceIterator::Count() const;
CCalInstanceIterator::NextL() returns the next instance in the set. If there are no more instances to be returned then it returns a NULL pointer.
CCalInstanceIterator::PreviousL() returns the previous instance in the set. If there are no more instances to be returned then the API returns a NULL pointer.
CCalInstanceIterator::HasMore() returns ETrue when there are more instances to be returned by NextL(), and EFalse when there are not.
Note: It is advised that CCalInstanceIterator::HasMore() is not used. It has no advantage and is less efficient than checking whether the value returned by NextL() is a NULL pointer or not.
CCalInstanceIterator::Count() returns the number of instances that are in the set of instances defined by the parameters that were used to create the iterator.
Note: It is advised that CCalInstanceIterator::Count() is not used because it takes a long time to work out the number of instances in the set.
The iterator has been designed for efficient memory usage. The instances that are returned are owned by the calling application and should therefore be deleted by the calling application. So that the calling application benefits from this when iterating, it is recommended that CCalInstance objects are queried, as needed, and then deleted before the application moves on to the next instance.
Please note that the instance iterator has undefined behaviour if changes are made to the Calendar data file after the iterator has been created. Therefore, if an entry is stored, updated, or deleted by your application or another application the iterator should be destroyed and recreated.
CCalFindInstanceSettings
This instance settings class is used to set filtering options when creating two of the iterators.
The following functions use the instance settings class
CCalFindInstanceSettings* CCalFindInstanceSettings::NewL(CalCommon::TCalViewFilter aFilter, const CalCommon::TCalTimeRange& aTimeRange); void CCalFindInstanceSettings::SetTextSearchL(const CCalInstanceView::TCalSearchParams& aSearchParams);
The constructor of this class takes a time range and a view filter, which describe the types of instances that should be returned.
An application can also optionally specify some search text using the CCalFindInstanceSettings::SetSearchTextL() function.
Four APIs in the CCalInstanceSettings class support customised sorting and filtering by priority and 32-bit user integer
// Define the filter for the 32 bit user integer void SetUserIntFilter(const CalCommon::TCalUserIntFilter& aUserIntFilter);
The parameter class CalCommon::TCalUserIntFilter has two members
A CCalFindInstanceSettings object with an empty CCalSortCriteria object calls CCalInstanceView::FindInstanceL(). The instances return with the default sort order.
Instances are ordered first by instance time. For instances with equal times the default sort order, applied by CCalInstanceView::FindInstanceL(), is as follows
To-do entries. Two or more to-do entries are ordered by due date, priority then start date
Anniversaries
Day notes
Appointments. Two or more appointments are ordered by start time then end time.
If two instances are the same then completed to-do instances appear after non-completed ones.
CCalSortCriteria
The CCalSortCriteria class represents a sort criterion sequence. Items within the sequence are represented by the CCalSortCriterion class. Sequence items are applied to determine the order of the calendar instances. If the first criterion is to order instances by end time and the second criterion is to order instances by priority, the instances are sorted by end time and then by priority.
You can fetch the CCalSortCriteria through CCalFindInstanceSettings using the following functions
CCalSortCriteria& SortCriteria(); const CCalSortCriteria& SortCriteria() const;
You can perform operations on CCalSortCriteria using the functions below.
To append a sort criterion to the end of the array of sort criteria, represented by a CCalSortCriteria object
void AppendCriterionL(CalCommon::TCalSortAttribute aAttr, CalCommon::TCalSortDirection aDir);
To return the number of sort orders contained in the CCalSortCriteria object
TInt Count() const;
To return a sort criterion at the specified index
const CCalSortCriterion& AtL(TInt aIndex) const;
To set the order to follow when sorting the instances according to their type
void SetEntryTypeOrderL(const RArray<CCalEntry::TType>& aTypeOrder);
To return the type order retained by the sort criteria object
const RArray<CCalEntry::TType>& EntryTypeOrder() const;
This iterator is given as an alternative to using the normal FindInstanceL() call to populate a month view. The benefit of using the iterator is that large views can be created without running out of application memory because the application can create only one instance of the view at a time. The disadvantage is that the iterator is not as fast as the normal FindInstanceL() call. This is a decision that must be made by the application developer. If there are too many instances for the normal FindInstanceL() call to work without running out of memory then this iterator could be used to populate the view where it was not possible before.
This iterator is created through the FindInstanceL() API
CCalInstanceIterator* CCalInstanceView::FindInstanceL(const CCalFindInstanceSettings& aSettings) const;
Iteration starts from the beginning of the time range and instances are returned in the same order as they are from a FindInstanceL() call.
This iterator enables calendar applications to iterate through all instances in the calendar, but starting from a specified instance.
The function below is used to create this version of the iterator
CCalInstanceIterator* CCalFindInstanceSettings::FindInstanceL(const CCalFindInstanceSettings& aSettings, TCalLocalUid aLocalId, const TCalTime& aInstanceTime) const;
Note that CCalFindInstanceSettings is used here. CCalFindInstanceSettings requires the application to provide a time range. It is expected that an application will not want to choose a time range because it is not known how far away the next or previous instance is. When specifying the time range in this iterator it is acceptable to use min time to max time.
The starting instance is selected by specifying the local UID of the entry that that instance belongs to, and the time of that instance. If either the time of the instance is incorrect or the local UID does not refer to an entry currently in the calendar store then construction leaves with KErrNotFound.
Here is some example code that demonstrates how to use the iterator
// Find an instance to start from CCalInstance& startingInstance = GetInstanceFromMonthView(); // Set up the find instance settings TCalTime startRange; startRange.SetTimeLocalL(TCalTime::MinTime()); TCalTime endRange; endRange.SetTimeLocalL(TCalTime::MaxTime()); CalCommon::TCalTimeRange timeRange(startRange, endRange); CCalFindInstanceSettings* settings = CCalFindInstanceSettings::NewL(CalCommon::EIncludeAll, timeRange); CleanupStack::PushL(settings); // Create the iterator CCalInstanceIterator* iterator = instanceView->FindInstanceL(*settings, startingInstance.Entry()->LocalUidL(), startingInstance.Time()); CleanupStack::PopAndDestroy(settings); CleanupStack::PushL(iterator); // Find the next instance CCalInstance* nextInstance = iterator->NextL(); delete nextInstance; // Find the previous instance CCalInstance* previousInstance = iterator->PreviousL(); delete previousInstance; CleanupStack::PopAndDestroy(iterator);
This iterator enables applications to iterate through all the instances of a repeating meeting schedule. This means that any instances that are defined by the same guide are considered by the iterator. Instances of other meetings are ignored. For example, this would allow an application to iterate through the instances of a repeating to-do. The user may then mark individual instances as completed.
The iterator can be created using the following function
CCalInstanceIterator* CCalInstanceView::FindInstanceByUidL(const TDesC8& aUid, const TCalTime& aInstanceTime) const;
In a similar way to the previously described iterator, the starting instance is specified by providing the time of the starting instance. This time, however, the application provides the UID of the repeating meeting schedule and not the local UID of the entry. The provided UID is used when considering which instance should be returned. Only those instances of entries belonging to the specified UID are considered. Again if the instance time is incorrect or the UID does not refer to an entry that is currently in the calendar store then construction of the iterator leaves with KErrNotFound.
Here is a code example that demonstrates this iterator
// Find an instance to start from CCalInstance& startingInstance = GetInstanceFromMonthView(); // Create the iterator CCalInstanceIterator* iterator = instanceView->FindInstanceByUidL(startingInstance.Entry()->UidL(), startingInstance.Time()); CleanupStack::PushL(iterator); // Find the next instance in the repeat meeting schedule CCalInstance* nextInstance = iterator->NextL(); delete nextInstance; // Find the previous instance in the repeat meeting schedule CCalInstance* previousInstance = iterator->PreviousL(); delete previousInstance; CleanupStack::PopAndDestroy(iterator);