How to use Calendar

CalInterimAPI
From Forum Nokia Wiki
The new CalInterim API has been introduced with the Symbian 9.1 releases to replace the old Agenda Model API.
Contents
[hide]
1 Connecting
2 Insert new Appointment
3 Insert new Todo
4 Add old AgendaModel Alarm data to the new CCalEntry Appointment item
5 Add old AgendaModel Alarm data to the new CCalEntry Todo item
6 Delete entry
7 Update Appointment entry
8 Update Todo item
9 Convert item CCalEntry IDs to old AgendaModel entry IDs
10 Copy entry to an other one without Global ID
 


Connecting
The CCalSession is the interface to the Calendar file. The instantiation of CCalSession will result in a connection to the Calendar Server:
Library reqired:
LIBRARY        calinterimapi.lib
Header files:
#include <calsession.h>
#include <calprogresscallback.h>
#include <caliterator.h>
#include <calentry.h>
#include <calentryview.h>
#include <caltime.h>
#include <calalarm.h>
#include <calcategory.h>
#include <caluser.h>
#include <calrrule.h>
#include <calinstance.h>
#include <calinstanceview.h>
 
 
class CCalendar : public MCalProgressCallBack
    {
    CCalendar();
    void ConstructL();
    ~CCalendar();
    [...]
    private:
    void OpenCalendarL();
    [...]
    CCalSession*       iCalSession;
    CCalIter*       iCalIter;
    CCalEntryView*       iCalEntryView;
    HBufC8*       iNext;
    TBool                    iReady;
    [...]
    }
--------------------------------------------------------------------------------
Source file:
#include "Calendar.h"
 
CCalendar::CCalendar()
    {
    }
 
CCalendar::~CCalendar()
    {
    if(iCalIter)
        {
 delete iCalIter;
 }
    if(iCalEntryView)
 {
 delete iCalEntryView;
 }
    if(iCalSession)
 {
 delete iCalSession; 
 }
    if( iNext )
 {
 delete iNext;
 iNext = NULL;
 }
    }
 
void CCalendar::ConstructL()
    {
    iReady=EFalse;
    iNext = HBufC8::NewL(50);
    OpenCalendarL();
    }
 
void CCalendar::OpenCalendarL()
    {
    // allocate and construct server
    // Check that calendar exists, and if not, create it.
    // Calendar does not exist until it is created by calendar app - or by us.
    iCalSession = CCalSession::NewL();
   
    //Open the default calendar file
    TRAPD(aErr, iCalSession->OpenL(KNullDesC));
    if(aErr == KErrNotFound)
        {
 TRAPD(err, iCalSession->CreateCalFileL(iCalSession->DefaultFileNameL()) );
 TRAPD(aErr2, iCalSession->OpenL(KNullDesC));
 }
 
    iCalEntryView = CCalEntryView::NewL(*iCalSession, *this);
    iCalIter = CCalIter::NewL(*iCalSession);
 
    //Reset to the begin of the Calendar entries
    TPtr8 aAddress( iNext->Des() );
    aAddress = iCalIter->FirstL();
    }
Do not forget implement other functions!
// Called during calendar entry view creation
void CCalendar::Progress(TInt aPercentageCompleted)
    {
    }
 
void CCalendar::Completed(TInt aError)
    {
    if(aError==KErrNone)
        iReady=ETrue;
    }
 
// Returns whether or not progress notification is required
TBool CCalendar::NotifyProgress()
    {
    // Progress notification is required
    return ETrue;
    }
 
// Utility function to handle CCalEntry insert
// Destroy the RPointerArray
void DestroyRPointerArray(TAny* aPtr)
    {
    RPointerArray<CCalEntry>* self = static_cast<RPointerArray<CCalEntry>*> (aPtr);
    self->ResetAndDestroy();
    }
Insert new Appointment
To insert new item with a given ID you should create a CCalEntry item and fill out with the desidered data.
 
