phoneuis/Ussd/src/UssdContainer.cpp
changeset 0 5f000ab63145
child 15 2a26698d78ba
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/phoneuis/Ussd/src/UssdContainer.cpp	Mon Jan 18 20:18:27 2010 +0200
@@ -0,0 +1,513 @@
+/*
+* Copyright (c) 2002-2009 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: 
+*             Declares container control for application.
+*
+*/
+
+
+// INCLUDE FILES
+#include    "UssdComms.h"
+#include    "UssdNaviPane.h"
+#include    "UssdAppUi.h"
+#include    "UssdContainer.h"
+#include    "UssdEditorLines.h"
+#include    <ussd.rsg>
+#include    "UssdLayout.h"
+#include    <aknkeys.h>
+#include    "ussd.hrh"
+#include    <eikedwin.h>
+#include    <bldvariant.hrh>
+#include    <featmgr.h>
+
+#include    <centralrepository.h>
+#include    <telinternalcrkeys.h>
+#include    "telephonyvariant.hrh"
+
+#include <csxhelp/ussd.hlp.hrh>  // for help context
+#include    "UssdApp.h" // for applicationUID
+#include    <AknUtils.h>
+
+// For skinning.
+#include    <AknsBasicBackgroundControlContext.h>
+#include    <AknsDrawUtils.h>
+#include    <AknsUtils.h>
+#include    <txtglobl.h>
+
+
+
+// ============================ MEMBER FUNCTIONS ===============================
+
+// -----------------------------------------------------------------------------
+// CUssdContainer::CUssdContainer
+// C++ constructor can NOT contain any code, that
+// might leave.
+// -----------------------------------------------------------------------------
+//
+CUssdContainer::CUssdContainer( CUssdAppUi& aAppUi ): iAppUi( aAppUi )
+    {
+    }
+
+
+// -----------------------------------------------------------------------------
+// CUssdContainer::ConstructL
+// Symbian 2nd phase constructor can leave.
+// -----------------------------------------------------------------------------
+//
+void CUssdContainer::ConstructL( const TRect& aRect )
+    {
+    CreateWindowL();
+
+    // Create background control context for skins.
+    iBgContext = CAknsBasicBackgroundControlContext::NewL(
+        KAknsIIDQsnBgAreaMainMessage, aRect, ETrue /*Parent absolute*/ );
+
+    // Create editor
+    iEditor = CreateEdwinL();
+
+    // Lines
+    iLines = new ( ELeave ) CUssdEditorLines;
+    iLines->ConstructL( this );
+
+    TInt featureBitmask( 0 );
+
+    // Connecting and initialization KCRUidTelVariation
+    CRepository* repository = CRepository::NewL( KCRUidTelVariation );
+    CleanupStack::PushL( repository );
+
+    // Get the value from Central Repository
+    repository->Get( KTelVariationFlags, featureBitmask );
+    if ( featureBitmask & KTelephonyLVFlagUssdUIRemainingChars )
+        {
+        iNaviPaneHandler = CUssdNaviPane::NewL( iAppUi );
+        }
+
+    CleanupStack::PopAndDestroy( repository );
+
+    // Finish the job
+    SetRect( aRect );
+    ActivateL();
+
+    iEditor->SetFocus( ETrue );
+    }
+
+
+// Destructor
+CUssdContainer::~CUssdContainer()
+    {
+    delete iLines;
+
+    AknsUtils::DeregisterControlPosition( iEditor );
+    delete iEditor;
+    delete iNaviPaneHandler;
+
+    delete iBgContext; // For skinning, can be deleted, NULL if not exist.
+    }
+
+// -----------------------------------------------------------------------------
+// CUssdContainer::HandleEdwinEventL
+// Called by framework when the Editor is changed
+//
+// -----------------------------------------------------------------------------
+//
+void CUssdContainer::HandleEdwinEventL( CEikEdwin* /*aEdwin*/,
+        TEdwinEvent aEventType )
+    {
+     switch( aEventType )
+         {
+         case EEventTextUpdate:
+             {
+             UpdateNavipaneMsgLengthL();
+             break;
+             }
+         default:
+             break;
+         }
+    }
+    
+// -----------------------------------------------------------------------------
+// CUssdContainer::SizeChanged
+// Called by framework when the view size is changed
+//
+// -----------------------------------------------------------------------------
+//
+void CUssdContainer::SizeChanged()
+    {
+    // Backgroud context
+    iBgContext->SetParentPos( PositionRelativeToScreen() );
+    iBgContext->SetRect( Rect() ) ;
+    // Edwin
+    AknLayoutUtils::LayoutEdwin(
+        iEditor,
+        Rect(),
+        UssdLayout::MessageWritingTexts3() );
+
+    // We need to make some room for scrollbar to fit
+    // so the editor must be narrowed down a bit.
+
+    TAknLayoutId layout = UssdLayout::CurrentLayout();
+    TRect sbr = iEditor->ScrollBarFrame()->VerticalScrollBar()->Rect();
+
+    if( layout != EAknLayoutIdABRW )
+        {
+        TPoint editorTLPoint(Rect().iTl.iX, iEditor->Rect().iTl.iY);
+
+        iEditor->SetExtent( editorTLPoint ,
+                    TSize( Rect().Width() - sbr.Width(), sbr.Height() ) );
+        }
+    else // right to left layout
+        {
+        TPoint editorTLPoint( ( Rect().iTl.iX + sbr.Width() ),
+                                iEditor->Rect().iTl.iY);
+
+        iEditor->SetExtent( editorTLPoint ,
+                            TSize( Rect().Width() - sbr.Width(),
+                            sbr.Height() ) );
+        }
+
+    TRAP_IGNORE( UpdateNavipaneMsgLengthL() );
+
+    // overwite inputmode in portraitmode
+    if ( Rect().Height() > Rect().Width() )
+        {
+        iEditor->SetAknEditorCurrentInputMode( EAknEditorNumericInputMode );
+        }
+
+    // Change the colour of the edwin if needed
+    MAknsSkinInstance* skin = AknsUtils::SkinInstance();
+    if ( skin )
+        {
+        TRgb color;
+        TInt error = AknsUtils::GetCachedColor(
+            skin,
+            color,
+            KAknsIIDQsnTextColors,
+            EAknsCIQsnTextColorsCG6 );
+
+        if ( error == KErrNone )
+            {
+            TCharFormat charFormat;
+            TCharFormatMask charFormatMask;
+            ( reinterpret_cast< CGlobalText* >( iEditor->Text() ) )
+                ->GetCharFormat( charFormat, charFormatMask, 0, 0 );
+
+            charFormat.iFontPresentation.iTextColor = color;
+            charFormatMask.SetAll();
+
+            CCharFormatLayer* charFormatLayer = NULL;
+
+            TRAP( error, charFormatLayer =
+                CCharFormatLayer::NewL( charFormat,charFormatMask ) );
+
+            if ( !error )
+                {
+                iEditor->SetCharFormatLayer( charFormatLayer );
+                }
+            }
+        }
+
+    // Set editor lines
+    iLines->SetRect( Rect() );
+
+    AknsUtils::RegisterControlPosition( iEditor );
+    }
+
+
+// -----------------------------------------------------------------------------
+// CUssdContainer::CountComponentControls
+//
+//
+// -----------------------------------------------------------------------------
+//
+TInt CUssdContainer::CountComponentControls() const
+    {
+    return 2; // editor and lines
+    }
+
+
+// -----------------------------------------------------------------------------
+// CUssdContainer::ComponentControl
+//
+// -----------------------------------------------------------------------------
+//
+CCoeControl* CUssdContainer::ComponentControl( TInt aIndex ) const
+    {
+    switch ( aIndex )
+        {
+        case 0:
+            return iEditor;
+        case 1:
+            return iLines;
+        default:
+            return NULL;
+        }
+
+    }
+
+
+// -----------------------------------------------------------------------------
+// CUssdContainer::Draw
+//
+// -----------------------------------------------------------------------------
+//
+void CUssdContainer::Draw( const TRect& aRect ) const
+    {
+    CWindowGc& gc = SystemGc();
+
+    MAknsSkinInstance* skin = AknsUtils::SkinInstance();
+
+    if ( iBgContext )
+        {
+        AknsDrawUtils::Background(
+            skin, iBgContext, this, gc, aRect);
+        }
+    else
+        {
+        // Otherwise clear the area
+        gc.SetBrushColor( AKN_LAF_COLOR( UssdLayout::LayoutColourWhite() ) );
+        DrawUtils::ClearBetweenRects( gc, aRect, iEditor->Rect() );
+        }
+    }
+
+
+// -----------------------------------------------------------------------------
+// CUssdContainer::OfferKeyEventL
+// -----------------------------------------------------------------------------
+//
+TKeyResponse CUssdContainer::OfferKeyEventL(
+    const TKeyEvent& aKeyEvent, TEventCode aType )
+    {
+    TKeyResponse response = EKeyWasNotConsumed;
+
+    // Special key handling comes first.
+    if ( aKeyEvent.iScanCode == EStdKeyYes ) // Send key.
+        {
+        // The reason that the send key is handled via TStdScanCode rather than TKeyCode is that
+        // we also have to be able to catch EEventKeyUp and EEventKeyDown key events in addition
+        // to EEventKey. This is because TKeyEvent::iCode is always 0 when TEventCode is EEventKey.
+        if ( iEditor->TextLength() )
+            {
+            if ( aType == EEventKey )
+                {
+                if ( FeatureManager::FeatureSupported( KFeatureIdHelp ) )
+                    {
+                    iAppUi.HandleCommandL( EUssdMenuItemSend );
+                    }
+                else
+                    {
+                    iAppUi.HandleCommandL( EUssdSoftkeySend );
+                    }
+                }
+            response = EKeyWasConsumed; // Dialer should not be launched when the USSD string exists and send key is used.
+            }
+        }
+    else if ( aKeyEvent.iCode == EKeyEscape )
+        {
+        iAppUi.HandleCommandL( EAknSoftkeyExit );
+        response = EKeyWasConsumed;
+        }
+    else // Default keys are handled here.
+        {
+        response = iEditor->OfferKeyEventL( aKeyEvent, aType );
+
+        if ( aType == EEventKey || aType == EEventKeyUp )
+            {
+            UpdateNavipaneMsgLengthL();
+            }
+
+        if ( !FeatureManager::FeatureSupported( KFeatureIdHelp ) )
+            {
+            // Change softkeys if needed.
+            iAppUi.SetSoftkeySendVisibleL( iEditor->TextLength() != 0 );
+            }
+
+            iAppUi.Cba()->SetCommandSetL( R_USSD_SOFTKEYS_OPTIONS_EXIT_OPTIONS );
+            iAppUi.Cba()->DrawNow();
+        }
+
+    return response;
+    }
+
+
+// -----------------------------------------------------------------------------
+// CUssdContainer::Editor
+// Give editor
+// -----------------------------------------------------------------------------
+//
+CEikEdwin& CUssdContainer::Editor()
+    {
+    return *iEditor;
+    }
+
+
+// -----------------------------------------------------------------------------
+// CUssdContainer::FocusChanged
+//
+// -----------------------------------------------------------------------------
+//
+void CUssdContainer::FocusChanged( TDrawNow aDrawNow )
+    {
+    iEditor->SetFocus( IsFocused(), aDrawNow );
+    }
+
+
+
+// -----------------------------------------------------------------------------
+// CUssdContainer::GetHelpContext
+// This function is called when Help application is launched.
+//
+// -----------------------------------------------------------------------------
+//
+void CUssdContainer::GetHelpContext(
+    TCoeHelpContext& aContext ) const
+    {
+    // If help defined.
+    if ( FeatureManager::FeatureSupported( KFeatureIdHelp ) )
+        {
+        aContext.iMajor = KUidussd;
+        aContext.iContext = KUSSD_HLP_EDITOR;
+        }
+
+    // If help not defined, do nothing
+    }
+
+
+
+// -----------------------------------------------------------------------------
+// CUssdContainer::HandleResourceChange
+// This function is called when Help application is launched.
+//
+// -----------------------------------------------------------------------------
+//
+void CUssdContainer::HandleResourceChange( TInt aType )
+    {
+    switch ( aType )
+        {
+        case KEikColorResourceChange:
+        case KAknsMessageSkinChange:
+            {
+            SizeChanged();
+            DrawDeferred();
+            break;
+            }
+
+        default:
+            {
+            CCoeControl::HandleResourceChange( aType );
+            }
+        }
+    }
+
+
+// -----------------------------------------------------------------------------
+// CUssdContainer::MopSupplyObject
+//
+// -----------------------------------------------------------------------------
+//
+TTypeUid::Ptr CUssdContainer::MopSupplyObject( TTypeUid aId )
+    {
+    if ( aId.iUid == MAknsControlContext::ETypeId )
+        {
+        return MAknsControlContext::SupplyMopObject( aId, iBgContext );
+        }
+    return CCoeControl::MopSupplyObject( aId );
+    }
+
+
+// -----------------------------------------------------------------------------
+// CUssdContainer::CreateEdwinL
+// Creates new edwin
+//
+// -----------------------------------------------------------------------------
+//
+CEikEdwin* CUssdContainer::CreateEdwinL()
+    {
+    CEikEdwin* newEditor = new ( ELeave ) CEikEdwin;
+    CleanupStack::PushL( newEditor );
+    newEditor->SetContainerWindowL( *this );
+    //Set the editor observer
+    newEditor->SetEdwinObserver( this );
+    
+    newEditor->SetAknEditorAllowedInputModes(
+        EAknEditorNumericInputMode | EAknEditorTextInputMode );
+    newEditor->SetAknEditorInputMode( EAknEditorNumericInputMode );
+    newEditor->SetAknEditorNumericKeymap( EAknEditorStandardNumberModeKeymap );
+
+    TInt editorFlags = EAknEditorFlagNoT9 | EAknEditorFlagEnableScrollBars;
+
+    if ( FeatureManager::FeatureSupported( KFeatureIdJapanese ) )
+        {
+        editorFlags |= EAknEditorFlagLatinInputModesOnly;
+        }
+
+     if( FeatureManager::FeatureSupported( KFeatureIdPenSupport ) )
+        {
+        editorFlags |= EAknEditorFlagDeliverVirtualKeyEventsToApplication;
+        }
+
+    newEditor->SetAknEditorFlags( editorFlags );
+
+    // Get the layout, i.e. variant.
+    EVariantFlag variant = AknLayoutUtils::Variant();
+
+    // According to layout, construct the editor.
+    if ( variant == EApacVariant )
+        {
+        // APAC variant
+        AknEditUtils::ConstructEditingL( newEditor , R_USSD_EDWIN_EDITOR_APAC );
+        }
+    else
+        {
+        // EEuropeanVariant (includes ABRW)
+        AknEditUtils::ConstructEditingL( newEditor , R_USSD_EDWIN_EDITOR_ELAF );
+        }
+
+    CleanupStack::Pop( newEditor );
+    return newEditor;
+    }
+
+// ---------------------------------------------------------
+// CUssdContainer::UpdateNavipaneMsgLengthL
+// ---------------------------------------------------------
+void CUssdContainer::UpdateNavipaneMsgLengthL()
+    {
+
+    if ( iNaviPaneHandler )
+        {
+
+        TInt maxLen=0;
+        TBuf<KUssdEditorMaxLenght> inputTexts;
+
+        iEditor->GetText( inputTexts );
+
+        maxLen = iNaviPaneHandler->UpdateMsgLengthL( inputTexts, this );
+
+        // if pasted more than 91 chinese characters then it must be
+        // cutted and set correct message length in navi pane
+        if ( inputTexts.Length() > maxLen )
+            {
+            inputTexts.Copy( inputTexts.Left( maxLen ) );
+            iEditor->SetTextL( &inputTexts );
+            iNaviPaneHandler->UpdateMsgLengthL( inputTexts, this );
+            iEditor->DrawNow();
+            iEditor->SetCursorPosL( maxLen, EFalse );
+            }
+
+        iEditor->SetMaxLength( maxLen );
+
+        }
+
+    }
+
+// End of File