diff -r cad71a31b7fc -r e36f3802f733 voiceui/voiceuivoicerecognition/src/vuiccontactresultsstate.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/voiceui/voiceuivoicerecognition/src/vuiccontactresultsstate.cpp Wed Sep 01 12:29:17 2010 +0100 @@ -0,0 +1,638 @@ +/* +* Copyright (c) 2006-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: +* +*/ + + +// INCLUDE FILES +#include +#include +#include + +#include + +#include + +#include "vuivoicerecognition.hrh" + +#include "vuicstate.h" +#include "vuiccontactresultsstate.h" +#include "vuicplaystate.h" +#include "vuicabortstate.h" +#include "vuicerrorstate.h" +#include "vuicexitstate.h" + +#include "vuicdatastorage.h" + +#include "vuicvoicerecogdialogimpl.h" +#include "vuicnbestlistdialog.h" +#include "vuicttsplayer.h" +#include "vuivoiceicondefs.h" + +#include "rubydebug.h" + +// Constants +_LIT( KTab, "\t" ); +_LIT( KStringPosition, "%U" ); + +// ----------------------------------------------------------------------------- +// CContactResultsState::NewL +// Two-phased constructor. +// ----------------------------------------------------------------------------- +// +CContactResultsState* CContactResultsState::NewL( CDataStorage& aDataStorage, CUiModel& aUiModel ) + { + CContactResultsState* self = new (ELeave) CContactResultsState( aDataStorage, aUiModel ); + CleanupStack::PushL( self ); + self->ConstructL(); + CleanupStack::Pop( self ); + return self; + } + +// Destructor +CContactResultsState::~CContactResultsState() + { + RUBY_DEBUG0( "CContactResultsState::~CContactResultsState START" ); + + DataStorage().TtsPlayer()->Stop(); + + delete iNBestListDialog; + + delete iTagList; // Only copies of pointers, do not reset and destroy + + DataStorage().SetAdditionalTagList( NULL ); // Reset for next time + + delete iNssVasDbManager; + iNssTagManager = NULL; + + RUBY_DEBUG0( "CContactResultsState::~CContactResultsState EXIT" ); + } + +// --------------------------------------------------------- +// CContactResultsState::HandleEventL +// --------------------------------------------------------- +// +void CContactResultsState::HandleEventL( TInt aEvent ) + { + RUBY_DEBUG_BLOCK( "CContactResultsState::HandleEventL" ); + + CState* nextState = NULL; + + switch( aEvent ) + { + case KErrNone: + + if ( iInternalState == ENotStarted ) + { + nextState = this; + } + else if ( iInternalState == EStarted ) + { + iInternalState = EInitialized; + nextState = this; + } + else if ( iInternalState == EInitialized ) + { + iInternalState = ECompleted; + nextState = this; + } + break; + + case EVoiceTagSoftKeySelect: + + nextState = CPlayState::NewL( DataStorage(), UiModel() ); + break; + + case EAknSoftkeyQuit: + case EAknSoftkeyNo: + case EVoiceTagSoftKeyQuit: + case EEndCallKeypress: + case ELongKeypress: + + nextState = CAbortState::NewL( DataStorage(), UiModel() ); + break; + + case EShortKeypress: + case EUpKeypress: + case EDownKeypress: + case ESelectKeypress: + case EDirectSelectKeypress: + case EDragKeypress: + case EScrollKeypress: + + iKeypress = aEvent; + nextState = this; + break; + + default: + + nextState = CErrorState::NewL( DataStorage(), UiModel(), aEvent ); + break; + } + + DataStorage().VoiceRecognitionImpl()->ChangeState( nextState ); + } + +// --------------------------------------------------------- +// CContactResultsState::ExecuteL +// --------------------------------------------------------- +// +void CContactResultsState::ExecuteL() + { + RUBY_DEBUG_BLOCK( "CContactResultsState::ExecuteL" ); + + if ( HandleKeypressL() ) + { + iKeypress = ENoKeypress; + } + else if ( iInternalState == EInitialized ) + { + // If automatic confirmation or device lock is on then start the timer + if ( DataStorage().VerificationMode() == EAutomatic || + DataStorage().DeviceLockMode() ) + { + TInt timeoutValue = DataStorage().PlayDuration().Int64(); + if ( timeoutValue < KTimeoutMicroseconds ) + { + timeoutValue = KTimeoutMicroseconds; + } + + StartTimerL( *this, timeoutValue, timeoutValue ); + } + } + else if ( iInternalState == ECompleted ) + { + DataStorage().TtsPlayer()->Stop(); + } + else + { + if ( !DataStorage().AdditionalTagList() ) + { + if ( iNssTagManager->GetTagList( DataStorage().VoiceRecognitionImpl(), + DataStorage().Tag()->Context(), + DataStorage().Tag()->RRD()->IntArray()->At( KVasContactIdRrdLocation ), + KVasContactIdRrdLocation ) != KErrNone ) + { + HandleEventL( KErrGeneral ); + } + } + else + { + iInternalState = EStarted; + + TInt returnValue = KErrNoResults; + + // Get the name for the n-best list title + HBufC* name = DataStorage().Tag()->SpeechItem()->PartialTextL( KNameTrainingIndex ); + CleanupStack::PushL( name ); + + CreateContactInfoArrayL(); + + if ( iTagList->Count() != KErrNone ) + { + iNBestListDialog = CNBestListDialog::NewL(); + iNBestListDialog->CreateNBestListPopupLC( CreateItemsArrayL(), *name ); + + PlaySelectedNameL(); + BringToForeground(); + + iNBestListDialog->RegisterForKeyCallback( DataStorage().VoiceRecognitionImpl() ); + returnValue = iNBestListDialog->ShowNBestListPopupL(); // Pops things pushed in CreateNBestListPopupLC + } + CleanupStack::PopAndDestroy( name ); + + if ( returnValue != KErrNone ) + { + iInternalState = ECompleted; + + SelectTag(); + + HandleEventL( returnValue ); + } + } + } + } + +// --------------------------------------------------------- +// CContactResultsState::CContactResultsState +// --------------------------------------------------------- +// +CContactResultsState::CContactResultsState( CDataStorage& aDataStorage, CUiModel& aUiModel ) + : CState( aDataStorage, aUiModel ), iKeypress( ENoKeypress ), + iInternalState( ENotStarted ) + { + } + +// --------------------------------------------------------- +// CContactResultsState::ConstructL +// --------------------------------------------------------- +// +void CContactResultsState::ConstructL() + { + RUBY_DEBUG_BLOCK( "CContactResultsState::ConstructL" ); + + CState::ConstructL(); + + iNssVasDbManager = CNssVASDBMgr::NewL(); + iNssVasDbManager->InitializeL(); + iNssTagManager = iNssVasDbManager->GetTagMgr(); + + DataStorage().SetVerificationMode(); + } + +// --------------------------------------------------------- +// CContactResultsState::DoTimedEventL +// --------------------------------------------------------- +// +void CContactResultsState::DoTimedEventL() + { + SelectTag(); + + HandleEventL( EVoiceTagSoftKeySelect ); + } + +// --------------------------------------------------------- +// CContactResultsState::HandleKeypressL +// --------------------------------------------------------- +// +TBool CContactResultsState::HandleKeypressL() + { + RUBY_DEBUG_BLOCK( "CContactResultsState::HandleKeypressL" ); + + TBool handled = ETrue; + + if ( iKeypress == EShortKeypress ) + { + if ( iNBestListDialog->HandleShortKeypressL( NULL ) ) + { + iInternalState = EStarted; + + PlaySelectedNameL(); + } + else + { + HandleEventL( KErrNoResults ); + } + } + else if ( iKeypress == EUpKeypress || iKeypress == EDownKeypress || + iKeypress == EDragKeypress ) + { + iInternalState = EStarted; + + PlaySelectedNameL(); + } + else if ( iKeypress == EScrollKeypress ) + { + StopTimer(); + } + else if ( iKeypress == ESelectKeypress || iKeypress == EDirectSelectKeypress ) + { + if ( !DataStorage().Tag() ) + { + SelectTag(); + + HandleEventL( EVoiceTagSoftKeySelect ); + } + } + else + { + handled = EFalse; + } + + return handled; + } + +// --------------------------------------------------------------------------- +// CContactResultsState::PlaySelectedNameL +// --------------------------------------------------------------------------- +// +void CContactResultsState::PlaySelectedNameL() + { + RUBY_DEBUG_BLOCK( "CContactResultsState::PlaySelectedNameL" ); + + // if TTS is used + if ( ( DataStorage().SynthesizerMode() != KErrNone || + DataStorage().DeviceLockMode() ) && + iTagList->Count() > 0 ) + { + TInt index = iNBestListDialog->SelectedIndex(); + MNssTag* tag = iTagList->At( index ); + + if ( tag->Context()->ContextName() == KVoiceDialContext && + tag->RRD()->IntArray()->At( KVasExtensionRrdLocation ) == EDial ) + { + HBufC* ttsText = StringLoader::LoadLC( R_QAN_VC_TTS_DIALLING ); + + TInt position = ttsText->FindC( KStringPosition ); + User::LeaveIfError( position ); + + CleanupStack::PopAndDestroy( ttsText ); + + ttsText = StringLoader::LoadLC( R_QAN_VC_TTS_DIALLING, + tag->SpeechItem()->Text() ); + + HBufC* text = tag->SpeechItem()->PartialTextL( KNameTrainingIndex ); + CleanupStack::PushL( text ); + + DataStorage().TtsPlayer()->PlayL( *ttsText, position, + tag->SpeechItem()->Text().Length() , *text ); + + CleanupStack::PopAndDestroy( text ); + CleanupStack::PopAndDestroy( ttsText ); + } + else if ( tag->Context()->ContextName() == KVoiceDialContext ) + { + HBufC* text = tag->SpeechItem()->PartialTextL( KNameTrainingIndex ); + CleanupStack::PushL( text ); + + DataStorage().TtsPlayer()->PlayL( tag->SpeechItem()->Text(), 0, + tag->SpeechItem()->Text().Length(), *text ); + + CleanupStack::PopAndDestroy( text ); + } + } + else + { + DataStorage().SetPlayDuration( KTimeoutMicroseconds ); + HandleEventL( KErrNone ); + } + } + +// --------------------------------------------------------------------------- +// CContactResultsState::CreateContactInfoArrayL +// --------------------------------------------------------------------------- +// +void CContactResultsState::CreateContactInfoArrayL() + { + RUBY_DEBUG_BLOCK( "CContactResultsState::CreateContactInfoArrayL" ); + + CArrayPtrFlat* completeTagList = DataStorage().CompleteTagList(); + CArrayPtrFlat* additionalTags = DataStorage().AdditionalTagList(); + + iTagList = new ( ELeave ) CArrayPtrFlat( KSindMaxResults ); + + iTagList->AppendL( DataStorage().Tag() ); + + // Add all commands from selected contact to taglist + for ( TInt i = 0; i < completeTagList->Count(); ++i ) + { + MNssTag* tag = completeTagList->At( i ); + + if ( tag->Context()->ContextName() == KVoiceDialContext && + ( !DataStorage().DeviceLockMode() || tag->RRD()->IntArray()->At( KVasExtensionRrdLocation ) == EDial ) && + tag->RRD()->IntArray()->At( KVasContactIdRrdLocation ) == + DataStorage().Tag()->RRD()->IntArray()->At( KVasContactIdRrdLocation ) && + CompareContactNamesL( tag ) ) + { + // Add tag to list + iTagList->AppendL( tag ); + } + } + + // Add all additional commands from selected contact to taglist if not added already + for ( TInt i = 0; i < additionalTags->Count(); ++i ) + { + MNssTag* tag = additionalTags->At( i ); + + if ( !CheckIfAlreadyAdded( tag ) && CompareContactNamesL( tag ) && + ( !DataStorage().DeviceLockMode() || tag->RRD()->IntArray()->At( KVasExtensionRrdLocation ) == EDial ) ) + { + // Add tag to list + iTagList->AppendL( tag ); + } + } + + // Add selected tag back to tag list + completeTagList->AppendL( DataStorage().Tag() ); + + // Clear selected tag + DataStorage().SetTag( NULL, EFalse ); + } + +// --------------------------------------------------------- +// CContactResultsState::CompareContactNamesL +// --------------------------------------------------------- +// +TBool CContactResultsState::CompareContactNamesL( MNssTag* aTag ) + { + RUBY_DEBUG_BLOCK( "CContactResultsState::CompareContactNamesL" ); + + TBool returnValue = EFalse; + + HBufC* firstName = DataStorage().Tag()->SpeechItem()->PartialTextL( KNameTrainingIndex ); + CleanupStack::PushL( firstName ); + + HBufC* secondName = aTag->SpeechItem()->PartialTextL( KNameTrainingIndex ); + CleanupStack::PushL( secondName ); + + returnValue = ( *firstName == *secondName ); + + CleanupStack::PopAndDestroy( secondName ); + CleanupStack::PopAndDestroy( firstName ); + + return returnValue; + } + +// --------------------------------------------------------- +// CContactResultsState::CheckIfAlreadyAdded +// --------------------------------------------------------- +// +TBool CContactResultsState::CheckIfAlreadyAdded( MNssTag* aTag ) + { + RUBY_DEBUG0( "CContactResultsState::CheckIfAlreadyAdded START" ); + + TBool returnValue = EFalse; + + for ( TInt i = 0; i < iTagList->Count(); ++i ) + { + if ( aTag->SpeechItem()->RawText() == + iTagList->At( i )->SpeechItem()->RawText() || + aTag->SpeechItem()->RawText() == + DataStorage().Tag()->SpeechItem()->RawText() ) + { + returnValue = ETrue; + + break; + } + } + + RUBY_DEBUG0( "CContactResultsState::CheckIfAlreadyAdded EXIT" ); + + return returnValue; + } + +// --------------------------------------------------------------------------- +// CContactResultsState::CreateItemsArrayLC +// --------------------------------------------------------------------------- +// +CDesC16ArrayFlat* CContactResultsState::CreateItemsArrayL() + { + RUBY_DEBUG_BLOCK( "CContactResultsState::CreateItemsArrayL" ); + + TInt count = iTagList->Count(); + + CDesC16ArrayFlat* items = new ( ELeave ) CDesC16ArrayFlat( KSindMaxResults ); + CleanupStack::PushL( items ); + + TFullName buffer; + + for ( TInt i = 0; i < count; ++i ) + { + MNssTag* tag = iTagList->At( i ); + + FillDialContextBufferL( tag, buffer ); + + items->AppendL( buffer ); + } + + CleanupStack::Pop( items ); + + return items; + } + +// --------------------------------------------------------- +// CContactResultsState::FillDialContextBufferL +// --------------------------------------------------------- +// +void CContactResultsState::FillDialContextBufferL( MNssTag* aTag, TDes& aBuffer ) + { + RUBY_DEBUG_BLOCK( "CContactResultsState::FillDialContextBufferL" ); + + TPtrC type = KNullDesC(); + + DataStorage().PbkHandler()->FindContactFieldL( aTag ); + + TBufC phoneNumber = DataStorage().PbkHandler()->TextL(); + type.Set( GetContactIconType( DataStorage().PbkHandler()->FieldTypeL() ) ); + + aBuffer.Zero(); + aBuffer.Append( type ); + aBuffer.Append( KTab ); + + HBufC* label = NULL; + + TRAPD( error, label = aTag->SpeechItem()->PartialTextL( KExtensionTrainingIndex ) ); + if ( error == KErrNone || error == KErrNotFound ) + { + // If there is no extension then the phonebook label is shown + if ( label ) + { + CleanupStack::PushL( label ); + + aBuffer.Append( *label ); + + CleanupStack::PopAndDestroy( label ); + } + else + { + aBuffer.Append( DataStorage().PbkHandler()->LabelL() ); + } + } + else + { + User::Leave( error ); + } + + aBuffer.Append( KTab ); + aBuffer.Append( phoneNumber ); + } + +// --------------------------------------------------------- +// CContactResultsState::GetContactIconType +// --------------------------------------------------------- +// +TPtrC CContactResultsState::GetContactIconType( TFieldType aFieldType ) + { + RUBY_DEBUG0( "CContactResultsState::GetContactIconType START" ); + + TPtrC type; + // select a phone type + if ( aFieldType == KUidContactFieldVCardMapVOICE ) + { + type.Set( KIconPhone ); + } + else if ( aFieldType == KUidContactFieldVCardMapCELL ) + { + type.Set( KIconMobile ); + } + else if ( aFieldType == KUidContactFieldVCardMapFAX ) + { + type.Set( KIconFax ); + } + else if ( aFieldType == KUidContactFieldVCardMapEMAILINTERNET ) + { + type.Set( KIconEmail ); + } + else if ( aFieldType == KUidContactFieldVCardMapVIDEO ) + { + type.Set( KIconVideo ); + } + else if ( aFieldType == KUidContactFieldVCardMapVOIP ) + { + type.Set( KIconVoip ); + } + else + { + type.Set( KIconBlank ); + } + + RUBY_DEBUG0( "CContactResultsState::GetContactIconType EXIT" ); + + return type; + } + +// --------------------------------------------------------- +// CContactResultsState::SelectTag +// --------------------------------------------------------- +// +void CContactResultsState::SelectTag() + { + RUBY_DEBUG0( "CContactResultsState::SelectTag START" ); + + if ( iTagList->Count() > 0 ) + { + DataStorage().SetTag( iTagList->At( iNBestListDialog->SelectedIndex() ), ETrue ); + + // Remove selected item from the complete taglist + for ( TInt i = 0; i < DataStorage().CompleteTagList()->Count(); ++i ) + { + if ( DataStorage().CompleteTagList()->At( i ) == + DataStorage().Tag() ) + { + DataStorage().CompleteTagList()->Delete( i ); + break; + } + } + + // Remove selected item from the additional taglist + for ( TInt i = 0; i < DataStorage().AdditionalTagList()->Count(); ++i ) + { + if ( DataStorage().AdditionalTagList()->At( i ) == + DataStorage().Tag() ) + { + // Disable adaptation since tag is not from recognition results + DataStorage().SetAdaptationEnabled( EFalse ); + + DataStorage().AdditionalTagList()->Delete( i ); + break; + } + } + } + + RUBY_DEBUG0( "CContactResultsState::SelectTag EXIT" ); + } + +// End of File +