agendainterface/agendautil/src/agendautil_p.cpp
changeset 49 5de72ea7a065
parent 37 360d55486d7f
child 50 579cc610882e
--- a/agendainterface/agendautil/src/agendautil_p.cpp	Fri Jun 11 13:37:54 2010 +0300
+++ b/agendainterface/agendautil/src/agendautil_p.cpp	Wed Jun 23 18:11:28 2010 +0300
@@ -20,6 +20,7 @@
 #include <calsession.h>
 #include <calinstance.h>
 #include <CalenImporter>
+#include <CalenInterimUtils2>
 #include <calentry.h>
 #include <calrrule.h>
 #include <e32math.h>
@@ -34,6 +35,7 @@
 #include "agendautil_p.h"
 #include "agendaentry.h"
 #include "agendaentry_p.h"
+#include "CleanupResetAndDestroy.h"
 
 // Constants
 //recognition string for ical
@@ -134,6 +136,8 @@
 void AgendaUtilPrivate::Completed(TInt aError)
 {
 	iError = aError;
+	static bool isInstanceViewDeleted = false;
+	static bool isEntryViewDeleted = false;
 
 	if (mIsDeleting) {
 		// If deletion was in progress, then it is completed now
@@ -144,11 +148,13 @@
 
 	if (KErrNone != iError) {
 		// Something has gone wrong, return
-		if (iCalEntryView) {
+		if (iCalEntryView && !isEntryViewDeleted) {
+		isEntryViewDeleted = true;
 		delete iCalEntryView;
 		iCalEntryView = NULL;
 		}
-		if (iCalInstanceView) {
+		if (iCalInstanceView && !isInstanceViewDeleted) {
+		isInstanceViewDeleted = true;
 		delete iCalInstanceView;
 		iCalInstanceView = NULL;
 		}
@@ -206,15 +212,13 @@
 				iError,
 
 				RPointerArray<CCalEntry> entryArray;
-				CleanupClosePushL(entryArray);
+                CleanupResetAndDestroyPushL(entryArray);
 
 				// Get the global uid.
-				TTime homeTime;
-				homeTime.HomeTime();
-				TInt64 seed = homeTime.Int64();
-				TInt randumNumber = Math::Rand(seed);
-				HBufC8* globalUid = HBufC8::NewLC(KGuidLength);
-				globalUid->Des().Num(randumNumber);
+				CCalenInterimUtils2* calenInterimUtils2 = CCalenInterimUtils2::NewL();
+				HBufC8* globalUid = calenInterimUtils2->GlobalUidL();
+				CleanupStack::PushL(globalUid);
+				delete calenInterimUtils2;
 
 				// Construct a CCalEntry object and start filling the details.
 				CCalEntry* newEntry = 0;
@@ -225,7 +229,6 @@
 						0);
 
 				CleanupStack::Pop(globalUid);
-				CleanupStack::PushL(newEntry);
 
 				// Add description.
 				TPtrC description(reinterpret_cast<const TUint16*>(
@@ -265,7 +268,6 @@
 				localUid = newEntry->LocalUidL();
 
 				// Cleanup.
-				CleanupStack::PopAndDestroy(newEntry);
 				CleanupStack::PopAndDestroy(&entryArray);
 		)
 	} else {
@@ -273,7 +275,7 @@
 				iError,
 
 				RPointerArray<CCalEntry> entryArray;
-				CleanupClosePushL(entryArray);
+                CleanupResetAndDestroyPushL(entryArray);
 
 				// Get the global uid.
 				TTime homeTime;
@@ -292,7 +294,6 @@
 						0);
 
 				CleanupStack::Pop(globalUid);
-				CleanupStack::PushL(newEntry);
 
 				// Add the summary.
 				if (!entry.summary().isNull()) {
@@ -391,7 +392,6 @@
 				localUid = newEntry->LocalUidL();
 
 				// Cleanup.
-				CleanupStack::PopAndDestroy(newEntry);
 				CleanupStack::PopAndDestroy(&entryArray);
 		)
 	}
@@ -458,7 +458,7 @@
 				iError,
 
 				RPointerArray<CCalEntry> entryArray;
-				CleanupClosePushL(entryArray);
+                CleanupResetAndDestroyPushL(entryArray);
 
 				// Construct a CCalEntry object and start filling the details.
 				CCalEntry* newEntry = 0;
@@ -467,7 +467,6 @@
 						globalUid,
 						static_cast<CCalEntry::TMethod>(entry.method()),
 						0);
-				CleanupStack::PushL(newEntry);
 
 				// Add description.
 				TPtrC description(reinterpret_cast<const TUint16*>(
@@ -483,7 +482,6 @@
 				localUid = newEntry->LocalUidL();
 
 				// Cleanup.
-				CleanupStack::PopAndDestroy(newEntry);
 				CleanupStack::PopAndDestroy(&entryArray);
 		)
 	} else {
@@ -491,7 +489,7 @@
 				iError,
 
 				RPointerArray<CCalEntry> entryArray;
-				CleanupClosePushL(entryArray);
+                CleanupResetAndDestroyPushL(entryArray);
 
 				// Construct a CCalEntry object and start filling the details.
 				CCalEntry* newEntry = 0;
@@ -500,7 +498,6 @@
 						globalUid,
 						static_cast<CCalEntry::TMethod>(entry.method()),
 						0);
-				CleanupStack::PushL(newEntry);
 
 				// Add the summary.
 				if (!entry.summary().isNull()) {
@@ -599,7 +596,6 @@
 				localUid = newEntry->LocalUidL();
 
 				// Cleanup.
-				CleanupStack::PopAndDestroy(newEntry);
 				CleanupStack::PopAndDestroy(&entryArray);
 		)
 	}
@@ -684,18 +680,12 @@
 				// the exceptional entries share the global uid with the parent
 				// entry.
 				RPointerArray<CCalEntry> entries;
-				CleanupClosePushL(entries);
+				CleanupResetAndDestroyPushL(entries);
 				iCalEntryView->FetchL(calEntry->UidL(), entries);
 				if (entries.Count()) {
 				    iCalEntryView->DeleteL(*entries[0]);
 				}
 
-				// Cleanup.
-				int count = entries.Count();
-				for (int i = count - 1; i >= 0; --i) {
-					CCalEntry *entry = entries[i];
-					delete entry;
-				}
 				CleanupStack::PopAndDestroy(&entries);
 				CleanupStack::PopAndDestroy();
 			}
