/**
Change the sorting order/text definition. It should be always called when 
there is not an iteration started in persistence layer.

@param aTextDef the new text definition to be used in the view session.
*/
void CCntPplViewSession::ChangeSortOrderL(const CContactTextDef& aTextDef)
	{
	//Cleanup the cached Prepare statement as the sort order will be changed
	Cancel();
    CleanupCachedPrepareStatement();
	
	//Copy the text definition
	CContactTextDef* textDef = CContactTextDef::NewLC();
	const TInt KTextDefCount = aTextDef.Count();
	for (TInt index = 0; index < KTextDefCount; ++index)
		{
		textDef->AppendL(TContactTextDefItem(aTextDef.At(index).iFieldType));
		}
	
	// Create select statement on contact table
	TCntSqlStatementType statementType(ESelect, KSqlContactTableName());
	CCntSqlStatement* sqlSmt = TSqlProvider::GetSqlStatementL(statementType);
	CleanupStack::PushL(sqlSmt);
	
	// Always select id, type flags.	
	sqlSmt->SetParamL(KContactId(), KSpace());
	sqlSmt->SetParamL(KContactTypeFlags(), KSpace());
	
	//Go through text definition to construct select statement.
	TBool isFastAccessOnly = ETrue;
	for(TInt ii = 0; ii < KTextDefCount; ++ii)
		{
		const TDesC& KColunmName = TCntPersistenceUtility::GetFastAccessColumnNameById(aTextDef.At(ii).iFieldType.iUid);
		if(KColunmName.Length() > 0) 
			{
			sqlSmt->SetParamL(KColunmName, KSpace());
			}
		else
			{
			isFastAccessOnly = EFalse;		
			}
		}
	
	if(!isFastAccessOnly)
		{
		//Fields in text blob are needed, add text fields header and
        //text blob columns in the select statement.		
		sqlSmt->SetParamL(KContactTextFieldHeader(), KSpace());
		sqlSmt->SetParamL(KContactTextFields(), KSpace());
		}

	CleanupStack::Pop(2, textDef); // sqlSmt, textDef.
	
	delete iCntSqlStatement;
	iCntSqlStatement = sqlSmt;
	
	delete iTextDef;
	iTextDef = textDef;
	
	iIsFastAccessFieldsOnly = isFastAccessOnly;
	}
TBool CPackagerCntComparator::Compare(const CContactTextDef& anItem1, const CContactTextDef& anItem2) const
/** Compares two CContactTextDef items. 

@param anItem1 The first CContactTextDef to be compared.
@param anItem2 The second CContactTextDef to be compared.
@return ETrue if the two items are equal, EFalse otherwise. */
	{
	return(DoCompareCContactTextDefArray(anItem1, anItem2)					&
		DoCompareTUid(anItem1.FallbackField(), anItem2.FallbackField())	&
		DoCompareTInt(const_cast<CContactTextDef&>(anItem1).ExactMatchOnly(), const_cast<CContactTextDef&>(anItem2).ExactMatchOnly()));
	}
Esempio n. 3
0
void CCntMatchLog::ReadContactNameL(TLogContactItemId aContactId, TDes &aName, TLogContactNameFormat aNameFormat)
	/** Gets the text data for the family and given name fields of a given contact Id.
	
	@capability ReadUserData
	@param aContactId Contact Id to find data for
	@param aName On return contains the family and given name in the desired format if found, a 0 length string otherwise.
	@param aNameFormat Desired format of returned string - Chinese or Western format */
	{
		
	// Specify what fields to fetch and concatenate
	CContactTextDef* textDef = CContactTextDef::NewLC();
	_LIT(KRemotePartyNameSeparator, " ");	
	
	if(ELogChineseFormat == aNameFormat)
		{
		textDef->AppendL(TContactTextDefItem(KUidContactFieldFamilyName, KRemotePartyNameSeparator));
		textDef->AppendL(TContactTextDefItem(KUidContactFieldGivenName));
		}
	else //ELogWesternFormat == iContactNameFormat
		{
		textDef->AppendL(TContactTextDefItem(KUidContactFieldGivenName, KRemotePartyNameSeparator));
		textDef->AppendL(TContactTextDefItem(KUidContactFieldFamilyName));
		}
	textDef->SetExactMatchOnly(ETrue);
	iContactDb->ReadContactTextDefL(aContactId, aName, textDef);
	CleanupStack::PopAndDestroy(textDef);
	}
