diff -r 000000000000 -r f979ecb2b13e calendarui/controller/src/calendeleteui.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/calendarui/controller/src/calendeleteui.cpp Tue Feb 02 10:12:19 2010 +0200 @@ -0,0 +1,1196 @@ +/* +* 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: Handles deletion +* +*/ + + +// INCLUDES +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include // Calendar commands +#include +#include // TCalenInstanceId +#include +#include + +#include "calendarui_debug.h" // Debug +#include "calendeleteui.h" +#include "calencontroller.h" +#include "CleanupResetAndDestroy.h" +#include "CalenInterimUtils2.h" +#include "CalendarPrivateCRKeys.h" // For CalendarInternalCRKeys.h +#include "calenmultipledbmanager.h" + +// Local constants +const TInt KEntriesToDelete = 1; + +// ---------------------------------------------------------------------------- +// CCalenDeleteUi::NewL +// Two phased constructor +// (other items were commented in a header). +// ---------------------------------------------------------------------------- +// +CCalenDeleteUi* CCalenDeleteUi::NewL( CCalenController& aController ) + { + TRACE_ENTRY_POINT; + + CCalenDeleteUi* self = new( ELeave ) CCalenDeleteUi( aController ); + CleanupStack::PushL( self ); + self->ConstructL(); + CleanupStack::Pop( self ); + + TRACE_EXIT_POINT; + return self; + } + +// ---------------------------------------------------------------------------- +// CCalenDeleteUi::CCalenDeleteUi +// ?implementation_description +// (other items were commented in a header). +// ---------------------------------------------------------------------------- +// +CCalenDeleteUi::CCalenDeleteUi( CCalenController& aController ) + : iEikEnv( CEikonEnv::Static() ), iController( aController ) + { + TRACE_ENTRY_POINT; + TRACE_EXIT_POINT; + } + +// ---------------------------------------------------------------------------- +// CCalenDeleteUi::~CCalenDeleteUi +// Destructor +// (other items were commented in a header). +// ---------------------------------------------------------------------------- +// +CCalenDeleteUi::~CCalenDeleteUi() + { + TRACE_ENTRY_POINT; + + if( iWaitDialog ) + { + delete iWaitDialog; + iWaitDialog = NULL; + } + + if( iGlobalData ) + { + iGlobalData->Release(); + } + + if( iDelAllRange ) + delete iDelAllRange; + + iDeleteColIds.Reset(); + + TRACE_EXIT_POINT; + } + +// ---------------------------------------------------------------------------- +// CCalenDeleteUi::ConstructL +// Second phase of construction +// (other items were commented in a header). +// ---------------------------------------------------------------------------- +// +void CCalenDeleteUi::ConstructL() + { + TRACE_ENTRY_POINT; + + iGlobalData = CCalenGlobalData::InstanceL(); + + // Both the entry view and instance views are needed + // by the deleteUi commands, there queue the construction of both + RArray colArray; + iController.GetActiveCollectionidsL(colArray); + + CCalInstanceView* instanceView = iGlobalData->InstanceViewL(colArray); + colArray.Reset(); + if( !instanceView ) + { + iController.RegisterForNotificationsL( this, ECalenNotifyEntryInstanceViewCreated ); + } + iController.RegisterForNotificationsL( this, ECalenNotifyCancelDelete ); + iMoreEntriesToDelete = EFalse; + iDisplayQuery = EFalse; + iEntriesToDelete = KEntriesToDelete; + iDelAllRange = NULL; + TRACE_EXIT_POINT; + } + +// ---------------------------------------------------------------------------- +// CCalenDeleteUi::HandleECalenNotifyViewCreatedL +// Handles ECalenNotifyViewCreated. +// (other items were commented in a header). +// ---------------------------------------------------------------------------- +// +void CCalenDeleteUi::HandleECalenNotifyViewCreatedL() + { + TRACE_ENTRY_POINT; + RArray colArray; + iController.GetActiveCollectionidsL(colArray); + + if( iGlobalData->InstanceViewL(colArray) ) + { + // Handle the outstanding command + HandleCommandL( iStoredCommand ); + + // Cancel the notify as the entry view is now + // constructed. + iController.CancelNotifications( this ); + } + colArray.Reset(); + TRACE_EXIT_POINT; + } + +// ---------------------------------------------------------------------------- +// CCalenDeleteUi::HandleNotification +// Handles notifications. +// (other items were commented in a header). +// ---------------------------------------------------------------------------- +// +void CCalenDeleteUi::HandleNotification(const TCalenNotification aNotification ) + { + TRACE_ENTRY_POINT; + + if ( aNotification == ECalenNotifyEntryInstanceViewCreated ) + { + PIM_TRAPD_HANDLE( HandleECalenNotifyViewCreatedL() ); + } + if( aNotification == ECalenNotifyCancelDelete) + { + if(iMutlipleContextIdsCount) + { + // get the context + MCalenContext& context = iGlobalData->Context(); + // reset the multiple contexts + context.ResetMultipleContextIds(); + + // dismiss the waitdialog + if(iWaitDialog) + { + TRAP_IGNORE(iWaitDialog->ProcessFinishedL()); + } + } + } + TRACE_EXIT_POINT; + } + +// ---------------------------------------------------------------------------- +// CCalenDeleteUi::HandleCommandL +// Handles action ui commands +// (other items were commented in a header). +// ---------------------------------------------------------------------------- +// +TBool CCalenDeleteUi::HandleCommandL( const TCalenCommand& aCommand ) + { + TRACE_ENTRY_POINT; + TBool continueCommand(EFalse); + + RArray colArray; + iController.GetActiveCollectionidsL(colArray); + + if( colArray.Count() && !( iGlobalData->InstanceViewL(colArray) ) ) + { + iStoredCommand = aCommand; + } + else + { + switch( aCommand.Command() ) + { + case ECalenDeleteCurrentEntry: + DeleteCurrentEntryL(); // Entry & instance + break; + + case ECalenDeleteSeries: + DeleteThisOrAllL( CalCommon::EThisAndAll ); + break; + + case ECalenDeleteCurrentOccurrence: + DeleteThisOrAllL( CalCommon::EThisOnly ); + break; + + case ECalenDeleteEntryWithoutQuery: + continueCommand = DeleteEntryWithoutQueryL(); + break; + + case ECalenDeleteAllEntries: + HandleDeleteAllEntriesL(); + break; + + case ECalenDeleteEntriesBeforeDate: + DeleteEntriesBeforeDateL(); // EntryView & instance + break; + + default: + // Controller decided this class was the place to handle this + // command but it wasn't in our list; something has gone wrong. + //ASSERT( EFalse ); + break; + } + } + colArray.Reset(); + TRACE_EXIT_POINT; + return continueCommand; + } + +// ---------------------------------------------------------------------------- +// CCalenDeleteUi::CalenCommandHandlerExtensionL +// Dummy implementation. +// (other items were commented in a header). +// ---------------------------------------------------------------------------- +// +TAny* CCalenDeleteUi::CalenCommandHandlerExtensionL( TUid /*aExtensionUid*/ ) + { + TRACE_ENTRY_POINT; + TRACE_EXIT_POINT; + return NULL; + } + +// ---------------------------------------------------------------------------- +// CCalenDeleteUi::DeleteThisOrAllL +// Deletes series repeating entry +// (other items were commented in a header). +// ---------------------------------------------------------------------------- +// +void CCalenDeleteUi::DeleteThisOrAllL( CalCommon::TRecurrenceRange aRepeatType ) + { + TRACE_ENTRY_POINT; + + TBool isDeleted( EFalse ); + + RArray colIdArray; + colIdArray.AppendL(iGlobalData->Context().InstanceId().iColId); + + if( iGlobalData->Context().InstanceId().iEntryLocalUid ) + { + CCalInstance* instance = + CalenActionUiUtils::FindPossibleInstanceL( + iGlobalData->Context().InstanceId(), + *iGlobalData->InstanceViewL(colIdArray) ); + if( instance ) + { + CleanupStack::PushL( instance ); + isDeleted = DeleteSingleInstanceL( instance, aRepeatType ); + + if( isDeleted ) + { + CleanupStack::Pop( instance ); + } + else + { + CleanupStack::PopAndDestroy( instance ); + } + } + } + colIdArray.Reset(); + + iController.BroadcastNotification( isDeleted? ECalenNotifyEntryDeleted : + ECalenNotifyDeleteFailed ); + + TRACE_EXIT_POINT; + } + +// ---------------------------------------------------------------------------- +// CCalenDeleteUi::DeleteEntryWithoutQueryL() +// Deletes the current entry +// (other items were commented in a header). +// ---------------------------------------------------------------------------- +// +TBool CCalenDeleteUi::DeleteEntryWithoutQueryL() + { + TRACE_ENTRY_POINT; + TBool continueCommand(EFalse); + + // get the context + MCalenContext& context = iGlobalData->Context(); + + // get the multliple context ids count + iMutlipleContextIdsCount = context.MutlipleContextIdsCount(); + + ASSERT( iMutlipleContextIdsCount ); + + if(!iMoreEntriesToDelete) + { + iDisplayQuery = ShowMultipleEntriesDeleteQueryL(iMutlipleContextIdsCount); + } + + if(iDisplayQuery) + { + if(!iMoreEntriesToDelete) + { + DisplayWaitDialogL(); + } + // get the multiple context instance ids + RArray& multipleContextIds = context.GetMutlipleContextIds(); + + if(iMutlipleContextIdsCount <= iEntriesToDelete ) + { + iMoreEntriesToDelete = EFalse; + iEntriesToDelete = iMutlipleContextIdsCount; + } + else + { + iMoreEntriesToDelete = ETrue; + // set the continue command flag if more entries are there to delete + continueCommand = ETrue; + } + + TInt index(0); + while(indexContext().InstanceId().iEntryLocalUid ) + { + //If todo, use the LUid. + //Todos returns the current time if start or end time has not been saved. + if( CCalEntry::ETodo == iGlobalData->Context().InstanceId().iType ) + { + CCalEntry* entry = iGlobalData->EntryViewL(iGlobalData->Context().InstanceId().iColId)->FetchL( + iGlobalData->Context().InstanceId().iEntryLocalUid ); + + if( entry ) + { + CleanupStack::PushL( entry ); + deleted = DeleteEntryL( iGlobalData->EntryViewL(iGlobalData->Context().InstanceId().iColId), entry ); + + if( deleted ) + { + CleanupStack::Pop( entry ); + notification = ECalenNotifyEntryDeleted; + } + else + { + CleanupStack::PopAndDestroy( entry ); + } + } + } + else // Not todo + { + RArray colIdArray; + colIdArray.AppendL(iGlobalData->Context().InstanceId().iColId); + + CCalInstance* instance = CalenActionUiUtils::FindPossibleInstanceL( + iGlobalData->Context().InstanceId(), + *iGlobalData->InstanceViewL(colIdArray) ); + // if we have instance we will do delete other wise just return + if( instance ) + { + // Note: ownership handling of instance is dirty in this case, + // because DeleteSingleInstanceLtakes ownership, if it's deletes + // instance (property of CalInterimApi), otherwise not. + CleanupStack::PushL( instance ); + deleted = DeleteSingleInstanceL( instance ); + + if( deleted ) + { + CleanupStack::Pop( instance ); + notification = ECalenNotifyEntryDeleted; + } + else + { + CleanupStack::PopAndDestroy( instance ); + } + } + colIdArray.Reset(); + } + } + else + { + TBool doDelete( ETrue ); + + doDelete = CalenActionUiUtils::ShowDeleteConfirmationQueryL( + iGlobalData->Context().InstanceId().iType == CCalEntry::ETodo ? + CalenActionUiUtils::EDeleteToDo : + CalenActionUiUtils::EDeleteEntry ); + if ( doDelete ) + { + notification = ECalenNotifyEntryDeleted; + } + } + + iController.BroadcastNotification( notification ); + + TRACE_EXIT_POINT; + } + +// ---------------------------------------------------------------------------- +// CCalenDeleteUi::DeleteAllEntriesL +// Deletes all entries +// (other items were commented in a header). +// ---------------------------------------------------------------------------- +// +void CCalenDeleteUi::DeleteAllEntriesL() + { + TRACE_ENTRY_POINT; + + ASSERT( !iIsDeleting ); + + const TInt buttonId = CalenActionUiUtils::ShowDeleteConfirmationQueryL( + CalenActionUiUtils::EDeleteAll ); + + if( buttonId ) + { + HandleDeleteMultipleEventsL( TCalTime::MinTime(), TCalTime::MaxTime(), + R_QTN_CALE_CONF_ALL_NOTES_DELETED ); + } + else + { + // notify delete failed + iController.BroadcastNotification(ECalenNotifyDeleteFailed); + } + + TRACE_EXIT_POINT; + } + +// ---------------------------------------------------------------------------- +// CCalenDeleteUi::DeleteEntriesBeforeDateL +// Deletes all entries before a set date. +// (other items were commented in a header). +// ---------------------------------------------------------------------------- +// +void CCalenDeleteUi::DeleteEntriesBeforeDateL() + { + TRACE_ENTRY_POINT; + + ASSERT( !iIsDeleting ); + TTime date; + date.HomeTime(); + TTime today = date; + + TBool execute( EFalse ); + TBool exit( ETrue ); + do{ + exit = ETrue; + execute = EFalse; + + TInt buttonId = CalenActionUiUtils::DateQueryL(date, R_CALEN_DEL_BEFORE_DATE_PROMPT); + + if( buttonId == EAknSoftkeyOk || buttonId == EEikBidOk ) + { + execute = ETrue; + if( today < date ) + { + CAknNoteDialog* dialog = new( ELeave ) CAknNoteDialog( + CAknNoteDialog::EConfirmationTone, + CAknNoteDialog::ELongTimeout ); + dialog->ExecuteLD( R_CALEN_DELETEERROR_NOTE ); + execute = EFalse; + exit = EFalse; + } + } + }while( !exit ); + + // Do delete only if inputted day is after beginning of range + if( execute && date > TCalTime::MinTime() ) + { + // Two pass delete: + // 1. pass + // To prevent destroying entries starting and ending midnight + // subtract one microsecond and do delete on that range. + date -= TTimeIntervalMicroSeconds32( 1 ); + date = Max( date, TCalTime::MinTime() ); + + HandleDeleteMultipleEventsL( TCalTime::MinTime(), + date, + R_QTN_CALE_CONF_PAST_NOTE_DELETED ); + } + else + { + iController.BroadcastNotification( ECalenNotifyDeleteFailed ); + } + + TRACE_EXIT_POINT; + } + +// ---------------------------------------------------------------------------- +// CCalenDeleteUi::HandleDeleteMultipleEventsL +// Handles multiple delete events +// (other items were commented in a header). +// ---------------------------------------------------------------------------- +// +void CCalenDeleteUi::HandleDeleteMultipleEventsL( const TTime& aFirstDay, + const TTime& aLastDay, + TInt aConfNoteId ) + { + TRACE_ENTRY_POINT; + + ASSERT( !iWaitDialog ); + ASSERT( !iIsDeleting ); + iConfirmationNoteId = aConfNoteId; + + iWaitDialog = new( ELeave ) CAknWaitDialog( REINTERPRET_CAST( CEikDialog**, + &iWaitDialog ) ); + iWaitDialog->ExecuteLD( R_CALEN_DELETE_WAIT_NOTE ); + + DeleteDayRangeL( aFirstDay, aLastDay ); + + TRACE_EXIT_POINT; + } + +// ---------------------------------------------------------------------------- +// CCalenDeleteUi::DeleteDayRangeL +// Deletes all entries in a given range. +// (other items were commented in a header). +// ---------------------------------------------------------------------------- +// +void CCalenDeleteUi::DeleteDayRangeL( const TTime& aStart, + const TTime& aEnd ) + { + TRACE_ENTRY_POINT; + + iStartTime = aStart; + iEndTime = aEnd; + + TCalTime start, end; + start.SetTimeLocalL( iStartTime ); + end.SetTimeLocalL( iEndTime ); + + if( iDelAllRange ) + { + delete iDelAllRange; + iDelAllRange = NULL; + } + + iDelAllRange = new(ELeave) CalCommon::TCalTimeRange( start, end ); + iDeleteColIds.Reset(); + + iIsDeleting = ETrue; + + iController.GetActiveCollectionidsL(iDeleteColIds); + + //remember the calenders, delete entries in each calendar one by one by calling DeleteL(...) after completed() + iNumberOfCalendars = iDeleteColIds.Count(); + iToShowDeleteNote = 0; + iGlobalData->EntryViewL(iDeleteColIds[iToShowDeleteNote])->DeleteL( *iDelAllRange, CalCommon::EIncludeAll, *this ); + + TRACE_EXIT_POINT; + } + +// ---------------------------------------------------------------------------- +// CCalenDeleteUi::Completed +// Completed callback +// (other items were commented in a header). +// ---------------------------------------------------------------------------- +// +void CCalenDeleteUi::Completed( TInt aFirstPassError ) + { + TRACE_ENTRY_POINT; + + PIM_TRAPD_HANDLE( DoCompletedL( aFirstPassError ) ); + + TRACE_EXIT_POINT; + } + +// ---------------------------------------------------------------------------- +// CCalenDeleteUi::DoCompletedL +// Handles delete callback +// (other items were commented in a header). +// ---------------------------------------------------------------------------- +// +void CCalenDeleteUi::DoCompletedL( TInt aFirstPassError ) + { + TRACE_ENTRY_POINT; + iToShowDeleteNote++; + if(iNumberOfCalendars == iToShowDeleteNote) + { + if( aFirstPassError == KErrNone ) + { + // 2: Second pass, delete notes that end 00:00 of next day of iEndTime + // We didn't delete them in first pass + TTime nextMidnight = CalenDateUtils::BeginningOfDay( iEndTime + TTimeIntervalDays( 1 ) ); + nextMidnight = Min( nextMidnight, TCalTime::MaxTime() ); + PIM_TRAPD_HANDLE( DeleteEntriesEndingAtMidnightL( nextMidnight ) ); + } + + // 3. End deleting, close wait dialog, and show confirmation or error note + iIsDeleting = EFalse; + iToShowDeleteNote = 0; + // dismiss the waitdialog + if(iWaitDialog) + { + TRAP_IGNORE(iWaitDialog->ProcessFinishedL()); + } + + if( aFirstPassError == KErrNone ) + { + // Show confirmation note + HBufC* buf = StringLoader::LoadLC( iConfirmationNoteId, iEikEnv ); + CAknConfirmationNote* dialog = new( ELeave ) CAknConfirmationNote(); + dialog->ExecuteLD(*buf); + CleanupStack::PopAndDestroy( buf ); + } + else + { + // Show error note + if(iEikEnv) + { + iEikEnv->ResolveError( aFirstPassError ); + } + } + iDeleteColIds.Reset(); + delete iDelAllRange; + iDelAllRange = NULL; + + iController.BroadcastNotification( ECalenNotifyMultipleEntriesDeleted ); + } + else + { + //delete entries in next calendar... + iGlobalData->EntryViewL(iDeleteColIds[iToShowDeleteNote])->DeleteL( *iDelAllRange, CalCommon::EIncludeAll, *this ); + } + + TRACE_EXIT_POINT; + } + +// ---------------------------------------------------------------------------- +// CCalenDeleteUi::NotifyProgress +// Delete progress notification +// (other items were commented in a header). +// ---------------------------------------------------------------------------- +// +TBool CCalenDeleteUi::NotifyProgress() + { + TRACE_ENTRY_POINT; + // Tell framework that we are not intrested in Progress notifications. + TRACE_EXIT_POINT; + return EFalse; + } + +// ---------------------------------------------------------------------------- +// CCalenDeleteUi::Progress +// Delete progress notification +// (other items were commented in a header). +// ---------------------------------------------------------------------------- +// +void CCalenDeleteUi::Progress( TInt /*aPercentageCompleted*/ ) + { + TRACE_ENTRY_POINT; + // do nothing, we are not intrested in Progress notifications + TRACE_EXIT_POINT; + } + +// ---------------------------------------------------------------------------- +// CCalenDeleteUi::DeleteEntriesEndingAtMidnightL +// Deletes entries ending at midnight on the given day +// (other items were commented in a header). +// ---------------------------------------------------------------------------- +// +void CCalenDeleteUi::DeleteEntriesEndingAtMidnightL( TTime aMidnight ) + { + TRACE_ENTRY_POINT; + + TCalTime start, end; + start.SetTimeLocalL( aMidnight - TTimeIntervalMinutes(1) ); + end.SetTimeLocalL( aMidnight ); + CalCommon::TCalTimeRange midnightRange( start, end ); + + RArray colIdArray; + iController.GetActiveCollectionidsL(colIdArray); + + // 1: Find instances falling on midnight moment + RPointerArray< CCalInstance > instances; + CleanupResetAndDestroyPushL( instances ); + iGlobalData->InstanceViewL(colIdArray)->FindInstanceL( instances, + CalCommon::EIncludeAll, + midnightRange ); + + colIdArray.Reset(); + + // 2. loop through them and delete those entries that end at midnight + for( TInt i=0; i < instances.Count(); ++i ) + { + CCalInstance* item = instances[i]; + RArray colIdArray; + colIdArray.AppendL(item->InstanceIdL().iCollectionId); + + // Checking that if entry ends at midnight, is quite clumsy, but here goes: + // EndsAtStartOfDay takes only CCalInstance, but here we mimic EndsAtStartOfDay + // for CCalEntry type. + + // First check that if _instance_ ends at midnight, but starts earlier + if( CalenAgendaUtils::EndsAtStartOfDayL( item, aMidnight ) ) + { + // Second, check that _entry's_ endtime is exactly the midnight + // This prevents us from destroying repeating entries, that has one + // instance falling on given midnight. + if( item->Entry().EndTimeL().TimeLocalL() == aMidnight ) + { + iGlobalData->InstanceViewL(colIdArray)->DeleteL( item, CalCommon::EThisOnly ); + // Ownership was transferred to DeleteL. + // Put null to array to prevent double-deletion + instances[i] = NULL; + } + } + colIdArray.Reset(); + } + CleanupStack::PopAndDestroy( &instances ); + + TRACE_EXIT_POINT; + } + +// ----------------------------------------------------------------------------- +// CCalenDeleteUi::DeleteSingleInstanceL +// Delete the given instance. Ask the user whether to delete the series or the instance. +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +TBool CCalenDeleteUi::DeleteSingleInstanceL( CCalInstance* aInstance ) + { + TRACE_ENTRY_POINT; + TRACE_EXIT_POINT; + return DoDeleteSingleInstanceL( aInstance, EFalse, CalCommon::EThisAndAll ); + } + +// ----------------------------------------------------------------------------- +// CCalenDeleteUi::DeleteSingleInstanceL +// Delete the given instance. Delete the entry range given by aRepeatType. +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +TBool CCalenDeleteUi::DeleteSingleInstanceL( CCalInstance* aInstance, + CalCommon::TRecurrenceRange aRepeatType ) + { + TRACE_ENTRY_POINT; + TRACE_EXIT_POINT; + return DoDeleteSingleInstanceL( aInstance, ETrue, aRepeatType ); + } + +// ----------------------------------------------------------------------------- +// CCalenDeleteUi::DoDeleteSingleInstanceL +// Performs the deletion of the instance. If aHasRepeatType is EFalse, the user +// is prompted to delete either the instance or the entire series. In this case, +// aRepeatType is ignored. If aHasRepeatType is ETrue, aRepeatType determines +// whether to delete the instance or the entire series. +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +TBool CCalenDeleteUi::DoDeleteSingleInstanceL( CCalInstance* aInstance, + TBool aHasRepeatType, + CalCommon::TRecurrenceRange aRepeatType ) + { + TRACE_ENTRY_POINT; + + CCalEntry& entry = aInstance->Entry(); + const CCalEntry::TType entryType = entry.EntryTypeL(); + RArray colIdArray; + colIdArray.AppendL(aInstance->InstanceIdL().iCollectionId); + + + TCalRRule rrule; + + TBool repeating = entry.GetRRuleL( rrule ); + + if( !repeating ) + { + // Even though there is no RRule, the entry might + // have a list of rdates. + RArray< TCalTime > rDateArray; + CleanupClosePushL( rDateArray ); + entry.GetRDatesL( rDateArray ); + repeating = ( rDateArray.Count() > 0 ); + CleanupStack::PopAndDestroy(); // rDateArray + } + + const TBool child = entry.RecurrenceIdL().TimeUtcL() != Time::NullTTime(); + + if( !aHasRepeatType ) + { + aRepeatType = CalCommon::EThisAndAll; + } + + TBool doDelete( ETrue ); + + if( !aHasRepeatType && ( child || repeating ) && ( entryType != CCalEntry::EAnniv ) ) + { + doDelete = CalenActionUiUtils::ShowRepeatTypeQueryL( aRepeatType, + CalenActionUiUtils::EDelete ); + } + else + { + doDelete = CalenActionUiUtils::ShowDeleteConfirmationQueryL( + entryType == CCalEntry::ETodo ? + CalenActionUiUtils::EDeleteToDo : + CalenActionUiUtils::EDeleteEntry ); + } + + if( doDelete ) + { + if( !TryDeleteWithMrUtilsL( aInstance, aRepeatType ) ) + { + if( !child || aRepeatType == CalCommon::EThisOnly ) + { + iGlobalData->InstanceViewL(colIdArray)->DeleteL( aInstance, aRepeatType ); + } + else if( aRepeatType == CalCommon::EThisAndAll ) + { + // Unfortunately we can't pass the existing child instance through to the + // InstanceView DeleteL function because even if we pass in EThisAndAll, it + // only ever deletes the exception. We'll have to fetch the parent then + // delete it via the entry view. + RPointerArray entries; + CleanupResetAndDestroyPushL( entries ); + iGlobalData->EntryViewL(aInstance->InstanceIdL().iCollectionId)->FetchL( aInstance->Entry().UidL(), entries ); + iGlobalData->EntryViewL(aInstance->InstanceIdL().iCollectionId)->DeleteL( *entries[0] ); + CleanupStack::PopAndDestroy( &entries ); + if( aInstance ) + { + delete aInstance; + aInstance = NULL; + } + } + else + { + User::Leave( KErrNotSupported ); + } + } + } + + colIdArray.Reset(); + TRACE_EXIT_POINT; + return doDelete; + } + +// ----------------------------------------------------------------------------- +// CCalenDeleteUi::DeleteEntryL +// Deletes an entry from the database +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +TBool CCalenDeleteUi::DeleteEntryL( CCalEntryView* aEntryView, CCalEntry* aEntry ) + { + TRACE_ENTRY_POINT; + const CCalEntry::TType entryType = aEntry->EntryTypeL(); + + TBool doDelete = CalenActionUiUtils::ShowDeleteConfirmationQueryL( + entryType == CCalEntry::ETodo ? + CalenActionUiUtils::EDeleteToDo : + CalenActionUiUtils::EDeleteEntry ); + if( doDelete ) + { + aEntryView->DeleteL( *aEntry ); + + if( aEntry ) + { + delete aEntry; + aEntry = NULL; + } + } + + TRACE_EXIT_POINT; + return doDelete; + } + +// ----------------------------------------------------------------------------- +// CCalenDeleteUi::TryDeleteWithMrUtilsL +// Attempt to delete the instance using the Meeting Request utilities, +// if MR viewers is enabled. +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +TBool CCalenDeleteUi::TryDeleteWithMrUtilsL( CCalInstance* aInstance, + CalCommon::TRecurrenceRange aRepeatType ) + { + TRACE_ENTRY_POINT; + + TBool doDelete = ETrue; + + if( iGlobalData->InterimUtilsL().MRViewersEnabledL() && + iGlobalData->InterimUtilsL().IsMeetingRequestL(aInstance->Entry())) + + { + CMRMailboxUtils::TMailboxInfo info; + if( iGlobalData->AttemptToRetrieveDefaultMailboxL( info ) ) + { + if(aRepeatType == CalCommon::EThisAndAll ) + { + iGlobalData->MeetingRequestUtilsL().DeleteWithUiL( aInstance->Entry(), + info.iEntryId ); + if( aInstance ) + { + delete aInstance; + aInstance = NULL; + } + } + else if( aRepeatType == CalCommon::EThisOnly ) + { + iGlobalData->MeetingRequestUtilsL().DeleteWithUiL( aInstance, info.iEntryId ); + } + else + { + User::Leave( KErrNotSupported ); + } + } + else + { + doDelete = EFalse; + } + } + else + { + doDelete = EFalse; + } + + TRACE_EXIT_POINT; + return doDelete; + } + +// ----------------------------------------------------------------------------- +// CCalenDeleteUi::ShowMultipleEntriesDeleteQueryL +// For displaying multiple entries deletion confirmation query +// ----------------------------------------------------------------------------- +// +TInt CCalenDeleteUi::ShowMultipleEntriesDeleteQueryL(TInt aCount) + { + TRACE_ENTRY_POINT; + + CAknQueryDialog *dialog = CAknQueryDialog::NewL( ); + CleanupStack::PushL( dialog ); + TInt resID; + HBufC* prompt; + if( aCount > 1 ) + { + resID = R_CALEN_QTN_TODO_QUEST_DELETE_MARKED_NOTES; + prompt = StringLoader::LoadLC( resID, aCount ); + } + else if( aCount == 1 ) + { + resID = R_CALEN_QTN_TODO_QUEST_DELETE_MARKED_NOTE; + prompt = StringLoader::LoadLC( resID ); + } + else + { + CleanupStack::PopAndDestroy( dialog ); + TRACE_EXIT_POINT; + return 0; //return 0 for other invalid aCount value ( < 0 ) + } + dialog->SetPromptL( *prompt ); + CleanupStack::PopAndDestroy( prompt ); + + CleanupStack::Pop( dialog ); + + TRACE_EXIT_POINT; + return dialog->ExecuteLD( R_CALEN_ERASEQUERY_NOTE ); + + } + +// ----------------------------------------------------------------------------- +// CCalenDeleteUi::DialogDismissedL +// From MProgressDialogCallback +// Callback method +// called when a dialog is dismissed. +// ----------------------------------------------------------------------------- +// +void CCalenDeleteUi::DialogDismissedL( const TInt /*aButtonId*/ ) + { + TRACE_ENTRY_POINT; + // dismiss the wait dialog + if(iWaitDialog) + { + iWaitDialog->ProcessFinishedL(); + } + + // no more entries to delete + iMoreEntriesToDelete = EFalse; + iDisplayQuery = EFalse; + + // issue notification cancel delete + iController.BroadcastNotification(ECalenNotifyCancelDelete); + TRACE_EXIT_POINT; + } + +// ----------------------------------------------------------------------------- +// CCalenDeleteUi::DeleteEntryL +// Delete entry using entry local uid +// ----------------------------------------------------------------------------- +// +void CCalenDeleteUi::DeleteEntryL(TCalLocalUid& aEntryLocalUid, TInt aColId) + { + TRACE_ENTRY_POINT; + + // fetch the entry + CCalEntry* entry = iGlobalData->EntryViewL(aColId)->FetchL(aEntryLocalUid); + if( entry ) + { + CleanupStack::PushL( entry ); + iGlobalData->EntryViewL(aColId)->DeleteL( *entry ); + CleanupStack::Pop( entry ); + delete entry; + entry = NULL; + } + + TRACE_EXIT_POINT; + } + +// ----------------------------------------------------------------------------- +// CCalenDeleteUi::DisplayWaitDialogL +// Display wait dialog +// ----------------------------------------------------------------------------- +// +void CCalenDeleteUi::DisplayWaitDialogL() + { + TRACE_ENTRY_POINT; + + delete iWaitDialog; + iWaitDialog = NULL; + iWaitDialog = new( ELeave )CAknWaitDialog( REINTERPRET_CAST( CEikDialog**, &iWaitDialog ), ETrue ); + iWaitDialog->ExecuteLD( R_TODO_VIEW_DELETE_WAIT_NOTE ); + iWaitDialog->SetCallback(this); + + TRACE_EXIT_POINT; + } + +// ----------------------------------------------------------------------------- +// CCalenDeleteUi::MarkedEntriesDeletedL +// Dismiss wait dialog and show information note +// ----------------------------------------------------------------------------- +// +void CCalenDeleteUi::MarkedEntriesDeletedL() + { + TRACE_ENTRY_POINT; + + // dismiss the waitdialog + if(iWaitDialog) + { + iWaitDialog->ProcessFinishedL(); + } + + // Show confirmation note + //HBufC* buf = StringLoader::LoadLC( R_QTN_CALE_CONF_ALL_NOTES_DELETED, iEikEnv ); + //CAknConfirmationNote* dialog = new( ELeave ) CAknConfirmationNote(); + //dialog->ExecuteLD(*buf); + //CleanupStack::PopAndDestroy( buf ); + + // notify marked entries deleted + iController.BroadcastNotification( ECalenNotifyMarkedEntryDeleted ); + + TRACE_EXIT_POINT; + } + +// ----------------------------------------------------------------------------- +// CCalenDeleteUi::HandleDeleteAllEntriesL +// Handles launching of the delete all entries list query +// ----------------------------------------------------------------------------- +// +void CCalenDeleteUi::HandleDeleteAllEntriesL() + { + TRACE_ENTRY_POINT; + RPointerArray calendarInfoList; + CleanupClosePushL(calendarInfoList); + iController.Services().GetAllCalendarInfoL(calendarInfoList); + TInt visibleCalendarsCount(0); + for(TInt index=0;indexEnabled()) + { + visibleCalendarsCount++; + } + if(visibleCalendarsCount>1) + { + break; + } + } + CleanupStack::PopAndDestroy(); + + TInt headingTextResourceId(0); + if(visibleCalendarsCount==1) + { + headingTextResourceId = R_CALE_SINGLE_CALENDAR_DELETE_ENTRIES; + } + else + { + headingTextResourceId = R_CALE_MULTI_CALENDAR_DELETE_ENTRIES; + } + + TInt selectedIndex(0); + CAknListQueryDialog* deleteEntriesListDialog = new(ELeave) CAknListQueryDialog(&selectedIndex); + deleteEntriesListDialog->PrepareLC(R_DELETE_ENTRIES_LIST_QUERY); + HBufC* buf = StringLoader::LoadLC( headingTextResourceId, iEikEnv ); + deleteEntriesListDialog->QueryHeading()->SetTextL(buf->Des()); + CleanupStack::PopAndDestroy( buf ); + + if(deleteEntriesListDialog->RunLD()) + { + if(selectedIndex) + { + DeleteAllEntriesL(); + } + else + { + DeleteEntriesBeforeDateL(); + } + } + else + { + iController.BroadcastNotification(ECalenNotifyDeleteFailed); + } + + TRACE_EXIT_POINT + } + +// End of File