예제 #1
0
EXPORT_C void CMsvEntryArray::SortL(TMsvSelectionOrdering aOrdering)
//
// sorts this array
//
	{
	// If we're going to reverse the array first sort by id so sorting twice will give the same result
	switch(aOrdering.Sorting())
		{
		case EMsvSortByDateReverse:
		case EMsvSortByIdReverse:
		case EMsvSortBySizeReverse:
		case EMsvSortByDescriptionReverse:
		case EMsvSortByDetailsReverse:
			{
			TKeyArrayFixPtr key = MessageSortKey(EMsvSortById);
			User::LeaveIfError(Sort(key));
			break;
			}
		default: // Not required - break
			break;
		}
	if (Count() && (aOrdering.Sorting()!=EMsvSortByNone || aOrdering.GroupingOn()))
		GroupL(EGroupByStandardFolders, aOrdering, (aOrdering.Sorting()!=EMsvSortByNone));
	}
예제 #2
0
void CMsvEntryArray::GroupL(TGroupCriterion aGroupCriterion,TMsvSelectionOrdering aOrdering,TBool aDoSort)
//
// This function works recursively, grouping and sorting the entry selection.  The 
// 'sort' happens at the same time as the 1st 'group', then separate grouped arrays 
// are grouped indidvidually and then merged together at the end. The order in which 
// the grouping occurs is determined by the CMsvEntryArray::TGroupCriterion enum
//	
	{
	TMsvSorting sortType=aOrdering.Sorting();
	TKeyArrayFixPtr key=MessageSortKey(sortType);
	
	if (aGroupCriterion==EStopGrouping)
		{  // if you haven't sorted yet
		if (aDoSort)
			{
			// Subject based sorting requires a special algorithm. Only message entries are treated as other entries normally
			// do not have a prefix like e.g. "re: " or "fwd: "
			if(At(0)->iType == KUidMsvMessageEntry && (sortType == 	EMsvSortByDescription || sortType == EMsvSortByDescriptionReverse))
				{
				SubjectBasedSortL(sortType == EMsvSortByDescriptionReverse,aOrdering.SubjectSkipString());							
				}
			else
				{
				CMsvEntryArray* temp=CMsvEntryArray::NewLC(iOrigMtmList);
				TInt count=Count();
				if (count)
					temp->InsertL(0,&(*(this))[0],count);
				Reset();
				const TMsvEntry** entry = &temp->At(0);
				while (count--)
					InsertIsqAllowDuplicatesL(*entry++, key); // Sorted
				ReverseOrder(sortType);
				CleanupStack::PopAndDestroy(); // temp
				}
			if (At(0)->iType == KUidMsvMessageEntry && (sortType == EMsvSortByDetails || sortType == EMsvSortByDetailsReverse))
				{
				DetailBasedSortL(); // Sort blocks of messages with matching details into newest first
				}
			}
		else
			{
			// The aDoSort flag is not set, but we still need to do a subject
			// based sort if this array contains only message entries, and we are
			// sorting by description. Alternatively, we need to do a date based sort
			// if this array contains only message entries and we are sorting by detail.
			// In order to ensure the array contains only message entries, we
			// check that we have previously grouped the entries by type which would
			// have put all the message entries together in their own array.
			if (Count() > 0 && At(0)->iType == KUidMsvMessageEntry && OkToGroup(EGroupByType, aOrdering))
				{
				if (sortType == EMsvSortByDescription || sortType == EMsvSortByDescriptionReverse)
					{
					SubjectBasedSortL(sortType == EMsvSortByDescriptionReverse,aOrdering.SubjectSkipString());
					}
				else if (sortType == EMsvSortByDetails || sortType == EMsvSortByDetailsReverse)
					{
					DetailBasedSortL(); // Sort blocks of messages with matching details into newest first
					}
				}
			}
		return;
		}

	if (OkToGroup(aGroupCriterion, aOrdering))
		{
		//
		// Copy contents into temp and then put new grouped contents into 'this'
		TInt count=Count();
		if (count==0)
			return; // nothing to do here
		const TInt numberOfArrays=NumberOfArraysToSplitIntoL(aGroupCriterion);
		if (numberOfArrays<1)  // cannot group on this so move on to next grouping
			{
			GroupL(TGroupCriterion(aGroupCriterion+1), aOrdering, aDoSort);
			return;
			}
		CMsvEntryArray* temp;
		if (iActualMtmList)
			temp = CMsvEntryArray::NewLC(*iActualMtmList);
		else
			temp = CMsvEntryArray::NewLC(iOrigMtmList);
		temp->InsertL(0,&(*(this))[0],count);
		Reset();

		//
		// create the separate arrays for each group
		CArrayFixFlat<CMsvEntryArray*>* arrays=new(ELeave) CArrayFixFlat<CMsvEntryArray*>(numberOfArrays);
		CleanupStack::PushL(arrays);
		for (TInt ii=0; ii<numberOfArrays; ii++)
			{
			if (iActualMtmList)
				arrays->AppendL(CMsvEntryArray::NewLC(*iActualMtmList));
			else
				arrays->AppendL(CMsvEntryArray::NewLC(iOrigMtmList));
			}

		//
		// split the selection into the correct group, 
		// sorting aswell if needed and not doing standard folders
		const TMsvEntry** entry = &temp->At(0);
		if (!aDoSort || aGroupCriterion==EGroupByStandardFolders)
			{
			while (count--)
				{
				arrays->At(ArrayId(*entry,aGroupCriterion))->AppendL(*entry);
				entry++;
				}
			}
		else if (aGroupCriterion==EGroupByType)
			{
			TKeyArrayFixPtr folderKey = TKeyArrayFixPtr(_FOFF(TMsvEntry,iDetails),ECmpCollated);
			while (count--)
				{
				if ((*entry)->iType==KUidMsvFolderEntry)
					arrays->At(ArrayId(*entry, aGroupCriterion))->InsertIsqAllowDuplicatesL(*entry, folderKey);
				else
					arrays->At(ArrayId(*entry, aGroupCriterion))->InsertIsqAllowDuplicatesL(*entry, key);
				entry++;
				}
			for (TInt jj=0; jj<numberOfArrays; jj++)
				{
				if (arrays->At(jj)->Count() && arrays->At(jj)->At(0)->iType!=KUidMsvFolderEntry)
					arrays->At(jj)->ReverseOrder(sortType);
				}
			aDoSort=EFalse; 
			}
		else
			{
			while (count--)
				{
				arrays->At(ArrayId(*entry, aGroupCriterion))->InsertIsqAllowDuplicatesL(*entry, key); // Sorted
				entry++;
				}
			for (TInt jj=0; jj<numberOfArrays; jj++)
				arrays->At(jj)->ReverseOrder(sortType);
			aDoSort=EFalse; 
			}

		
		
		
		
		//
		// group further - but check that standard entries and grouped folders are not grouped anymore
		if (aGroupCriterion==EGroupByStandardFolders)
			{
			__ASSERT_DEBUG(numberOfArrays==2, PanicServer(EMsvToManyGroups));
			arrays->At(0)->GroupL(TGroupCriterion(aGroupCriterion+1), aOrdering, aDoSort);
			}
		else if (aGroupCriterion==EGroupByType)
			{
			for (TInt jj=0; jj<numberOfArrays; jj++)
				if (arrays->At(jj)->Count() && arrays->At(jj)->At(0)->iType!=KUidMsvFolderEntry)
					arrays->At(jj)->GroupL(TGroupCriterion(aGroupCriterion+1), aOrdering, aDoSort);
			}
		else 
			{
			for (TInt jj=0; jj<numberOfArrays; jj++)
				arrays->At(jj)->GroupL(TGroupCriterion(aGroupCriterion+1), aOrdering, aDoSort);
			}
		
		//
		// merge the separate arrays into 'this'
		for (TInt kk=0; kk<numberOfArrays; kk++)
			{
			count=arrays->At(kk)->Count();
			if (count)
				InsertL(0,&(*(arrays->At(kk)))[0],count);
			}
		CleanupStack::PopAndDestroy(numberOfArrays+2); // arrays contents + temp + arrays
		}
	else // move on to the next grouping
		GroupL(TGroupCriterion(aGroupCriterion+1), aOrdering, aDoSort);
	}