TBool CPackagerCntComparator::DoCompareCContactTextDefArray(const CContactTextDef& aTextDefArray1, const CContactTextDef& aTextDefArray2) const
/** Compares two CContactTextDef arrays. 

@param aTextDefArray1 The first CContactTextDef to be compared.
@param aTextDefArray2 The second CContactTextDef to be compared.
@return ETrue if the two items are equal, EFalse otherwise. */
	{// Need to check for NULL  arrays first.
	if((!&aTextDefArray1) && (!&aTextDefArray2))
		{
		return ETrue;
		}

	if((!&aTextDefArray1) || (!&aTextDefArray2))
		{
		return EFalse;
		}
	
	// Check if arrays are same length to begin with.
	TInt maxCount = aTextDefArray1.Count();
	if(!DoCompareTInt(maxCount, aTextDefArray2.Count()))
		{
		return EFalse;
		}

	for(TInt i=0; i<maxCount; ++i)
		{
		if(!DoCompareTUid(aTextDefArray1[i].iFieldType, aTextDefArray2[i].iFieldType))
			{
			return EFalse;
			}
			
		if(aTextDefArray1[i].iSeperator!=aTextDefArray2[i].iSeperator)
			{
			return EFalse;
			}		
		}

	return ETrue;
	}
CContactTextDef* CPackagerCntFactory::doCreateDefaultCContactTextDefL() const
/** Implementation method for constructing a new default CContactTextDef object. 

@return a Pointer to the CContactTextDef object. */
	{
	CContactTextDef* theTextDef = CContactTextDef::NewLC();
	theTextDef->AppendL(TContactTextDefItem(KUidContactFieldFamilyName));
	theTextDef->AppendL(TContactTextDefItem(KUidContactFieldGivenName));
	theTextDef->AppendL(TContactTextDefItem(KUidContactFieldCompanyName));
	theTextDef->AppendL(TContactTextDefItem(KUidContactFieldAddress));
	theTextDef->AppendL(TContactTextDefItem(KUidContactFieldEMail));
	theTextDef->AppendL(TContactTextDefItem(KUidContactFieldAdditionalName));
	CleanupStack::Pop(theTextDef);
	return theTextDef;
	}	
/**
Utility class to read text blob from given header stream and text buffer, and
return an array of contact item fields defined in aTextDef.

The method loops through the fields of the given text definition and adds (text)
fields from text buffer which match the text definition field types.

@param aHeaderStream the read stream contains text header blob data 
@param aTextBuffer  text buffer storing text fields.
@param aTextDef The text defintion containing the fields IDs required in the
				view contact.
@param aSearchFastAccessFields Return value indicating that additional fields can
							   be found in the Fast Access fields.

@return An array of contact item fields.
*/	
void TCntPersistenceUtility::ReadTextBlobL(RReadStream& aHeaderStream, const HBufC* aTextBuffer, const CContactTextDef& aTextDef, const CContactTemplate& aSystemTemplate, RPointerArray<CContactItemField>& aFields, TBool& aSearchFastAccessFields)
	{
	TInt max = aTextDef.Count();
	for(TInt i=0; i<max; ++i)
		{
		aFields.AppendL(NULL);
		}	
	
	// Extract the number of fields from the header stream.
	TCardinality headerFieldCount;
	aHeaderStream>>headerFieldCount;
	
	TInt textFieldIndex = 0;
	const TInt KMaxTextDefFlds = aTextDef.Count();
	
	CContactItemField* itemField = CContactItemField::NewLC();
	for(TInt hdrFldIndex = 0; hdrFldIndex < headerFieldCount; ++hdrFldIndex)
		{
		// Internalization in RestoreFieldTypesL() moves headerStream on to
		// point to the next element.  RestoreFieldTypesL() knows how to format
		// a header element.
		itemField->RestoreFieldTypesL(aHeaderStream, &aSystemTemplate.CardFields());
	
		// Loop through all the text definition fields.
		for(TInt defIndex = 0; defIndex < KMaxTextDefFlds; ++defIndex)
			{
			// Check if text definition field and current header field types
			// match.
			if((itemField->ContentType().ContainsFieldType(aTextDef.At(defIndex).iFieldType) 
				|| aTextDef.At(defIndex).iFieldType == KUidContactFieldMatchAll) 
				&& itemField->StorageType() == KStorageTypeText)
				{
				// They do match but take care of duplicates.
				if(aFields[defIndex] == NULL)
					{
					itemField->ResetStore();
					// Restore field text from the searchable buffer.
					itemField->RestoreTextL(const_cast<HBufC*>(aTextBuffer), textFieldIndex);
					// Although there's an entry there may be more tables to
					// read.
					if(itemField->TextStorage()->Text().Length() == KNullBlobTextField().Length()
						&& itemField->TextStorage()->Text().Compare(KNullBlobTextField) == 0)
						{
						aSearchFastAccessFields = ETrue;
						}
						
					// Assign the array in correct sequence then clone a new one
					// to continue the search in case there's more than one of
					// this field type.			
					aFields[defIndex] = CContactItemField::NewL(*itemField);
					}
				}
			}
			
		if(itemField->StorageType() == KStorageTypeText)
			{
			++textFieldIndex;
			}
			
		// Always one left over.
		itemField->Reset();
		}
		CleanupStack::PopAndDestroy(itemField);
	}