voiceui/voiceuivoicerecognition/src/vuicnbestlistdialog.cpp
author Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
Tue, 25 May 2010 12:43:51 +0300
branchRCL_3
changeset 16 994c46bea969
parent 0 bf1d17376201
permissions -rw-r--r--
Revision: 201019 Kit: 2010121

/*
* Copyright (c) 2004-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:  Implementation of CNBestListDialog
*
*/


// INCLUDE FILES
#include <featmgr.h>

#include <aknPopup.h>
#include <data_caging_path_literals.hrh>

#include <AknIconArray.h>

#include <AknMediatorFacade.h>

#include <secondarydisplay/vuisecondarydisplayapi.h>
#include <SecondaryDisplay/AknSecondaryDisplayDefs.h>

#include <vuivoicerecognition.rsg>
#include <vuivoicerecogdefs.h>

#include "vuivoicerecognition.hrh"

#include "vuiclistquerydialog.h"
#include "vuicnbestlistdialog.h"

#include "vuimkeycallback.h"

#include "vuivoiceicondefs.h"

#include "rubydebug.h"

// ================= MEMBER FUNCTIONS =======================

// -----------------------------------------------------------------------------
// CNBestListDialog::CNBestListDialog
// C++ default constructor can NOT contain any code, that
// might leave.
// -----------------------------------------------------------------------------
//
CNBestListDialog::CNBestListDialog() 
 : iCurrentIndex( 0 ), iTagCount( 0 ),
   iCba( R_SOFTKEYS_SELECT_QUIT__SELECT )
    {
    }


// Destructor
CNBestListDialog::~CNBestListDialog()
    {
    RUBY_DEBUG0( "CNBestListDialog::~CNBestListDialog START" );
     
    RegisterForKeyCallback( NULL );
    
    delete iDialog;
    iDialog = NULL;
    
    iEikonEnv->EikAppUi()->RemoveFromStack( this );
        
    RUBY_DEBUG0( "CNBestListDialog::~CNBestListDialog EXIT" );          
    }


// -----------------------------------------------------------------------------
// CNBestListDialog::ConstructL
// Symbian 2nd phase constructor can leave.
// -----------------------------------------------------------------------------
//
void CNBestListDialog::ConstructL()
    {
    RUBY_DEBUG_BLOCK( "CNBestListDialog::ConstructL" );
      
    iEikonEnv->EikAppUi()->AddToStackL( this, ECoeStackPriorityAlert );
    }


// ---------------------------------------------------------
// CNBestListDialog::NewL
// Two-phased constructor.
// ---------------------------------------------------------
//
CNBestListDialog* CNBestListDialog::NewL()                                                           
    {
    CNBestListDialog* self = new (ELeave) CNBestListDialog();
    CleanupStack::PushL(self);
    self->ConstructL();
    CleanupStack::Pop( self );
    return self;
    }
    
// -----------------------------------------------------------------------------
// CNBestListDialog::RegisterForKeyCallback
// -----------------------------------------------------------------------------
//
void CNBestListDialog::RegisterForKeyCallback( MKeyCallback* aKeyCallback )
    {
    iKeyCallback = aKeyCallback;
    }

// ---------------------------------------------------------
// TKeyResponse CNBestListDialog::OfferKeyEventL
// ---------------------------------------------------------
//
TKeyResponse CNBestListDialog::OfferKeyEventL( const TKeyEvent& aKeyEvent, TEventCode /*aType*/ )
    {
    RUBY_DEBUG_BLOCK( "CNBestListDialog::OfferKeyEventL" );

    TKeyResponse keyStatus = EKeyWasNotConsumed;

    TInt event = ConvertKeyEventL( aKeyEvent );
    
    // Check if event should be ignored
    if ( iDialog && iDialog->IsMenuVisible() )
        {
        switch( event )
            {
            case EVoiceTagSoftKeyQuit:
                {
                break;
                }
            
            default:
                {
                event = ENoKeypress;
                break;
                }
            }
        }

    if ( event != ENoKeypress )
        {
        switch( event )
            {
            case ESelectKeypress:
            case EDirectSelectKeypress:
                {                   
                keyStatus = EKeyWasConsumed;
                break;
                }
            
            case EUpKeypress:
                {
                --iCurrentIndex;
                if ( iCurrentIndex <= -1 )
                    {
                    iCurrentIndex = iTagCount - 1;    
                    }
                break;
                }
                        
            case EDownKeypress:
                {
                ++iCurrentIndex;
                if ( iCurrentIndex >= iTagCount )
                    {
                    iCurrentIndex = 0;
                    }
                break;
                }
               
            case EVoiceTagSoftKeyQuit:
                {
                iEikonEnv->EikAppUi()->RemoveFromStack( this );
                break;
                }
                                        
            default:
                break;            
            }
         
         if ( iKeyCallback )
             {
             iKeyCallback->HandleKeypressL( event );
             }
         }
         
    return keyStatus;
    }
    
