/*
* Copyright (c) 2007 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: Calendar notifier
*
*/
#include <aknappui.h> // iavkonappui macro
#include <bacntf.h> // cenvironmentchangenotifier
#include <coemain.h> // eactiveprioritylogona
#include <centralrepository.h> // crepository
#include <ErrorUI.h> // cerrorui
#ifndef SYMBIAN_ENABLE_SPLIT_HEADERS // new
#include <asshdalarm.h>
#else // new
#include <asshdalarm.h>
#include <ASShdAlarmCal.h>
#endif // new
#include <e32property.h>
#include <calfilechangenotification.h>
#include <calenecomwatcher.h>
#include <calenglobaldata.h>
#include <calenconstants.h>
#include <calencontext.h>
#include <calsession.h>
#include <calcalendarinfo.h>
#include <calenmulticaluids.hrh>
#include "calendarui_debug.h"
#include "calennotifier.h" // CCalenNotifier
#include "CalendarPrivateCRKeys.h" // Central Repository keys
#include "calensetting.h"
#include "calenstatemachine.h"
#include "calencontroller.h"
const TInt KHashLength = 64;
const TInt KBuffLength = 24;
_LIT( KCalendarDatabaseFilePath, "c:calendar" );
// ----------------------------------------------------------------------------
// CCalenNotifier::CCalenNotifier
// C++ default constructor.
// (other items were commented in a header).
// ----------------------------------------------------------------------------
//
CCalenNotifier::CCalenNotifier( CCalenController& aController )
: iController( aController )
{
TRACE_ENTRY_POINT;
TRACE_EXIT_POINT;
}
// ----------------------------------------------------------------------------
// CCalenNotifier::~CCalenNotifier
// Destructor.
// (other items were commented in a header).
// ----------------------------------------------------------------------------
//
CCalenNotifier::~CCalenNotifier()
{
TRACE_ENTRY_POINT;
// Reset the handler array.
// Before we reset , close hashset for each handler
for(TInt i = 0 ; i < iHandlers.Count() ; i++)
{
iHandlers[i].iHashSet.Close();
}
iHandlers.Close();
iBroadcastQueue.Close();
if( iFilnameDeleted )
{
delete iFilnameDeleted;
iFilnameDeleted = NULL;
}
// Stop ECom change notifications
if( iEComWatcher )
{
delete iEComWatcher;
iEComWatcher = NULL;
}
// Stop settings change notifications
if( iCenRepChangeNotifier )
{
delete iCenRepChangeNotifier;
iCenRepChangeNotifier = NULL;
}
if( iRepository )
{
delete iRepository;
iRepository = NULL;
}
// Stop environment change notifications
if( iEnvChangeNotifier )
{
iEnvChangeNotifier->Cancel();
delete iEnvChangeNotifier;
}
if( iSetting )
{
iSetting->Release();
}
// Release the global data
if( iGlobalData )
{
// stop listening for calendar file change notifications
iGlobalData->CalSessionL().StopFileChangeNotification();
iGlobalData->Release();
}
TRACE_EXIT_POINT;
}
// ----------------------------------------------------------------------------
// CCalenNotifier::ConstructL
// Symbian 2nd phase of construction.
// (other items were commented in a header).
// ----------------------------------------------------------------------------
//
void CCalenNotifier::ConstructL()
{
TRACE_ENTRY_POINT;
// Get the global data
iGlobalData = CCalenGlobalData::InstanceL();
// Get the setting singleton. We update it when settings change.
iSetting = CCalenSetting::InstanceL();
// Register for system environment changes
TCallBack envCallback( EnvChangeCallbackL, this );
iEnvChangeNotifier =
CEnvironmentChangeNotifier::NewL( EActivePriorityLogonA, envCallback );
iEnvChangeNotifier->Start();
// Register for changes to Calendar settings from the Central Repository
iRepository = CRepository::NewL( KCRUidCalendar );
iCenRepChangeNotifier = CCenRepNotifyHandler::NewL( *this, *iRepository );
iCenRepChangeNotifier->StartListeningL();
// Register for changes to the ECom registry
iEComWatcher = CCalenEComWatcher::NewL( *this );
iIgnoreFirstLocaleChange = ETrue;
// start listening for calendar file change notifications
iGlobalData->CalSessionL().StartFileChangeNotificationL(*this);
iFilnameDeleted = NULL;
TRACE_EXIT_POINT;
}
// ----------------------------------------------------------------------------
// CCalenNotifier::RegisterForNotificationsL
// Adds the passed handler to the handler array.
// (other items were commented in a header).
// ----------------------------------------------------------------------------
//
void CCalenNotifier::RegisterForNotificationsL( MCalenNotificationHandler* aHandler,
TCalenNotification aNotification)
{
TRACE_ENTRY_POINT;
TNotificationHandler handler;
handler.iHandler = aHandler;
//Prepare hash
handler.iHashSet.ReserveL(KHashLength);
if(ECalenNotifyAll == aNotification)
{
//ECalenNotifyAll indicates that all notifications to be registered
//iterate through TCalenNotification enum and add the notifications to iHashSet
for(TCalenNotification notificationIter = TCalenNotification(ECalenNotifyAll + 1);
notificationIter < ECalenNotifyLast;
notificationIter = TCalenNotification(notificationIter + 1))
{
handler.iHashSet.InsertL(notificationIter);
}
}
else
{
//Add only single notification.
handler.iHashSet.InsertL(aNotification);
}
iHandlers.Append( handler );
TRACE_EXIT_POINT;
}
// ----------------------------------------------------------------------------
// CCalenNotifier::RegisterForNotificationsL
// Adds the passed handler to the handler array.
// (other items were commented in a header).
// ----------------------------------------------------------------------------
//
void CCalenNotifier::RegisterForNotificationsL( MCalenNotificationHandler* aHandler,
RArray<TCalenNotification>& aNotifications )
{
TRACE_ENTRY_POINT;
TNotificationHandler handler;
handler.iHandler = aHandler;
//Prepare hash
handler.iHashSet.ReserveL(KHashLength);
if(aNotifications.Find(ECalenNotifyAll) != KErrNotFound)
{
//ECalenNotifyAll indicates that all notifications to be registered
//If ECalenNotifyAll is found in aNotifications along with other notifications
//iterate through TCalenNotification enum and add the notifications to iHashSet
for(TCalenNotification notificationIter = TCalenNotification(ECalenNotifyAll + 1);
notificationIter < ECalenNotifyLast;
notificationIter = TCalenNotification(notificationIter + 1))
{
handler.iHashSet.InsertL(notificationIter);
}
}
else
{
//Add notifocations from Array(aNotifications) into iHashSet member
for(TInt i = 0 ; i < aNotifications.Count() ; i++)
{
handler.iHashSet.InsertL(aNotifications[i]);
}
}
iHandlers.Append( handler );
TRACE_EXIT_POINT;
}
// ----------------------------------------------------------------------------
// CCalenNotifier::CancelNotifications
// Removes the passed handler from the handler array.
// (other items were commented in a header).
// ----------------------------------------------------------------------------
//
void CCalenNotifier::CancelNotifications( MCalenNotificationHandler* aHandler )
{
TRACE_ENTRY_POINT;
for( TInt x = 0; x < iHandlers.Count(); ++x )
{
if( iHandlers[x].iHandler == aHandler )
{
// Mark the notification for deletion by
// settings the handler to NULL. Actual deletion
// will take place in DoBroadcast
iHandlers[x].iHashSet.Close();
iHandlers[x].iHandler = NULL;
TRACE_EXIT_POINT;
return;
}
}
TRACE_EXIT_POINT;
}
// ----------------------------------------------------------------------------
// CCalenNotifier::EnvChangeCallbackL
// CEnvironmentChangeNotifier callback. Calendar is only interested in:
// EChangesLocale - System locale changed
// EChangesMidnightCrossover - System time passed midnight
// EChangesSystemTime - System time changed
// (other items were commented in a header).
// ----------------------------------------------------------------------------
//
TInt CCalenNotifier::EnvChangeCallbackL( TAny* aThisPtr )
{
TRACE_ENTRY_POINT;
/* CCalenNotifier* thisPtr = static_cast<CCalenNotifier*>( aThisPtr );
if( thisPtr->iEnvChangeNotifier->Change() & EChangesMidnightCrossover )
{
thisPtr->BroadcastNotification( ECalenNotifySystemTimeChanged );
}
if( thisPtr->iEnvChangeNotifier->Change() & EChangesLocale )
{
thisPtr->BroadcastNotification( ECalenNotifySystemLocaleChanged );
}
if( thisPtr->iEnvChangeNotifier->Change() & EChangesSystemTime )
{
thisPtr->BroadcastNotification( ECalenNotifySystemTimeChanged );
}*/
TRACE_EXIT_POINT;
// Return value for functions used as TCallBack objects should be EFalse
// unless the function is intended to be called again from a timer.
// return EFalse;
return static_cast<CCalenNotifier*>(aThisPtr)->DoEnvChange();
}
// ----------------------------------------------------------------------------
// CCalenNotifier::DoEnvChange
// EnvChangeCallbackL calls this function
// ----------------------------------------------------------------------------
//
TInt CCalenNotifier::DoEnvChange()
{
TRACE_ENTRY_POINT;
if( ((iEnvChangeNotifier->Change() & EChangesMidnightCrossover)
|| (iEnvChangeNotifier->Change() & EChangesSystemTime))
&& !iIgnoreFirstLocaleChange )
{
BroadcastNotification( ECalenNotifySystemTimeChanged );
}
else if( (iEnvChangeNotifier->Change() & EChangesLocale)
&& !iIgnoreFirstLocaleChange )
{
BroadcastNotification( ECalenNotifySystemLocaleChanged );
}
else
{
iIgnoreFirstLocaleChange = EFalse;
}
TRACE_EXIT_POINT;
return EFalse ;
}
// ----------------------------------------------------------------------------
// CCalenNotifier::HandleNotifyGeneric
// From MCenRepNotifyHandlerCallback
// Generic notification that one of our central repository keys has changed
// If any keys change we broadcast a settings changed notification
// (other items were commented in a header).
// ----------------------------------------------------------------------------
//
void CCalenNotifier::HandleNotifyGeneric( TUint32 /*aId*/ )
{
TRACE_ENTRY_POINT;
PIM_TRAPD_HANDLE( iSetting->LoadL() );
BroadcastNotification( ECalenNotifySettingsChanged );
// Use another trap to make sure we start listening again, regardless
// of whether the previous function left or not.
PIM_TRAPD_HANDLE( iCenRepChangeNotifier->StartListeningL() );
TRACE_EXIT_POINT;
}
// ----------------------------------------------------------------------------
// CCalenNotifier::HandleNotifyError
// Cenrep watcher error callback
// (other items were commented in a header).
// ----------------------------------------------------------------------------
//
void CCalenNotifier::HandleNotifyError( TUint32 /*aId*/,
TInt /*aError*/,
CCenRepNotifyHandler* /*aHandler*/ )
{
TRACE_ENTRY_POINT;
PIM_TRAPD_HANDLE( iCenRepChangeNotifier->StartListeningL() );
TRACE_EXIT_POINT;
}
// ----------------------------------------------------------------------------
// CCalenNotifier::HandleDBChangeL
// From MCalenDBChangeObserver
// Notification that an external CCalSession has modified the database we are
// using in some way. This notification is limited to a maximum of one per
// second. This is to avoid multiple notifications when performing large sync
// operations
// (other items were commented in a header).
// ----------------------------------------------------------------------------
//
void CCalenNotifier::HandleDBChangeL()
{
TRACE_ENTRY_POINT;
BroadcastNotification( ECalenNotifyExternalDatabaseChanged );
TRACE_EXIT_POINT;
}
// ----------------------------------------------------------------------------
// CCalenNotifier::ContextChanged
// From MCalenContextChangeObserver. Called when the context changes.
// (other items were commented in a header).
// ----------------------------------------------------------------------------
//
void CCalenNotifier::ContextChanged()
{
TRACE_ENTRY_POINT;
BroadcastNotification( ECalenNotifyContextChanged );
TRACE_EXIT_POINT;
}
// ----------------------------------------------------------------------------
// CCalenNotifier::EComChanged
// From MCalenEComChangeObserver. Called when the ECom registry changes
// (install/uninstall).
// ----------------------------------------------------------------------------
//
void CCalenNotifier::EComChanged()
{
TRACE_ENTRY_POINT;
if(!iController.IsFasterAppFlagEnabled())
{
BroadcastNotification( ECalenNotifyEComRegistryChanged );
}
TRACE_EXIT_POINT;
}
// ----------------------------------------------------------------------------
// CCalenNotifier::DeferSettingsNotifications
// After calling this function, any settings changed notifications
// will not be broadcast until after ResumeSettingsNotifications
// has been called.
// (other items were commented in a header).
// ----------------------------------------------------------------------------
//
void CCalenNotifier::DeferSettingsNotifications()
{
TRACE_ENTRY_POINT;
iIsSettingsBroadcastDeferred = ETrue;
TRACE_EXIT_POINT;
}
// ----------------------------------------------------------------------------
// CCalenNotifier::ResumeSettingsNotifications
// Resumes settings notifications after they have been paused
// with DeferSettingsNotifications.
// (other items were commented in a header).
// ----------------------------------------------------------------------------
//
void CCalenNotifier::ResumeSettingsNotifications()
{
TRACE_ENTRY_POINT;
iIsSettingsBroadcastDeferred = EFalse;
if( iSettingsNeedsBroadcast )
{
iSettingsNeedsBroadcast = EFalse;
BroadcastNotification( ECalenNotifySettingsChanged );
}
if( iLocaleNeedsBroadcast )
{
iLocaleNeedsBroadcast = EFalse;
BroadcastNotification( ECalenNotifySystemLocaleChanged );
}
TRACE_EXIT_POINT;
}
// ----------------------------------------------------------------------------
// CCalenNotifier::BroadcastNotification
// Issues a notification to all registered handlers
// (other items were commented in a header).
// ----------------------------------------------------------------------------
//
void CCalenNotifier::BroadcastNotification( TCalenNotification aNotification )
{
TRACE_ENTRY_POINT;
// Someone has told us to broadcast, or one of our notifiers completed.
// We run it past the state machine and that may or may not call the
// function to really do the broadcast.
iController.StateMachine().HandleNotification( aNotification );
TRACE_EXIT_POINT;
}
// ----------------------------------------------------------------------------
// CCalenNotifier::BroadcastApprovedNotification
// Issues a notification to all registered handlers
// (other items were commented in a header).
// ----------------------------------------------------------------------------
//
void CCalenNotifier::BroadcastApprovedNotification( TCalenNotification aNotification )
{
TRACE_ENTRY_POINT;
/*if ( aNotification == ECalenNotifySettingsChanged
&& iIsSettingsBroadcastDeferred )
{
iSettingsNeedsBroadcast = ETrue;
}
else if ( aNotification == ECalenNotifySystemLocaleChanged
&& iIsSettingsBroadcastDeferred)
{
iLocaleNeedsBroadcast = ETrue;
}
else*/
{
iBroadcastQueue.Append( aNotification );
if( !iBroadcastActive )
{
iBroadcastActive = ETrue;
while( iBroadcastQueue.Count() )
{
TCalenNotification notification = iBroadcastQueue[0];
DoBroadcast( notification );
iBroadcastQueue.Remove( 0 );
}
iBroadcastActive = EFalse;
}
}
TRACE_EXIT_POINT;
}
// ----------------------------------------------------------------------------
// CCalenNotifier::DoBroadcast
// Issues a notification to all registered handlers
// (other items were commented in a header).
// ----------------------------------------------------------------------------
//
void CCalenNotifier::DoBroadcast( TCalenNotification aNotification )
{
TRACE_ENTRY_POINT;
for( TInt x = 0; x < iHandlers.Count(); ++x )
{
TNotificationHandler handler = iHandlers[x];
if( handler.iHandler )
{
if( handler.iHashSet.Find(aNotification) )
{
handler.iHandler->HandleNotification( aNotification );
}
}
else
{
// The handler has been marked for deletion
iHandlers.Remove( x ); // remove the entry
--x; // decrement the index.
}
}
TRACE_EXIT_POINT;
}
// ----------------------------------------------------------------------------
// CCalenNotifier::Progress
// From MCalProgressCallback. Intentionally empty.
// (other items were commented in a header).
// ----------------------------------------------------------------------------
//
void CCalenNotifier::Progress( TInt /*aPercentageCompleted*/ )
{
TRACE_ENTRY_POINT;
TRACE_EXIT_POINT;
}
// ----------------------------------------------------------------------------
// CCalenNotifier::NotifyProgress
// From MCalProgressCallback. Don't notify us about progress updates.
// (other items were commented in a header).
// ----------------------------------------------------------------------------
//
TBool CCalenNotifier::NotifyProgress()
{
TRACE_ENTRY_POINT;
// No one interested in this notification.Removing to avoid notification clutter.
// BroadcastNotification( ECalenNotifyViewCreationStarted );
TRACE_EXIT_POINT;
return EFalse;
}
// ----------------------------------------------------------------------------
// CCalenNotifier::Completed
// From MCalProgressCallback.
// Notifies observer of completion
// (other items were commented in a header).
// ----------------------------------------------------------------------------
//
void CCalenNotifier::Completed( TInt aStatus )
{
TRACE_ENTRY_POINT;
if( aStatus == KErrNone )
{
BroadcastNotification( ECalenNotifyEntryInstanceViewCreated );
}
else
{
BroadcastNotification( ECalenNotifyEntryInstanceViewCreationFailed );
// The view creation has failed, hence the calendar
// application needs to close gracefully
// 1) Display error note.
CErrorUI* errorUi;
TRAPD(error,errorUi = CErrorUI::NewLC();
if(error!=KErrNone)
{
// do avoid warning
}
errorUi->ShowGlobalErrorNoteL( aStatus );
CleanupStack::PopAndDestroy( errorUi );
);
// If Instance view creation is cancelled, no need to
// exit application.All other errors exit application.
if(aStatus != KErrCancel)
{
// Exit application
if (iAvkonAppUi)
{
iAvkonAppUi->Exit();
}
}
}
TRACE_EXIT_POINT;
}
// ----------------------------------------------------------------------------
// CCalenNotifier::SystemTimeChangedL
// Check if the system time changed since Calendar was last launched
// If the system time did change, we need to notify the user that alarms may
// have been missed.
// (other items were commented in a header).
// ----------------------------------------------------------------------------
//
TInt CCalenNotifier::SystemTimeChangedL()
{
TRACE_ENTRY_POINT;
TBool timeZoneChanged(EFalse);
TPckgBuf<TMissedAlarmPubSubData> alarmPkgVarBuf;
TInt errorVal = RProperty::Get( KAlarmServerPubSubCategory,
KMissingAlarmPubSubKey, alarmPkgVarBuf);
if(errorVal != KErrNone)
{
// Error in accessing the P&S key.
// Alarm server defines this key when first time SystemTime Changes after bootup.
// But Calendar may try to access this before it is defined by Alarm server.
// So better not leaving based on errorVal
return timeZoneChanged;
}
// read the latest timechange from agenda Server Time Stamp
TTime timeOfChangeUtc = alarmPkgVarBuf().iTimeOfChangeUtc;
//timeOfChangeUtc.RoundUpToNextMinute();
iTimeOfChangeUtcReal = I64REAL(timeOfChangeUtc.Int64());
// read the persistent time stamp from CalendarInternalCRKeys
TReal previousTimeOfChange = 1.0;
CRepository* repository = CRepository::NewL( KCRUidCalendar );
CleanupStack::PushL( repository );
errorVal = repository->Get( KCalendarPersistentTime, previousTimeOfChange );
User::LeaveIfError( errorVal );
TInt tzChangedOrAlarmsMissed(0);
// compare the times. If the time set in the PubSub key by the Alarm Server is
// greater than the last time we looked at it, we will show 1 of the 2 info notes
// to the user.
if (iTimeOfChangeUtcReal != previousTimeOfChange)
{
// Agenda Server set this value to tell what has happened since
// the time change
tzChangedOrAlarmsMissed = alarmPkgVarBuf().iValue;
}
CleanupStack::PopAndDestroy( repository );
TRACE_EXIT_POINT;
return tzChangedOrAlarmsMissed;
}
// ----------------------------------------------------------------------------
// CCalenNotifier::UpdateSytemTimeChangeInfoL
// Update cenrep with latest system time change info
// (other items were commented in a header).
// ----------------------------------------------------------------------------
//
void CCalenNotifier::UpdateSytemTimeChangeInfoL()
{
TRACE_ENTRY_POINT;
CRepository* repository = CRepository::NewL( KCRUidCalendar );
CleanupStack::PushL( repository );
// Update the persistent time stamp to the time stamp
// indicated by the agenda server
TInt errorVal = repository->Set( KCalendarPersistentTime, iTimeOfChangeUtcReal);
User::LeaveIfError( errorVal );
CleanupStack::PopAndDestroy( repository );
TRACE_EXIT_POINT;
}
// ----------------------------------------------------------------------------
// CCalenNotifier::TNotificationHandler()
// TNotificationHandler contructor
// ----------------------------------------------------------------------------
CCalenNotifier::TNotificationHandler::TNotificationHandler() :
iHashSet(&::HashCalenNotificationFunction,&::HashCalenNotificationIdentityRelation)
{
TRACE_ENTRY_POINT;
TRACE_EXIT_POINT;
}
// ----------------------------------------------------------------------------
// CCalenNotifier::CalendarInfoChangeNotificationL()
// Handle calendar file change notifications
// ----------------------------------------------------------------------------
void CCalenNotifier::CalendarInfoChangeNotificationL(
RPointerArray<CCalFileChangeInfo>& aCalendarInfoChangeEntries)
{
TRACE_ENTRY_POINT;
// get the file change count
TInt calenInfoChangeCount = aCalendarInfoChangeEntries.Count();
for(TInt index = 0;index < calenInfoChangeCount;index++)
{
//get the context and set the calendar filename which triggered the
// notification
MCalenContext &context = iController.Services().Context();
context.SetCalendarFileNameL(
aCalendarInfoChangeEntries[index]->FileNameL());
MCalFileChangeObserver::TChangeType changeType =
aCalendarInfoChangeEntries[index]->ChangeType();
switch(changeType)
{
case MCalFileChangeObserver::ECalendarFileCreated:
{
TFileName lastCreatedFileName = aCalendarInfoChangeEntries[index]->FileNameL();
CRepository* cenRep = CRepository::NewLC(KCRUidCalendar);
User::LeaveIfError( cenRep->Set( KCalendarLastUsedCalendar, lastCreatedFileName ) );
CleanupStack::PopAndDestroy( cenRep );
}
case MCalFileChangeObserver::ECalendarInfoCreated:
{
BroadcastNotification(ECalenNotifyDeleteInstanceView);
BroadcastNotification(ECalenNotifyCalendarInfoCreated);
}
break;
case MCalFileChangeObserver::ECalendarFileDeleted:
{
BroadcastNotification(ECalenNotifyCalendarFileDeleted);
}
break;
case MCalFileChangeObserver::ECalendarInfoUpdated:
case MCalFileChangeObserver::ECalendarInfoDeleted:
{
TFileName calFileName = aCalendarInfoChangeEntries[index]->FileNameL();
CCalSession* session = NULL;
TRAPD(err, session = &iGlobalData->CalSessionL( calFileName ));
if(KErrNotFound == err && ECalendarInfoUpdated == changeType)
{
BroadcastNotification(ECalenNotifyDeleteInstanceView);
BroadcastNotification(ECalenNotifyCalendarInfoCreated);
break;
}
CCalCalendarInfo* calendarInfo = session->CalendarInfoL();
CleanupStack::PushL(calendarInfo);
TBuf8<KBuffLength> keyBuff;
keyBuff.AppendNum(EMarkAsDelete);
TBool markAsdelete;
TPckgC<TBool> pkgMarkAsDelete(markAsdelete);
TRAP(err,pkgMarkAsDelete.Set(calendarInfo->PropertyValueL(keyBuff)));
markAsdelete = pkgMarkAsDelete();
CleanupStack::PopAndDestroy(calendarInfo);
if (err == KErrNone && markAsdelete && aCalendarInfoChangeEntries[index]->FileNameL().CompareF(
KCalendarDatabaseFilePath))
{
iFilnameDeleted = aCalendarInfoChangeEntries[index]->FileNameL().AllocL();
BroadcastNotification(ECalenNotifyDeleteInstanceView);
iGlobalData->RemoveCalendarL(iFilnameDeleted->Des());
BroadcastNotification(ECalenNotifyCalendarFileDeleted);
delete iFilnameDeleted;
iFilnameDeleted = NULL;
}
else
{
BroadcastNotification(ECalenNotifyCalendarInfoUpdated);
}
}
break;
default:
break;
}
context.ResetCalendarFileName();
}
TRACE_EXIT_POINT;
}
// End of file