@@ -733,7 +723,6 @@
 				// Get the entry corresponding to the id.
 				AgendaEntry storedEntry = fetchById(entry.id());
 				CCalEntry* calEntry = iCalEntryView->FetchL(entry.id());
-				CleanupStack::PushL(calEntry);
 
 				// Update the description.
 				if (storedEntry.description() != entry.description()
@@ -787,12 +776,12 @@
 
 				// Update the entry using the CCalEntryView.
 				RPointerArray<CCalEntry> entryArray;
-				CleanupClosePushL(entryArray);
+				CleanupResetAndDestroyPushL(entryArray);
 				entryArray.AppendL(calEntry);
 				iCalEntryView->UpdateL(entryArray, success);
 
 				// Cleanup.
-				CleanupStack::PopAndDestroy(2, calEntry);
+				CleanupStack::PopAndDestroy( &entryArray );
 		)
 	} else {
 		TRAP(
@@ -801,22 +790,18 @@
 				// Get the entry corresponding to the id.
 				AgendaEntry storedEntry = fetchById(entry.id());
 				CCalEntry* calEntry = iCalEntryView->FetchL(entry.id());
-				CleanupStack::PushL(calEntry);
 
 				// Update the attendees.
 				if (!entry.isNull()
 						&& (entry.d->m_attendees != storedEntry.attendees())) {
 
-					RPointerArray<CCalAttendee> attendeesArray =
+					RPointerArray<CCalAttendee>& attendeesArray =
 							calEntry->AttendeesL();
-					CleanupClosePushL(attendeesArray);
 					int iterator = 0;
 					while (attendeesArray.Count() > iterator) {
 						calEntry->DeleteAttendeeL(iterator);
 						iterator++;
 					}
-					// Cleanup.
-					CleanupStack::PopAndDestroy(&attendeesArray);
 
 					addAttendeesToEntry(entry.d->m_attendees, *calEntry);
 				}
@@ -826,14 +811,11 @@
 
 					RPointerArray<CCalCategory> categories =
 							calEntry->CategoryListL();
-					CleanupClosePushL(categories);
 					int iterator = 0;
 					while (categories.Count() > iterator) {
 						calEntry->DeleteCategoryL(iterator);
 						iterator++;
 					}
-					// Cleanup.
-					CleanupStack::PopAndDestroy(&categories);
 
 					addCategoriesToEntry(entry.d->m_categories, *calEntry);
 				}
@@ -942,7 +924,7 @@
 				
 				// Save the geo value if any
 				AgendaGeoValue entryGeoValue = entry.geoValue();
-				if (!entryGeoValue.isNull()) {
+				if (!entryGeoValue.isNull() && (entryGeoValue != storedEntry.geoValue())) {
 					CCalGeoValue* geoValue = CCalGeoValue::NewL();
 					double latitude;
 					double longitude;
@@ -954,11 +936,14 @@
 					// set it to CCalentry
 					calEntry->SetGeoValueL(*geoValue);
 					delete geoValue;
+				} else if (entryGeoValue.isNull()) {
+                    // Clear the geo values if any
+                    calEntry->ClearGeoValueL();
 				}
 								
 				// Update the entry using the calen entry view.
 				RPointerArray<CCalEntry> entryArray;
-				CleanupClosePushL(entryArray);
+				CleanupResetAndDestroyPushL(entryArray);
 				entryArray.AppendL(calEntry);
 				if (!isChild) {
 					iCalEntryView->UpdateL(entryArray, success);
@@ -966,7 +951,7 @@
 					iCalEntryView->StoreL(entryArray, success);
 				}
 				// Cleanup.
-				CleanupStack::PopAndDestroy(2, calEntry);
+				CleanupStack::PopAndDestroy( &entryArray );
 		)
 	}
 
