voiceui/voiceuivoicerecognition/src/vuicplaystate.cpp
author Pat Downey <patd@symbian.org>
Wed, 01 Sep 2010 12:29:17 +0100
branchRCL_3
changeset 19 e36f3802f733
permissions -rw-r--r--
Revert incorrect RCL_3 drop: Revision: 201033 Kit: 201035

/*
* Copyright (c) 2006-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:  
*
*/


// INCLUDE FILES
#include <aknappui.h>
#include <AknUtils.h> 
#include <AknIconUtils.h> 
#include <cntdef.h>
#include <AknsConstants.h>
#include <StringLoader.h>
#include <AudioPreference.h>

#include <vasmbasepbkhandler.h>

#include <secondarydisplay/vuisecondarydisplayapi.h>

#include <vuivoicerecognition.rsg>

#include "vuivoicerecognition.hrh"

#include "vuicstate.h"
#include "vuicplaystate.h"
#include "vuictutorialstate.h"
#include "vuicresultsstate.h"
#include "vuicverificationinitstate.h"
#include "vuicabortstate.h"

#include "vuicdatastorage.h"

#include "vuicvoicerecogdialogimpl.h"
#include "vuicpropertyhandler.h"
#include "vuictoneplayer.h"
#include "vuicttsplayer.h"
#include "vuicglobalprogressdialog.h"
#include "vuivoiceicondefs.h"

#include "rubydebug.h"

// Constants
_LIT( KStringPosition, "%U" );

// -----------------------------------------------------------------------------
// CPlayState::NewL
// Two-phased constructor.
// -----------------------------------------------------------------------------
//
CPlayState* CPlayState::NewL( CDataStorage& aDataStorage, CUiModel& aUiModel )
    {
    CPlayState* self = new (ELeave) CPlayState( aDataStorage, aUiModel );
    CleanupStack::PushL( self );
    self->ConstructL();
    CleanupStack::Pop( self );
    return self;
    }       
    
// Destructor       
CPlayState::~CPlayState()
    {
    RUBY_DEBUG0( "CPlayState::~CPlayState START" );
    
    DataStorage().TtsPlayer()->Stop();
    
    delete iProgressDialog;
    
    RUBY_DEBUG0( "CPlayState::~CPlayState EXIT" );
    }
    
// ---------------------------------------------------------
// CPlayState::HandleEventL
// ---------------------------------------------------------
//       
void CPlayState::HandleEventL( TInt aEvent )
    {
    RUBY_DEBUG_BLOCK( "CPlayState::HandleEventL" );

    CState* nextState = NULL;

    switch( aEvent )
        {
        case KErrNone:
        
            if ( iInternalState == EStarted )
                {
                iInternalState = EInitialized;
                nextState = this;
                }
            else if ( iInternalState == EInitialized )
                {
                iInternalState = ECompleted;
                nextState = this;
                }
            break;
        
        case KErrPathNotFound:
        
            // Ignore mysterious path not found error when loading confirmation tone
            if ( iInternalState == EStarted )
                {
                nextState = CTutorialState::NewL( DataStorage(), UiModel() );
                }
            break;
        
        case EVoiceTagSoftKeySelect:
        
            nextState = CTutorialState::NewL( DataStorage(), UiModel() );
            break;
            
        case EShortKeypress:
        case EVoiceTagSoftKeyOther:
        case EAknSoftkeyOther:
        case EAknSoftkeyDone:
        case EStdKeyDevice2:
        
            if ( iInternalState != EStarted )
                {
                if ( DataStorage().VerificationMode() != EVoice )
                    {
                    nextState = CResultsState::NewL( DataStorage(), UiModel() );
                    }
                else
                    {
                    if ( DataStorage().Tag()->Context()->ContextName() == KVoiceDialContext &&
                         DataStorage().Tag()->RRD()->IntArray()->At( KVasExtensionRrdLocation ) == EDial )
                        {
                        nextState = CVerificationInitState::NewL( DataStorage(), UiModel() );
                        }
                    }
                }
            break;
            
        case EEndCallKeypress:
        
            // Do nothing
            break;
            
        default:
        
            nextState = CAbortState::NewL( DataStorage(), UiModel() );
            break;
        }

    DataStorage().VoiceRecognitionImpl()->ChangeState( nextState );
    }

