The source code for this example application can be found in the
directory: examples\AppEngine\CalInterimAPI\
.
// CalExample.cpp
//
// Copyright (c) Symbian Software Ltd 2006. All rights reserved.
//
#include "CalExample.h"
#include <calinstance.h>
CCalExample::CCalExample()
{
}
CCalExample::~CCalExample()
{
_LIT(KExitMsg,"\n\nPress any key to exit the application ");
iConsole->Printf(KExitMsg);
iConsole->Getch();
delete iCalEntryView;
delete iCalSession;
delete iConsole;
}
CCalExample* CCalExample::NewL()
{
CCalExample* self= new (ELeave) CCalExample();
CleanupStack::PushL(self);
self->ConstructL();
CleanupStack::Pop();
return self;
}
void CCalExample::ConstructL()
{
_LIT(KTitle, "calexample" );
iConsole = Console::NewL(KTitle,TSize(KConsFullScreen,KConsFullScreen));
_LIT(KPressAKeyMsg, "\n\nPress any key to step through the example");
iConsole->Printf ( KPressAKeyMsg );
iConsole->Getch ();
iCalSession = CCalSession::NewL();
// Create and open a calendar file
_LIT(KFileName,"calendarfile");
TRAPD(err, iCalSession->CreateCalFileL(KFileName));
// ignore KErrAlreadyExists leave code
if (err != KErrAlreadyExists)
{
User::LeaveIfError(err);
}
// Open the calendar file
iCalSession->OpenL(KFileName);
_LIT(KProgressMsg, "\nCalendar entry view creation is in progress...");
iConsole->Printf(KProgressMsg);
// Create a calendar entry view to view the entries
iCalEntryView = CCalEntryView::NewL(*iCalSession,*this);
CActiveScheduler::Start();
}
// Called during calendar entry view creation
void CCalExample::Progress(TInt aProgress)
{
_LIT(KProgressVal,"\n%d%% complete");
iConsole->Printf(KProgressVal,aProgress);
}
// Called on completion of calendar entry view creation
void CCalExample::Completed(TInt /*aError*/)
{
CActiveScheduler::Stop();
}
// Returns whether or not progress notification is required
TBool CCalExample::NotifyProgress()
{
// Progress notification is required
return ETrue;
}
// Sets some entry details - start and end date/time, description, categories and attendees
void CCalExample::SetEntryDetailsL(CCalEntry* aEntry,const TDesC& aDescription, TDateTime& aStartTime,TDateTime& aEndTime)
{
TCalTime startTime;
TCalTime endTime;
// Set the start and end times using time values local to the current system time zone
startTime.SetTimeLocalL(aStartTime);
endTime.SetTimeLocalL(aEndTime);
aEntry->SetStartAndEndTimeL(startTime, endTime);
// Set the description text
aEntry->SetDescriptionL(aDescription);
// Add a category
const RPointerArray<CCalCategory> categoryList = aEntry->CategoryListL();
if(categoryList.Count() == 0)
{
TBuf<32> buf;
_LIT(KCategoryName, "Dummy Category");
buf.Copy(KCategoryName);
CCalCategory* category = CCalCategory::NewL(buf);
CleanupStack::PushL(category);
aEntry->AddCategoryL(category);
CleanupStack::Pop(category);
}
// Add some attendees
const RPointerArray<CCalAttendee>attendeeList = aEntry->AttendeesL();
if(attendeeList.Count() == 0)
{
_LIT(KAttendeeOne, "[email protected]");
_LIT(KAttendeeTwo, "[email protected]");
CCalAttendee* attendeeOne = CCalAttendee::NewL(KAttendeeOne);
CleanupStack::PushL(attendeeOne);
aEntry->AddAttendeeL(attendeeOne);
CleanupStack::Pop(attendeeOne);
CCalAttendee* attendeeTwo = CCalAttendee::NewL(KAttendeeTwo);
CleanupStack::PushL(attendeeTwo);
aEntry->AddAttendeeL(attendeeTwo);
CleanupStack::Pop(attendeeTwo);
}
}
// Add a non-repeating appointment to the calendar file
void CCalExample::AddEntryL()
{
const TDesC8& guidDes = KGuid;
HBufC8* guid = guidDes.AllocL();
CCalEntry* entry = CCalEntry::NewL(CCalEntry::EAppt, guid, CCalEntry::EMethodNone, 0);
CleanupStack::PushL(entry);
// For an appointment, the time as well as the date is relevant
TDateTime startTime(2006, EJanuary, 04, 10, 0, 0, 0);
TDateTime endTime(2006, EJanuary, 05, 16, 0, 0, 0);
_LIT(KAddingMsg, "\n\nAdding an entry...");
iConsole->Printf ( KAddingMsg );
_LIT(KDescription,"Meeting is scheduled in 1st week of January");
SetEntryDetailsL(entry,KDescription, startTime, endTime);
RPointerArray<CCalEntry> array;
CleanupClosePushL(array);
array.AppendL(entry);
TInt success(0);
// If StoreL() leaves, 'success' contains the number of entries that were
// stored before it failed
iCalEntryView->StoreL(array, success);
CleanupStack::PopAndDestroy(&array);
CleanupStack::PopAndDestroy(entry);
}
// Destroy the RPointerArray
void DestroyRPointerArray(TAny* aPtr)
{
RPointerArray<CCalEntry>* self = static_cast<RPointerArray<CCalEntry>*> (aPtr);
self->ResetAndDestroy();
}
// Fetch the entry and update some of its details
void CCalExample::UpdateEntryL()
{
RPointerArray<CCalEntry> array;
CleanupStack::PushL(TCleanupItem(DestroyRPointerArray, &array));
iCalEntryView->FetchL(KGuid, array);
//Fetch the first entry in the list
_LIT(KUpdatingMsg,"\n\nUpdating the entry...");
iConsole->Printf(KUpdatingMsg);
CCalEntry* entry = array[0];
_LIT(KNewDescription,"Meeting rescheduled to 2nd week of January");
TDateTime startTime(2006, EJanuary, 11, 10, 0, 0, 0);
TDateTime endTime(2006, EJanuary, 12, 16, 0, 0, 0);
SetEntryDetailsL(entry,KNewDescription, startTime, endTime);
TInt numberOfEntries(0);
// If UpdateL() leaves, 'numberOfEntries' contains the number of entries that were
// updated before it failed
iCalEntryView->UpdateL(array,numberOfEntries);
CleanupStack::PopAndDestroy(&array);
}
// Add a repeating appointment. This is called the originating entry.
void CCalExample::AddOriginatingEntryL()
{
_LIT(KAddingMsg, "\n\nAdding a repeating entry...");
iConsole->Printf ( KAddingMsg );
TTime startTime(TDateTime(2006, EJanuary, 0, 14, 0, 0, 0)); // January 1st 2pm
TTime endTime(startTime + TTimeIntervalHours(1)); // January 1st 3pm
const TDesC8& guidDes = KGuid;
HBufC8* guid = guidDes.AllocL();
CCalEntry* originatingEntry = CCalEntry::NewL(CCalEntry::EAppt, guid, CCalEntry::EMethodNone, 0);
CleanupStack::PushL(originatingEntry);
_LIT(KDescription,"An originating entry");
originatingEntry->SetDescriptionL(KDescription);
TCalTime entryStartTime;
entryStartTime.SetTimeLocalL(startTime);
TCalTime entryEndTime;
entryEndTime.SetTimeLocalL(endTime);
originatingEntry->SetStartAndEndTimeL(entryStartTime, entryEndTime);
// Set the repeat rule
// The entry repeats weekly with 3 instances being created
TCalRRule weeklyRptRule(TCalRRule::EWeekly);
weeklyRptRule.SetDtStart(entryStartTime);
weeklyRptRule.SetCount(3);
weeklyRptRule.SetInterval(1);
// Also need to set the day that the entry repeats on
RArray<TDay> days;
CleanupClosePushL(days);
days.AppendL(ESunday);
weeklyRptRule.SetByDay(days);
CleanupStack::PopAndDestroy(&days);
originatingEntry->SetRRuleL(weeklyRptRule);
// Now write the entry to the view
RPointerArray<CCalEntry> array;
CleanupStack::PushL(TCleanupItem(DestroyRPointerArray, &array));
array.AppendL(originatingEntry);
TInt success(0);
// If StoreL() leaves, 'success' contains the number of entries that were
// stored before it failed
iCalEntryView->StoreL(array, success);
// clean up
array.Close();
CleanupStack::PopAndDestroy(&array);
CleanupStack::PopAndDestroy(originatingEntry);
}
// Adds a modifying, or "child" entry.
// A modifying entry modifies one or more instances of the "originating" repeating entry.
// It has the same UID, and is deleted when the originating entry is deleted.
//
void CCalExample::AddmodifyingEntryL()
{
RPointerArray<CCalEntry> modifyingArray;
CleanupStack::PushL(TCleanupItem(DestroyRPointerArray, &modifyingArray));
_LIT(KAddingMsg, "\n\nAdding a modifying entry...");
iConsole->Printf ( KAddingMsg );
// Create repeating modifying entry
// Has the same recurrence Id as the second instance of the originating and
// this and all future instances are modified.
TTime recurrenceId(TDateTime(2006, EJanuary, 7, 14, 0, 0, 0)); // January 8th 2pm
TCalTime recurrenceIdCal;
recurrenceIdCal.SetTimeLocalL(recurrenceId);
const TDesC8& guidDes = KGuid;
HBufC8* guid = guidDes.AllocL();
// Entry type is appointment, group scheduling method none and modifying this and all future instances
CCalEntry* modifyingEntry = CCalEntry::NewL(CCalEntry::EAppt, guid, CCalEntry::EMethodNone, 1, recurrenceIdCal, CalCommon::EThisAndFuture);
CleanupStack::PushL(modifyingEntry);
// The modifying entry has a different description to the originating entry
_LIT(KChildDescription,"A modifying entry");
modifyingEntry->SetDescriptionL(KChildDescription);
// The modifying entry modifies the originating entry's date by one day
TTime childStartTime(TDateTime(2006, EJanuary, 8, 14, 0, 0, 0)); // January 9th 2pm
TTime childEndTime(childStartTime + TTimeIntervalHours(1)); // January 9th 3pm
TCalTime childEntryStartTime;
childEntryStartTime.SetTimeLocalL(childStartTime);
TCalTime childEntryEndTime;
childEntryEndTime.SetTimeLocalL(childEndTime);
modifyingEntry->SetStartAndEndTimeL(childEntryStartTime, childEntryEndTime);
// Target instance for recurrence range in the modifying entry is second instance
TCalRRule childRptRule(TCalRRule::EWeekly);
childRptRule.SetDtStart(childEntryStartTime);
childRptRule.SetCount(2);
childRptRule.SetInterval(1);
// The modifying entry modifies the originating entry by occurring on Mondays
RArray<TDay> days;
CleanupClosePushL(days);
days.AppendL(EMonday);
childRptRule.SetByDay(days);
CleanupStack::PopAndDestroy(&days);
modifyingEntry->SetRRuleL(childRptRule);
// add the modifying entry to the entry view.
modifyingArray.AppendL(modifyingEntry);
TInt success(0);
// If StoreL() leaves, 'success' contains the number of entries that were
// stored before it failed
iCalEntryView->StoreL(modifyingArray, success);
// clean up
CleanupStack::PopAndDestroy(modifyingEntry);
modifyingArray.Reset();
CleanupStack::PopAndDestroy(&modifyingArray);
}
// Searches for all instances in January, then prints out their details.
// Creates an instance view to display the instances.
void CCalExample::FindInstanceL()
{
_LIT(KPressAKeyMsg, "\n\nPress any key to view the instances");
iConsole->Printf(KPressAKeyMsg);
iConsole->Getch ();
_LIT(KProgressMsg, "\nCalendar instance view creation is in progress...");
iConsole->Printf(KProgressMsg);
CCalInstanceView* instanceView = CCalInstanceView::NewL(*iCalSession, *this);
CleanupStack::PushL(instanceView);
CActiveScheduler::Start();
RPointerArray<CCalInstance> instanceList;
CleanupStack::PushL(TCleanupItem(DestroyRPointerArray, &instanceList));
CalCommon::TCalViewFilter filter = CalCommon::EIncludeAll;
TCalTime startDateForInstanceSearch;
TCalTime endDateForInstanceSearch;
// Set date and time range for searching for instances
startDateForInstanceSearch.SetTimeLocalL(TDateTime( 2006, EJanuary, 0, 12, 0, 0, 0)); // 1st January 12 pm
endDateForInstanceSearch.SetTimeLocalL(TDateTime( 2006, EJanuary, 30, 10, 0, 0, 0)); // 31st January 10 am
CalCommon::TCalTimeRange searchTimeRange(startDateForInstanceSearch, endDateForInstanceSearch);
// Searches for instances within the specified date range
instanceView->FindInstanceL(instanceList, filter, searchTimeRange);
_LIT(KInstancesFound,"\n\nFound %d instances:");
iConsole->Printf(KInstancesFound,instanceList.Count());
TDateTime date;
for(TInt i = 0; i<instanceList.Count(); i++)
{
TPtrC des = instanceList[i]->Entry().DescriptionL();
_LIT(KEntryDesc,"\nDescription: %S");
iConsole->Printf(KEntryDesc,&des);
TTime time = instanceList[i]->StartTimeL().TimeLocalL();
TBuf<40> datetimeStr;
_LIT(KFormat,"%D%M%Y%/0%1%/1%2%/2%3%/3 %:0%H%:1%T%:2%S");
time.FormatL(datetimeStr,KFormat);
// Print out the start date/time
_LIT(KStartDate,"\nLocal instance start date/time: %S ");
iConsole->Printf(KStartDate,&datetimeStr);
}
CleanupStack::PopAndDestroy(&instanceList);
CleanupStack::PopAndDestroy(instanceView);
}
// Fetch and print the entry details
void CCalExample::PrintEntryDetailsL()
{
_LIT(KPressAKeyMsg, "\nPress any key to view entry details");
iConsole->Printf ( KPressAKeyMsg );
iConsole->Getch ();
RPointerArray<CCalEntry> array;
CleanupStack::PushL(TCleanupItem(DestroyRPointerArray, &array));
iCalEntryView->FetchL(KGuid, array);
for(TInt i=0; i<array.Count(); i++)
{
CCalEntry* entry = array[i];
CleanupStack::PushL(entry);
TPtrC des = entry->DescriptionL();
_LIT(KEntryDesc," \n\nDescription: %S");
iConsole->Printf(KEntryDesc,&des);
TCalTime startTime = entry->StartTimeL();
TCalTime endTime = entry->EndTimeL();
TTime time = startTime.TimeLocalL();
TBuf<40> datetimeStr;
_LIT(KFormat,"%D%M%Y%/0%1%/1%2%/2%3%/3 %:0%H%:1%T%:2%S");
time.FormatL(datetimeStr,KFormat);
// Print out the start date/time
_LIT(KStartDate,"\nStart date/time: %S ");
iConsole->Printf(KStartDate,&datetimeStr);
// Now, print out the end date/time
time = endTime.TimeLocalL();
time.FormatL(datetimeStr,KFormat);
_LIT(KEndDate,"\nEnd date/time: %S");
iConsole->Printf(KEndDate,&datetimeStr);
CleanupStack::Pop(entry);
// Fetch category
RPointerArray<CCalCategory> categoryList = entry->CategoryListL();
for( int j=0; j<categoryList.Count(); j++)
{
const TDesC& category = categoryList[j]->ExtendedCategoryName();
HBufC* catbuf = category.AllocL();
_LIT(KCatType,"\nCategory type: %S");
iConsole->Printf(KCatType,catbuf);
delete catbuf;
}
// Fetch attendee
RPointerArray<CCalAttendee> attendeeList;
attendeeList = entry->AttendeesL();
for( int k=0; k<attendeeList.Count(); k++)
{
const TDesC16& address = attendeeList[k]->Address();
HBufC16* addr = address.AllocL();
_LIT(KAttendee,"\nAttendee %d: %S");
iConsole->Printf(KAttendee,k+1, addr);
delete addr;
}
}
CleanupStack::PopAndDestroy(&array);
}
// Delete the originating entry
void CCalExample::DeleteEntryL()
{
_LIT(KPressAKeyMsg, "\n\nPress any key to delete the originating entry, (also deletes the modifying entry)");
iConsole->Printf ( KPressAKeyMsg );
iConsole->Getch ();
RPointerArray<CCalEntry> entryArray;
CleanupStack::PushL(TCleanupItem(DestroyRPointerArray, &entryArray));
// Fetch the entry to be deleted
iCalEntryView->FetchL(KGuid, entryArray);
CCalEntry* entry = entryArray[0];
// Delete originating entry, thereby also deleting the modifying entry
iCalEntryView->DeleteL(*entry);
CleanupStack::PopAndDestroy(&entryArray);
}
LOCAL_C void MainL()
{
CCalExample* app = CCalExample::NewL();
CleanupStack::PushL(app);
// Add an entry and display the entry details
app->AddEntryL();
app->PrintEntryDetailsL();
// Update an entry and display the updated entry details
app->UpdateEntryL();
app->PrintEntryDetailsL();
// Create a repeating entry and display the entry details
app->AddOriginatingEntryL();
app->PrintEntryDetailsL();
// Display the repeat instances
app->FindInstanceL();
// Create a modifying entry and display the entry details
app->AddmodifyingEntryL();
app->PrintEntryDetailsL();
// Display the repeat instances
app->FindInstanceL();
// Delete the originating thereby deleting the modifying entry and all repeat instances
app->DeleteEntryL();
CleanupStack::PopAndDestroy(app);
}
GLDEF_C TInt E32Main()
{
__UHEAP_MARK;
// Active scheduler required as this is a console app
CActiveScheduler* scheduler=new CActiveScheduler;
// If active scheduler has been created, install it.
if (scheduler)
{
CActiveScheduler::Install(scheduler);
// Cleanup stack needed
CTrapCleanup* cleanup = CTrapCleanup::New();
if(cleanup)
{
TRAPD(err, MainL());
if(err != KErrNone)
{
_LIT(KUserPanic,"Failed to complete");
User::Panic(KUserPanic, err);
}
delete cleanup;
}
}
delete scheduler;
__UHEAP_MARKEND;
return KErrNone;
}
// BLD.INF
//
// CalInterimApi
// Copyright (c) Symbian Software Ltd 2006. All rights reserved.
//
PRJ_PLATFORMS
DEFAULT GCCE
PRJ_MMPFILES
CalExample.mmp
// CalExample.mmp
//
// Copyright (c) Symbian Software Ltd 2006. All rights reserved.
//
TARGET calexample.exe
TARGETTYPE exe
UID 0xE8000090
VENDORID 0x70000001
CAPABILITY ReadUserData WriteUserData
SOURCEPATH .
SOURCE CalExample.cpp
USERINCLUDE .
SYSTEMINCLUDE \Epoc32\include
LIBRARY EUSER.LIB
LIBRARY EFSRV.LIB
LIBRARY calinterimapi.lib
// CalExample.h
//
// Copyright (c) Symbian Software Ltd 2006. All rights reserved.
//
#ifndef __CALEXAMPLE_H__
#define __CALEXAMPLE_H__
#include <e32base.h>
#include <e32cons.h>
#include <calsession.h>
#include <calprogresscallback.h>
#include <calrrule.h>
#include <calentry.h>
#include <calentryview.h>
#include <caltime.h>
#include <calalarm.h>
#include <calcategory.h>
#include <caluser.h>
#include <calinstanceview.h>
_LIT8(KGuid, "[email protected]");
// Demonstrates how to create, add, fetch and update entries.
// Uses an entry view to display a non repeating appointment, with
// a start and end date/time, a description, a category and some attendees.
class CCalExample: public CBase, public MCalProgressCallBack
{
public:
static CCalExample* NewL();
~CCalExample();
void AddEntryL();
void UpdateEntryL();
void FetchEntriesL(RPointerArray<CCalEntry>& aCalEntryArray);
void PrintEntryDetailsL();
void FindInstanceL();
void AddOriginatingEntryL();
void AddmodifyingEntryL();
void DeleteEntryL();
// Overridden functions of MCalProgressCallBack class
void Progress(TInt aPercentageCompleted);
void Completed(TInt aError);
TBool NotifyProgress();
private:
CCalExample();
void ConstructL();
void SetEntryDetailsL(CCalEntry* aEntry,const TDesC& aDescription, TDateTime& aStartTime,TDateTime& aEndTime);
private:
CConsoleBase* iConsole;
CCalSession* iCalSession;
CCalEntryView* iCalEntryView;
};
#endif //__CALEXAMPLE_H__
This example demonstrates how to use the
Calendar API. The
main class in the example, CCalExample
, creates and opens a
calendar file, then creates a view of the entries in the file. It then creates
a calendar entry and adds it to the file, via the view. Next, it sets
properties such as attendees, category, and description. It then adds a repeat
appointment called the 'originating entry' and an entry modifying the instances
of the originating entry (modifying entry). It finally deletes the originating
entry thereby deleting all the modifying entries.
CCalExample::ConstructL()
instantiates a
CCalSession
with the calendar server by calling
CCalSession::NewL()
. All calendar file operations, for
instance creation and opening, are done through the CCalSession
class.
Note that a session with the calendar server must exist before you can use any of the Calendar API classes, and the session object must not be destroyed until all the objects which were created by referencing it have been destroyed.
Next, CCalExample::ConstructL()
creates and opens a
named calendar file, to store the calendar entries (using
CCalSession::CreateCalFileL()
and
CCalSession::OpenL()
). File creation leaves with
KErrAlreadyExists
if a file with that name already exists.
A calendar entry defines a type of calendar event. There are several
types of entries; to-do, appointment, all day event, reminder and anniversary.
A calendar entry view (CCalEntryView
) is used to access
and manipulate calendar entries. In this example it is used to display the
non-repeating appointment.
View creation can take some time because of the processing that must
be done in the server to prepare entry indexes. So,
CCalEntryView::NewL()
takes a progress callback object
(MCalProgressCallBack
). When the callback function
MCalProgressCallBack::Completed()
is called, the view is
ready for use. CCalExample
implements the
MCalProgressCallBack
interface.
A calendar entry is created using
CCalEntry::NewL()
. This specifies the type of entry, its
global UID and some optional properties used for group scheduling.
An entry's start and end times are represented using class
TCalTime
. This class requires the caller to specify
whether the time is UTC or local. In this example, the times are considered to
be local, so TCalTime::SetTimeLocalL()
is called before
setting the entry's start and end times using
CCalEntry::SetStartAndEndTimeL()
.
CCalEntryView::StoreL()
is used to store one or
more new entries into the file. CCalEntryView::FetchL()
is
used to retrieve entries, based on their UID and
CCalEntryView::UpdateL()
is used to update one or more
entries.
The originating entry (parent entry) is a repeating appointment. The modifying entry (child entry) inherits all properties of the originating entry. It can have a different repeat rule and description from its originating entry. The originating and its modified (children) entries will have the same UID.
Attendee is a specialised calendar user information (for example,
email ID, phone number etc.) which is used only in group scheduled entries for
attendees of an event, and not for a single calendar user.
CCalEntry::AttendeesL()
is called to get a list of
attendees. Attendees can be added to or deleted from a calendar entry using
CCalEntry::AddAttendeeL
and
CCalEntry::DeleteAttendeeL()
respectively.
A calendar entry can be categorised into pre-defined or user defined types such as appointment, business,education, holiday etc. In this example we have used extended category and not the pre-defined ones.
Create a new category using CCalCategory::NewL()
and pass a buffer as argument. CCalEntry::AddCategoryL()
is called to set a category for the calendar entry. To get a list of available
categories call CalCategory::CategoryListL()
.
For an event which occurs repetitively, such as a weekly progress
meeting, you need to set a repeat rule. Repeat frequency
(TCalRRule
)can be set to daily, weekly, monthly by day and
yearly by date to a calendar entry. When a repeat rule is assigned to an entry,
that entry's start time should be an instance of the repeat rule. It can be
either same as the start time value or a later instance. Repeat rule is set by
passing an instance of TCalRRule
to
CCalEntry::SetRuleL()
.
An instance view is used to display instances of a repeating entry.
It gets a list of all entry views or instances by calling
InstanceList()
.
CCalInstanceView::FindInstanceL()
is used to fetch all
instances within the specified date and time range.
A calendar entry is deleted by specifying a pointer to the enrty
array index. In this example, the originating entry is deleted using
CCalEntryView::DeleteL()
.
The Symbian OS build process describes how to build an application.
This is a console application, so does not have a GUI. It builds an
executable called calexample.exe
in the standard location
(\epoc32\release\winscw\
<build_variant> for
CodeWarrior). After launching the executable, depending on the emulator you are
using, you may need to task away from the app launcher/shell screen to view the
console. Alternatively, adding the string textshell
to the
emulator configuration file epoc.ini
causes the emulator to start
in text mode.