@@ -1002,9 +987,10 @@
 	if (instance) {
 		// Get all the entries with same global Uid.
 		RPointerArray<CCalEntry> entries;
-		CleanupClosePushL(entries);
+		CleanupResetAndDestroyPushL(entries);
 		iCalEntryView->FetchL(instance->UidL(), entries);
 		calEntry = entries[0];
+		entries.Remove(0);
 		CleanupStack::PopAndDestroy(&entries);
 	} else {
 		CleanupStack::PopAndDestroy(instance);
@@ -1040,7 +1026,7 @@
 	// Entry is not a child, but does it have any children?
 	// Fetch array of entries associated with this UID.
 	RPointerArray<CCalEntry> oldEntries;
-	CleanupClosePushL(oldEntries);
+	CleanupResetAndDestroyPushL(oldEntries);
 	iCalEntryView->FetchL(calEntry->UidL(), oldEntries);
 	bool hasChildren = oldEntries.Count() > 0;
 	
@@ -1070,6 +1056,9 @@
 		// set it to CCalentry
 		calEntry->SetGeoValueL(*geoValue);
 		delete geoValue;
+	} else {
+        // Clear the geo values
+        calEntry->ClearGeoValueL();
 	}
 	
 	// set the description
@@ -1147,9 +1136,9 @@
 	return success;    
 }
 
-bool AgendaUtilPrivate::createException(const AgendaEntry& entry)
-{
-
+bool AgendaUtilPrivate::createException(const AgendaEntry& entry, 
+										QDateTime instanceOriginalDateTime)
+{ 
 	// First prepare the session with agenda server.
 	if (!mInstanceViewCreated) {
 		// Something went wrong.
@@ -1174,7 +1163,12 @@
 				HBufC8* guid = calEntry->UidL().AllocLC();
 				// create new (child) entry
 				// Use original instance time for recurrenceID as this entry hasn't got one.
-				TCalTime originalCalTime = calEntry->StartTimeL();
+				TCalTime originalCalTime;
+				TDateTime originalDateTime(instanceOriginalDateTime.date().year(),
+							TMonth(instanceOriginalDateTime.date().month() - 1),
+							instanceOriginalDateTime.date().day() -1, 0, 0, 0, 0);
+				TTime originalDateTimeTTime(originalDateTime);
+				originalCalTime.SetTimeLocalL(originalDateTimeTTime);
 				// create the new child now
 				CCalEntry* newEntry = CCalEntry::NewL( calEntry->EntryTypeL(), 
 													   guid,
@@ -1185,7 +1179,6 @@
 				
 				CleanupStack::Pop(guid);
 				CleanupStack::PopAndDestroy(calEntry);
-				CleanupStack::PushL(newEntry);
 
 				// Update the description.
 				if (!entry.description().isNull()) {
@@ -1222,13 +1215,13 @@
 
 				// Update the entry using the CCalEntryView.
 				RPointerArray<CCalEntry> entryArray;
-				CleanupClosePushL(entryArray);
+				CleanupResetAndDestroyPushL(entryArray);
 				entryArray.AppendL(newEntry);
 				iCalEntryView->StoreL(entryArray, success);
 
 				localUid = newEntry->LocalUidL();
 				// Cleanup.
-				CleanupStack::PopAndDestroy(2, newEntry);
+				CleanupStack::PopAndDestroy(&entryArray);
 		)
 	} else {
 		TRAP(
@@ -1240,7 +1233,12 @@
 				HBufC8* guid = calEntry->UidL().AllocLC();
 				// create new (child) entry
 				// Use original instance time for recurrenceID as this entry hasn't got one.
-				TCalTime originalCalTime = calEntry->StartTimeL();
+				TCalTime originalCalTime;
+				TDateTime originalDateTime(instanceOriginalDateTime.date().year(),
+							TMonth(instanceOriginalDateTime.date().month() - 1),
+							instanceOriginalDateTime.date().day() -1, 0, 0, 0, 0);
+				TTime originalDateTimeTTime(originalDateTime);
+				originalCalTime.SetTimeLocalL(originalDateTimeTTime);
 				// create the new child now
 				CCalEntry* newEntry = CCalEntry::NewL( calEntry->EntryTypeL(), 
 													   guid,
@@ -1251,7 +1249,6 @@
 				
 				CleanupStack::Pop(guid);
 				CleanupStack::PopAndDestroy(calEntry);
-				CleanupStack::PushL(newEntry);
 				// Store the attendees.
 				if (!entry.isNull()) {
 					addAttendeesToEntry(entry.d->m_attendees, *newEntry);
@@ -1359,14 +1356,13 @@
 				newEntry->ClearRepeatingPropertiesL();
 				// Update the entry using the calen entry view.
 				RPointerArray<CCalEntry> entryArray;
-				CleanupClosePushL(entryArray);
+				CleanupResetAndDestroyPushL(entryArray);
 				entryArray.AppendL(newEntry);
 				iCalEntryView->StoreL(entryArray, success);
 				
 				localUid = newEntry->LocalUidL();
 				// Cleanup.
 				CleanupStack::PopAndDestroy(&entryArray);
-				CleanupStack::PopAndDestroy(newEntry);
 		)
 	}
 
@@ -1433,7 +1429,7 @@
 			iError,
 
 			RPointerArray<CCalInstance> instanceList;
-			CleanupClosePushL(instanceList);
+            CleanupResetAndDestroyPushL(instanceList);
 			CalCommon::TCalViewFilter filters = filter;
 			TCalTime startDateForInstanceSearch;
 			TCalTime endDateForInstanceSearch;
@@ -1460,14 +1456,8 @@
 				listOfIds.append(instanceList[iter]->Entry().LocalUidL());
 			}
 
-			int count = instanceList.Count();
-			for (int iter = count - 1; iter >= 0; --iter) {
-				CCalInstance *instance = instanceList[iter];
-				delete instance;
-			}
-
 			// Cleanup.
-			CleanupStack::PopAndDestroy();
+			CleanupStack::PopAndDestroy(&instanceList);
 	)
 
 	return listOfIds;
@@ -1494,7 +1484,7 @@
 			iError,
 
 			RPointerArray<CCalInstance> instanceList;
-			CleanupClosePushL(instanceList);
+            CleanupResetAndDestroyPushL(instanceList);
 			CalCommon::TCalViewFilter filters = filter;
 			TCalTime startDateForInstanceSearch;
 			TCalTime endDateForInstanceSearch;
@@ -1525,14 +1515,8 @@
 								instanceList[iter]));
 			}
 