void CCalendar::NewApptL(TInt aID)
    {
    if(!iReady) //if this function is called too soon then return. Calendar opening
                //must finish first.
    return;
   
    //Create entry with the given new GUid
    HBufC8* guidBuf;
    TBuf8<30> tmpGuid;
    tmpGuid.Num( aID );
    guidBuf = tmpGuid.AllocL();
 
    CCalEntry* appt = CCalEntry::NewL(CCalEntry::EAppt, guidBuf, 
    CCalEntry::EMethodNone, 0);
    CleanupStack::PushL(appt);
   
    //Some data
    appt->SetSummaryL( _L("Summary") );
    appt->SetLocationL( _L("Location") );
    appt->SetDescriptionL( _L("Description") );
 
    //Start / end date
    TTime start;
    start.UniversalTime();
    TTime end;
    end.UniversalTime();
    TCalTime startCalTime;
    startCalTime.SetTimeUtcL(start);
    TCalTime endCalTime; //NullTTime()
   
    //Comment out the next line if you do not want to set end time
    endCalTime.SetTimeUtcL(end);
   
    //Set it
    appt->SetStartAndEndTimeL(startCalTime, endCalTime);
 
    //Store this new Entry
 
    RPointerArray<CCalEntry> entryArray;
    CleanupStack::PushL(TCleanupItem(DestroyRPointerArray, &entryArray));
    entryArray.AppendL(appt);
    TInt success(0);
    iCalEntryView->StoreL(entryArray, success);
    entryArray.Reset();
    CleanupStack::PopAndDestroy(&entryArray);
    CleanupStack::PopAndDestroy(appt);
    }
Insert new Todo
To insert new item with a given ID you should create a CCalEntry item and fill out with the desidered data.
void CCalendar::NewTodoL(TInt aID)
    {
    //Create an antry with the given GUid
    HBufC8* guidBuf;
    TBuf8<30> tmpGuid;
    tmpGuid.Num( aID );
    guidBuf = tmpGuid.AllocL();
 
    CCalEntry* todo = CCalEntry::NewL(CCalEntry::ETodo, guidBuf,
     CCalEntry::EMethodNone, 0);
    CleanupStack::PushL(todo);
 
    todo->SetSummaryL( _L("Summary") );
 
    //Priority
    TInt priority = 1;
    todo->SetPriorityL(priority);
 
    //Completed
    TCalTime calTime;
    TTime time; time.UniversalTime();
    calTime.SetTimeUtcL(time);
    todo->SetCompletedL(ETrue, calTime);
 
    //End date
    TTime end;
    end.UniversalTime();
    TCalTime calEndDate;
    calEndDate.SetTimeUtcL(end);
    todo->SetStartAndEndTimeL(calStartDate, calEndDate);
 
    //Store New Entry
    RPointerArray<CCalEntry> entryArray;
    CleanupStack::PushL(TCleanupItem(DestroyRPointerArray, &entryArray));
    entryArray.AppendL(aTask);
    TInt success(0);
    iCalEntryView->StoreL(entryArray, success);
    entryArray.Reset();
    CleanupStack::PopAndDestroy(&entryArray);
    CleanupStack::PopAndDestroy(todo);
}
Add old AgendaModel Alarm data to the new CCalEntry Appointment item
This code sample is useful if you port your application from the previous agenda model. In the old model you should use the SetAlarm(TTimeIntervalDays aDaysWarning,TTimeIntervalMinutes aTime). In the new API you can set the alarm only by giving the offset time according to the start date of the entry.
//Get old alarm data
TTimeIntervalDays aDays = ...;
TTimeIntervalMinutes aMinutes= ...;
 
//tmp variables
TInt oneDayInMin = 1440;
TInt64 oneDayInMicroSec = 86400000000LL;
TInt64 oneMinInMicroSec = 60000000;
TCalTime startCalTime;
 
//Set the start time
startCalTime.SetTimeUtcL(start);
TInt offSet =
((startCalTime.TimeLocalL().Int64() % oneDayInMicroSec) / oneMinInMicroSec) -
 aMinutes.Int();
if( offSet < 0 ) offSet = oneDayInMin - Abs(offSet);
TTimeIntervalMinutes tmp( offSet + aDays.Int() * oneDayInMin);
CCalAlarm* alarm = CCalAlarm::NewL();
 
if(alarm)
    {
    alarm->SetTimeOffset(tmp);
    appt->SetAlarmL(alarm);
    delete alarm;
    }
Add old AgendaModel Alarm data to the new CCalEntry Todo item
This lines are similar to the appointment code, but now the alarm offset is calculated from the end date (due date).
//Get old alarm data
TTimeIntervalDays aDays = ...;
TTimeIntervalMinutes aMinutes= ...;
 
//tmp variables
TInt oneDayInMin = 1440;
TInt64 oneDayInMicroSec = 86400000000LL;
TInt64 oneMinInMicroSec = 60000000;
TCalTime endCalTime;
 
