TBool CPackagerCntComparator::DoCompareCViewContactField(const CViewContact& anItem1, const CViewContact& anItem2) const /** Compares two CViewContact items' field arrays. @param anItem1 The first CViewContact to be compared. @param anItem2 The second CViewContact to be compared. @return ETrue if the two items are equal, EFalse otherwise. */ {// Need to check for NULL arrays first. if((!&anItem1) && (!&anItem2)) { return ETrue; } if((!&anItem1) || (!&anItem2)) { return EFalse; } // Check if arrays are same length to begin with. TInt maxCount = anItem1.FieldCount(); if(!DoCompareTInt(maxCount, anItem2.FieldCount())) { return EFalse; } for(TInt i=0; i<maxCount; ++i) { if(!DoCompareTPtrC(anItem1.Field(i), anItem2.Field(i))) { return EFalse; } } return ETrue; }
/** Refine the field content and add the refined content to the given view contact object. @param aViewContact reference to the retrieved view contact object. @param aFieldPtrC The actual field content read from database. @param aViewPreferences The view preferences for how to format the content. */ void CCntPplViewSession::AddFieldInViewContactL(CViewContact& aViewContact, TPtrC& aFieldPtrC, const TContactViewPreferences& aViewPreferences) { _LIT(KBlank," "); // Truncate to 64 if necessary. TPtr ptr(const_cast<TUint16*>(aFieldPtrC.Ptr()), KTextFieldMinimalLength); if(aFieldPtrC.Length() > KTextFieldMinimalLength) { ptr.SetLength(KTextFieldMinimalLength); } else { ptr.SetLength(aFieldPtrC.Length()); } // Add the field to the view. if((ptr.Length() == 0) || (ptr.Length() == 1 && (aViewPreferences & ESingleWhiteSpaceIsEmptyField) && ptr.Compare(KBlank)==KErrNone)) { /* empty field */ aViewContact.AddFieldL(KNullDesC); } else { aViewContact.AddFieldL(ptr); } }
/** * Test case 1 * Add an empty Field when the existing iFieldTextBuf is empty * Action : Add an empty Field (i.e. length = 0) when the existing iFieldTextBuf is empty * Result : Empty field added */ LOCAL_C void AddEmptyFieldL() { CViewContact* contact = CViewContact::NewLC(KContactId); contact->AddFieldL(KNullDesC); test(contact->FieldCount()==1); test(contact->Field(0)==KNullDesC); CleanupStack::PopAndDestroy(contact); }
CViewContact* CPackagerCntFactory::doCreateDefaultCViewContactL() const /** Implementation method for constructing a new default CPackagerCntFactory object. @return a Pointer to the CPackagerCntFactory object. */ { CViewContact* theContact = CViewContact::NewLC(KId5); theContact->AddFieldL(KContactItemGivenName); theContact->AddFieldL(KContactItemFamilyName); theContact->AddFieldL(KNullDesC); CleanupStack::Pop(theContact); return theContact; }
TBool CContactViewTest::CheckViewContact(const CViewContact &aVContact, const TDesC &aVal) { TBool SingleCheckResult = EFalse; TBool OverallCheckResult = ETrue; TInt length = aVContact.FieldCount(); TInt i = 0; for(; i < length; ++i) { SingleCheckResult = STRINGCOMPARE( aVContact.Field(i), ==, aVal, i, 0); OverallCheckResult = OverallCheckResult && SingleCheckResult; } return ( OverallCheckResult && length > 0 ); }
/** Create view contact object based on given sql statement. @return CViewContact object or NULL the contact is not found. */ CViewContact* CCntPplViewSession::CreateViewItemL(RSqlStatement& aSqlStmt, const CCntSqlStatement& aCntSqlStmt, const TContactViewPreferences& aViewPrefs) { if (! iContactsFile.IsOpened()) { User::Leave(KErrInUse); } CViewContact* viewContact = InitialiseViewItemL(aSqlStmt, aCntSqlStmt, aViewPrefs); if(!viewContact) { //Couldn't find the contact. return NULL; } CleanupStack::PushL(viewContact); if(viewContact->ContactType() == CViewContact::EContactItem) { FillViewItemL(*viewContact, aSqlStmt, aViewPrefs); } TUid typeUid = GetContactFieldMatchUid(*viewContact, aViewPrefs); if(typeUid != KUidContactFieldNone) { RSqlStatement contactSqlStmt; CleanupClosePushL(contactSqlStmt); /* we have to reload the row from SQL database to cache in text header and text blob */ contactSqlStmt.PrepareL(iContactsFile.NamedDatabase(), iSqlSmtSelectAllFieldsById.SqlStringL()); User::LeaveIfError(contactSqlStmt.BindInt(KFirstIndex, viewContact->Id())); //Bind item id into the condition. TInt err = contactSqlStmt.Next(); if(err == KSqlAtEnd) { //Should never be here, we found it in InitialiseViewItemL //but couldn't find the same contact in same database. CleanupStack::PopAndDestroy(viewContact); return NULL; } User::LeaveIfError(err); /* set first field with possible content for group or unsorted contact */ CContactDatabase::TTextFieldMinimal buf; TextFieldL(contactSqlStmt, iSqlSmtSelectAllFieldsById, iContactProperties.SystemTemplateL(), typeUid, buf); viewContact->SetFirstFieldForBlankContactL(buf); CleanupStack::PopAndDestroy(&contactSqlStmt); } //if(typeUid != 0) CleanupStack::Pop(viewContact); return viewContact; }
/** Check that contents of all fields in view contact equal corresponding fields in contact item */ TBool CContactViewTest::CheckViewContactL(const CViewContact &aVContact) { TBool OverallCheckResult = EFalse; //retrieve contact item id of view contact TContactItemId cid = aVContact.Id(); //open contact item ReadL(cid, *iViewAll); TInt length = aVContact.FieldCount(); TInt i = 0; for(; i < length; ++i) { OverallCheckResult = EFalse; //find first field in contact item that equals uid (of view contact field) stored in sort order TInt pos = iFields->Find((*iSortOrder)[i]); TDesC *ContactField = NULL; if(pos < 0) { ContactField = const_cast<TDesC *>(&KNullDesC); } else { //converts contents of field - matching the view contact uid - to a string ContactField = FieldStringLC( (*iFields)[pos] ); } //check that conents of contact item field equal conents of corresponing view contact field OverallCheckResult = STRINGCOMPARE( aVContact.Field(i), ==, *ContactField, i, 0 ); if(pos > -1) { CleanupStack::PopAndDestroy( ContactField ); } //if view contact field doesnt equal contact item field, fail test if( !OverallCheckResult ) { break;//test failed } } Close(); return OverallCheckResult; }
/** Check if the retrieved view contact is group or unsorted contact, if so return suitable field match uid in order to fill in a possible text for the contact: For group contact -- find template label. For unsorted contact -- find first not none field. @param aViewContact reference to the retrieved view contact object. @param aViewPreferences the view preferences made by client. @return suitable match uid or KUidContactFieldNone if it's not group or unsorted contact. */ TUid CCntPplViewSession::GetContactFieldMatchUid(const CViewContact& aViewContact, const TContactViewPreferences& aViewPreferences) { TUid typeUid = KUidContactFieldNone; if(aViewContact.ContactType() == CViewContact::EGroup && (aViewPreferences & (EGroupsOnly | EContactAndGroups))) { // Check for group view contact type. This type of view contact uses the // template label field to populate the first view contact field. typeUid = KUidContactFieldTemplateLabel; } else if(!aViewContact.IsSortable() && (aViewPreferences & (EIgnoreUnSorted | EUnSortedAtBeginning | EUnSortedAtEnd)) == 0) { // None of the sort fields contained any data. We want this contact to // be sorted by the first bit of text we find so we need to retrieve the // first text available from the contact and use this to populate the // first view contact field. typeUid = KUidContactFieldMatchAll; } return typeUid; }
/** * Test other CViewContact methods. */ LOCAL_C void TestMiscMethodsL() { CViewContact* contact = CViewContact::NewLC(KContactId); test(contact->Id()==KContactId); contact->SetId(KModifiedContactId); test(contact->Id()==KModifiedContactId); contact->SetContactType(CViewContact::EContactItem); test(contact->ContactType()==CViewContact::EContactItem); contact->SetContactType(CViewContact::EGroup); test(contact->ContactType()==CViewContact::EGroup); CleanupStack::PopAndDestroy(contact); }
TBool CPackagerCntComparator::Compare(const CViewContact& anItem1, const CViewContact& anItem2) const /** Compares two CViewContact items. @param anItem1 The first CViewContact to be compared. @param anItem2 The second CViewContact to be compared. @return ETrue if the two items are equal, EFalse otherwise. */ { return(DoCompareTUid(anItem1.ContactTypeUid(), anItem2.ContactTypeUid())&& DoCompareTContactItemId(anItem1.Id(), anItem2.Id()) && DoCompareTInt(anItem1.ContactType(), anItem2.ContactType()) && DoCompareCViewContactField(anItem1, anItem2) && DoCompareTInt(anItem1.ContactHint(), anItem2.ContactHint())); }
/** * Test case 2 * Add an empty Field when the existing iFieldTextBuf is not empty * Action : Add an empty Field (i.e. length = 0) when the existing iFieldTextBuf contains some fields already * Result : Empty field added */ LOCAL_C void AddFieldL() { CViewContact* contact = CViewContact::NewLC(KContactId); contact->AddFieldL(KContactName); contact->AddFieldL(KContactSurname); contact->AddFieldL(KNullDesC); test(contact->FieldCount()==3); test(contact->Field(0)==KContactName); test(contact->Field(1)==KContactSurname); test(contact->Field(2)==KNullDesC); CleanupStack::PopAndDestroy(contact); }
/* * Filter the results from ContactsMatchingCriteria/ContactsMatchingPrefix * removing contacts which are not in the current filtered view */ void CContactFilteredView::FilterResultsArray(RPointerArray<CViewContact>& aMatchedContacts) { TInt counter = 0; CViewContact* contactPtr; TContactIdWithMapping contactIdWithMapping; TInt max = aMatchedContacts.Count(); // for each returned CContactFilteredView, check to // make sure that it is a contact which exists in // our list. // our list : iFilteredIdArray // list to export is : aMatchedContacts while (counter < max) { contactPtr = aMatchedContacts[counter]; contactIdWithMapping.iId = contactPtr->Id(); // if the contact does not exist in our filtered list, then if ( iFilteredIdArray.Find(contactIdWithMapping, CompareMappings) == KErrNotFound ) { // remove it from our list aMatchedContacts.Remove(counter); // does not delete pointer delete contactPtr; // we've removed an item from the array // this means that the item above, will drop to fill the hole left by // the item we've deleted. // so there is no need to increment the counter, but we do need to // decrement the max number of contacts we're parsing. max--; } else { counter++; } } }
/** Initialise requested view contact object based on given parameters: 1. search the contact in contact table. 2. fill in contact type and hint to the view contact object. @param aSqlStmt reference to a RSqlStatement to be read in data @return initialized CViewContact object or NULL if reached end of rows. */ CViewContact* CCntPplViewSession::InitialiseViewItemL(RSqlStatement& aSqlStmt, const CCntSqlStatement& aCntSqlStmt, const TContactViewPreferences& aViewPrefs) { CViewContact* viewContact = NULL; while(viewContact == NULL) { TInt err = aSqlStmt.Next(); if(err == KSqlAtEnd) { return NULL; } User::LeaveIfError(err); TInt typeFlags = aSqlStmt.ColumnInt(aCntSqlStmt.ParameterIndex(KContactTypeFlags())); TUid contactTypeUid = TCntPersistenceUtility::TypeFlagsToContactTypeUid(typeFlags); if(!ContactCorrectType(contactTypeUid, aViewPrefs)) { //The contact type doesn't match the view prefreference continue; } viewContact = CViewContact::NewLC(KNullContactId); /* Got a row and add common fields for both Groups and Contact view items. */ viewContact->SetId(aSqlStmt.ColumnInt(aCntSqlStmt.ParameterIndex(KContactId()))); viewContact->SetContactHint(TCntPersistenceUtility::TypeFlagsToHint(typeFlags)); viewContact->SetContactTypeUid(contactTypeUid); if(contactTypeUid == KUidContactGroup) { // Groups don't require all the field types to be set. viewContact->SetContactType(CViewContact::EGroup); } else { // All other contact types do require field types to be set. viewContact->SetContactType(CViewContact::EContactItem); } CleanupStack::Pop(viewContact); } return viewContact; }
/** Filling content for the given view contact object. @param aViewContact reference to the view contact object to be filled @param aSqlStmt the sql statement which contains the retrieved content for the view object. */ void CCntPplViewSession::FillViewItemL(CViewContact& aViewContact, RSqlStatement& aSqlStmt, const TContactViewPreferences& aViewPrefs) { if(iIsFastAccessFieldsOnly) { //The view gets fields only from fast access columns const TInt KTextDefCount = iTextDef->Count(); for(TInt index = 0; index < KTextDefCount; ++index) { const TDesC& KColumnName = TCntPersistenceUtility::GetFastAccessColumnNameById(iTextDef->At(index).iFieldType.iUid); ASSERT(KColumnName.Length() > 0); TPtrC fieldPtrC = aSqlStmt.ColumnTextL(iCntSqlStatement->ParameterIndex(KColumnName)); AddFieldInViewContactL(aViewContact, fieldPtrC, aViewPrefs); } //for } else { TBool searchFastAccessFields = EFalse; // iTextDef contains the fields that should be included in the view. // The array of all the field objects in a contact item is returned from // the Contacts table. RPointerArray<CContactItemField> fields; CleanupStack::PushL(TCleanupItem(TCntPersistenceUtility::ResetAndDestroyRPointerArray, &fields)); TPtrC8 textHeader; aSqlStmt.ColumnBinary(iCntSqlStatement->ParameterIndex(KContactTextFieldHeader()), textHeader); RDesReadStream textHeaderStream(textHeader); CleanupClosePushL(textHeaderStream); CEmbeddedStore* textHeaderStore = CEmbeddedStore::FromLC(textHeaderStream); RStoreReadStream textHeaderStoreStream; textHeaderStoreStream.OpenLC(*textHeaderStore,textHeaderStore->Root()); TPtrC textFieldPtrC = aSqlStmt.ColumnTextL(iCntSqlStatement->ParameterIndex(KContactTextFields())); HBufC* textFieldsBuf = textFieldPtrC.AllocLC(); TCntPersistenceUtility::ReadTextBlobL(textHeaderStoreStream, textFieldsBuf, *iTextDef, iContactProperties.SystemTemplateL(), fields, searchFastAccessFields); CleanupStack::PopAndDestroy(4, &textHeaderStream); //textHeaderStore, textHeaderStream, textHeaderStoreStream, textFieldsBuf // Loop through fields, checking for fields from fast access fields, and add // the fields to the view contact object. const TInt KFieldsNumMax = fields.Count(); for(TInt fieldsIndex = 0; fieldsIndex < KFieldsNumMax; ++fieldsIndex) { // this doesn't own the instance stored in fields array. CContactItemField* itemField = fields[fieldsIndex]; if(itemField == NULL) { aViewContact.AddFieldL(KNullDesC); continue; } // The array of fields retrieved from the text fields blob does not // contain the text data Fast Access fields. If the searchFastAccessFields // flags have been set then get the data from Fast Access columns // before adding the data to the view. TPtrC fieldText; if(searchFastAccessFields && itemField->ContentType().FieldTypeCount() > 0) { //Check the field name of the first field type(key field type) //in the field's field types array const TDesC& KColumnName = TCntPersistenceUtility::GetFastAccessColumnNameById(itemField->ContentType().FieldType(0).iUid); if(KColumnName.Length() > 0) { //this is a fast access field. fieldText.Set(aSqlStmt.ColumnTextL(iCntSqlStatement->ParameterIndex(KColumnName))); } else { fieldText.Set(itemField->TextStorage()->Text()); } } else { fieldText.Set(itemField->TextStorage()->Text()); } AddFieldInViewContactL(aViewContact, fieldText, aViewPrefs); } CleanupStack::PopAndDestroy(&fields); } }