-			int count = instanceList.Count();
-			for (int iter = count - 1; iter >= 0; --iter) {
-				CCalInstance *instance = instanceList[iter];
-				delete instance;
-			}
-
 			// Cleanup.
-			CleanupStack::PopAndDestroy();
+			CleanupStack::PopAndDestroy(&instanceList);
 	)
 
 	return entryList;
@@ -1552,7 +1536,7 @@
     TRAP(iError,
 
         RPointerArray<CCalInstance> instanceList;
-        CleanupClosePushL(instanceList);
+        CleanupResetAndDestroyPushL(instanceList);
         CalCommon::TCalViewFilter filters = filter;
         TCalTime startDateForInstanceSearch;
         TCalTime endDateForInstanceSearch;
@@ -1585,12 +1569,7 @@
         {
             entryList.append(createAgendaEntryFromCalEntry(instanceList[i]->Entry(), instanceList[i]));
         }
-        int count = instanceList.Count();
-        for (int i = count - 1; i >= 0; --i) {
-            CCalInstance *instance = instanceList[i];
-            delete instance;
-        }
-        CleanupStack::PopAndDestroy();
+        CleanupStack::PopAndDestroy(&instanceList);
     )
 
     return entryList;
@@ -1606,7 +1585,7 @@
 	    return;
 	}
 	
-	CleanupClosePushL(instanceList);
+	CleanupResetAndDestroyPushL(instanceList);
 	CalCommon::TCalViewFilter filters = filter;
 	TCalTime startDateForInstanceSearch;
 	TCalTime endDateForInstanceSearch;
@@ -1634,7 +1613,7 @@
 			endDateForInstanceSearch);
 
 	iCalInstanceView->FindInstanceL(instanceList, filters, searchTimeRange);