//Set end date
endCalTime.SetTimeUtcL(dueDate);
TInt offSet =
((endCalTime.TimeLocalL().Int64() % oneDayInMicroSec) / oneMinInMicroSec) -
 aMinutes.Int();
TTimeIntervalMinutes tmp( offSet + aDays.Int() * oneDayInMin);
CCalAlarm* alarm = CCalAlarm::NewL();
if( alarm )
    {
    alarm->SetTimeOffset(tmp);
    todo->SetAlarmL(alarm);
    delete alarm;
    }
Delete entry
void CCalendar::DeleteItemL(TInt aID)
    {
    CCalEntry* aEntry = NULL;
    TBuf8<30> tmpGuid;
    tmpGuid.Num( aID );
    HBufC8* guidBuf = tmpGuid.AllocL();
    RPointerArray<CCalEntry> tmpArray;
    CleanupStack::PushL(TCleanupItem(DestroyRPointerArray, &tmpArray));
    iCalEntryView->FetchL( guidBuf->Des(), tmpArray );
    delete guidBuf;
   
    if( tmpArray.Count() == 0 )
        {
 CleanupStack::PopAndDestroy(&tmpArray);
 return;
 }
    aEntry = tmpArray[0];
    iCalEntryView->DeleteL(*aEntry);
    CleanupStack::PopAndDestroy(&tmpArray);
    }
Update Appointment entry
Because the CCalEntryView->UpdateL() can't update all the attributes of an entry i use a tmpEntry to store the copied data to store the new modified entry, there are some entry swapping to avoid the data loss if a break occour. You can also implement this function using the CopyCalEntryL() function, described at the end of this document.
void CCalendar::UpdateApptL(TInt aID)
    {
    CCalEntry* aAppt = NULL;
    CCalEntry* tmpEntry = NULL;
    TInt aID = GetInt(*aIDText);
    TBuf8<30> tmpGuid;
    tmpGuid.Num(aID);
    HBufC8* guidBuf = tmpGuid.AllocL();
    HBufC8*  guidTmp;
 
    TBool aFound = EFalse;
 
    RPointerArray<CCalEntry> array;
    CleanupStack::PushL(TCleanupItem(DestroyRPointerArray, &array));
    TRAPD(aErr, iCalEntryView->FetchL(guidBuf->Des(), array) );
    if (!aErr && array.Count() > 0 )
        {
 aAppt = array[0];
 if( aAppt->EntryTypeL() != CCalEntry::EAppt ) aAppt = NULL;
 aFound = ETrue;
 }
 
    if (aFound)
 {        //This will create new unique UID
 HBufC8* guidTmp = CalenInterimUtils::GlobalUidL();
/*
        //Check the existence of the newly created tmp guid
 TInt itemCount = 0;
 do
     {
     TInt guidNum = Math::Random();
     TBuf8<30> tmpGuid;
     tmpGuid.Num( Abs(guidNum) );
     guidTmp = tmpGuid.AllocL();
     RPointerArray<CCalEntry> tmparray;
     CleanupStack::PushL(TCleanupItem(DestroyRPointerArray, &tmparray));
     iCalEntryView->FetchL(guidTmp->Des(), tmparray);
            itemCount = tmparray.Count();
     CleanupStack::PopAndDestroy(&tmparray);
     if( itemCount > 0 ) delete guidTmp;
     }
 while( itemCount > 0 );
*/
 tmpEntry =
  CCalEntry::NewL(CCalEntry::EAppt, guidTmp, CCalEntry::EMethodNone, 0);
 CleanupStack::PushL(tmpEntry);
 CopyCalEntryL(aAppt, tmpEntry);
 CleanupStack::Pop(tmpEntry);
 }
 
    CleanupStack::PopAndDestroy(&array);
    if( tmpEntry ) CleanupStack::PushL(tmpEntry);
 
    //Set new data:
    tmpEntry->SetSummaryL(_L("Summary"));
    // [...]
 
    //Store it
 
    if( tmpEntry ) CleanupStack::Pop(tmpEntry);
    if (aFound)
        {
 HBufC8* guidUpdate = guidBuf->AllocL();
 CCalEntry* updateEntry =
  CCalEntry::NewL(CCalEntry::EAppt, guidUpdate, CCalEntry::EMethodNone, 0);
 CleanupStack::PushL(updateEntry);
 CopyCalEntryL(tmpEntry, updateEntry);
 CleanupStack::Pop(updateEntry);
 
 HBufC8* deleteGuidTmp = guidTmp->AllocL();
 
 //Insert the tmp entry
 RPointerArray<CCalEntry> insertArray;
 CleanupStack::PushL(TCleanupItem(DestroyRPointerArray, &insertArray));
 insertArray.AppendL(tmpEntry);
 TInt success(0);
 iCalEntryView->StoreL(insertArray, success);
 insertArray.Reset();
 CleanupStack::PopAndDestroy(&insertArray);
 delete tmpEntry;
 
 //Delete old
 RPointerArray<CCalEntry> deleteArray;
 CleanupStack::PushL(TCleanupItem(DestroyRPointerArray, &deleteArray));
 iCalEntryView->FetchL(guidBuf->Des(), deleteArray);
 CCalEntry* deleteEntry = deleteArray[0];
 iCalEntryView->DeleteL(*deleteEntry);
 CleanupStack::PopAndDestroy(&deleteArray);
 
 //insert new update Entry
 RPointerArray<CCalEntry> updateArray;
 CleanupStack::PushL(TCleanupItem(DestroyRPointerArray, &updateArray));
 updateArray.AppendL(updateEntry);
 success = 0;
 iCalEntryView->StoreL(updateArray, success);
 updateArray.Reset();
 CleanupStack::PopAndDestroy(&updateArray);
 delete updateEntry;
 
 //Delete tmp Entry
 RPointerArray<CCalEntry> deleteTmpArray;
 CleanupStack::PushL(TCleanupItem(DestroyRPointerArray, &deleteTmpArray));
 iCalEntryView->FetchL(deleteGuidTmp->Des(), deleteTmpArray);
 CCalEntry* deleteTmpEntry = deleteTmpArray[0];
 iCalEntryView->DeleteL(*deleteTmpEntry);
 CleanupStack::PopAndDestroy(&deleteTmpArray);
 delete deleteGuidTmp;
 }
    delete guidBuf;
    }
