diff -r 5b6f26637ad3 -r f4a778e096c2 phonebookui/Phonebook2/Commands/src/CPbk2CallCmd.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/phonebookui/Phonebook2/Commands/src/CPbk2CallCmd.cpp Wed Sep 01 12:29:52 2010 +0100 @@ -0,0 +1,536 @@ +/* +* Copyright (c) 2005-2007 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Phonebook 2 call command object. +* +*/ + + +// INCLUDE FILES +#include "CPbk2CallCmd.h" + +// Phonebook 2 +#include "CPbk2CallTypeSelector.h" +#include +#include +#include +#include +#include +#include + +// Virtual Phonebook +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// System includes +#include +#include +#include +#include +#include + +//SPSettings +#include +#include + +// Debugging headers +#include + +/// Unnamed namespace for local definitions +namespace { + +#ifdef _DEBUG +enum TPanicCode + { + EPanicPreCond_ExecuteLD = 1 + }; + +void Panic(TPanicCode aReason) + { + _LIT(KPanicText, "CPbk2CallCmd"); + User::Panic(KPanicText,aReason); + } +#endif // _DEBUG + +/** + * Field type matcher. + * + * @param aFieldTypeList List of field types. + * @param aFieldType Field type to search for. + * @param aResourceId Field type selector resources. + * @return ETrue if match was found. + */ +TBool MatchesFieldTypeL + ( const MVPbkFieldTypeList& aFieldTypeList, + const MVPbkFieldType& aFieldType, + TInt aResourceId ) + { + TResourceReader reader; + CCoeEnv::Static()->CreateResourceReaderLC( reader, aResourceId ); + + CVPbkFieldTypeSelector* selector = CVPbkFieldTypeSelector::NewL + ( reader, aFieldTypeList ); + + // Check if the field type is the one needed + TBool ret = selector->IsFieldTypeIncluded(aFieldType); + CleanupStack::PopAndDestroy(); // resource buffer + delete selector; + return ret; + } + +/** + * Sets a phone number to AIW dial data. + * + * @param aDialData Dial data to modify. + * @param aContact Contact containing the number. + */ +void SetDialDataNumberL + ( CAiwDialDataExt& aDialData, const MVPbkStoreContact& aContact ) + { + const MVPbkFieldTypeList& fieldTypeList = + aContact.ParentStore().StoreProperties().SupportedFields(); + const MVPbkStoreContactFieldCollection& fieldCollection = + aContact.Fields(); + TInt fieldCount( fieldCollection.FieldCount() ); + for ( TInt i = 0; i < fieldCount; ++i ) + { + const MVPbkStoreContactField& field = fieldCollection.FieldAt( i ); + const MVPbkFieldType* fieldType = field.BestMatchingFieldType(); + if( MatchesFieldTypeL( fieldTypeList, *fieldType, + R_PHONEBOOK2_PHONENUMBER_SELECTOR ) ) + { + const MVPbkContactFieldTextData* textData = + &MVPbkContactFieldTextData::Cast + ( field.FieldData() ); + const TDesC& phoneNumber( textData->Text().Left + ( AIWDialData::KMaximumPhoneNumberLength ) ); + aDialData.SetPhoneNumberL( phoneNumber ); + } + } + } + +/** + * Sets a phone number to AIW dial data. + * + * @param aDialData Dial data to modify. + * @param aField Contact field containing the number. + */ +void SetDialDataNumberL + ( CAiwDialDataExt& aDialData, const MVPbkStoreContactField& aField ) + { + TVPbkFieldStorageType dataType = aField.FieldData().DataType(); + + if ( dataType == EVPbkFieldStorageTypeText ) + { + const MVPbkContactFieldTextData* textData = + &MVPbkContactFieldTextData::Cast( aField.FieldData() ); + const TDesC& phoneNumber( textData->Text().Left + ( AIWDialData::KMaximumPhoneNumberLength ) ); + aDialData.SetPhoneNumberL( phoneNumber ); + } + + if ( dataType == EVPbkFieldStorageTypeUri ) + { + const MVPbkContactFieldUriData* textData = + &MVPbkContactFieldUriData::Cast( aField.FieldData() ); + const TDesC& phoneNumber( textData->Text().Left + ( AIWDialData::KMaximumPhoneNumberLength ) ); + aDialData.SetPhoneNumberL( phoneNumber ); + } + } +} /// namespace + +// -------------------------------------------------------------------------- +// CPbk2CallCmd::CPbk2CallCmd +// -------------------------------------------------------------------------- +// +CPbk2CallCmd::CPbk2CallCmd( MVPbkStoreContact*& aContact, + MVPbkStoreContactField* aSelectedField, + MPbk2ContactUiControl& aControl, + const TInt aCommandId, CAiwServiceHandler& aServiceHandler, + CPbk2CallTypeSelector& aSelector, + VPbkFieldTypeSelectorFactory::TVPbkContactActionTypeSelector aActionSelector ) : + iContact( aContact ), + iSelectedField( aSelectedField ), + iControl( &aControl ), + iCommandId( aCommandId ), + iServiceHandler( aServiceHandler ), + iSelector( aSelector ), + iActionSelector( aActionSelector ) + + { + PBK2_DEBUG_PRINT + (PBK2_DEBUG_STRING("CPbk2CallCmd::CPbk2CallCmd(0x%x)"), this); + + iControl->RegisterCommand( this ); + } + +// -------------------------------------------------------------------------- +// CPbk2CallCmd::~CPbk2CallCmd +// -------------------------------------------------------------------------- +// +CPbk2CallCmd::~CPbk2CallCmd() + { + PBK2_DEBUG_PRINT + (PBK2_DEBUG_STRING("CPbk2CallCmd::~CPbk2CallCmd(0x%x)"), this); + + delete iSelectedField; + if( iControl ) + { + iControl->RegisterCommand( NULL ); + } + } + +// -------------------------------------------------------------------------- +// CPbk2CallCmd::NewL +// -------------------------------------------------------------------------- +// +CPbk2CallCmd* CPbk2CallCmd::NewL( MVPbkStoreContact*& aContact, + MVPbkStoreContactField* aSelectedField, + MPbk2ContactUiControl& aControl, + const TInt aCommandId, CAiwServiceHandler& aServiceHandler, + CPbk2CallTypeSelector& aSelector ) + { + CPbk2CallCmd* self = new (ELeave ) CPbk2CallCmd + ( aContact, aSelectedField, aControl, aCommandId, + aServiceHandler, aSelector, VPbkFieldTypeSelectorFactory::EEmptySelector ); + return self; + } + +// -------------------------------------------------------------------------- +// CPbk2CallCmd::NewL +// -------------------------------------------------------------------------- +// +CPbk2CallCmd* CPbk2CallCmd::NewL( MVPbkStoreContact*& aContact, + MVPbkStoreContactField* aSelectedField, + MPbk2ContactUiControl& aControl, + const TInt aCommandId, CAiwServiceHandler& aServiceHandler, + CPbk2CallTypeSelector& aSelector, + VPbkFieldTypeSelectorFactory::TVPbkContactActionTypeSelector aActionSelector ) + { + CPbk2CallCmd* self = new (ELeave ) CPbk2CallCmd + ( aContact, aSelectedField, aControl, aCommandId, + aServiceHandler, aSelector, aActionSelector ); + return self; + } + +// -------------------------------------------------------------------------- +// CPbk2CallCmd::ExecuteLD +// -------------------------------------------------------------------------- +// +void CPbk2CallCmd::ExecuteLD() + { + PBK2_DEBUG_PRINT + (PBK2_DEBUG_STRING("CPbk2CallCmd::ExecuteLD(0x%x)"), this); + + CleanupStack::PushL( this ); + + // Setup dial data + CAiwDialDataExt* dialData = CAiwDialDataExt::NewLC(); + dialData->SetWindowGroup + ( CCoeEnv::Static()->RootWin().Identifier() ); + + // If there is a default service, use the service + TUint serviceId; + CSPSettingsVoIPUtils* sPSettings = CSPSettingsVoIPUtils::NewLC(); + if ( !sPSettings->GetPreferredService( serviceId ) ) + { + dialData->SetServiceId( serviceId ); + } + CleanupStack::PopAndDestroy( sPSettings ); + + MVPbkContactLink* contactLink = NULL; + + if ( iCommandId == EPbk2CmdCall ) + { + // Call was launched with send key, which means + // Phonebook has performed address select by itself + // and there is selected field instance + __ASSERT_DEBUG( iSelectedField && + ( iSelectedField->FieldData().DataType() == + EVPbkFieldStorageTypeText || + iSelectedField->FieldData().DataType() == + EVPbkFieldStorageTypeUri ), + Panic( EPanicPreCond_ExecuteLD ) ); + + // Create field link + contactLink = iSelectedField->CreateLinkLC(); + + // Set number + SetDialDataNumberL( *dialData, *iSelectedField ); + + // We also have select call type by ourselves + SetCallTypeL( *dialData ); + + // If field data has service prefix, extract it and find matched service id + // from SP setting, then set the matched service id to daildata. + // Service prefix from field data has higher priority over preferred service + TPtrC xspId; + if ( ExtractXspId( iSelectedField, xspId ) ) + { + TUint srcId = GetMatchedServiceIdL( xspId ); + + if ( srcId != (TUint)KErrNotFound ) + { + dialData->SetServiceId( srcId ); + } + } + } + else + { + if ( iSelectedField ) + { + // If selected field is set create field link from it. + contactLink = iSelectedField->CreateLinkLC(); + } + else + { + // Otherwise use contact + contactLink = iContact->CreateLinkLC(); + } + + if ( !contactLink ) + { + // Temporary contact, set number here + SetDialDataNumberL( *dialData, *iContact ); + } + } + + if ( contactLink ) + { + HBufC8* linkBuffer = contactLink->PackLC(); + dialData->SetContactLinkL( *linkBuffer ); + } + else + { + CPbk2ApplicationServices* appServices = CPbk2ApplicationServices::InstanceLC(); + MPbk2ContactNameFormatter& nameFormatter = + appServices->NameFormatter(); + const MVPbkStoreContactFieldCollection& fieldCollection = + iContact->Fields(); + HBufC* title = nameFormatter.GetContactTitleOrNullL( + fieldCollection, + MPbk2ContactNameFormatter::EPreserveLeadingSpaces ); + CleanupStack::PopAndDestroy(); + CleanupStack::PushL( title ); + + if ( title ) + { + dialData->SetNameL( *title ); + } + } + + // Get an empty in param list.. + CAiwGenericParamList& inParamList = iServiceHandler.InParamListL(); + // ..and pass it to dial data in order for it to fill it + dialData->FillInParamListL( inParamList ); + + if ( contactLink ) + { + CleanupStack::PopAndDestroy( 3 ); // linkBuffer, contactLink, dialData + } + else + { + CleanupStack::PopAndDestroy( 2 ); // title, dialData + } + + + // If the command id is EPbk2CmdCall it means the call was launched + // with send key and we therefore must use different AIW command + // than when the call was selected from the menu + if ( iCommandId == EPbk2CmdCall ) + { + iServiceHandler.ExecuteServiceCmdL( + KAiwCmdCall, + inParamList, + iServiceHandler.OutParamListL(), + 0, // No options used. + NULL); // No need for callback + } + else // the call was launched from menu + { + // Relay the command to AIW for handling + iServiceHandler.ExecuteMenuCmdL( + iCommandId, + inParamList, + iServiceHandler.OutParamListL(), + 0, // No options used. + NULL); // No need for callback + } + + // Update UI control + if( iControl ) + { + TInt fieldIndex = iControl->FocusedFieldIndex(); + iControl->ResetFindL(); + if( iContact ) + { + iControl->SetFocusedContactL( *iContact ); + } + iControl->SetFocusedFieldIndex( fieldIndex ); + } + + // Destroy itself as promised + CleanupStack::PopAndDestroy(); // this + } + +// -------------------------------------------------------------------------- +// CPbk2CallCmd::ResetUiControl +// -------------------------------------------------------------------------- +// +void CPbk2CallCmd::ResetUiControl( MPbk2ContactUiControl& aUiControl ) + { + if( iControl == &aUiControl ) + { + iControl = NULL; + } + } + +// -------------------------------------------------------------------------- +// CPbk2CallCmd::AddObserver +// -------------------------------------------------------------------------- +// +void CPbk2CallCmd::AddObserver( MPbk2CommandObserver& /*aObserver*/ ) + { + // Do nothing + } + +// -------------------------------------------------------------------------- +// CPbk2CallCmd::SetCallTypeL +// -------------------------------------------------------------------------- +// +void CPbk2CallCmd::SetCallTypeL( CAiwDialDataExt& dialData ) + { + switch( iActionSelector ) + { + CAiwDialData::TCallType callType; + case VPbkFieldTypeSelectorFactory::EEmptySelector: + callType = iSelector.SelectCallTypeL + ( iCommandId, *iContact, iControl->FocusedField(), *iSelectedField ); + dialData.SetCallType( callType ); + break; + case VPbkFieldTypeSelectorFactory::EVoiceCallSelector: + dialData.SetCallType( CAiwDialData::EAIWForcedCS ); + break; + case VPbkFieldTypeSelectorFactory::EVOIPCallSelector: + callType = iSelector.SelectVoipCallTypeL( iSelectedField ); + dialData.SetCallType( callType ); + break; + case VPbkFieldTypeSelectorFactory::EVideoCallSelector: + dialData.SetCallType( CAiwDialData::EAIWForcedVideo ); + break; + default: + dialData.SetCallType ( CAiwDialData::EAIWForcedCS); + break; + } + } + +// -------------------------------------------------------------------------- +// CPbk2CallCmd::ExtractXspId +// -------------------------------------------------------------------------- +// +TBool CPbk2CallCmd::ExtractXspId( + const MVPbkStoreContactField* aSelectedField, TPtrC& aXSPId ) const + { + TBool found = EFalse; + _LIT( KColon, ":" ); + + const MVPbkContactFieldData& fieldData = aSelectedField->FieldData(); + TPtrC data = GetFieldData( fieldData ); + TInt pos = data.Find( KColon ); + + if ( pos > 0 ) + { + aXSPId.Set( data.Left( pos ) ); + found = ETrue; + } + + return found; + } + +// -------------------------------------------------------------------------- +// CPbk2CallCmd::GetMatchedServiceIdL +// -------------------------------------------------------------------------- +// +TServiceId CPbk2CallCmd::GetMatchedServiceIdL( const TDesC& aXSPId ) + { + TUint ret = ( TUint )KErrNotFound; + CDesCArrayFlat* nameArray = NULL; + + RIdArray ids; + CleanupClosePushL( ids ); + + nameArray = new (ELeave) CDesCArrayFlat( 2 ); + CleanupStack::PushL( nameArray ); + + CSPSettings* settings = CSPSettings::NewLC(); + + settings->FindServiceIdsL( ids ); + settings->FindServiceNamesL( ids, *nameArray ); + + const TInt count = nameArray->MdcaCount(); + for ( TInt i=0; i < count; i++ ) + { + // Find the mathched service + TPtrC name = nameArray->MdcaPoint( i ); + if ( !name.CompareF( aXSPId ) ) + { + // Service found + ret = ids[i]; + break; + } + } + CleanupStack::PopAndDestroy( 3 ); // ids, nameArray, settings + + return ret; + } + +// -------------------------------------------------------------------------- +// CPbk2CallCmd::GetFieldData +// -------------------------------------------------------------------------- +// +TPtrC CPbk2CallCmd::GetFieldData( const MVPbkContactFieldData& aFieldData ) const + { + TPtrC text ( KNullDesC() ); + + switch ( aFieldData.DataType() ) + { + // Text storage type + case EVPbkFieldStorageTypeText: + { + const MVPbkContactFieldTextData& textData = MVPbkContactFieldTextData::Cast( aFieldData ); + text.Set( textData.Text() ); + break; + } + // URI storage type + case EVPbkFieldStorageTypeUri: + { + const MVPbkContactFieldUriData& textData = MVPbkContactFieldUriData::Cast( aFieldData ); + text.Set( textData.Text() ); + break; + } + } + + return text; + } + +// End of File