-	
+
 	// Parse thru the list and mark the dates which have events
 	for (int i = 0; i < instanceList.Count(); i++) {
 		CCalEntry::TType type = instanceList[i]->Entry().EntryTypeL();
@@ -1642,39 +1621,48 @@
 		TCalTime startCalTime = instanceList[i]->StartTimeL();
 		TCalTime endCalTime = instanceList[i]->EndTimeL();
 		TDateTime startDateTime = startCalTime.TimeLocalL().DateTime();
-    TDateTime endDateTime = endCalTime.TimeLocalL().DateTime();
+		TDateTime endDateTime = endCalTime.TimeLocalL().DateTime();
 		QDate startDate(startDateTime.Year(), startDateTime.Month()+1,
 						startDateTime.Day() + 1);
-    QDate endDate(endDateTime.Year(), endDateTime.Month()+1,
-                    endDateTime.Day() + 1);
+        QDate endDate(endDateTime.Year(), endDateTime.Month()+1,
+                        endDateTime.Day() + 1);
 		if (type == CCalEntry::EEvent || type == CCalEntry::EAppt ||
 				type == CCalEntry::EReminder) {
 			if(endsAtStartOfDay(instanceList[i], endCalTime.TimeLocalL())) {
-				// instance ends at start of endtime day, month view doesnt 
-				// want to show event on this day
 				TDateTime endDateTime = endCalTime.TimeLocalL().DateTime();
+				// prevent problems with items ending tomorrow at 00:00
 				endDateTime.SetMinute(endDateTime.Minute() - 1);
 				TTime time(endDateTime);
+				// If it is ending before the start of the grid 
 				if (time <= startDateForInstanceSearch.TimeLocalL()) {
 					continue;
 				}
 			}
         // Mark the required dates frm start date to end date
         TTimeIntervalDays days ;
+        int numOfDays = 0;
         //check if the start date of the entry is before the start day of the grid
         if(startDate < rangeStart.date()){
             if(endDate<=rangeEnd.date()){
                 //if the end date of entry is lying in the grid ,
                 //then mark the entry from start day of the grid to the end date of the entry
                 days = endCalTime.TimeLocalL().DaysFrom(startDateForInstanceSearch.TimeLocalL());
+                numOfDays = days.Int();
             }
             else{
                 //if end date of the entry is greater then the last date of grid, 
                 //then mark all the date of the grid with the entry 
                 days = endDateForInstanceSearch.TimeLocalL().DaysFrom(startDateForInstanceSearch.TimeLocalL()) ;
+                numOfDays = days.Int();
             }
+            // Check if the event is all-day
+            if (instanceList[i]->Entry().EntryTypeL() == CCalEntry::EEvent) {
+                // no need to consider the date on which it ends
+                // reduce days count by 1
+                numOfDays--;
+                }
             //start the entries from the first day of the grid
-            for (int j = 0; j <= days.Int(); j++) {
+            for (int j = 0; j <= numOfDays; j++) {
                 QDate date = rangeStart.date().addDays(j);
                 if (date <= rangeEnd.date()) {
                     dates.append(date);
@@ -1689,13 +1677,21 @@
                 //if the end date of entry is lying in the grid ,
                 //then mark the entry from start date of the entry to the end date of the entry
                 days = endCalTime.TimeLocalL().DaysFrom(startCalTime.TimeLocalL()) ;
+                numOfDays = days.Int();
             }
             else{
                 //if end date of the entry is greater then the last date of grid, 
                 //then mark all the date from start date of the entry to the end date of the grid 
                 days = endDateForInstanceSearch.TimeLocalL().DaysFrom(startCalTime.TimeLocalL()) ;
+                numOfDays = days.Int();
             }
-            for (int j = 0; j <= days.Int(); j++) {
+            // Check if the event is all-day
+            if (instanceList[i]->Entry().EntryTypeL() == CCalEntry::EEvent) {
+                // no need to consider the date on which it ends
+                // reduce days count by 1
+                numOfDays--;
+                }
+            for (int j = 0; j <= numOfDays; j++) {
                 QDate date = startDate.addDays(j);
                 if (date <= rangeEnd.date()) {
                     dates.append(date);
@@ -1717,12 +1713,7 @@
             }
         }
     }
-	int count = instanceList.Count();
-	for (int i = count - 1; i >= 0; --i) {
-	            CCalInstance *instance = instanceList[i];
-	            delete instance;
-	        }
-    CleanupStack::PopAndDestroy();
+    CleanupStack::PopAndDestroy(&instanceList);
 }
 
 QList<AgendaEntry> AgendaUtilPrivate::createEntryIdListForDay( QDateTime day,
@@ -1738,7 +1729,7 @@
     TRAP(iError,
         getDayRange(day, day, dayRange);
         RPointerArray<CCalInstance> instanceList;
-        CleanupClosePushL(instanceList);
+        CleanupResetAndDestroyPushL(instanceList);
         CalCommon::TCalViewFilter filters = filter;
         // Check if the filter has todos also to be included
         if(filter & CalCommon::EIncludeIncompletedTodos)
@@ -1781,6 +1772,26 @@
             {
             iCalInstanceView->FindInstanceL(instanceList, filters, dayRange);
             }
+        
+        // In this list, check if any all day events are there
+        // As all day events end at 12.00AM of next day, we should not show it again on next day
+        TCalTime calTime;
+        TDateTime dateTime(
+                day.date().year(),
+                static_cast<TMonth>(day.date().month() - 1),
+                day.date().day() - 1, day.time().hour(),
+                day.time().minute(), 0, 0);
+        TTime time(dateTime);
+        for (int i(0); i < instanceList.Count(); i++) {
+            if ((endsAtStartOfDay(instanceList[i], time)) &&
+                    instanceList[i]->Entry().EntryTypeL() == CCalEntry::EEvent) {
+                // Previous day all-day event has been found, we are not supposed to
+                // show it on current day, hence remove it from the instance list
+                instanceList.Remove(i);
+                i--;
+            }
+        }
+        
         // Sort the list
         sortInstanceList(instanceList);
         for(TInt i = 0; i<instanceList.Count(); i++)
@@ -1788,12 +1799,7 @@
                 entryList.append(createAgendaEntryFromCalEntry(
                                     instanceList[i]->Entry(), instanceList[i]));
             }
-        int count = instanceList.Count();
-        for (int i = count - 1; i >= 0; --i) {
-            CCalInstance *instance = instanceList[i];
-            delete instance;
-        }
-        CleanupStack::PopAndDestroy();
+        CleanupStack::PopAndDestroy( &instanceList );
         )
 
     return entryList;
@@ -1925,18 +1931,16 @@
 
 			// Fetch the calentry
 			CCalEntry* calEntry = iCalEntryView->FetchL(entry.id());
-			CleanupStack::PushL(calEntry);
 			calEntry->SetCompletedL(complete, calTime);
 
 			// Update the entry in the Database
 			RPointerArray<CCalEntry> array;
-			CleanupClosePushL(array);
+			CleanupResetAndDestroyPushL(array);
 			array.AppendL(calEntry);
 			iCalEntryView->UpdateL(array, success);
 
 			// Cleanup.
-			CleanupStack::PopAndDestroy(&array);
-			CleanupStack::PopAndDestroy(calEntry);
+			CleanupStack::PopAndDestroy( &array );
 	)
 
 	if (0 < success) {
@@ -2008,7 +2012,7 @@
 			if (calEntry) {
 				// Get all the entries with same global Uid.
 				RPointerArray<CCalEntry> entries;
-				CleanupClosePushL(entries);
+				CleanupResetAndDestroyPushL(entries);
 				iCalEntryView->FetchL(calEntry->UidL(), entries);
 				parentEntry = createAgendaEntryFromCalEntry(*entries[0]);
 				CleanupStack::PopAndDestroy(&entries);
@@ -2036,7 +2040,7 @@
 	if (calEntry) {
 		// Get all the entries with same global Uid.
 		RPointerArray<CCalEntry> entries;
-		CleanupClosePushL(entries);
+		CleanupResetAndDestroyPushL(entries);
 		iCalEntryView->FetchL(calEntry->UidL(), entries);
 		entries[0]->ClearRepeatingPropertiesL();
 		CleanupStack::PopAndDestroy(&entries);
@@ -2055,7 +2059,7 @@
 												QDateTime& endTime)
 {
 	RPointerArray<CCalEntry> entries;
-	CleanupClosePushL(entries);
+	CleanupResetAndDestroyPushL(entries);
 	TCalTime previousStartTime;
 	TCalTime previousEndTime;
 	TTime zero(TInt64(0));
@@ -2172,6 +2176,16 @@
 			// Is currentInstanceDate before parent dt start?
 			if (currentInstanceDate.TimeLocalL() < 
 					entries[0]->StartTimeL().TimeLocalL()) {
+				TBool exceptionEntryBeforeParentStartPresent = EFalse;
+				for (TInt i=0; i<exdates.Count(); ++i) {
+					if( exdates[i].TimeLocalL() < currentInstanceDate.TimeLocalL() ) {
+						exceptionEntryBeforeParentStartPresent = ETrue;
+					}
+				}
+				if (!exceptionEntryBeforeParentStartPresent) {
+					currentInstanceDate.SetTimeLocalL(Time::NullTTime());
+					previousStartTime = currentInstanceDate;
+				}
 				// There are no instances before the exception
 				keepLooking = EFalse;
 			} else {
@@ -2214,22 +2228,23 @@
 		}
 		CleanupStack::PopAndDestroy(&exdates);
 	}
-	// Convert TCalTimes to QDateTimes
-	TDateTime prevStart = previousStartTime.TimeLocalL().DateTime();
-	TDateTime prevEnd = previousEndTime.TimeLocalL().DateTime();
-	startTime.setDate(QDate(prevStart.Year(), prevStart.Month()+1,
-					prevStart.Day() + 1));
-	startTime.setTime(QTime(prevStart.Hour(), prevStart.Minute(), 0, 0));
-	endTime.setDate(QDate(prevEnd.Year(), prevEnd.Month()+1,
-	                      prevEnd.Day() + 1));
-	endTime.setTime(QTime(prevEnd.Hour(), prevEnd.Minute(), 0, 0));
 	
+	if(previousStartTime.TimeUtcL() != Time::NullTTime()) {
+		// Convert TCalTimes to QDateTimes
+		TDateTime prevStart = previousStartTime.TimeLocalL().DateTime();
+		TDateTime prevEnd = previousEndTime.TimeLocalL().DateTime();
+		startTime.setDate(QDate(prevStart.Year(), prevStart.Month()+1,
+		                        prevStart.Day() + 1));
+		startTime.setTime(QTime(prevStart.Hour(), prevStart.Minute(), 0, 0));
+		endTime.setDate(QDate(prevEnd.Year(), prevEnd.Month()+1,
+		                      prevEnd.Day() + 1));
+		endTime.setTime(QTime(prevEnd.Hour(), prevEnd.Minute(), 0, 0));
+	} else {
+		QDateTime nullDateTime;
+		startTime = nullDateTime;
+		endTime = nullDateTime;
+	}
 	delete calEntry;
-	int count = entries.Count();
-	for (int i = count - 1; i >= 0; --i) {
-		CCalEntry *instance = entries[i];
-		delete instance;
-	}
 	CleanupStack::PopAndDestroy(&entries);
 }
 
@@ -2245,7 +2260,7 @@
                                           QDateTime& endTime)
 {
 	RPointerArray<CCalEntry> entries;
-	CleanupClosePushL(entries);
+	CleanupResetAndDestroyPushL(entries);
 	TCalTime nextStartTime;
 	TCalTime nextEndTime;
 	TTime zero(TInt64(0));
@@ -2359,9 +2374,19 @@
 					keepLooking = EFalse;
 					break;
 			}
-			// Is currentInstanceDate before parent dt start?
-			if (currentInstanceDate.TimeLocalL() < 
-					entries[0]->StartTimeL().TimeLocalL()) {
+			// Is currentInstanceDate after repeat until date?
+			if (currentInstanceDate.TimeLocalL() >  
+					rrule.Until().TimeLocalL()) {
+				TBool exceptionEntryAfterRepeatUntilPresent = EFalse;
+				for (TInt i=0; i<exdates.Count(); ++i) {
+					if(exdates[i].TimeLocalL() > rrule.Until().TimeLocalL()) {
+						exceptionEntryAfterRepeatUntilPresent = ETrue;
+					}
+				}
+				if (!exceptionEntryAfterRepeatUntilPresent) {
+					currentInstanceDate.SetTimeLocalL(Time::NullTTime());
+					nextStartTime = currentInstanceDate;
+				}
 				// There are no instances before the exception
 				keepLooking = EFalse;
 			} else {
@@ -2404,22 +2429,24 @@
 		CleanupStack::PopAndDestroy( &exdates );
 		}
 	}
-	// Convert TCalTimes to QDateTimes
-	TDateTime nextStart = nextStartTime.TimeLocalL().DateTime();
-	TDateTime nextEnd = nextEndTime.TimeLocalL().DateTime();
-	startTime.setDate(QDate(nextStart.Year(), nextStart.Month()+1,
-	                        nextStart.Day() + 1));
-	startTime.setTime(QTime(nextStart.Hour(), nextStart.Minute(), 0, 0));
-	endTime.setDate(QDate(nextEnd.Year(), nextEnd.Month()+1,
-	                      nextEnd.Day() + 1));
-	endTime.setTime(QTime(nextEnd.Hour(), nextEnd.Minute(), 0, 0));	
 	
+	if (nextStartTime.TimeUtcL() != Time::NullTTime()) {
+		// Convert TCalTimes to QDateTimes
+		TDateTime nextStart = nextStartTime.TimeLocalL().DateTime();
+		TDateTime nextEnd = nextEndTime.TimeLocalL().DateTime();
+		startTime.setDate(QDate(nextStart.Year(), nextStart.Month()+1,
+		                        nextStart.Day() + 1));
+		startTime.setTime(QTime(nextStart.Hour(), nextStart.Minute(), 0, 0));
+		endTime.setDate(QDate(nextEnd.Year(), nextEnd.Month()+1,
+		                      nextEnd.Day() + 1));
+		endTime.setTime(QTime(nextEnd.Hour(), nextEnd.Minute(), 0, 0));	
+	} else {
+		QDateTime nullDateTime;
+		startTime = nullDateTime;
+		endTime = nullDateTime;
+	}
 	delete calEntry;
-	int count = entries.Count();
-		for (int i = count - 1; i >= 0; --i) {
-			CCalEntry *instance = entries[i];
-			delete instance;
-		}
+	
 	CleanupStack::PopAndDestroy(&entries);
 }
 
@@ -2438,7 +2465,7 @@
 	bool isEmpty;
 	// Query for the entries for entire range
 	RPointerArray<CCalInstance> instanceList;
-	CleanupClosePushL(instanceList);
+	CleanupResetAndDestroyPushL(instanceList);
 	
 	// Create the filter
 	CalCommon::TCalViewFilter filters = AgendaUtil::IncludeAnniversaries
@@ -2475,12 +2502,9 @@
 	} else {
 		isEmpty = true;
 	}
-	int count = instanceList.Count();
-	for (int i = count - 1; i >= 0; --i) {
-	            CCalInstance *instance = instanceList[i];
-	            delete instance;
-	        }
-	CleanupStack::PopAndDestroy();
+	
+	// Cleanup
+	CleanupStack::PopAndDestroy( &instanceList );
 	return isEmpty;
 }
 