// ---------------------------------------------------------
// CNBestListDialog::ProcessCommandL
// ---------------------------------------------------------
//      
void CNBestListDialog::ProcessCommandL( TInt aCommandId )
    {
    RUBY_DEBUG_BLOCK( "CNBestListDialog::ProcessCommandL" );
    
    TInt event = KErrNone;
    
    if ( aCommandId == EVoiceTagSoftKeySelect )
        {
        event = ESelectKeypress;
        }
    else if ( aCommandId == EVoiceTagSoftKeyOpen )
        {
        event = EOpenKeypress;
        }
    else if ( aCommandId == EVoiceTagSoftKeyQuit )
        {
        event = EVoiceTagSoftKeyQuit;
        }
    else if ( aCommandId == EAknSoftkeyOptions )
        {
        event = EOptionsKeypress;
        }
    else if ( aCommandId == EDragKeypress )
        {
        event = EDragKeypress;
        
        // Don't forward keypress if current index hasn't changed
        if ( iCurrentIndex == iDialog->ListBox()->CurrentItemIndex() )
            {
            return;
            }

        iCurrentIndex = iDialog->ListBox()->CurrentItemIndex();
        }
    else if ( aCommandId == EScrollKeypress )
        {
        event = EScrollKeypress;
        }
                    
    iKeyCallback->HandleKeypressL( event );
    }

// ---------------------------------------------------------------------------
// CNBestListDialog::MediatorCommandL
// ---------------------------------------------------------------------------
//
TAknDialogMediatorObserverCommand CNBestListDialog::MediatorCommandL( TUid /*aDomain*/, 
                                                                      TUid aCategory, 
                                                                      TInt aCommandId, 
                                                                      const TDesC8& aData )
    { 
    RUBY_DEBUG_BLOCK( "CNBestListDialog::MediatorCommandL" );
    
    TAknDialogMediatorObserverCommand retValue = EHandleAsNormal;
    
    if ( aCategory == SecondaryDisplay::KCatVoiceUi && 
         aCommandId == SecondaryDisplay::ECmdShowNBestListQuery )
        {
        if ( aData.Length() == sizeof( SAknDialogFeedback ) ) 
            {
            const SAknDialogFeedback& params = 
                reinterpret_cast<const SAknDialogFeedback&>( *( aData.Ptr() ) );
            
            if ( params.iKey.iCode == EKeyCBA1 )
                {
                // LSK should select current selection
                iKeyCallback->HandleKeypressL( ESelectKeypress );
                
                retValue = EDoNothingWithThisCommand;
                }
            }
        else
            {
            SAknIntegerUpdate* params = (SAknIntegerUpdate*) &aData;
        
            if ( params->iCmd == EAknListQueryUpdateSelection )
                {
                iCurrentIndex = params->iId;
                iDialog->ListControl()->Listbox()->SetCurrentItemIndexAndDraw( iCurrentIndex );

                // Just send EUpKeypress or EDownKeypress event to notify that selection
                // has changed
                iKeyCallback->HandleKeypressL( EDownKeypress );
                }
            }
        }
    return retValue; 
    } 

// ---------------------------------------------------------------------------
// CNBestListDialog::NotifyMediatorExit
// ---------------------------------------------------------------------------
//
void CNBestListDialog::NotifyMediatorExit() 
    { 
    RUBY_DEBUG0( "CNBestListDialog::NotifyMediatorExit" );
    // Do nothing
    }

// -----------------------------------------------------------------------------
// CNBestListDialog::CreateNBestListPopupLC
// -----------------------------------------------------------------------------
//
void CNBestListDialog::CreateNBestListPopupLC( CDesC16ArrayFlat* aItems,
                                               const TDesC& aHeader )
    {
    RUBY_DEBUG0( "CNBestListDialog::ShowNBestListPopupLC START" );
       
    iDialog = CListQueryDialog::NewL( &iCurrentIndex, &iDialog, this, R_NBEST_OPTIONS_MENU );
    iDialog->PrepareLC( R_NBEST_POPUP_LIST );
    
    if ( aHeader != KNullDesC )
        {
        iDialog->QueryHeading()->SetTextL( aHeader );
        }

    iDialog->SetOwnershipType( ELbmOwnsItemArray );
    iDialog->SetItemTextArray( aItems );
    
    iDialog->ListControl()->Listbox()->ItemDrawer()->FormattedCellData()->EnableMarqueeL( ETrue );
        
    iTagCount = aItems->Count();
    
    CreateAndSetSecondaryDisplayDataL( aItems );
        
    // Create icon array
    CArrayPtr<CGulIcon>* icons = CreateIconArrayL();    
    iDialog->SetIconArrayL( icons );
    
    RUBY_DEBUG0( "CNBestListDialog::ShowNBestListPopupLC EXIT" );
    }