Update Todo item
The Todo entry update can be made in similar mode than the Appointment entry.
Convert item CCalEntry IDs to old AgendaModel entry IDs
If you are porting your application from the old Agenda API to the new CalInterim API, presumably you have head-ache how to convert the new alphanumeric IDs to the old integer ID-s. Here is an example:
/
/*
Because the Global Uid(22 char length &HBufC8) of an entry
is out of range of TInt32...
This function must be called after the & CCalIter creation
and before any other functions.
*/
 
// Update the Global uids to be in the range of TInt32
void CCalendar::ConvertL()
{
    HBufC8* next = HBufC8::NewL(50);
    TPtr8 aAddress( next->Des() );
    aAddress = iCalIter->FirstL();
 
    while( next->Des() != KNullDesC8 )
        {
        //Checking if the ( UID is string) || (bigger then 2147483646)
 TBool toConvert = EFalse;
 TBuf8<100> des8 = _L8("");
 TRAPD(err_fetch, des8.Copy( next->Des() ) );
 if( err_fetch == KErrNone )
     {
     TLex8 lex8 = TLex8(des8);
     TInt id = 0;
     TInt err_lex = lex8.Val(id);
     if( err_lex != KErrNone ) toConvert = ETrue;
     }
 
        //Update
 if( toConvert != EFalse )
            {
     RPointerArray<CCalEntry> fetchArray;
     CleanupStack::PushL(TCleanupItem(DestroyRPointerArray, &fetchArray));
     iCalEntryView->FetchL(next->Des(), fetchArray);
     CCalEntry* aEntry = fetchArray[0];
 
     ///
 
 
     //Convert only the Appontment & Todo
     if( aEntry->EntryTypeL() == CCalEntry::EAppt || aEntry->EntryTypeL() ==
                  CCalEntry::ETodo )
                {
  //Check the existence of an entry with the new GUid
  HBufC8* guidBuf;
         TInt itemCount = 0;
  do
      {
      TInt guidNum = Math::Random();
             TBuf8<30> tmpGuid;
      tmpGuid.Num( Abs(guidNum) );
             guidBuf = tmpGuid.AllocL();
      RPointerArray<CCalEntry> tmparray;
      CleanupStack::PushL(TCleanupItem(DestroyRPointerArray,
                     &tmparray));
      iCalEntryView->FetchL(guidBuf->Des(), tmparray);
      itemCount = tmparray.Count();
      CleanupStack::PopAndDestroy(&tmparray);
      if( itemCount > 0 ) delete guidBuf;
      }
  while( itemCount > 0 );
                    CCalEntry* updateEntry;
      if( aEntry->EntryTypeL() == CCalEntry::EAppt )
          {
          updateEntry =
          CCalEntry::NewL(CCalEntry::EAppt, guidBuf,
                        CCalEntry::EMethodNone, 0);
          }
      else
          {
          updateEntry =
          CCalEntry::NewL(CCalEntry::ETodo, guidBuf,
                        CCalEntry::EMethodNone, 0);
          }
 
      //Copy: because updateEntry->CopyFromL( *aEntry, EDontCopyId );   
                    //doesn't work :(
      CopyCalEntryL(aEntry, updateEntry);
 
      RPointerArray<CCalEntry> modifyingArray;
      CleanupStack::PushL(TCleanupItem(DestroyRPointerArray,
                     &modifyingArray));
      modifyingArray.AppendL(updateEntry);
      TInt numberOfEntries(0);
      iCalEntryView->StoreL(modifyingArray, numberOfEntries);
             CleanupStack::PopAndDestroy(&modifyingArray);
 
      //Delete old
      RPointerArray<CCalEntry> deleteArray;
             CleanupStack::PushL(TCleanupItem(DestroyRPointerArray, 
                     &deleteArray));
      iCalEntryView->FetchL(aEntry->UidL(), deleteArray);
      CCalEntry* deleteEntry = deleteArray[0];
             iCalEntryView->DeleteL(*deleteEntry);
      CleanupStack::PopAndDestroy(&deleteArray);
      }
         CleanupStack::PopAndDestroy(&fetchArray);
         }
     aAddress = iCalIter->NextL();
     }
        delete next;
 next = NULL;
    }