// ---------------------------------------------------------
// CPlayState::ExecuteL
// ---------------------------------------------------------
//       
void CPlayState::ExecuteL()
    {
    RUBY_DEBUG_BLOCK( "CPlayState::ExecuteL" );

    if ( iInternalState == ENotStarted )
        {
        TBuf<KMaxFieldLength> phoneNumber;        
        TFieldType fieldType;        
        TName name;
        
        iInternalState = EStarted;

        if ( DataStorage().Tag()->Context()->ContextName() == KVoiceDialContext )
            {
            if ( DataStorage().VerificationMode() == EVoice &&
                 DataStorage().Tag()->RRD()->IntArray()->At( KVasExtensionRrdLocation ) == EDial )
                {
                FormatDataL( name, phoneNumber, fieldType );

                ShowPlaydialogL( name, phoneNumber, fieldType );
                }
            else
                {
                TRAP_IGNORE( HandleEventL( EVoiceTagSoftKeySelect ) );
                }
            }
        else
            {
            DataStorage().TonePlayer()->InitToneL( EAvkonSIDConfirmationTone );
            }                
        }
    else if ( iInternalState == EInitialized )
        {
        if ( DataStorage().Tag()->Context()->ContextName() == KVoiceDialContext &&
             DataStorage().Tag()->RRD()->IntArray()->At( KVasExtensionRrdLocation ) == EDial )
            {
            iTModel.iFinalValue = DataStorage().PlayDuration().Int64() / KKRecogInterval + 4 * KRecogDelay;
            StartTimerL( *this, KRecogDelay, KKRecogInterval * iTModel.iHundreths );
            }
        else
            {
            DataStorage().TonePlayer()->PlayTone( EAvkonSIDConfirmationTone );
            }
        }
    else  if ( iInternalState == ECompleted )
        {
        if ( DataStorage().Tag()->Context()->ContextName() != KVoiceDialContext ||
             DataStorage().Tag()->RRD()->IntArray()->At( KVasExtensionRrdLocation ) != EDial )
            {
            TRAP_IGNORE( HandleEventL( EVoiceTagSoftKeySelect ) );
            }
        }
    }

// ---------------------------------------------------------
// CPlayState::CPlayState
// ---------------------------------------------------------
//              
CPlayState::CPlayState( CDataStorage& aDataStorage, CUiModel& aUiModel )
 : CState( aDataStorage, aUiModel ), iInternalState( ENotStarted ),
   iTickCount( 0 ), iPlaybackDelay( KPlaybackTimeout )
    {
    iTModel.iFinalValue = KRecogFinal;
    iTModel.iHundreths = KRecogInterval;
    iTModel.iIncrement = KRecogIncrement;
    iTModel.iRunning = EFalse;
    }

// ---------------------------------------------------------
// CPlayState::ConstructL
// ---------------------------------------------------------
//           
void CPlayState::ConstructL()
    {
    RUBY_DEBUG_BLOCK( "CPlayState::ConstructL" );
    
    CState::ConstructL();
    }
    
// ---------------------------------------------------------
// CPlayState::DoTimedEventL
// ---------------------------------------------------------
//
void CPlayState::DoTimedEventL()
    {
    if ( ( ++iTickCount < iTModel.iFinalValue + iPlaybackDelay ) && iProgressDialog )
        {
        iProgressDialog->UpdateProgressDialogL( iTickCount, iTModel.iFinalValue ); 
        }
    else 
        {
        HandleEventL( EVoiceTagSoftKeySelect );
        } 
    }
    
// ---------------------------------------------------------
// CPlayState::FormatName
// ---------------------------------------------------------
//           
void CPlayState::FormatName( TDes& aName )
    {
    RUBY_DEBUG0( "CPlayState::FormatName START" );
    
    const CFont* font = CEikonEnv::Static()->NormalFont();
    if ( AknLayoutUtils::Variant() == EApacVariant )
        {
        font = ApacPlain16();
        }

    TRect rect = iAvkonAppUi->ClientRect();
    TAknLayoutText layoutText;
    layoutText.LayoutText( rect, AKN_LAYOUT_TEXT_Wait_or_progress_note_pop_up_window_texts_Line_1(0,0,0) );
    TInt maxWidth = layoutText.TextRect().Width();

    AknTextUtils::ClipToFit( aName, *font, maxWidth, AknTextUtils::EClipFromEnd );
    
    RUBY_DEBUG0( "CPlayState::FormatName EXIT" );
    }     
    