// -----------------------------------------------------------------------------
// CNBestListDialog::ShowNBestListPopupL
// -----------------------------------------------------------------------------
//
TInt CNBestListDialog::ShowNBestListPopupL()
    {
    RUBY_DEBUG0( "CNBestListDialog::ShowNBestListPopupL START" );

    // Show N-Best List
    TInt returnValue = iDialog->RunLD();
    
    // Touch selection returns EAknSoftkeyOk
    if ( returnValue == EAknSoftkeyOk )
        {
        returnValue = EVoiceTagSoftKeySelect;
        }
            
    RUBY_DEBUG0( "CNBestListDialog::ShowNBestListPopupL EXIT" );

    return returnValue;
    }

// -----------------------------------------------------------------------------
// CNBestListDialog::SetSoftkeys
// -----------------------------------------------------------------------------
//    
void CNBestListDialog::SetSoftkeysL( TInt aResourceId )
    {
    RUBY_DEBUG_BLOCK( "CNBestListDialog::SetSoftkeysL" );
    
    iCba = aResourceId;
    
    // Set softkey labels
    CEikButtonGroupContainer* cba = &iDialog->ButtonGroupContainer();
    cba->SetCommandSetL( aResourceId );
    cba->DrawDeferred();
    }
    
// -----------------------------------------------------------------------------
// CNBestListDialog::SetCommandsHidden
// -----------------------------------------------------------------------------
//    
void CNBestListDialog::SetCommandsHidden( TBool aHidden )
    {
    RUBY_DEBUG_BLOCK( "CNBestListDialog::SetCommandsHidden" );
    
    iDialog->SetCommandVisibility( aHidden );
    }
    
// -----------------------------------------------------------------------------
// CNBestListDialog::ConvertKeyEventL
// -----------------------------------------------------------------------------
// 
TInt CNBestListDialog::ConvertKeyEventL( const TKeyEvent& aKeyEvent )
    {
    TInt event = ENoKeypress;
    
    switch( aKeyEvent.iCode )
        {
        case EKeyNo:
        case EKeyEscape:
            {
            event = EVoiceTagSoftKeyQuit;
            break;
            }

        case EKeyDevice3:
            {
            event = ESelectKeypress;
            break;
            }
            
        case EKeyYes:
            {
            event = EDirectSelectKeypress;
            break;
            }

        case EKeyUpArrow:
            {
            event = EUpKeypress;
            break;
            }
                        
        case EKeyDownArrow:
            {
            event = EDownKeypress;
            break;
            }
                                        
        default:
            {
            event = ENoKeypress;
            break;            
            }
        }
            
    return event;
    }
    
// ---------------------------------------------------------
// CNBestListDialog::CreateIconArrayL
// Creates new icon array
// ---------------------------------------------------------
//
CArrayPtr<CGulIcon>* CNBestListDialog::CreateIconArrayL()
    {
    RUBY_DEBUG_BLOCK( "CNBestListDialog::CreateIconArrayL" );
    
    CAknIconArray* icons = new ( ELeave ) CAknIconArray( KSindNumberOfIcons );
    CleanupStack::PushL( icons );

    // 0. Phone
    // 1. Home
    // 2. Work
    // 3. Mobile
    // 4. Fax
    // 5. Pager
    // 6. Blank
    // 7. Profile
    // 8. Application or function
    // 9. Video call icon
    //10. VoIP icon
    
    for ( int i = 0; i < KSindNumberOfIcons; ++i )
        {
        AppendIconToArrayL( icons, *KIconId[ i ], KBitmapId[ i ], KMaskId[ i ] );
        }
        
    CleanupStack::Pop( icons );
    return icons;
    }


