diff -r 6465d5bb863a -r 13e71d907dc3 gssettingsuis/Gs/GSCallDivertPlugin/Src/GSCallDivertView.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gssettingsuis/Gs/GSCallDivertPlugin/Src/GSCallDivertView.cpp Thu Nov 04 13:38:47 2010 +0800 @@ -0,0 +1,1386 @@ +/* +* Copyright (c) 2002-2008 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: Main view handling for Call Divert. +* +*/ + + +// INCLUDE FILES +#include "GSCallDivertContainer.h" +#include "GSCallDivertModel.h" +#include "GSCallDivertQuery.h" +#include "GSCallDivertView.h" +#include "GsLogger.h" +#include "GSPhoneSettingConstants.h" +#include "GSRestrictedDivertContainer.h" +#include "LocalViewId.h" + + +#include +#include +#include //for AknErrorNote +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include // for restricted call forward +#include +#include +#include +#include +#include +#include +#include +#include +#include // for Number Grouping +#include +#include +#include +#include +#include +#include +#include +#include +#include // for Help Launcher +#include // For HlpLauncher +#include +#include +#include +#include +#include + +using namespace AiwContactAssign; + +// LOCAL CONSTANTS +_LIT( KGSDivertClassName, "CGSCallDivertView" ); + +_LIT( KCallDivertInvalidchars, " ()" ); + +// ========================= MEMBER FUNCTIONS ================================ + +// --------------------------------------------------------------------------- +// CGSCallDivertView::CGSCallDivertView +// +// C++ constructor. +// --------------------------------------------------------------------------- +CGSCallDivertView::CGSCallDivertView( CGSCallDivertModel* aModel ) + : iModel( aModel ) + { + } + +// --------------------------------------------------------------------------- +// CGSCallDivertView::ConstructL +// +// Symbian OS two-phased constructor. +// --------------------------------------------------------------------------- +void CGSCallDivertView::ConstructL() + { + if( FeatureManager::FeatureSupported( KFeatureIdRestrictedCallDivert ) ) + { + iModel->SetDivertServiceGroup( EGSSettIdVoiceDivert ); + } + iModel->SetDivertView( this ); + + iStoresOpened = EFalse; + iNumberFetchedAsynchronously = EFalse; + + BaseConstructL( R_CF_DIV_VIEW ); + + iTitles = iCoeEnv->ReadDesCArrayResourceL( R_TITLE_ARRAY ); + iRockerPress = EFalse; + + //Check video mailbox suppport from cenrep + //Since it is static feature, needs to be checked only once + CRepository* videoMailboxRepository = + CRepository::NewLC( KCRUidVideoMailbox ); + videoMailboxRepository->Get( KVideoMbxSupport, iVideoMailboxSupported ); + CleanupStack::PopAndDestroy( videoMailboxRepository ); + + // AIW for pbk2 contact selection functionality. Construct contact manager + // with the same store configuration as in Phonebook currently. + iServiceHandler = CAiwServiceHandler::NewL(); + iServiceHandler->AttachL( R_CALL_DIVERT_CONTACT_SELECTION_INTEREST ); + CPbk2StoreConfiguration* configuration = CPbk2StoreConfiguration::NewL(); + CleanupStack::PushL( configuration ); + CVPbkContactStoreUriArray* uriArray = configuration->CurrentConfigurationL(); + CleanupStack::PushL( uriArray ); + iContactManager = CVPbkContactManager::NewL( *uriArray ); + iContactManager->ContactStoresL().OpenAllL( *this ); + CleanupStack::PopAndDestroy( uriArray ); + CleanupStack::PopAndDestroy( configuration ); + } + +// --------------------------------------------------------------------------- +// CGSCallDivertView::~CGSCallDivertView +// +// Destructor. +// --------------------------------------------------------------------------- +CGSCallDivertView::~CGSCallDivertView() + { + if ( iTitles ) + { + delete iTitles; + } + if( iRetrieveOperation ) + { + delete iRetrieveOperation; + iRetrieveOperation = NULL; + } + if( iContactLinks ) + { + delete iContactLinks; + iContactLinks = NULL; + } + + TRAP_IGNORE + ( + if( iContactManager ) + { + iContactManager->ContactStoresL().CloseAll( *this ); + iStoresOpened = EFalse; + delete iContactManager; + } + ); + delete iServiceHandler; + + + if( iContextMenuItems ) + { + delete iContextMenuItems; + iContextMenuItems = NULL; + } + } + +// --------------------------------------------------------------------------- +// CGSCallDivertView::NewLC +// +// 1st phase constructor. +// --------------------------------------------------------------------------- +CGSCallDivertView* CGSCallDivertView::NewLC( CGSCallDivertModel* aModel ) + { + CGSCallDivertView* self; + self = new ( ELeave ) CGSCallDivertView( aModel ); + CleanupStack::PushL( self ); + self->ConstructL(); + return self; + } + +// --------------------------------------------------------------------------- +// CGSCallDivertView::NewContainerL +// +// Creates new iContainer. +// --------------------------------------------------------------------------- +void CGSCallDivertView::NewContainerL() + { + if( FeatureManager::FeatureSupported( KFeatureIdRestrictedCallDivert ) ) + { + iContainer = new (ELeave) CGSRestrictedDivertContainer(); + } + else + { + iContainer = new (ELeave) CGSCallDivertContainer( + iModel->DivertServiceGroup() ); + } + } + + +// --------------------------------------------------------------------------- +// CGSCallDivertView::Id +// +// implementation of the frameworks virtual function, closely related with view +// architecture and has little or no relevance here +// --------------------------------------------------------------------------- +TUid CGSCallDivertView::Id() const + { + if( FeatureManager::FeatureSupported( KFeatureIdRestrictedCallDivert ) ) + { + return KCallDivertPluginId; + } + else + { + return KCallDivertViewId; + } + } + +// --------------------------------------------------------------------------- +// CGSCallDivertView::HandleCommandL +// +// Handles the received commands +// --------------------------------------------------------------------------- +void CGSCallDivertView::HandleCommandL( TInt aCommand ) + { + iVoiceMailboxDivert = EFalse; + TBool sendRequest = EFalse; + RMobilePhone::TMobilePhoneServiceAction info = + RMobilePhone::EServiceActionRegister; + TCallDivertSetting divertRequest; + + if ( aCommand != ECFCmdCancelAll && iContainer ) + { + if( FeatureManager::FeatureSupported( KFeatureIdRestrictedCallDivert ) ) + { + CGSRestrictedDivertContainer& container = + *static_cast( iContainer ); + iCurrentItem = container.CurrentFeatureId(); + } + else + { + CGSCallDivertContainer& container = + *static_cast( iContainer ); + iCurrentItem = container.CurrentFeatureId(); + } + __GSLOGSTRING1("[CGSCallDivertView::HandleCommandL] iCurrentItem: %d", iCurrentItem); + + __ASSERT_ALWAYS( iCurrentItem != KErrNotFound, Panic( KGSDivertClassName, + EInvalidCurrentItem ) ); + } + + switch ( aCommand ) + { + case EGSCmdAppChange: + iRockerPress = EFalse; + if ( iContainer ) + { + HandleListBoxEventL( iContainer->iListBox, EEventEnterKeyPressed ); + } + break; + case EAknSoftkeyBack: + if( FeatureManager::FeatureSupported( KFeatureIdRestrictedCallDivert ) ) + { + iAppUi->ActivateLocalViewL( KGSTelPluginUid ); + } + else + { + iAppUi->ActivateLocalViewL( KCallDivertPluginId ); + } + break; + case EAknSoftkeyExit: + AppUi()->HandleCommandL( EEikCmdExit ); + break; + case ECFCmdActivate: + divertRequest.iSetting = EActivateDiverting; + info = RMobilePhone::EServiceActionRegister; + + // Activate depends on the selected call type (voice/data/fax) + switch( iModel->DivertServiceGroup() ) + { + case EGSSettIdVoiceDivert: + // Handle voice divert. Fetch used numbers and show it in query. + ExecuteDivertQueryL( + divertRequest.iNumber, + iTitles->MdcaPoint( iCurrentItem ), + iVoiceMailboxDivert ); + sendRequest = ETrue; + break; + case EGSSettIdVideoDivert: + if( iVideoMailboxSupported ) + { + // Fetch used data divert number and show it in query. + ExecuteDivertQueryL( + divertRequest.iNumber, + iTitles->MdcaPoint( iCurrentItem ), + iVoiceMailboxDivert ); + sendRequest = ETrue; + } + else + { + DisplayDataCallDivertNumberQueryL( divertRequest.iNumber ); + sendRequest = ETrue; + } + break; + default: + User::Panic( KGSDivertClassName, KErrArgument ); + break; + } + break; + case ECFCmdCancel: + if( FeatureManager::FeatureSupported( KFeatureIdRestrictedCallDivert ) ) + { + sendRequest = EFalse; + iModel->CancelRestrictedCallDivertL(); + } + else + { + sendRequest = ETrue; + divertRequest.iSetting = ECancelDiverting; + info = RMobilePhone::EServiceActionErase; + } + break; + case ECFCmdCheckStatus: + if( FeatureManager::FeatureSupported( KFeatureIdRestrictedCallDivert ) ) + { + sendRequest = EFalse; + iModel->CheckStatusRestrictedCallDivertL(); + } + else + { + sendRequest = ETrue; + divertRequest.iSetting = ECheckStatus; + info = RMobilePhone::EServiceActionUnspecified; + } + break; + case ECFCmdCancelAll: + sendRequest = ETrue; + divertRequest.iSetting = EEraseDiverting; + info = RMobilePhone::EServiceActionErase; + break; + case EAknCmdHelp: + { + if( FeatureManager::FeatureSupported( KFeatureIdHelp ) ) + { + HlpLauncher::LaunchHelpApplicationL( + iEikonEnv->WsSession(), iAppUi->AppHelpContextL() ); + } + break; + } + default: + iAppUi->HandleCommandL( aCommand ); + break; + } + + // If a request needs to be sent. + if ( sendRequest ) + { + // will not divert in case empty number + iModel->SendCallDivertRequestL( divertRequest, + info, + iVoiceMailboxDivert, + aCommand, + (TGSCallDivertServices) iCurrentItem ); + } + } + + +// --------------------------------------------------------------------------- +// CGSCallDivertView::HandleListBoxSelectionL +// +// Handles List box selection +// --------------------------------------------------------------------------- +void CGSCallDivertView::HandleListBoxSelectionL() + { + iRockerPress = ETrue; + CEikMenuBar* menuBar = MenuBar(); + if ( iRockerPress ) + { + menuBar->SetMenuTitleResourceId( R_CF_MENUBAR_OPTIONS_VIEW ); + menuBar->SetMenuType( CEikMenuBar::EMenuContext ); + } + else + { + menuBar->SetMenuTitleResourceId( R_CF_MENUBAR_DIV_VIEW ); + menuBar->SetMenuType( CEikMenuBar::EMenuOptions ); + } + + // Display menu bar. + menuBar->TryDisplayMenuBarL(); + + // Reset menu type to original default (EMenuOptions). + menuBar->SetMenuType( CEikMenuBar::EMenuOptions ); + + iRockerPress = EFalse; + } + + +// --------------------------------------------------------------------------- +// CGSCallDivertView::ExecuteDivertQueryL +// +// --> voice calls -> all voice calls -> activate -> this popup. +// OR +// --> video calls -> all video calls -> activate -> this popup. +// +// ---Example--- +// All [voice/]video calls: +// To [voice/]video mailbox +// [050512345678] +// [543454545435] +// [342343242343] +// To other number +// --------------------------------------------------------------------------- +// +void CGSCallDivertView::ExecuteDivertQueryL( TTelNumber& aTelNumber, + const TPtrC& aTitle, + TBool& aVmbxValidNumber ) + { + __GSLOGSTRING("[CGSCallDivertView::ExecuteDivertQueryL]"); + + CAknSinglePopupMenuStyleListBox* list = + new ( ELeave ) CAknSinglePopupMenuStyleListBox; + CleanupStack::PushL( list ); + + CDesC16ArrayFlat* defNumbers = + new ( ELeave ) CDesC16ArrayFlat( KCFDefaultNumbers ); + CleanupStack::PushL( defNumbers ); + + CAknPopupList* divertPopup = + CAknPopupList::NewL( list, R_AVKON_SOFTKEYS_OK_CANCEL__OK ); + CleanupStack::PushL( divertPopup ); + + list->ConstructL( divertPopup,CEikListBox::ELeftDownInViewRect ); + list->CreateScrollBarFrameL( ETrue ); + list->ScrollBarFrame()->SetScrollBarVisibilityL( + CEikScrollBarFrame::EOff, + CEikScrollBarFrame::EAuto ); + divertPopup->SetTitleL( aTitle ); + if( iContextMenuItems ) + { + delete iContextMenuItems; + iContextMenuItems = NULL; + } + iContextMenuItems = new ( ELeave ) CDesCArrayFlat( KCFMaxNrOfTargets ); + if( iModel->DivertServiceGroup() == EGSSettIdVoiceDivert ) + { + CreateVoiceDivertItemsL( *iContextMenuItems, *defNumbers ); + } + else + { + CreateVideoDivertItemsL( *iContextMenuItems ); + } + __GSLOGSTRING2( "[CGSCallDivertView::ExecuteDivertQueryL] ItemCount: %d, defNumCount: %d", + iContextMenuItems->Count(), + defNumbers->Count() ); + CTextListBoxModel* model = list->Model(); + model->SetItemTextArray( iContextMenuItems ); + model->SetOwnershipType( ELbmDoesNotOwnItemArray ); + + // Executeld handles the events in the list + TBool modified = divertPopup->ExecuteLD(); + __GSLOGSTRING1("[CGSCallDivertView::ExecuteDivertQueryL] modified: %d", modified); + CleanupStack::Pop(); //voiceDivertPopup + + if ( modified ) + { + if( iModel->DivertServiceGroup() == EGSSettIdVoiceDivert ) + { + aTelNumber = HandleVoiceDivertSelectionL( *list, + *defNumbers, + aVmbxValidNumber ); + } + else + { + aTelNumber = HandleVideoDivertSelectionL( *list ); + } + } + __GSLOGSTRING1( "[CGSCallDivertView::ExecuteVoiceDivertQueryL] aTelNumber: %S", + &aTelNumber); + CleanupStack::PopAndDestroy( 2 ); //defNumbers, list + __GSLOGSTRING( "[CGSCallDivertView::ExecuteVoiceDivertQueryL] End." ); + } + + +// --------------------------------------------------------------------------- +// CGSCallDivertView::HandleVoiceDivertSelectionL +// +// Handles user's choice in the Target list. +// --------------------------------------------------------------------------- +TTelNumber CGSCallDivertView::HandleVoiceDivertSelectionL( + CAknSinglePopupMenuStyleListBox& aList, + CDesC16ArrayFlat& aDefNumbers, + TBool& aVmbxDivert ) + { + __GSLOGSTRING("[CGSCallDivertView::HandleVoiceDivertSelectionL] Start..."); + TTelNumber telNumber; + telNumber.Zero(); + TInt index = aList.CurrentItemIndex(); + __GSLOGSTRING1("[CGSCallDivertView::HandleVoiceDivertSelectionL] index: %d", index); + + if ( index == KCFDivertToMailBox ) + { + if ( iModel->VoiceMailActivationL( telNumber ) == KErrNone ) + { + if ( telNumber == KNullDesC ) + { + ShowErrorNoteL(); + } + aVmbxDivert = ETrue; + } + } + //To other number - make a dataquery + else if ( index == ( aList.Model()->NumberOfItems() - 1 ) ) + { + ExecuteDivertNumberQueryL( telNumber, R_TEXT_PRMPT_NUMBER ); + __GSLOGSTRING1("[CGSCallDivertView::HandleVoiceDivertSelectionL] telNumber: %S", &telNumber); + + UpdateDefaultVoiceDivertNumbersL( telNumber ); + } + //To pre-defined default number + else + { + telNumber = aDefNumbers.MdcaPoint( index - 1 ); + iModel->DivertHandler()->SwapDefaultNumberL( index ); + } + __GSLOGSTRING("[CGSCallDivertView::HandleVoiceDivertSelectionL] End."); + return telNumber; + } + + +// --------------------------------------------------------------------------- +// CGSCallDivertView::HandleVideoDivertSelectionL +// +// Handles user's choice in the video Target list. +// --------------------------------------------------------------------------- +TTelNumber CGSCallDivertView::HandleVideoDivertSelectionL( + CAknSinglePopupMenuStyleListBox& aList ) + { + __GSLOGSTRING("[GSCallDivertView::HandleVideoDivertSelectionL] Start"); + TTelNumber telNumber( 0 ); + TInt index = aList.CurrentItemIndex(); + if ( index == KCFDivertToMailBox ) + { + if ( iModel->VideoMailActivationL( telNumber ) == KErrNone ) + { + if ( telNumber == KNullDesC ) + { + ShowErrorNoteL(); + } + } + } + else if( index == ( aList.Model()->NumberOfItems() - 1 ) ) + { // To other number - make a dataquery (Last item in list) + DisplayDataCallDivertNumberQueryL( telNumber ); + __GSLOGSTRING1("[GSCallDivertView::HandleVideoDivertSelectionL] telNumber: %S", &telNumber ); + } + __GSLOGSTRING("[GSCallDivertView::HandleVideoDivertSelectionL] Finished"); + return telNumber; + } + + +// --------------------------------------------------------------------------- +// CGSCallDivertView::DisplayDataCallDivertNumberQueryL +// +// Displays data call number query and sets call divert +// --------------------------------------------------------------------------- +void CGSCallDivertView::DisplayDataCallDivertNumberQueryL( TTelNumber& aTelNumber ) + { + aTelNumber = *iModel->DivertHandler()->GetUsedDataNumberLC(); + ExecuteDivertNumberQueryL( aTelNumber, R_TEXT_PRMPT_DATA_NUMBER ); + if( aTelNumber != KNullDesC ) + { + iModel->DivertHandler()->SetUsedDataNumberL( aTelNumber ); + } + CleanupStack::PopAndDestroy(); // aTelNumber from GetUsedDataNumberLC() + } + + +// --------------------------------------------------------------------------- +// CGSCallDivertView::ExecuteDivertNumberQueryL +// +// Executes general number query dialog used by all diverts (voice/data/fax) +// --------------------------------------------------------------------------- +// +void CGSCallDivertView::ExecuteDivertNumberQueryL( TDes& aValue, TInt aType ) + { + TBool accepted = EFalse; + while ( !accepted ) + { + RemoveInvalidChars( aValue ); + if ( aValue.Length() > KGSMaxDataLength ) + { + //Chop the first extra digits and keep the last KGSMaxDataLength + //digits intact. This is according to the spec. + aValue.Delete( 0, aValue.Length() - KGSMaxDataLength ); + } + + __GSLOGSTRING1("[CGSCallDivertView] ExecuteDivertNumberQueryL: aValue: %S", &aValue); + + if( AknTextUtils::DigitModeQuery( AknTextUtils::EDigitModeEditorDefault ) ) + { + AknTextUtils::DisplayTextLanguageSpecificNumberConversion( aValue ); + } + CGSCallDivertQuery* query = CGSCallDivertQuery::NewL( aValue, + CAknQueryDialog::ENoTone, + R_AVKON_SOFTKEYS_OK_CANCEL__OK, R_CF_SOFTKEYS_SEARCH_CANCEL ); + CleanupStack::PushL( query ); + SetPromptToQueryL( *query, aType ); + TInt queryAction = query->ExecuteLD( R_DATA_QUERY ); + CleanupStack::Pop( query ); + AknTextUtils::ConvertDigitsTo( aValue, EDigitTypeWestern ); + switch ( queryAction ) + { + case EAknSoftkeySearch: + if( iStoresOpened ) + { + // Reset the number selection because 'search' is selected. + aValue.Zero(); + StartAsyncPhoneNumberFetchL(); + accepted = ETrue;// Change to asynchronous mode + } + break; + case EAknSoftkeyOk: + accepted = ETrue; + if ( ValidatePhoneNumberL( aValue ) > KCFValidPhoneNumber || + aValue.Length() == 0 ) + { + accepted = EFalse; + } + if ( iNumberFetchedAsynchronously ) + { + switch( iModel->DivertServiceGroup() ) + { + case EGSSettIdVoiceDivert: + UpdateDefaultVoiceDivertNumbersL( aValue ); + break; + case EGSSettIdVideoDivert: + { + TTelNumber dataNumber( aValue );// Convert to TTelNumber + iModel->DivertHandler()->SetUsedDataNumberL( dataNumber ); + break; + } + default: + break; + } + iNumberFetchedAsynchronously = EFalse; + } + break; + case EAknSoftkeyBack: + case EAknSoftkeyCancel: + default: + accepted = ETrue; + aValue.Zero(); + break; + } + } + } + + +// --------------------------------------------------------------------------- +// CGSCallDivertView::StartAsyncPhoneNumberFetchL +// +// Fetches values from phonebook ASYNCHRONOUSLY (pbk2 requirement). +// --------------------------------------------------------------------------- +// +void CGSCallDivertView::StartAsyncPhoneNumberFetchL() + { + TUint fetchFlags = 0; + + // Construct empty filter + CVPbkFieldTypeSelector* contactViewFilter = + CVPbkFieldTypeSelector::NewL(iContactManager->FieldTypes()); + CleanupStack::PushL(contactViewFilter); + + // Append the filter object with suitable criteria (only contacts with + // phone number shown) + VPbkContactViewFilterBuilder::BuildContactViewFilterL(*contactViewFilter, + EVPbkContactViewFilterPhoneNumber, *iContactManager); + RVPbkContactFieldDefaultPriorities array; + CleanupClosePushL(array); + + TAiwSingleItemSelectionDataV3 data = TAiwSingleItemSelectionDataV3(); + // Details selection shows only phone numbers + data.SetAddressSelectType(EAiwPhoneNumberSelect); + data.SetDefaultPriorities(array); + // Contact list shows only contacts that have phone number(s) + data.SetFetchFilter(contactViewFilter); + data.SetFlags(fetchFlags); + + CAiwGenericParamList& inParamList = iServiceHandler->InParamListL(); + TAiwGenericParam param(EGenericParamContactSelectionData, + TAiwVariant(TAiwSingleItemSelectionDataV3Pckg(data))); + inParamList.AppendL(param); + + iServiceHandler->ExecuteServiceCmdL( + KAiwCmdSelect, + inParamList, + iServiceHandler->OutParamListL(), + 0, + this); + + CleanupStack::PopAndDestroy(); // array + CleanupStack::PopAndDestroy( contactViewFilter ); + } + + +// --------------------------------------------------------------------------- +// CGSCallDivertView::ValidatePhoneNumberL +// +// Puts a single resource string into a list. +// --------------------------------------------------------------------------- +TInt CGSCallDivertView::ValidatePhoneNumberL( const TDesC& aDivertTo ) + { + TInt enteredNumber = KErrNone; + TInt noOfInvalidChars = KCFInvalidChars().Length(); + + // Plus is a special case, as it is accepted as first character. + // FindPlus returns KCFErrIllegalNumber(1) if the number is not + // acceptable. + enteredNumber += FindPlus( aDivertTo ); + for ( TInt index = 0; index < noOfInvalidChars; index++ ) + { + enteredNumber += aDivertTo.Find( + KCFInvalidChars().Mid( index, 1 ) ); + } + // Find returns KErrNotFound(-1), if character(s) is not found. + // Therefore, after four searches for special characters in the + // number, all results that have greater than -5 as result are not + // acceptable. + if ( enteredNumber > KCFValidPhoneNumber ) + { + ShowErrorNoteL(); + __GSLOGSTRING( "[CGSCallDivertView::ValidatePhoneNumberL] Invalid phone number. " ); + } + return enteredNumber; + } + + +// --------------------------------------------------------------------------- +// CGSCallDivertView::AppendDelayItemL +// +// Appends items to delay time list. +// --------------------------------------------------------------------------- +void CGSCallDivertView::AppendDelayItemL( CDesCArrayFlat& aArrayToAppend, + TInt aIndex ) + { + //Delay times are defined as 5,10,15,20,25,30. + //Append each of these to a list. + TInt delaySeconds = KCFDelayStep * ( aIndex + 1); + HBufC* string = StringLoader::LoadLC( R_TEXT_SLIST_SECONDS, delaySeconds ); + + TPtr bufPtr = string->Des(); + if( AknTextUtils::DigitModeQuery( AknTextUtils::EDigitModeShownToUser ) ) + { + AknTextUtils::LanguageSpecificNumberConversion( bufPtr ); + } + aArrayToAppend.AppendL( *string ); + CleanupStack::PopAndDestroy( string ); + } + + +// --------------------------------------------------------------------------- +// CGSCallDivertView::CreateVoiceDivertItemsL +// +// Creates items for the targert list. +// --------------------------------------------------------------------------- +void CGSCallDivertView::CreateVoiceDivertItemsL( + CDesCArray& aItems, + CDesC16ArrayFlat& aDefaultNumbers ) + { + HBufC* item = StringLoader::LoadLC( R_TEXT_DIVERT_TO_VOICE_MAIL ); + aItems.AppendL( *item ); + CleanupStack::PopAndDestroy( item ); + ReadDefaultVoiceDivertNumbersL( aItems, aDefaultNumbers ); + HBufC* string = StringLoader::LoadLC( R_TEXT_DIVERT_TO_NUMBER ); + aItems.AppendL( *string ); + CleanupStack::PopAndDestroy( string ); + } + + +// --------------------------------------------------------------------------- +// CGSCallDivertView::CreateVideoDivertItemsL +// +// Creates items for the data target list. +// --------------------------------------------------------------------------- +void CGSCallDivertView::CreateVideoDivertItemsL( CDesCArray& aItems ) + { + HBufC* item = StringLoader::LoadLC( R_QTN_SS_DIVERT_TO_VIDEO_MAILBOX ); + aItems.AppendL( *item ); + CleanupStack::PopAndDestroy( item ); + HBufC* string = StringLoader::LoadLC( R_QTN_SS_DIVERT_VCALL_TO_OTHER_NUMBER ); + aItems.AppendL( *string ); + CleanupStack::PopAndDestroy( string ); + } + + +// --------------------------------------------------------------------------- +// +// Seeks '+' from given number. If '+' is first character, it is ignored. +// +// --------------------------------------------------------------------------- +TInt CGSCallDivertView::FindPlus( const TDesC& aDivertTo ) + { + TInt seekPlus = aDivertTo.Find( KCFPlusSign ); + if ( seekPlus == KErrNotFound ) + { + //no '+' in the number + return KErrNone; + } + //first char '+', but there can additional '+'s + if ( seekPlus == 0 ) + { + //ignore first '+' + TPtrC concat = aDivertTo.Right( aDivertTo.Length() - 1 ); + seekPlus = concat.Find( KCFPlusSign ); + if ( seekPlus != KErrNotFound ) + { + return KCFErrIllegalNumber; //two '+'s in number + } + return KErrNone; + } + //'+' in number, but not first char + else + { + return KCFErrIllegalNumber; + } + } + + +// --------------------------------------------------------------------------- +// CGSCallDivertView::SetPromptToQueryL +// Sets prompt to a query. +// +// --------------------------------------------------------------------------- +void CGSCallDivertView::SetPromptToQueryL( CGSCallDivertQuery& aQuery, + const TInt& aType ) + { + HBufC* title = StringLoader::LoadLC( aType ); + aQuery.SetPromptL( *title ); + CleanupStack::PopAndDestroy( title ); + } + + +// --------------------------------------------------------------------------- +// CGSCallDivertView::CreateDelayTimeItemsL +// Creates items for delay time list. +// +// --------------------------------------------------------------------------- +// +void CGSCallDivertView::CreateDelayTimeItemsL( CDesCArrayFlat& aItems) + { + for ( TInt index = 0; index < KGSNrOfDelays; index++ ) + { + AppendDelayItemL( aItems, index ); + } + } + + +// --------------------------------------------------------------------------- +// CGSCallDivertView::CreateRestrictedCallDivertDelayTimeItemsL +// Creates items for Delay time list for restricted call divert. +// +// --------------------------------------------------------------------------- +// +void CGSCallDivertView::CreateRestrictedCallDivertDelayTimeItemsL( + CDesCArrayFlat& aItems ) + { + // first item is 0 seconds + AppendDelayItemL( aItems, -1); + for ( TInt index = 0; index < KGSNrOfDelays; index++ ) + { + AppendDelayItemL( aItems, index ); + } + AppendDelayItemL( aItems, ( 60 / KCFDelayStep ) - 1); + AppendDelayItemL( aItems, ( 90 / KCFDelayStep ) - 1); + AppendDelayItemL( aItems, ( 120 / KCFDelayStep ) - 1); + } + +// ----------------------------------------------------------------------------- +// CGSCallDivertView::ProcessCommandL +// ----------------------------------------------------------------------------- +void CGSCallDivertView::ProcessCommandL( TInt aCommand ) + { + MenuBar()->SetContextMenuTitleResourceId( R_CALL_DIVERT_MSK_CONTEXTMENUBAR ); + // Call base class + CAknView::ProcessCommandL( aCommand ); + } + + +// --------------------------------------------------------------------------- +// +// Before showing a options menu, delete options key specific settings if +// rocker key has been pressed. +// --------------------------------------------------------------------------- +// +void CGSCallDivertView::DynInitMenuPaneL( TInt aResourceId, + CEikMenuPane* aMenuPane ) + { + TInt currentItem; + CEikMenuBar* menuBar = MenuBar(); + if( FeatureManager::FeatureSupported( KFeatureIdRestrictedCallDivert ) ) + { + CGSRestrictedDivertContainer &container = + *static_cast( iContainer ); + currentItem = container.CurrentFeatureId(); + } + else + { + CGSCallDivertContainer& container = + *static_cast( iContainer ); + currentItem = container.CurrentFeatureId(); + } + + if ( aResourceId == R_CF_DIV_VIEW_MENU ) + { + if (!menuBar->ItemSpecificCommandsEnabled() && menuBar->GetMenuType() == CEikMenuBar::EMenuOptions) + { + aMenuPane->SetItemDimmed( ECFCmdActivate, ETrue ); + aMenuPane->SetItemDimmed( ECFCmdCancel, ETrue ); + aMenuPane->SetItemDimmed( ECFCmdCheckStatus, ETrue ); + } + //remove help, if not supported from the main divert view + //in this step, help is added to context menu too, which + //is deleted in the next conditional stmt + if ( FeatureManager::FeatureSupported ( KFeatureIdHelp ) ) + { + aMenuPane->SetItemDimmed( EAknCmdHelp, EFalse ); + } + else + { + aMenuPane->SetItemDimmed( EAknCmdHelp, ETrue ); + } + + if ( iRockerPress ) + { + //remove Exit & Help from the menu + aMenuPane->SetItemDimmed( EAknCmdExit, ETrue ); + aMenuPane->SetItemDimmed( EAknCmdHelp, ETrue ); + } + else + { + iRockerPress = EFalse; + } + } + + if ( aResourceId == R_CF_MSK_DIV_VIEW_MENU || + aResourceId == R_CF_DIV_VIEW_MENU ) + { + // when not available does not have check status + if ( currentItem == ECFDivertWhenNotAvailable ) + { + aMenuPane->SetItemDimmed( ECFCmdCheckStatus, ETrue ); + } + } + } + +// --------------------------------------------------------- +// CGSCallDivertView::ShowErrorNote +// +// --------------------------------------------------------- +void CGSCallDivertView::ShowErrorNoteL() + { + HBufC* string = StringLoader::LoadLC( R_INVALID_NUMBER ); + CAknErrorNote* note = new ( ELeave ) CAknErrorNote ( ETrue ); + note->ExecuteLD( *string ); + CleanupStack::PopAndDestroy( string ); + } + +// --------------------------------------------------------------------------- +// CGSCallDivertView::ReadDefaultVoiceDivertNumbersL +// +// Creates defcault items for the target list. +// --------------------------------------------------------------------------- +void CGSCallDivertView::ReadDefaultVoiceDivertNumbersL( + CDesCArray& aItems, + CDesC16ArrayFlat& aDefaultNumbers ) + { + TInt amount = KErrNone; + + // this is for fetching name to a number from phonebook + HBufC* defaultName = NULL; + + //Default numbers are fetched from shared data + amount = iModel->DivertHandler()->GetDefaultNumbersL( aDefaultNumbers ); + __ASSERT_ALWAYS( amount == aDefaultNumbers.MdcaCount(), + Panic( KGSDivertClassName, ECFDefaultNumberCountError ) ); + + for ( TInt i = 0; i < amount; i++ ) + { + //Default numbers should be checked, if there is a contact name associated + // with it. + defaultName = NULL; + defaultName = iModel->MatchNumberToContactLC( aDefaultNumbers.MdcaPoint( i ) ); + __GSLOGSTRING1("[CGSCallDivertView] ReadDefaultVoiceDivertNumbersL: defaultName: %S", &defaultName); + if ( defaultName ) + { + aItems.AppendL( *defaultName ); + } + else + { + TTelNumber string; + if ( iModel->NumberGroupingSupportedL() ) + { + CPNGNumberGrouping* numberGrouping = CPNGNumberGrouping::NewL( + KPSUIMaxPSUIItemLength ); + CleanupStack::PushL( numberGrouping ); + + if ( aDefaultNumbers.MdcaPoint( i ).Length() <= + numberGrouping->MaxDisplayLength() ) + { + numberGrouping->Set( aDefaultNumbers.MdcaPoint( i ) ); + string = numberGrouping->FormattedNumber(); + } + CleanupStack::PopAndDestroy( numberGrouping ); + } + if ( !string.Length() ) + { + string = aDefaultNumbers.MdcaPoint(i); + } + AknTextUtils::DisplayTextLanguageSpecificNumberConversion( string ); + aItems.AppendL( string ); + __GSLOGSTRING1("[CGSCallDivertView] ReadDefaultVoiceDivertNumbersL: string: %S", &string); + } + CleanupStack::PopAndDestroy(); //defaultName + } + } + +// --------------------------------------------------------------------------- +// CGSCallDivertView::UpdateDefaultVoiceDivertNumbersL +// +// Updates most recently used numbers to cenrep +// --------------------------------------------------------------------------- +void CGSCallDivertView::UpdateDefaultVoiceDivertNumbersL( TDes& aNumber ) + + { + if ( aNumber != KNullDesC && iContextMenuItems ) + { + //If activation is done to already existing default number, + //but using the "Other number" selection, this must be verified. + HBufC* contactName = iModel->MatchNumberToContactLC( aNumber ); + + TInt found = KErrNone; + TInt loc = KErrNotFound; + + if ( contactName ) + { + found = iContextMenuItems->Find( *contactName, loc ); + } + else + { + found = iContextMenuItems->Find( aNumber, loc ); + } + CleanupStack::PopAndDestroy(); //contactName + + if ( found > 0 ) //number is not part of current def.numbers + { + iModel->DivertHandler()->SetNewDefaultNumberL( aNumber ); + } + else + { + iModel->DivertHandler()->SwapDefaultNumberL( loc ); + } + } + else + { + __GSLOGSTRING( "[CGSCallDivertView::UpdateDefaultVoiceDivertNumbersL] iContextMenuItems == NULL!!" ); + } + + } + +// --------------------------------------------------------------------------- +// CGSCallDivertView::HandleNotifyL +// +// AIW callback function. +// --------------------------------------------------------------------------- +TInt CGSCallDivertView::HandleNotifyL( + TInt aCmdId, + TInt aEventId, + CAiwGenericParamList& aEventParamList, + const CAiwGenericParamList& /*aInParamList*/ ) + { + TInt err = KErrNone; + if( ( aCmdId == KAiwCmdSelect ) || ( aCmdId == KAiwCmdAssign ) ) + { + if( aEventId == KAiwEventCompleted ) + { + TInt index = 0; + iNumberFetchedAsynchronously = ETrue; + const TAiwGenericParam* param = aEventParamList.FindFirst( + index, EGenericParamContactLinkArray ); + + if( param && iStoresOpened ) + { + if( iContactLinks ) + { + delete iContactLinks; + iContactLinks = NULL; + } + TPtrC8 contactLinks = param->Value().AsData(); + + CVPbkContactLinkArray* localContactLinks = + CVPbkContactLinkArray::NewLC( + contactLinks, + iContactManager->ContactStoresL() ); + + CleanupStack::Pop( localContactLinks ); + iContactLinks = localContactLinks; + + if( iContactLinks->Count() > 0 ) + { + iRetrieveOperation = iContactManager->RetrieveContactL( iContactLinks->At( 0 ), *this ); + } + } + } + else if (aEventId == KAiwEventCanceled) + { + // Do nothing. + } + else if (aEventId == KAiwEventOutParamCheck) + { + // This is needed as PBK2 mysteriously crashes if check is not + // acccepted. There's no actual need to check anything but to go + // ahead here so setting to ETrue. + err = ETrue; + } + else if (aEventId == KAiwEventQueryExit) + { + err = ETrue; + } + } + return err; + } + + +// -------------------------------------------------------------------------- +// CGSCallDivertView::VPbkSingleContactOperationComplete +// -------------------------------------------------------------------------- +// +void CGSCallDivertView::VPbkSingleContactOperationComplete( + MVPbkContactOperationBase& /*aOperation*/, + MVPbkStoreContact* aContact ) + { + if( iRetrieveOperation ) + { + delete iRetrieveOperation; + iRetrieveOperation = NULL; + } + TRAP_IGNORE + ( + MVPbkStoreContactField* field = aContact->Fields().RetrieveField( iContactLinks->At( 0 ) ); + if ( field && field->FieldData().DataType() == EVPbkFieldStorageTypeText ) + { + // aContact has selected phone number from Pbk2 dialog. Set this as + // a text for ExecuteDivertNumberQueryL. + TCallDivertSetting setting; + setting.iSetting = EActivateDiverting; + setting.iNumber = MVPbkContactFieldTextData::Cast( field->FieldData() ).Text(); + + //Ask for user input. + ExecuteDivertNumberQueryL( setting.iNumber, R_TEXT_PRMPT_NUMBER ); + + // ExecuteDivertNumberQueryL() will set setting.iNumber to KNullDesC if user + // selected 'search'. In this case program execution is moved to + // pbk2 asynchronous dialog and this function can exit without + // sending call divert request. + if( setting.iNumber != KNullDesC ) + { + // Send divert request. + iModel->SendCallDivertRequestL( setting, + RMobilePhone::EServiceActionRegister, + iVoiceMailboxDivert, + ECFCmdActivate, + (TGSCallDivertServices) iCurrentItem ); + } + } + ); + delete aContact;// Ownership is taken by this + } + + +// -------------------------------------------------------------------------- +// CGSCallDivertView::VPbkSingleContactOperationFailed +// -------------------------------------------------------------------------- +// +void CGSCallDivertView::VPbkSingleContactOperationFailed( + MVPbkContactOperationBase& /*aOperation*/, + TInt /*aError*/) + { + if( iRetrieveOperation ) + { + delete iRetrieveOperation; + iRetrieveOperation = NULL; + } + + } + +// -------------------------------------------------------------------------- +// CGSCallDivertView::OpenComplete +// -------------------------------------------------------------------------- +// +void CGSCallDivertView::OpenComplete() + { + iStoresOpened = ETrue; + } + +// -------------------------------------------------------------------------- +// CGSCallDivertView::StoreReady +// -------------------------------------------------------------------------- +// +void CGSCallDivertView::StoreReady( MVPbkContactStore& /*aContactStore*/ ) + { + // Do nothing + } + +// -------------------------------------------------------------------------- +// CGSCallDivertView::StoreUnavailable +// -------------------------------------------------------------------------- +// +void CGSCallDivertView::StoreUnavailable + ( MVPbkContactStore& /*aContactStore*/, TInt /*aReason*/ ) + { + // Do nothing + } + +// -------------------------------------------------------------------------- +// CGSCallDivertView::HandleStoreEventL +// -------------------------------------------------------------------------- +// +void CGSCallDivertView::HandleStoreEventL( MVPbkContactStore& /*aContactStore*/, + TVPbkContactStoreEvent /*aStoreEvent*/ ) + { + // Do nothing + } + + + +// --------------------------------------------------------------------------- +// CGSCallDivertView::CreateTimeListL +// +// Activates this view's popup list in order to change time-setting. +// --------------------------------------------------------------------------- +TInt CGSCallDivertView::CreateTimeListL() + { + CAknSinglePopupMenuStyleListBox* list = + new ( ELeave ) CAknSinglePopupMenuStyleListBox; + CleanupStack::PushL( list ); + + CAknPopupList* popupList = + CAknPopupList::NewL( list, R_AVKON_SOFTKEYS_OK_CANCEL__OK ); + CleanupStack::PushL( popupList ); + + HBufC* title = StringLoader::LoadLC( R_TEXT_DELAY_HEADER ); + popupList->SetTitleL( *title ); + CleanupStack::PopAndDestroy( title ); + + list->ConstructL( popupList,CEikListBox::ELeftDownInViewRect ); + list->CreateScrollBarFrameL( ETrue ); + list->ScrollBarFrame()->SetScrollBarVisibilityL( + CEikScrollBarFrame::EOff, + CEikScrollBarFrame::EAuto ); + + CDesCArrayFlat* items; + if( FeatureManager::FeatureSupported( KFeatureIdRestrictedCallDivert ) ) + { + items = new ( ELeave ) CDesCArrayFlat( KGSNrOfDelays + 4 ); + CleanupStack::PushL( items ); + CreateRestrictedCallDivertDelayTimeItemsL( *items ); + } + else + { + items = new ( ELeave ) CDesCArrayFlat( KGSNrOfDelays ); + CleanupStack::PushL( items ); + CreateDelayTimeItemsL( *items ); + } + CTextListBoxModel* model = list->Model(); + model->SetItemTextArray( items ); + model->SetOwnershipType( ELbmOwnsItemArray ); + CleanupStack::Pop(); //items + list->HandleItemAdditionL(); + + //set focus according to file read by phonesettings + //set delay timer field value + TInt currIndex = KErrNone; + if( FeatureManager::FeatureSupported( KFeatureIdRestrictedCallDivert ) ) + { + TInt itemCount = items->Count(); + if (( iModel->DivertHandler()->GetTimerValueL() / KCFDelayStep ) > ( itemCount - 4)) + { + // Within 60, 90, 120 range + switch ( iModel->DivertHandler()->GetTimerValueL() ) + { + case 60: + currIndex = itemCount - 3; + break; + case 90: + currIndex = itemCount - 2; + break; + case 120: + currIndex = itemCount - 1; + break; + } + } + else + { + currIndex = iModel->DivertHandler()->GetTimerValueL() / KCFDelayStep; + } + } + else + { + currIndex = ( iModel->DivertHandler()->GetTimerValueL() / KCFDelayStep ) - 1; + } + __GSLOGSTRING1( "[CGSCallDivertView::CreateTimeListL] currIndex: %d", currIndex ); + + list->SetCurrentItemIndex( currIndex ); + //if possible show topmost item + list->SetTopItemIndex(0); + + TInt keyPress = popupList->ExecuteLD(); + CleanupStack::Pop( popupList ); + if ( keyPress ) + { + TInt index = list->CurrentItemIndex(); + __GSLOGSTRING1( "[CGSCallDivertView::CreateTimeListL] index: %d", index ); + + if( FeatureManager::FeatureSupported( KFeatureIdRestrictedCallDivert ) ) + { + TInt itemCount = items->Count(); + if ( index > ( itemCount - 4)) + { + // Within 60, 90, 120 range + if ( index == itemCount - 3) + { + iModel->DivertHandler()->SetTimerValueL( 60 ); + } + else if ( index == itemCount - 2 ) + { + iModel->DivertHandler()->SetTimerValueL( 90 ); + } + else if ( index == itemCount - 1 ) + { + iModel->DivertHandler()->SetTimerValueL( 120 ); + } + } + else + { + // first entry is 0 seconds + currIndex = iModel->DivertHandler()->SetTimerValueL( index * KCFDelayStep ); + } + } + else + { + //save to file the correct value calculated from index + iModel->DivertHandler()->SetTimerValueL( ( index + 1 ) * KCFDelayStep ); + } + } + CleanupStack::PopAndDestroy( list ); + return keyPress; + } + +// -------------------------------------------------------------------------- +// CGSCallDivertView::RemoveInvalidChars +// Remove invalid " ", "()" which were sync with PC suite. +// -------------------------------------------------------------------------- +// +void CGSCallDivertView::RemoveInvalidChars( TDes& aNumber ) + { + TInt noOfInvalidchars = KCallDivertInvalidchars().Length(); + TInt location = KErrNone; + // delete the invalid chars of KCallDivertInvalidchars. + //aNumber changed to valid phone number if it contains invalid chars + for ( TInt index = 0; index < noOfInvalidchars; index++ ) + { + while ( ETrue ) + { + location = aNumber.Find( KCallDivertInvalidchars().Mid( index, 1 ) ); + if ( location == KErrNotFound ) + { + break; + } + aNumber.Delete( location, 1 ); //delete the invalid char, aNumber changed + } + } + } +// End of File