calendarui/controller/src/calendeleteui.cpp
changeset 0 f979ecb2b13e
child 18 c198609911f9
child 20 21239b3bcd78
--- /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 <Calendar.rsg>
+#include <calendateutils.h>
+#include <calenagendautils.h>
+#include <aknnotewrappers.h>
+#include <AknWaitDialog.h>
+#include <calcommon.h>
+#include <calentryview.h>
+#include <calinstance.h>
+#include <calinstanceview.h>
+#include <caltime.h>
+#include <centralrepository.h>
+#include <eikenv.h>
+#include <StringLoader.h>
+#include <sysutil.h>
+#include <calenglobaldata.h>
+#include <calrrule.h>
+#include <calsession.h>
+#include <calencommands.hrh>            // Calendar commands
+#include <calencontext.h>
+#include <caleninstanceid.h>            // TCalenInstanceId
+#include <calenactionuiutils.h>
+#include <calcalendarinfo.h>
+
+#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<TInt> 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<TInt> 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<TInt> 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<TInt> 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<TCalenInstanceId>& 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(index<iEntriesToDelete)
+			    {
+			    // get the local uid of the entry through multiple context list
+			    TCalLocalUid entryLocalUid = multipleContextIds[0].iEntryLocalUid;			    
+			    if(entryLocalUid)
+			        {
+			        DeleteEntryL(entryLocalUid, multipleContextIds[0].iColId);
+			        }
+			    // remove mutliple context based on the instanceid
+			    context.RemoveMultipleContextId(multipleContextIds[0]);
+			    index++;
+			   }
+
+			if(!iMoreEntriesToDelete)
+			    {
+			    MarkedEntriesDeletedL();    
+			    }
+			}
+        else
+            {
+            context.ResetMultipleContextIds();
+            // notify delete failed
+            iController.BroadcastNotification(ECalenNotifyDeleteFailed);    
+            }
+	
+    TRACE_EXIT_POINT;
+    return continueCommand;
+    }
+
+// ----------------------------------------------------------------------------
+// CCalenDeleteUi::DeleteCurrentEntryL
+// Deletes the current entry
+// (other items were commented in a header).
+// ----------------------------------------------------------------------------
+//
+void CCalenDeleteUi::DeleteCurrentEntryL()
+    {
+    TRACE_ENTRY_POINT;
+
+    TBool deleted( EFalse );
+    TCalenNotification notification = ECalenNotifyDeleteFailed;
+    
+    // Make sure we're focused on an entry.
+    if( iGlobalData->Context().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<TInt> 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<TInt> 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<TInt> 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<TInt> 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<CCalEntry> 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<CCalCalendarInfo> calendarInfoList;
+    CleanupClosePushL(calendarInfoList);
+	iController.Services().GetAllCalendarInfoL(calendarInfoList);
+    TInt visibleCalendarsCount(0);
+    for(TInt index=0;index<calendarInfoList.Count();index++)
+        {
+        if(calendarInfoList[index]->Enabled())
+            {
+            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