// ---------------------------------------------------------
// CNBestListDialog::AppendIconToArrayL
// ---------------------------------------------------------
//
void CNBestListDialog::AppendIconToArrayL( CAknIconArray* aArray,
                                           const TAknsItemID& aID,
                                           TInt aBitmapId,
                                           TInt aMaskId )
    {
    RUBY_DEBUG_BLOCK( "CNBestListDialog::AppendIconToArrayL" );

    MAknsSkinInstance* skin = AknsUtils::SkinInstance();

    CFbsBitmap* bitmap = NULL;
    CFbsBitmap* mask = NULL;
    TBuf<KMaxFileName> fileName = AknIconUtils::AvkonIconFileName();
    
    if ( aID == *KIconId[ EIconProfile ] || aID == *KIconId[ EIconApplication ] )
        {
        TParse* fp = new ( ELeave ) TParse();
        CleanupStack::PushL( fp );
        User::LeaveIfError( fp->Set( KDirAndFile, &KDC_BITMAP_DIR, NULL ) );

        fileName = fp->FullName();
        CleanupStack::PopAndDestroy( fp );
        }

    AknsUtils::CreateIconL( skin, aID, bitmap, mask, fileName,
                            aBitmapId, aMaskId );
    CleanupStack::PushL( bitmap );
    CleanupStack::PushL( mask );

    CGulIcon* icon = CGulIcon::NewL( bitmap, mask );
    icon->SetBitmapsOwnedExternally( EFalse );

    // icon now owns the bitmaps, no need to keep on cleanup stack.
    CleanupStack::Pop( mask );
    CleanupStack::Pop( bitmap );
    bitmap = NULL;
    mask = NULL;

    CleanupStack::PushL( icon );
    aArray->AppendL( icon );

    // aArray now owns the icon, no need to delete.
    CleanupStack::Pop( icon );
    }

// ---------------------------------------------------------
// CNBestListDialog::CreateAndSetSecondaryDisplayDataL
// ---------------------------------------------------------
//    
void CNBestListDialog::CreateAndSetSecondaryDisplayDataL( CDesC16ArrayFlat* aItems )
    {
    RUBY_DEBUG_BLOCK( "CNBestListDialog::CreateAndSetSecondaryDisplayDataL" );

    if ( FeatureManager::FeatureSupported( KFeatureIdCoverDisplay ) )
        {        
        // Create dummy id list (needed for list query automation)
        CArrayFixFlat<TInt>* array = new ( ELeave ) CArrayFixFlat<TInt>( 1 );
        CleanupStack::PushL( array );
        for( TInt i = 0; i < iTagCount; ++i )
            {
            array->AppendL( i );
            }

        // Publish to secondary display
        iDialog->PublishDialogL( SecondaryDisplay::ECmdShowNBestListQuery,
                                 SecondaryDisplay::KCatVoiceUi,
                                 array );
                                 
        iDialog->SetMediatorObserver( this );
        
        CleanupStack::Pop( array ); // Dialog takes ownership of array

        // Generate n-best data for secondary display
        CAknMediatorFacade* covercl = AknMediatorFacade( iDialog );
        if( covercl )
            {
            // Current index
            covercl->BufStream().WriteInt32L( iCurrentIndex );

            // Item count and items
            covercl->BufStream().WriteInt32L( iTagCount );
            for( TInt i = 0; i < iTagCount; ++i )
                {
                TPtrC16 item = aItems->MdcaPoint( i );
                covercl->BufStream().WriteInt32L( item.Length() );
                covercl->BufStream().WriteL( item, item.Length() );
                }

            covercl->BufStream().CommitL(); // no more data to send so commit buf
            }
        }
    }

// ---------------------------------------------------------
// CNBestListDialog::HandleShortKeypressL
// ---------------------------------------------------------
//
TBool CNBestListDialog::HandleShortKeypressL( CDesC16ArrayFlat* aItems )
    {        
    RUBY_DEBUG_BLOCK( "CNBestListDialog::HandleShortKeypressL" );

    TBool returnValue = ETrue;

    if ( aItems )
        {
        iDialog->SetItemTextArray( aItems );        
        iDialog->ListControl()->Listbox()->SetCurrentItemIndexAndDraw( iCurrentIndex );
        
        CreateAndSetSecondaryDisplayDataL( aItems );
        }
    else
        {
        ++iCurrentIndex;
        if ( iCurrentIndex == iTagCount )
            {    
            returnValue = EFalse;
            }

        if ( returnValue ) 
            {
            // Move focus to the current item
            TKeyEvent keyEvent;
            keyEvent.iRepeats = 0;
            keyEvent.iCode = EKeyDownArrow;
        
            iDialog->OfferKeyEventL( keyEvent, EEventKey );
            }
        }
    
    return returnValue;                
    }
    
// ---------------------------------------------------------------------------
// CNBestListDialog::SelectedIndex
// ---------------------------------------------------------------------------
//    
TInt CNBestListDialog::SelectedIndex()
    {
    RUBY_DEBUG1( "CNBestListDialog::SelectedIndex - index = %d", iCurrentIndex );
    
    TInt index = iCurrentIndex;
    
    if ( index < 0 )
        {
        index = 0;
        }
    
    return index;
    }
    
//  End of File