/* ============================================================================ Name : Phonebook.cpp Author : Anton Antonov Version : 1.0 Copyright : Copyright (C) 2008 Rhomobile. All rights reserved. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . Description : CPhonebook implementation ============================================================================ */ #include "Phonebook.h" #include "ext\phonebook\phonebook.h" #include #include #include #include #include #include #include #include "ContactsConstants.h" #include #include #include #include //IMPLEMENT_LOGCLASS(CPhonebook,"Phonebook"); CPhonebook::CPhonebook() { // No implementation required } CPhonebook::~CPhonebook() { if ( iContactDb ) { iContactDb->CloseTables(); delete iContactDb; } } CPhonebook* CPhonebook::NewLC() { CPhonebook* self = new (ELeave)CPhonebook(); CleanupStack::PushL(self); self->ConstructL(); return self; } CPhonebook* CPhonebook::NewL() { CPhonebook* self=CPhonebook::NewLC(); CleanupStack::Pop(); // self; return self; } void CPhonebook::ConstructL() { // Read name of the default database _LIT( KOrgContactFile,"" ); TBuf orgContactFile( KOrgContactFile ); CContactDatabase::GetDefaultNameL( orgContactFile ); orgContactFile.LowerCase(); TRAPD(err, iContactDb = CContactDatabase::OpenL( orgContactFile );); // Check if database already exist if ( err == KErrNotFound ) { HBufC* text = StringLoader::LoadLC( R_CONTACTS_DB_NOT_FOUND ); CAknInformationNote* informationNote = new (ELeave) CAknInformationNote; informationNote->ExecuteLD( *text ); CleanupStack::PopAndDestroy( text ); iContactDb = NULL; } } /** * Auxilary functions */ char* CPhonebook::descriptorToStringL(const TDesC& aDescriptor) { TInt length = aDescriptor.Length(); if ( length > 0 ) { HBufC8* buffer = HBufC8::NewLC(length); buffer->Des().Copy(aDescriptor); char* str = (char*)malloc(length + 1); Mem::Copy(str, buffer->Ptr(), length); str[length] = '\0'; CleanupStack::PopAndDestroy(buffer); return str; } return NULL; } void CPhonebook::add2hash(VALUE* hash, const char* key, TPtrC& aValue ) { char* value = descriptorToStringL(aValue); if ( key && value ) { //LOG(INFO) + "Adding field [" + key + ":" + value + "]"; addStrToHash(*hash, key, value, strlen(value)); } if ( value ) free( value ); } VALUE CPhonebook::getFields(CContactItemFieldSet& fieldSet, char* id) { VALUE hash = createHash(); // Get field ID //LOG(INFO) + "Adding field [id:" + id + "]"; addStrToHash(hash, RUBY_PB_ID, id, strlen(id)); // Get first name TInt findpos( fieldSet.Find( KUidContactFieldGivenName ) ); // Check that the first name field is actually there. if ( (findpos > -1) || (findpos >= fieldSet.Count()) ) { CContactItemField& firstNameField = fieldSet[findpos]; CContactTextField* firstName = firstNameField.TextStorage(); TPtrC value = firstName->Text(); add2hash(&hash, RUBY_PB_FIRST_NAME, value); } else { addStrToHash(hash, RUBY_PB_FIRST_NAME, "", strlen("")); } // Get last name findpos = fieldSet.Find( KUidContactFieldFamilyName ); // Check that the last name field is actually there. if ( (findpos > -1) || (findpos >= fieldSet.Count()) ) { CContactItemField& lastNameField = fieldSet[ findpos ]; CContactTextField* lastName = lastNameField.TextStorage(); TPtrC value = lastName->Text(); add2hash(&hash, RUBY_PB_LAST_NAME, value); } else { addStrToHash(hash, RUBY_PB_LAST_NAME, "", strlen("")); } // Get home phone findpos = fieldSet.Find( KUidContactFieldPhoneNumber ); // Check that the last name field is actually there. if ( (findpos > -1) || (findpos >= fieldSet.Count()) ) { CContactItemField& itemField = fieldSet[ findpos ]; CContactTextField* textField = itemField.TextStorage(); TPtrC value = textField->Text(); add2hash(&hash, RUBY_PB_HOME_NUMBER, value); add2hash(&hash, RUBY_PB_MOBILE_NUMBER, value); add2hash(&hash, RUBY_PB_BUSINESS_NUMBER, value); } else { addStrToHash(hash, RUBY_PB_HOME_NUMBER, "", strlen("")); addStrToHash(hash, RUBY_PB_MOBILE_NUMBER, "", strlen("")); addStrToHash(hash, RUBY_PB_BUSINESS_NUMBER, "", strlen("")); } // Get email findpos = fieldSet.Find( KUidContactFieldEMail ); // Check that the last name field is actually there. if ( (findpos > -1) || (findpos >= fieldSet.Count()) ) { CContactItemField& itemField = fieldSet[ findpos ]; CContactTextField* textField = itemField.TextStorage(); TPtrC value = textField->Text(); add2hash(&hash, RUBY_PB_EMAIL_ADDRESS, value); } else { addStrToHash(hash, RUBY_PB_EMAIL_ADDRESS, "", strlen("")); } // Get company findpos = fieldSet.Find( KUidContactFieldCompanyName ); // Check that the last name field is actually there. if ( (findpos > -1) || (findpos >= fieldSet.Count()) ) { CContactItemField& itemField = fieldSet[ findpos ]; CContactTextField* textField = itemField.TextStorage(); TPtrC value = textField->Text(); add2hash(&hash, RUBY_PB_COMPANY_NAME, value); } else { addStrToHash(hash, RUBY_PB_COMPANY_NAME, "", strlen("")); } return hash; } VALUE CPhonebook::getallPhonebookRecords() { VALUE hash = createHash(); //retval iContactDb->SetDbViewContactType( KUidContactCard ); TFieldType aFieldType1( KUidContactFieldFamilyName ); TFieldType aFieldType2( KUidContactFieldGivenName ); CContactDatabase::TSortPref sortPref1( aFieldType1 ); CContactDatabase::TSortPref sortPref2( aFieldType2 ); // Sort contacts by Family and Given Name CArrayFixFlat* aSortOrder = new (ELeave) CArrayFixFlat(2); CleanupStack::PushL( aSortOrder ); aSortOrder->AppendL( sortPref1 ); aSortOrder->AppendL( sortPref2 ); // The database takes ownership of the sort order array passed in iContactDb->SortL( aSortOrder ); // The caller does not take ownership of this object. // so do not push it onto the CleanupStack const CContactIdArray* contacts = iContactDb->SortedItemsL(); // Go through each contact item and // make items for listbox const TInt nc( contacts->Count() ); for ( TInt i = 0; i < nc; i++ ) //For each ContactId { CContactItem* contact = NULL; // The caller takes ownership of the returned object. // So push it onto the CleanupStack contact = iContactDb->OpenContactL( (*contacts)[i] ); CleanupStack::PushL( contact ); char rid[20] = {0}; sprintf( rid, "{%d}", contact->Id()); if (rid) { //LOG(INFO) + "Adding record " + rid; CContactItemFieldSet& fieldSet = contact->CardFields(); addHashToHash(hash,rid,getFields(fieldSet, rid)); } iContactDb->CloseContactL( contact->Id() ); CleanupStack::PopAndDestroy( contact ); } return hash; } CContactItem* CPhonebook::openContact(char* id) { TInt nID = -1; sscanf( id, "{%d}", &nID ); if ( nID >= 0 ) { CContactItem* contact = NULL; // The caller takes ownership of the returned object. // So push it onto the CleanupStack contact = iContactDb->OpenContactL( nID ); CleanupStack::PushL( contact ); return contact; } return NULL; } VALUE CPhonebook::getContact(char* id) { CContactItem* contact = openContact(id); if ( contact ) { CContactItemFieldSet& fieldSet = contact->CardFields(); VALUE hash = getFields(fieldSet, id); iContactDb->CloseContactL( contact->Id() ); CleanupStack::PopAndDestroy( contact ); return hash; } return rho_ruby_get_NIL(); } CContactCard* CPhonebook::createRecord() { CContactCard* card = CContactCard::NewLC(); return card; } TUid CPhonebook::getFieldId( char* prop ) { TUid fieldID = {-1}; if ( strcmp(RUBY_PB_FIRST_NAME, prop) == 0 ) { fieldID = KUidContactFieldGivenName; } else if ( strcmp(RUBY_PB_LAST_NAME, prop) == 0 ) { fieldID = KUidContactFieldFamilyName; } else if ( strcmp(RUBY_PB_MOBILE_NUMBER, prop) == 0 || strcmp(RUBY_PB_HOME_NUMBER, prop) == 0 || strcmp(RUBY_PB_BUSINESS_NUMBER, prop) == 0 ) { fieldID = KUidContactFieldPhoneNumber; } else if ( strcmp(RUBY_PB_EMAIL_ADDRESS, prop) == 0 ) { fieldID = KUidContactFieldEMail; } else if ( strcmp(RUBY_PB_COMPANY_NAME, prop) == 0 ) { fieldID = KUidContactFieldCompanyName; } return fieldID; } void ConvertToUnicode(RFs& session, TDes16& aUnicode, const char *str) { CCnvCharacterSetConverter *converter = CCnvCharacterSetConverter::NewL(); converter->PrepareToConvertToOrFromL(KCharacterSetIdentifierUtf8, session); TPtrC8 ptr((const unsigned char*)str); int state = CCnvCharacterSetConverter::KStateDefault; converter->ConvertToUnicode(aUnicode, ptr, state); delete converter; } void CPhonebook::setRecordValue(CContactItem* contactItem, char* prop, char* value) { if ( contactItem && prop && value ) { TUid fieldId = CPhonebook::getFieldId(prop); if ( fieldId.iUid >= 0 ) //if supported id { TInt phoneFieldIndex = contactItem->CardFields().Find(fieldId); RFs iSession; User::LeaveIfError(iSession.Connect()); TBuf<100> textValue; ConvertToUnicode( iSession, textValue, value ); if(phoneFieldIndex == KErrNotFound) { // The contact has no existing phone field, so add one. CContactItemField* addPhoneField = CContactItemField::NewLC(KStorageTypeText, fieldId); addPhoneField->SetMapping(fieldId); addPhoneField->TextStorage()->SetTextL(textValue); contactItem->AddFieldL(*addPhoneField); // Takes ownership CleanupStack::Pop(addPhoneField); } else { // Modify the existing phone field’s contents. CContactItemField& phoneField = contactItem->CardFields()[phoneFieldIndex]; phoneField.TextStorage()->SetTextL(textValue); } iSession.Close(); } } } void CPhonebook::addRecord( CContactCard* card ) { if ( card ) { TContactItemId cardId = iContactDb->AddNewContactL(*card); delete card; } } void CPhonebook::saveContact(CContactItem* contactItem) { if ( contactItem ) { iContactDb->CommitContactL( *contactItem ); CleanupStack::PopAndDestroy( contactItem ); } } void CPhonebook::deleteContact(CContactItem* contactItem) { if ( contactItem ) { TContactItemId id = contactItem->Id(); iContactDb->CloseContactL( id ); CleanupStack::PopAndDestroy( contactItem ); iContactDb->DeleteContactL( id ); } }