// ---------------------------------------------------------------------------
// CPlayState::PlayVoiceTagL
// ---------------------------------------------------------------------------
//
void CPlayState::PlayVoiceTagL()
    {
    RUBY_DEBUG_BLOCK( "CPlayState::PlayVoiceTagL" );
    
    // if TTS is used
    if ( DataStorage().SynthesizerMode() != KErrNone ||
         DataStorage().DeviceLockMode() )
        {            
        // Add text "dialling" in front of the name if using voice dialing
        if ( DataStorage().Tag()->Context()->ContextName() == KVoiceDialContext &&
             DataStorage().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,
                                            DataStorage().Tag()->SpeechItem()->Text() );
                                                   
            HBufC* text = DataStorage().Tag()->SpeechItem()->PartialTextL( KNameTrainingIndex );        
            CleanupStack::PushL( text ); 
            
            DataStorage().TtsPlayer()->PlayL( *ttsText, position,
                                              DataStorage().Tag()->SpeechItem()->Text().Length(),
                                              *text );
            
            CleanupStack::PopAndDestroy( text );
            CleanupStack::PopAndDestroy( ttsText );
            }
        else if ( DataStorage().Tag()->Context()->ContextName() == KVoiceDialContext )
            {           
            HBufC* text = DataStorage().Tag()->SpeechItem()->PartialTextL( KNameTrainingIndex );        
            CleanupStack::PushL( text ); 
        
            DataStorage().TtsPlayer()->PlayL( DataStorage().Tag()->SpeechItem()->Text(), 0,
                                              DataStorage().Tag()->SpeechItem()->Text().Length(),
                                              *text );

            CleanupStack::PopAndDestroy( text );
            }
        else
            {            
            DataStorage().TtsPlayer()->PlayL( DataStorage().Tag()->SpeechItem()->Text() );
            }
        }
    else
        {
        // Set playback delay so that dialog will be dismissed immediately when
        // progess bar reaches final value
        iPlaybackDelay = 1;
                
        // Show playback dialog without TTS.
        DataStorage().SetPlayDuration( KTimeoutMicroseconds );
        HandleEventL( KErrNone );
        }
    }

// ---------------------------------------------------------------------------
// CPlayState::FormatDataL
// ---------------------------------------------------------------------------
//
void CPlayState::FormatDataL( TDes& aName, TDes& aPhoneNumber, TFieldType& aFieldType )
    {
    RUBY_DEBUG_BLOCK( "CPlayState::FormatDataL" );
    
    TPtrC phoneNumber( KNullDesC );
    aPhoneNumber = (TDes&) phoneNumber;
        
    aFieldType = KNullUid;
    
    aName.Zero();
        
    if ( DataStorage().Tag()->Context()->ContextName() == KVoiceDialContext )
        {
        HBufC* name = DataStorage().Tag()->SpeechItem()->PartialTextL( KNameTrainingIndex );
        CleanupStack::PushL( name );
        
        aName.Copy( *name );
            
        CleanupStack::PopAndDestroy( name );
        
        // Format name so that it fits on one line
        FormatName( aName );
 
        DataStorage().PbkHandler()->FindContactFieldL( DataStorage().Tag() );

        // Format phone number
        phoneNumber.Set( DataStorage().PbkHandler()->TextL() );
        aPhoneNumber = (TDes&) phoneNumber;
        AknTextUtils::LanguageSpecificNumberConversion( aPhoneNumber );
 
        aFieldType = DataStorage().PbkHandler()->FieldTypeL();      
        }
    else
        {
        aName.Copy( DataStorage().Tag()->SpeechItem()->Text() );
        }
    }  