@@ -2644,8 +2668,7 @@
 	entry.setStartAndEndTime(startDateTime, endDateTime);
 
 	// Attendees.
-	RPointerArray<CCalAttendee> calAttendees = calEntry.AttendeesL();
-	CleanupClosePushL(calAttendees);
+	RPointerArray<CCalAttendee>& calAttendees = calEntry.AttendeesL();
 
 	for (int i = 0; i < calAttendees.Count(); i++) {
 		AgendaAttendee attendee;
@@ -2672,11 +2695,9 @@
 						calAttendees[i]->StatusL()));
 		entry.addAttendee(attendee);
 	}
-	CleanupStack::Pop(&calAttendees);
 
 	// Categories.
-	RPointerArray<CCalCategory> calCategories = calEntry.CategoryListL();
-	CleanupClosePushL(calCategories);
+	const RPointerArray<CCalCategory>& calCategories = calEntry.CategoryListL();
 
 	for (int i = 0; i < calCategories.Count(); i++) {
 		AgendaCategory category;
@@ -2692,7 +2713,6 @@
 				static_cast<AgendaCategory::CategoryType>(categoryType));
 		entry.addCategory(category);
 	}
-	CleanupStack::PopAndDestroy(&calCategories);
 
 	// Id.
 	entry.d->m_id = calEntry.LocalUidL();