Copy entry to an other one without Global ID
This function is usefull if CCalEntry CopyFromL( *aEntry, EDontCopyId ) doesn't work. aSource and aTarget should exist before calling this function. All 2 entries should be the same type!
void CCalendar::CopyCalEntryL(CCalEntry* aSource, CCalEntry* aTarget)
    {
    aTarget->SetSummaryL( aSource->SummaryL() );
    aTarget->SetDescriptionL( aSource->DescriptionL() );
    aTarget->SetLastModifiedDateL();
    aTarget->SetDTStampL( aSource->DTStampL() );
    aTarget->SetLocationL( aSource->LocationL() );
    aTarget->SetStatusL( aSource->StatusL() );
    aTarget->SetReplicationStatusL( aSource->ReplicationStatusL() );
    aTarget->SetPriorityL( aSource->PriorityL() );
 
    //On Nokia E60 - sometimes at Todo entries, getting startTime/endTime Leaves!
    //In this case create a new NullTTime Enty
    TCalTime startCalTime;
    TRAPD(err, startCalTime = aSource->StartTimeL());
    if( err != KErrNone )
        {
 TTime time = Time::NullTTime();
 startCalTime.SetTimeUtcL(time);
 }
 
    TCalTime endCalTime;
    TRAPD(err1, endCalTime = aSource->EndTimeL());
    if( err1 != KErrNone )
        {
 TTime time = Time::NullTTime();
 endCalTime.SetTimeUtcL(time);
 }
 
    aTarget->SetStartAndEndTimeL(startCalTime, aSource->EndTimeL());
 
    if( aSource->EntryTypeL() == CCalEntry::ETodo )
        {
 TCalTime time = aSource->CompletedTimeL();
 if( time.TimeUtcL() != Time::NullTTime() ) aTarget->SetCompletedL    
                 (ETrue time);
 aSource->CompletedTimeL().TimeUtcL(), ETrue, 3);
 }
 
    TCalRRule rule;
    if( aSource->GetRRuleL( rule ) != EFalse ) aTarget->SetRRuleL( rule );
 
    RArray<TCalTime> array;
    aSource->GetRDatesL( array );
    if( array.Count() > 0 ) aTarget->SetRDatesL( array );
 
    array.Reset();
    aSource->GetExceptionDatesL( array );
    if( array.Count() > 0 ) aTarget->SetExceptionDatesL( array );
    array.Close();
 
    CCalAlarm* alarm = aSource->AlarmL();
    aTarget->SetAlarmL( alarm );
    if( alarm )
        {
 aSource->AlarmL()->TimeOffset().Int(), 3);
 delete alarm;
 }
 
    //If,
    //Category, Attendee, Organizer, PhoneOwner, Method,
    //SequenceNumber, RecurrenceID, TzRules, LocalUid are not needed
    }
Retrieved from "http://wiki.forum.nokia.com/index.php/CalInterimAPI"

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值