// ---------------------------------------------------------------------------
// CPlayState::ShowPlaydialogL
// ---------------------------------------------------------------------------
//
void CPlayState::ShowPlaydialogL( const TDesC& aName, const TDesC& aPhoneNumber,
                                  const TFieldType aFieldType )
    {
    RUBY_DEBUG_BLOCK( "CPlayState::ShowPlaydialogL" );
    
    // Get icon information
    TInt iconId;
    TInt iconMaskId;
    TAknsItemID iconSkinId;
    GetDialogIcon( aFieldType, iconId, iconMaskId, iconSkinId );

    iProgressDialog = CGlobalProgressDialog::NewL();

    // Set icon, image and skin for the playback dialog
    iProgressDialog->SetIconL( AknIconUtils::AvkonIconFileName(),
                               iconId, iconMaskId );
    
    iProgressDialog->SetImageL( AknIconUtils::AvkonIconFileName(),
                                EMbmAvkonQgn_note_voice_found,
                                EMbmAvkonQgn_note_voice_found_mask );

    iProgressDialog->SetSkinIds( KAknsIIDQgnNoteVoiceFound, EMbmAvkonQgn_note_voice_found,
                                 EMbmAvkonQgn_note_voice_found_mask, iconSkinId );
   
    iProgressDialog->RegisterForKeyCallback( DataStorage().VoiceRecognitionImpl() );
        
    // Package dialog data for coverui
    SecondaryDisplay::TMatchData matchData;
    matchData.iType = aFieldType;
    matchData.iName.Append( aName );
    matchData.iNumber.Append( aPhoneNumber );

    // Publish the data for the secondary display
    iProgressDialog->SetSecondaryDisplayDataL( SecondaryDisplay::KCatVoiceUi,
                                               SecondaryDisplay::ECmdShowMatchedItemNote,
                                               &matchData );
                                               
    BringToForeground();

    iProgressDialog->ShowProgressDialogL( aName, aPhoneNumber, R_AVKON_SOFTKEYS_OTHER_QUIT );
           
    // Play selected name using TTS
    PlayVoiceTagL();
    }    
    
// ---------------------------------------------------------
// CPlayState::GetDialogIcon
// Chooses appropriate dialog icon
// ---------------------------------------------------------
//
void CPlayState::GetDialogIcon( const TFieldType& aType, TInt& aIcon,
                                TInt& aIconMask, TAknsItemID& aIconId )
   {   
   // select a phone type bitmap
   if ( aType == KUidContactFieldVCardMapVOICE )
      {
      aIcon = KBitmapId[ EIconPhone ];
      aIconMask = KMaskId[ EIconPhone ];
      aIconId = *KIconId[ EIconPhone ];
      }
   else if ( aType == KUidContactFieldVCardMapCELL )
      {
      aIcon = KBitmapId[ EIconMobile ];
      aIconMask = KMaskId[ EIconMobile ];
      aIconId = *KIconId[ EIconMobile ];
      }
   else if ( aType == KUidContactFieldVCardMapFAX )
      {
      aIcon = KBitmapId[ EIconFax ];
      aIconMask = KMaskId[ EIconFax ];
      aIconId = *KIconId[ EIconFax ];
      }
   else if ( aType == KUidContactFieldVCardMapEMAILINTERNET )
      {
      aIcon = KBitmapId[ EIconEmail ];
      aIconMask = KMaskId[ EIconEmail ];
      aIconId = *KIconId[ EIconEmail ];
      }
   else if ( aType == KUidContactFieldVCardMapVIDEO )
      {
      aIcon = KBitmapId[ EIconVideo ];
      aIconMask = KMaskId[ EIconVideo ];
      aIconId = *KIconId[ EIconVideo ];
      }
   else if ( aType == KUidContactFieldVCardMapVOIP )
      {
      aIcon = KBitmapId[ EIconVoip ];
      aIconMask = KMaskId[ EIconVoip ];
      aIconId = *KIconId[ EIconVoip ];
      }   
   else
      {
      aIcon = KBitmapId[ EIconBlank ];
      aIconMask = KMaskId[ EIconBlank ];
      aIconId = *KIconId[ EIconBlank ];
      }
   }

// End of File