@@ -2974,7 +2994,7 @@
 	CalCommon::TCalTimeRange dayRange(dummy, dummy);
 	getDayRange(entry.startTime(), entry.startTime(), dayRange);
 	RPointerArray<CCalInstance> instances;
-	CleanupClosePushL(instances);
+	CleanupResetAndDestroyPushL(instances);
 	iCalInstanceView->FindInstanceL(instances, CalCommon::EIncludeAll, dayRange);
 	TTime entryStartTime(dayRange.StartTime().TimeLocalL());
 
@@ -3394,7 +3414,7 @@
 									const CalCommon::TCalTimeRange& timeRange)
 {
 	RPointerArray<CCalInstance> allInstances;
-	CleanupClosePushL( allInstances );
+	CleanupResetAndDestroyPushL(allInstances);
 	
 	TInt filter;
 	// Get the entry type to be filtered
@@ -3443,7 +3463,7 @@
 								   const CalCommon::TCalTimeRange& timeRange)
 {
 	RPointerArray<CCalInstance> allInstances;
-	CleanupClosePushL( allInstances );
+	CleanupResetAndDestroyPushL(allInstances);
     
     TInt filter;
     // Get the entry type to be filtered
@@ -3684,16 +3704,14 @@
                                                 oldEntries[i]->SequenceNumberL(),
                                                 recId,
                                                 oldEntries[i]->RecurrenceRangeL() );
-            CleanupStack::PushL(exception);
             exception->CopyFromL(*oldEntries[i]);
             exception->SetLastModifiedDateL();
             TInt successCount=0;
 			RPointerArray<CCalEntry> entries;
-			CleanupClosePushL( entries );
+			CleanupResetAndDestroyPushL(entries);
 			entries.Append( exception );
 			iCalEntryView->StoreL( entries, successCount );
 			CleanupStack::PopAndDestroy( &entries );
-            CleanupStack::PopAndDestroy(exception);
             }
         else
             {
@@ -3706,10 +3724,10 @@
         	oldEntries[i]->SetLastModifiedDateL();
 			TInt successCount=0;
 			RPointerArray<CCalEntry> entries;
-			CleanupClosePushL( entries );
+			CleanupClosePushL(entries);
 			entries.Append( oldEntries[i] );
 			iCalEntryView->StoreL( entries, successCount );
-			CleanupStack::PopAndDestroy( &entries );
+			CleanupStack::Pop( &entries );
             }
         }
     }