uifw/AvKon/src/AknPhoneNumberEditor.cpp
changeset 0 2f259fa3e83a
child 3 8ca85d2f0db7
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/uifw/AvKon/src/AknPhoneNumberEditor.cpp	Tue Feb 02 01:00:49 2010 +0200
@@ -0,0 +1,1298 @@
+/*
+* 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: 
+*
+*/
+
+#include "AknPhoneNumberEditor.h"
+#include "AknPhedView.h"
+
+#include <AknUtils.h>
+#include <frmtlay.h>
+#include <eikenv.h>
+#include <barsread.h>
+#include <aknedsts.h>
+#include <featmgr.h>    
+#include <aknextendedinputcapabilities.h>
+#include <eikcoctl.rsg>
+#include <txtetext.h>
+
+#include <AknTasHook.h>
+#include <touchfeedback.h>
+#include <aknnotedialog.h>
+
+static const TInt KPlainTextPos = 0;
+
+typedef CArrayFixFlat<CAknPhoneNumberEditor::TFormat> CFormatArray;
+
+NONSHARABLE_CLASS( CAknPhoneNumberEditorExtension ) : public CBase, 
+    public MObjectProvider
+    {
+    public:
+        CAknPhoneNumberEditorExtension();
+        ~CAknPhoneNumberEditorExtension();
+    
+    protected:  // from MObjectProvider        
+         TTypeUid::Ptr MopSupplyObject( TTypeUid aId );       
+    
+    public:
+        CFormatArray* iFormats;
+        CAknExtendedInputCapabilities* iExtendedInputCapabilities;
+        TInt iPointPos;
+        CAknCcpuSupport* iCcpuSupport; 
+        HBufC* iPasteText;       
+      };
+
+CAknPhoneNumberEditorExtension::CAknPhoneNumberEditorExtension()
+    {
+    iFormats = NULL;
+    iExtendedInputCapabilities = NULL;
+    }
+
+
+CAknPhoneNumberEditorExtension::~CAknPhoneNumberEditorExtension()
+    {
+    delete iPasteText;
+    delete iFormats;
+    delete iExtendedInputCapabilities;    
+    delete iCcpuSupport;
+    }
+
+// ---------------------------------------------------------
+// CAknPhoneNumberEditorExtension::MopSupplyObject
+// ---------------------------------------------------------
+//
+TTypeUid::Ptr CAknPhoneNumberEditorExtension::MopSupplyObject( TTypeUid aId )
+    {
+    if ( aId.iUid == CAknExtendedInputCapabilities::ETypeId )
+        {
+        return aId.MakePtr( iExtendedInputCapabilities );
+        }
+    
+    return TTypeUid::Null();
+    }
+
+enum TAknPhedFlags
+    {
+    ERedrawAll,
+    EInlineEditInProgress,
+    EFeaturePhoneNumberGrouping
+    };
+
+enum TAknPhedControlPanic
+    {
+    ELeaveInStateChange,
+    EIncorrectInlineEditState
+    };
+
+void PhedControlPanic( TAknPhedControlPanic aPanic )
+    {
+    _LIT( KAknPhedControl,"AknPhedControl" );
+    User::Panic( KAknPhedControl, aPanic );
+    }
+
+
+EXPORT_C CAknPhoneNumberEditor::TFormat::TFormat()
+    {
+    Mem::FillZ( this, sizeof( *this ) );
+    }
+
+EXPORT_C CAknPhoneNumberEditor::TFormat::TFormat( TResourceReader& aReader )
+    {
+    Mem::FillZ( this, sizeof( *this ) );
+
+    TInt top = aReader.ReadInt16();
+    TInt left = aReader.ReadInt16();
+    TInt bottom = aReader.ReadInt16();
+    TInt right = aReader.ReadInt16();
+    iOuterRect = TRect( TPoint( left, top ), TPoint( right, bottom ) );
+
+    iBorderType = aReader.ReadInt32();
+    iNumLines = aReader.ReadInt16();
+    iBottomBaselineOffset = aReader.ReadInt16();
+    iBaselineSeparation = aReader.ReadInt16();
+    iFont = AknLayoutUtils::FontFromId( aReader.ReadInt16() );
+    }
+
+EXPORT_C CAknPhoneNumberEditor::TFormat::TFormat( const TRect& aOuterRect, TInt aBorderType, 
+    TInt aNumLines, TInt aBottomBaselineOffset, TInt aBaselineSeparation, const CFont* aFont )
+    : iOuterRect( aOuterRect ), iBorderType( aBorderType ), iNumLines( aNumLines ), 
+      iBottomBaselineOffset( aBottomBaselineOffset ), iBaselineSeparation( aBaselineSeparation ), 
+      iFont( aFont )
+    {
+    }
+
+
+
+EXPORT_C CAknPhoneNumberEditor::CAknPhoneNumberEditor()
+    {
+    iFlags.Set( ERedrawAll );
+    AKNTASHOOK_ADD( this, "CAknPhoneNumberEditor" );
+    }
+
+EXPORT_C CAknPhoneNumberEditor::~CAknPhoneNumberEditor()
+    {
+    AKNTASHOOK_REMOVE();
+    delete iView;
+    delete iModel;
+    delete iExtension;
+    delete iFepState;
+    }
+
+EXPORT_C void CAknPhoneNumberEditor::ConstructFromResourceL( TResourceReader& aReader )
+    {
+    TInt maxChars = aReader.ReadInt16();
+    TInt maxLines = aReader.ReadInt16();
+    HBufC* truncation = aReader.ReadHBufCL();
+    CleanupStack::PushL( truncation );
+    TInt formatCount = aReader.ReadInt16();
+    ConstructL( maxChars, maxLines, formatCount, *truncation );
+    CleanupStack::PopAndDestroy();  // truncation
+
+    for ( TInt ii=0; ii<formatCount; ii++ )
+        {
+        AddFormat( TFormat(aReader ) );
+        }
+
+    SetFormat( 0 );
+    
+    TUint cap = iExtension->iExtendedInputCapabilities->Capabilities();
+    cap |= CAknExtendedInputCapabilities::EInputEditorDisableVKB;
+    iExtension->iExtendedInputCapabilities->SetCapabilities( cap );
+    
+    }
+
+EXPORT_C void CAknPhoneNumberEditor::ConstructL( TInt aMaxChars, 
+                                                 TInt aMaxLines, 
+                                                 TInt aMaxFormats, 
+                                                 const TDesC& aTruncation )
+    {
+    iExtension = new(ELeave) CAknPhoneNumberEditorExtension();
+    iExtension->iFormats = new(ELeave) CFormatArray( 1 );
+    iExtension->iFormats->ResizeL( aMaxFormats );
+    iModel = CAknPhedModel::NewL( aMaxChars );
+    iView = new(ELeave) CAknPhedView( iModel );
+    iView->ConstructL( aMaxLines, aTruncation );
+    iView->SetWindows( &iEikonEnv->RootWin(), DrawableWindow() );
+    iView->SetChangeReceiver( this );
+    CreateFepStateL();
+    iExtension->iExtendedInputCapabilities = CAknExtendedInputCapabilities::NewL();
+    
+    TUint cap = iExtension->iExtendedInputCapabilities->Capabilities();
+    cap |= CAknExtendedInputCapabilities::EInputEditorDisableVKB;
+    iExtension->iExtendedInputCapabilities->SetCapabilities( cap );
+
+    EnableDragEvents();      
+    EnableCcpuSupportL( ETrue );
+    }
+
+EXPORT_C void CAknPhoneNumberEditor::AddFormat( const TFormat& aFormat )
+    {
+    iExtension->iFormats->At( iNumFormats++ ) = aFormat;
+    }
+
+EXPORT_C TInt CAknPhoneNumberEditor::CountFormats() const
+    {
+    return iNumFormats;
+    }
+
+EXPORT_C CAknPhoneNumberEditor::TFormat& CAknPhoneNumberEditor::Format( TInt aFormatIndex ) const
+    {
+    return iExtension->iFormats->At( aFormatIndex );
+    }
+
+EXPORT_C TInt CAknPhoneNumberEditor::CurrentFormatIndex() const
+    {
+    return iCurrentFormatIndex;
+    }
+
+EXPORT_C TBool CAknPhoneNumberEditor::WouldTextFitInFormat( TInt aFormatIndex ) const
+    {
+    TFormat& format = Format( aFormatIndex );
+
+    // create a line and see how many times the text takes to fit it.
+    TAknPhedViewLine line;
+    line.SetModel( iModel );
+    line.SetFormat( format.iFont, Border().InnerRect( format.iOuterRect ),
+                    format.iBaselineSeparation );
+
+    TInt count = 1;
+    line.SetRightPos( 0 );
+    if ( line.LeftPos() > 0 )
+        {
+    while ( line.LeftPos() != iModel->Length() )
+        {
+        line.SetRightPos( line.LeftPos() );
+        line.SetRightLine( &line );
+        count++;
+        }
+        }
+    return count <= format.iNumLines;
+    }
+
+EXPORT_C void CAknPhoneNumberEditor::SetFormat( TInt aFormatIndex )
+    {
+    iCurrentFormatIndex = aFormatIndex;
+    TFormat& format = Format( aFormatIndex );
+    SetBorder( format.iBorderType );
+    SetRect( format.iOuterRect );
+    }
+
+EXPORT_C TPtrC CAknPhoneNumberEditor::Text( TInt aFrom ) const
+    {
+    return iModel->UnFormattedText(aFrom);
+    }
+
+EXPORT_C void CAknPhoneNumberEditor::SetText( const TDesC& aText )
+    {
+    iModel->SetText( aText );
+    }
+
+void CAknPhoneNumberEditor::DrawChanges()
+    {
+    // DrawChanges actually draws everything. Flicker is not
+    // a problem now.
+    DrawDeferred();
+    }
+
+EXPORT_C void CAknPhoneNumberEditor::SizeChanged()
+    {
+    TFormat& format = Format( CurrentFormatIndex() );
+    TPoint pt = DrawableWindow()->Position();
+    TSize size = DrawableWindow()->Size();
+    TRect rect = Rect();
+    TInt offset = rect.iBr.iX - ( pt.iX + size.iWidth );   
+    if ( offset > 0 )
+        {        
+        rect.iTl.iX -= offset;
+        rect.iBr.iX = pt.iX + size.iWidth;    
+        SetRect( rect );
+        }     
+    iView->SetFormat( format.iNumLines, format.iFont, Border().InnerRect( Rect() ),
+        format.iBottomBaselineOffset, format.iBaselineSeparation);
+    }
+
+EXPORT_C TKeyResponse CAknPhoneNumberEditor::OfferKeyEventL( const TKeyEvent& aKeyEvent,
+                                                             TEventCode aType )
+    {
+    if ( aType != EEventKey )
+        return EKeyWasNotConsumed;
+
+    TKeyResponse resp = EKeyWasConsumed;
+
+    TInt cursorX = iView->CursorPosition().iX;
+    TBool targetPosUsed = EFalse;
+    
+    // when user inputs digit, the screen should be drawn, otherwise
+    // we need to check whether the screen will be drawn by view
+    TBool needDraw = EFalse;
+
+    // record cursorline before cursor moves for preventing flicker
+    TInt cursorLinePre = iView->CursorLine();
+
+    // record leftpos of current line to help to decide how the 
+    // cursor moves between different lines.
+    const CAknPhedViewLineArray* lineArray = iView->LineArray();
+    TInt leftPosPre = lineArray->At( cursorLinePre ).LeftPos();
+
+    // phone number editor does not respond to shift key.
+    // The code is still here because it may need to be turned back on if
+    // the phone number editor needs to support selection, cut, copy and paste.
+    TBool shift = ( ( aKeyEvent.iModifiers & EModifierShift ) == EModifierShift );
+    TBool cousorChanged = EFalse;
+    switch(aKeyEvent.iCode)
+        {
+        case EKeyLeftArrow:
+            if (shift)
+                iModel->SelectLeft();
+            else
+                iModel->CursorLeft();
+            cousorChanged = ETrue;
+            break;
+
+        case EKeyRightArrow:
+            if (shift)
+                iModel->SelectRight();
+            else
+                iModel->CursorRight();
+            cousorChanged = ETrue;
+            break;
+
+        case EKeyUpArrow:
+            if ( shift )
+                targetPosUsed = iView->SelectUp( TargetCursorPos( cursorX ) );
+            else
+                targetPosUsed = iView->CursorUp( TargetCursorPos( cursorX ) );
+            cousorChanged = ETrue;
+            break;
+
+        case EKeyDownArrow:
+            if ( shift )
+                targetPosUsed = iView->SelectDown( TargetCursorPos( cursorX ) );
+            else
+                targetPosUsed = iView->CursorDown( TargetCursorPos( cursorX ) );
+            cousorChanged = ETrue;
+            break;
+
+        case EKeyBackspace:
+            iModel->DeleteLeft();
+            needDraw = ETrue;
+            break;
+
+        default:
+            if ( aKeyEvent.iCode < ENonCharacterKeyBase )
+                {
+                iModel->Insert( TText( aKeyEvent.iCode ) );
+                needDraw = ETrue;
+                }
+            else
+                resp = EKeyWasNotConsumed;
+            break;
+        }
+        
+    if ( iExtension->iExtendedInputCapabilities )
+        {
+        iExtension->iExtendedInputCapabilities->ReportEventL( 
+            CAknExtendedInputCapabilities::
+            MAknEventObserver::EControlContentUpdatedInternally,
+            NULL );
+        }
+        
+    if ( shift && iExtension->iCcpuSupport )
+        {
+        iExtension->iCcpuSupport->HandleSelectionChangeL();
+        }
+    if ( cousorChanged )
+    	{
+        ReportAknEdStateEventL( MAknEdStateObserver::EAknCursorPositionChanged );
+    	}
+    // see if we want to remember the old cursor X position
+    if ( targetPosUsed )
+        {
+        if ( iTargetCursorPos == CAknPhedView::KNoPos )
+            iTargetCursorPos = cursorX;
+        }
+    else
+        iTargetCursorPos = CAknPhedView::KNoPos;
+
+    // To prevent flicker by avoiding drawing screen multi-times in short 
+    // time. When cursor moves between two lines that are both shown at 
+    // the same time, the screen will be drawn by CAknPhedView, and the 
+    // DrawNow need not be called, otherwise the screen should be drawn here. 
+    TInt leftPosPost = lineArray->At( iView->CursorLine() ).LeftPos();    
+    if ( needDraw || 
+        Abs( leftPosPost - leftPosPre ) != lineArray->At( 0 ).LineWidth() )
+        {
+        DrawNow();
+        }
+    ReportEventL( MCoeControlObserver::EEventStateChanged );
+    return resp;
+    }
+
+EXPORT_C TSize CAknPhoneNumberEditor::MinimumSize()
+    {
+    return iView->Rect().Size();
+    }
+
+EXPORT_C void CAknPhoneNumberEditor::FocusChanged( TDrawNow aDrawNow )
+    {
+    if ( iView )
+        {
+        if ( IsFocused() )
+            iView->EnableCursor();
+        else
+            iView->DisableCursor(); 
+        }
+            
+    if ( iExtension->iCcpuSupport )
+        {
+        TRAP_IGNORE( iExtension->iCcpuSupport->HandleFocusChangeL() );        
+        }    
+    if ( ! IsFocused() )
+        {
+        TRAP_IGNORE( ReportAknEdStateEventL( MAknEdStateObserver::EAknSyncEdwinState ) );
+        }
+    if ( aDrawNow )
+        DrawNow();
+    }
+
+EXPORT_C void CAknPhoneNumberEditor::Draw( const TRect& aRect ) const
+    {
+    CEikBorderedControl::Draw( aRect );
+    iView->Draw( SystemGc(), iFlags[ERedrawAll], this );
+    }
+
+EXPORT_C TCoeInputCapabilities CAknPhoneNumberEditor::InputCapabilities() const
+    {
+    if ( FeatureManager::FeatureSupported( KFeatureIdCommonVoip ) )
+        {
+        TCoeInputCapabilities inputCaps(
+            TCoeInputCapabilities::EWesternAlphabetic | 
+            TCoeInputCapabilities::ENavigation, 
+            const_cast<CAknPhoneNumberEditor*>( this ), NULL ); 
+            
+        // Voip-enabled phone editor wants to use edit-key style hash key mode selection.    
+        iExtension->iExtendedInputCapabilities->SetEditorType( 
+            CAknExtendedInputCapabilities::EPhoneNumberEditor );                    
+        iExtension->iExtendedInputCapabilities->SetCapabilities(
+            CAknExtendedInputCapabilities::EForceHashKeySelectionStatusFlagOff |
+            CAknExtendedInputCapabilities::EForceEditSubmenuStatusFlagOff );              
+        inputCaps.SetObjectProvider( 
+            const_cast<CAknPhoneNumberEditorExtension*>( iExtension ) );                        
+                        
+        return inputCaps;                                                   
+        }
+    else if ( FeatureManager::FeatureSupported( KFeatureIdCsVideoTelephony ) )
+        {
+        TCoeInputCapabilities inputCaps(
+            TCoeInputCapabilities::EDialableCharacters | 
+            TCoeInputCapabilities::ENavigation, 
+            const_cast<CAknPhoneNumberEditor*>(this), NULL); 
+            
+        iExtension->iExtendedInputCapabilities->SetEditorType(
+            CAknExtendedInputCapabilities::EPhoneNumberEditor );                                                                                          
+        inputCaps.SetObjectProvider(
+            const_cast<CAknPhoneNumberEditorExtension*>( iExtension ) );                                
+                    
+        return inputCaps;                                  
+        }  
+    return TCoeInputCapabilities( 0, const_cast<CAknPhoneNumberEditor*>(this), NULL );
+    }
+
+EXPORT_C TInt CAknPhoneNumberEditor::TextLength() const
+    {
+    return iModel->Length();
+    }
+
+EXPORT_C TInt CAknPhoneNumberEditor::CursorPos() const
+    {
+    return iModel->CursorPosition();
+    }
+
+EXPORT_C TInt CAknPhoneNumberEditor::SelectionLength() const
+    {
+    return iModel->SelectionWidth();
+    }
+
+EXPORT_C TCursorSelection CAknPhoneNumberEditor::Selection() const
+    {
+    return TCursorSelection( iModel->CursorPosition(), iModel->AnchorPosition() );
+    }
+
+EXPORT_C void CAknPhoneNumberEditor::ClearSelectionL()
+    {
+    if ( iModel->SelectionExists() )
+        iModel->DeleteLeft();
+    }
+
+EXPORT_C void CAknPhoneNumberEditor::SetSelectionL( TInt aCursorPos,TInt aAnchorPos )
+    {
+    iModel->SetRealCursorPosition(aCursorPos);
+    iModel->SetAnchorPosition( aAnchorPos );
+    ReportAknEdStateEventL( 
+            MAknEdStateObserver::EAknCursorPositionChanged );
+    }
+
+EXPORT_C void CAknPhoneNumberEditor::SetCursorPosL( TInt aCursorPos,TBool aSelect )
+    {
+    TInt anchor = iModel->AnchorPosition();
+    iModel->SetRealCursorPosition( aCursorPos );
+    if ( aSelect )
+        iModel->SetAnchorPosition( anchor );
+    ReportAknEdStateEventL( 
+        MAknEdStateObserver::EAknCursorPositionChanged );
+    }
+
+EXPORT_C void CAknPhoneNumberEditor::SelectAllL()
+    {
+    iModel->SetRealCursorPosition(iModel->Length());
+    iModel->SetAnchorPosition( 0 );
+    }
+
+EXPORT_C void CAknPhoneNumberEditor::GetText( TDes& aDes ) const
+    {
+    if ( Text().Length() <= aDes.MaxLength() )
+        {
+        aDes = Text();
+        }
+    else
+        {
+        aDes = Text().Left( aDes.MaxLength() );
+        }
+    }
+
+EXPORT_C HBufC* CAknPhoneNumberEditor::GetTextInHBufL() const
+    {
+    return Text().AllocL();
+    }
+
+EXPORT_C void CAknPhoneNumberEditor::SetTextL( const TDesC* aDes )
+    {
+    if ( aDes )
+        iModel->SetText( *aDes );
+    else
+        iModel->SetText( KNullDesC() );
+    }
+
+EXPORT_C void CAknPhoneNumberEditor::CancelFepTransaction()
+    {
+    CCoeFep* fep = iCoeEnv->Fep();
+    if ( fep )
+        {
+        fep->CancelTransaction();
+        }   
+    }
+
+EXPORT_C void CAknPhoneNumberEditor::UpdateScrollBarsL()
+    {
+    }
+
+EXPORT_C CEikScrollBarFrame* CAknPhoneNumberEditor::CreateScrollBarFrameL()
+    {
+    return NULL;
+    }
+
+EXPORT_C TInt CAknPhoneNumberEditor::LineCursorWidth() const
+    {
+    return 0;
+    }
+
+EXPORT_C TMargins8 CAknPhoneNumberEditor::Margins() const
+    {
+    return TMargins8();
+    }
+
+void CAknPhoneNumberEditor::StartFepInlineEditL( 
+         const TDesC& aInitialInlineText, 
+         TInt /*aPositionOfInsertionPointInInlineText*/, 
+         TBool /*aCursorVisibility*/, 
+         const MFormCustomDraw* /*aCustomDraw*/, 
+         MFepInlineTextFormatRetriever& /*aInlineTextFormatRetriever*/, 
+         MFepPointerEventHandlerDuringInlineEdit& /*aPointerEventHandlerDuringInlineEdit*/)
+    {
+    if ( aInitialInlineText.Length() == 0 )
+        {
+        // This method used to ignore aInitialInlineText. For improved 
+        // backwards compatibility just do what it did before.  
+        // That is, do not admit a new state of "in inline edit", but with no text.
+        iFlags.Clear( EInlineEditInProgress );
+        }
+    else
+        {
+        // flag is set by a StartFepInlineEdit with text
+        // or by UpdateFepInlineTextL. Should not get a 2nd start.
+        __ASSERT_DEBUG( !iFlags[EInlineEditInProgress], 
+                        PhedControlPanic(EIncorrectInlineEditState) );
+        iModel->Insert( aInitialInlineText[0] );
+        iFlags.Set( EInlineEditInProgress );
+        DrawChanges();
+        }
+    }
+
+void CAknPhoneNumberEditor::UpdateFepInlineTextL(const TDesC& aNewInlineText, 
+    TInt /*aPositionOfInsertionPointInInlineText*/ )
+    {
+    if ( iFlags[EInlineEditInProgress] )
+        iModel->DeleteLeft();
+    
+    if ( aNewInlineText != KNullDesC )
+        {
+        iModel->Insert( aNewInlineText[0] );    
+        }
+    else
+        {
+        iModel->DeleteLeft();
+        }
+    
+    iFlags.Set( EInlineEditInProgress );
+    DrawChanges();
+    }
+
+void CAknPhoneNumberEditor::SetInlineEditingCursorVisibilityL(TBool /*aCursorVisibility*/)
+    {
+    }
+
+void CAknPhoneNumberEditor::CancelFepInlineEdit()
+    {
+    iFlags.Clear( EInlineEditInProgress );
+    }
+
+TInt CAknPhoneNumberEditor::DocumentLengthForFep() const
+    {
+    return iModel->UnFormattedText( 0 ).Length();
+    }
+
+TInt CAknPhoneNumberEditor::DocumentMaximumLengthForFep() const
+    {
+    // Lie to FEP about the maximum length, because we handle our own overflow.
+    return iModel->MaxDisplayLength() + 1;
+    }
+
+void CAknPhoneNumberEditor::SetCursorSelectionForFepL( const TCursorSelection& aCursorSelection )
+    {
+    iModel->SetRealCursorPosition( iModel->Uncompensate( aCursorSelection.iCursorPos ) );
+    iModel->SetAnchorPosition( iModel->Uncompensate( aCursorSelection.iAnchorPos  ) );
+    
+    ReportAknEdStateEventL( 
+            MAknEdStateObserver::EAknCursorPositionChanged );
+    DrawNow();
+    }
+
+void CAknPhoneNumberEditor::GetCursorSelectionForFep( TCursorSelection& aCursorSelection ) const
+    {
+    aCursorSelection.iCursorPos = iModel->CursorPosition();
+    aCursorSelection.iAnchorPos = iModel->AnchorPosition();
+    }
+
+void CAknPhoneNumberEditor::GetEditorContentForFep( TDes& aEditorContent, 
+                                                    TInt aDocumentPosition, 
+                                                    TInt aLengthToRetrieve ) const
+    {
+    TInt realLength = Min( iModel->Length() - aDocumentPosition, aLengthToRetrieve );
+    if ( iModel->Length() > 0 )
+        {
+        if ( iModel->UnFormattedText( 0 ).Length() >= aDocumentPosition + realLength )
+            {
+            aEditorContent.Copy(
+                iModel->UnFormattedText( 0 ).Mid( aDocumentPosition, realLength ) );
+            }
+        }
+    }
+void CAknPhoneNumberEditor::GetFormatForFep( TCharFormat& /*aFormat*/, 
+                                             TInt /*aDocumentPosition*/ ) const
+    {
+    }
+
+void CAknPhoneNumberEditor::GetScreenCoordinatesForFepL( TPoint& /*aLeftSideOfBaseLine*/, 
+                                                         TInt& /*aHeight*/, 
+                                                         TInt& /*aAscent*/, 
+                                                         TInt /*aDocumentPosition*/) const
+    {
+    }
+
+void CAknPhoneNumberEditor::DoCommitFepInlineEditL()
+    {
+    iFlags.Clear( EInlineEditInProgress );
+    }
+
+MCoeFepAwareTextEditor_Extension1* CAknPhoneNumberEditor::Extension1(TBool& aSetToTrue)
+    {
+    aSetToTrue=ETrue;
+    return STATIC_CAST( MCoeFepAwareTextEditor_Extension1*, this );
+    }
+
+TInt CAknPhoneNumberEditor::TargetCursorPos( TInt aCurrentPos )
+    {
+    if ( iTargetCursorPos == CAknPhedView::KNoPos )
+        return aCurrentPos;
+    else
+        return iTargetCursorPos;
+    }
+
+void CAknPhoneNumberEditor::StateChanged()
+    {
+#ifdef _DEBUG
+    TRAPD(err, ReportEventL( MCoeControlObserver::EEventStateChanged ) );
+    // phone number editor should never leave.
+    TRAP_IGNORE(__ASSERT_DEBUG( err == KErrNone, PhedControlPanic( ELeaveInStateChange ) ) ); 
+#else
+    TRAP_IGNORE( ReportEventL( MCoeControlObserver::EEventStateChanged ) );
+#endif // _DEBUG
+    }
+
+CEikScrollBarFrame* CAknPhoneNumberEditor::CreateScrollBarFrameL(TBool /*aPreAlloc*/)
+    {
+    return NULL;
+    }
+
+void CAknPhoneNumberEditor::SetStateTransferingOwnershipL( CState* aState,
+                                                           TUid /*aTypeSafetyUid*/)
+    {
+    if ( iFepState )
+        delete iFepState;
+    iFepState=aState;
+    }
+
+MCoeFepAwareTextEditor_Extension1::CState* CAknPhoneNumberEditor::State( TUid /*aTypeSafetyUid*/ )
+    {
+    return iFepState;
+    }
+
+void CAknPhoneNumberEditor::CreateFepStateL()
+    {
+    CAknEdwinState* fepState = new(ELeave) CAknEdwinState();
+    iFepState = fepState;
+    
+    fepState->SetObjectProvider( this );
+    fepState->SetFlags( EAknEditorFlagFixedCase | EAknEditorFlagNoT9 | 
+        EAknEditorFlagNoEditIndicators | EAknEditorFlagSelectionVisible ); 
+    fepState->SetDefaultInputMode( EAknEditorNumericInputMode );
+    fepState->SetCurrentInputMode( EAknEditorNumericInputMode );
+    fepState->SetPermittedInputModes( EAknEditorNumericInputMode );
+    fepState->SetDefaultCase( EAknEditorLowerCase );
+    fepState->SetCurrentCase( EAknEditorLowerCase );
+    fepState->SetPermittedCases( EAknEditorLowerCase|EAknEditorUpperCase );
+    fepState->SetSpecialCharacterTableResourceId( 0 );
+    fepState->SetNumericKeymap( EAknEditorStandardNumberModeKeymap );
+    }
+
+EXPORT_C void CAknPhoneNumberEditor::MCoeFepAwareTextEditor_Reserved_2()
+    {
+    }
+
+EXPORT_C void CAknPhoneNumberEditor::MCoeFepAwareTextEditor_Extension1_Reserved_2()
+    {
+    }
+
+EXPORT_C void CAknPhoneNumberEditor::MCoeFepAwareTextEditor_Extension1_Reserved_3()
+    {
+    }
+
+EXPORT_C void CAknPhoneNumberEditor::MCoeFepAwareTextEditor_Extension1_Reserved_4()
+    {
+    }
+
+
+// ---------------------------------------------------------
+// CAknPhoneNumberEditor::ChangeEditorMode
+// ---------------------------------------------------------
+//
+EXPORT_C TInt CAknPhoneNumberEditor::ChangeEditorMode( TBool aDefaultMode )
+    {
+    TInt value( EAknEditorNumericInputMode ); // Return value.
+    
+    if ( FeatureManager::FeatureSupported( KFeatureIdCommonVoip ) )
+        {
+        CAknEdwinState* fepState = ( CAknEdwinState* )iFepState; 
+
+        // Get current input mode.
+        TInt currentInputMode = fepState->CurrentInputMode();
+    
+        // Set default values.
+        if ( aDefaultMode )
+            {
+            fepState->SetCurrentInputMode( EAknEditorNumericInputMode );   
+            value = EAknEditorNumericInputMode;
+            }
+        // Set next input mode. 123 -> abc -> 123...    
+        else
+            {
+            if ( currentInputMode == EAknEditorNumericInputMode )
+                {
+                fepState->SetCurrentInputMode( EAknEditorTextInputMode );
+                fepState->SetSpecialCharacterTableResourceId( 
+                    R_AVKON_URL_SPECIAL_CHARACTER_TABLE_DIALOG );
+                value = EAknEditorTextInputMode;
+                }
+            else if ( currentInputMode == EAknEditorTextInputMode )
+                {
+                fepState->SetCurrentInputMode(EAknEditorNumericInputMode);
+                fepState->SetSpecialCharacterTableResourceId( 0 );
+                value = EAknEditorNumericInputMode;
+                }
+            }   
+            
+        fepState->SetCurrentCase(EAknEditorLowerCase);        
+        // Set some other VoIP specific editor settings.    
+        if ( FeatureManager::FeatureSupported( KFeatureIdOnScreenDialer ) ) 
+            {
+            fepState->SetFlags( EAknEditorFlagNoT9  
+                | EAknEditorFlagLatinInputModesOnly | EAknEditorFlagNoEditIndicators );
+            }
+        else
+            {
+            fepState->SetFlags( EAknEditorFlagNoT9  
+                | EAknEditorFlagLatinInputModesOnly );
+            }
+        
+        fepState->SetPermittedInputModes( 
+            EAknEditorNumericInputMode|EAknEditorTextInputMode );       
+        fepState->SetNumericKeymap(EAknEditorAlphanumericNumberModeKeymap);
+    
+        // Report FEP from new settings.
+        TRAP_IGNORE( fepState->ReportAknEdStateEventL(
+            MAknEdStateObserver::EAknEdwinStateEventStateUpdate ) ); 
+        
+        fepState->SetMenu();  
+        }
+    DrawChanges();
+    return value;
+    }
+    
+// ---------------------------------------------------------
+// CAknPhoneNumberEditor::GetEditorMode
+// ---------------------------------------------------------
+//
+EXPORT_C TInt CAknPhoneNumberEditor::GetEditorMode() const
+    {
+    CAknEdwinState* fepState = ( CAknEdwinState* )iFepState; 
+
+    TInt currentInputMode = fepState->CurrentInputMode();
+
+    fepState->SetCurrentCase(EAknEditorLowerCase);    
+    if ( currentInputMode == EAknEditorNumericInputMode )
+        {
+        fepState->SetSpecialCharacterTableResourceId( 0 );        
+        }
+    else if ( currentInputMode == EAknEditorTextInputMode )
+        {
+        
+        fepState->SetSpecialCharacterTableResourceId( 
+            R_AVKON_URL_SPECIAL_CHARACTER_TABLE_DIALOG );
+        } 
+        
+    fepState->SetMenu(); 
+    return currentInputMode;
+    }
+
+// ---------------------------------------------------------
+// CAknPhoneNumberEditor::ResetEditorToDefaultValues
+// ---------------------------------------------------------
+//
+EXPORT_C void CAknPhoneNumberEditor::ResetEditorToDefaultValues()
+    {
+    CAknEdwinState* fepState = ( CAknEdwinState* )iFepState; 
+    CloseVKB();
+    // Set FEP-state to default values. 
+    fepState->SetFlags( EAknEditorFlagFixedCase | EAknEditorFlagNoT9 | 
+        EAknEditorFlagNoEditIndicators );
+    fepState->SetDefaultInputMode( EAknEditorNumericInputMode );
+    fepState->SetCurrentInputMode( EAknEditorNumericInputMode );
+    fepState->SetPermittedInputModes( EAknEditorNumericInputMode );
+    fepState->SetDefaultCase( EAknEditorLowerCase );
+    fepState->SetCurrentCase( EAknEditorLowerCase );
+    fepState->SetPermittedCases( EAknEditorLowerCase | EAknEditorUpperCase );
+    fepState->SetSpecialCharacterTableResourceId( 0 );
+    fepState->SetNumericKeymap( EAknEditorStandardNumberModeKeymap );
+    
+    DrawChanges();
+    }
+
+// --------------------------------------------------------------------------
+// CAknPhoneNumberEditor::HandlePointerEventL
+// --------------------------------------------------------------------------
+//
+EXPORT_C void CAknPhoneNumberEditor::HandlePointerEventL(
+    const TPointerEvent& aPointerEvent)
+    {   
+    TCursorSelection selectionBefore = Selection();
+    TInt cursor = iView->GetCursorPosByPoint( aPointerEvent.iPosition );
+    // if cursro is not in accepted range. cancel current selection
+    
+    if ( cursor < 0 ) 
+        {
+        cursor = CursorPos();
+        DrawNow();
+        return;
+        }
+    
+    const CAknPhedViewLineArray* lineArray = iView->LineArray(); 
+    TInt cursorLinePre = iView->CursorLine();
+    TInt leftPosPre = lineArray->At( cursorLinePre ).LeftPos();
+    switch( aPointerEvent.iType )
+        {
+        case TPointerEvent::EButton1Down:
+            {
+            MTouchFeedback* feedback = MTouchFeedback::Instance();
+            
+            if ( feedback )
+                {
+                feedback->InstantFeedback( this, ETouchFeedbackEdit );
+                }
+            }
+            //cancel previous selection
+            if ( iExtension->iPointPos != cursor )
+                {                
+                SetCursorPosL( iModel->Uncompensate( cursor ), EFalse  );              
+                iExtension->iPointPos = cursor;
+                }
+            break;
+        case TPointerEvent::EButton1Up:
+            if ( iExtension->iPointPos == cursor )
+                {
+                SetCursorPosL( iModel->Uncompensate( cursor ), EFalse );
+                }
+            else
+                {
+                SetSelectionL( iModel->Uncompensate( cursor ), 
+                    iModel->Uncompensate( iExtension->iPointPos ) );
+                }
+            break;
+        case TPointerEvent::EButtonRepeat:
+        case TPointerEvent::EDrag:
+            {              
+            SetSelectionL( iModel->Uncompensate( cursor ), 
+                iModel->Uncompensate( iExtension->iPointPos ) );
+            TCursorSelection selectionAfter = Selection();
+            TBool selectionChanged = 
+                   (  ( selectionAfter.iCursorPos != selectionBefore.iCursorPos )
+                   || ( selectionAfter.iAnchorPos != selectionBefore.iAnchorPos ) );
+            if ( selectionChanged )
+                {
+                MTouchFeedback* feedback = MTouchFeedback::Instance();
+                if ( feedback )
+                    {
+                    feedback->InstantFeedback( this, ETouchFeedbackTextSelection );
+                    }
+                }
+            }
+            break;        
+        default:
+            break;          
+        }    
+    
+    // same handling as OfferKeyEvent to prevent flicker.   
+    TInt leftPosPost = lineArray->At( iView->CursorLine() ).LeftPos();    
+    if ( Abs( leftPosPost - leftPosPre ) != lineArray->At( 0 ).LineWidth() )
+        {
+        DrawNow();
+        }
+    }
+
+// --------------------------------------------------------------------------
+// CAknPhoneNumberEditor::MopSupplyObject
+// --------------------------------------------------------------------------
+//    
+EXPORT_C TTypeUid::Ptr CAknPhoneNumberEditor::MopSupplyObject( TTypeUid aId )
+    {
+    if ( aId.iUid == CEikMenuBar::ETypeId )    
+        {
+        return aId.MakePtr( iEikonEnv->AppUiFactory()->MenuBar() );
+        }
+    return TTypeUid::Null();
+    }
+
+// --------------------------------------------------------------------------
+// CAknPhoneNumberEditor::CcpuIsFocused
+// --------------------------------------------------------------------------
+//
+EXPORT_C TBool CAknPhoneNumberEditor::CcpuIsFocused() const
+    {
+    return IsFocused();
+    }
+
+// --------------------------------------------------------------------------
+// CAknPhoneNumberEditor::CcpuCanCut
+// --------------------------------------------------------------------------
+//
+EXPORT_C TBool CAknPhoneNumberEditor::CcpuCanCut() const
+    {
+    return ( iExtension->iCcpuSupport && SelectionLength() != 0 );
+    }
+
+// --------------------------------------------------------------------------
+// CAknPhoneNumberEditor::CcpuCutL
+// --------------------------------------------------------------------------
+//
+EXPORT_C void CAknPhoneNumberEditor::CcpuCutL()
+    {
+    ClipboardL( EFalse );
+    }
+
+// --------------------------------------------------------------------------
+// CAknPhoneNumberEditor::CcpuCanCopy
+// --------------------------------------------------------------------------
+//
+EXPORT_C TBool CAknPhoneNumberEditor::CcpuCanCopy() const
+    {
+    return ( iExtension->iCcpuSupport && SelectionLength() != 0 );
+    }
+
+// --------------------------------------------------------------------------
+// CAknPhoneNumberEditor::CcpuCopyL
+// --------------------------------------------------------------------------
+//
+EXPORT_C void CAknPhoneNumberEditor::CcpuCopyL()
+    {
+    ClipboardL( ETrue );
+    }
+
+// --------------------------------------------------------------------------
+// CAknPhoneNumberEditor::CcpuCanPaste
+// --------------------------------------------------------------------------
+//
+EXPORT_C TBool CAknPhoneNumberEditor::CcpuCanPaste() const
+    {
+    if ( !iExtension->iCcpuSupport )
+        return EFalse;
+    
+    if ( iExtension->iPasteText )
+        {
+        delete iExtension->iPasteText;
+        iExtension->iPasteText = NULL;
+        }   
+    TRAPD( err, DoCanPasteL() );    
+    return ( err == KErrNone );
+    }
+
+// --------------------------------------------------------------------------
+// CAknPhoneNumberEditor::DoCanPasteL
+// Check if there are data in clipboard and if the format of the data is 
+// accepted by phone number editor
+// --------------------------------------------------------------------------
+//  
+void CAknPhoneNumberEditor::DoCanPasteL() const
+    {    
+    CClipboard* cb = NULL;
+    cb = CClipboard::NewForReadingL( iCoeEnv->FsSession() );
+    CleanupStack::PushL( cb );
+    CStreamStore& store = cb->Store();
+    CStreamDictionary& dict = cb->StreamDictionary();
+    
+    // get plain text data from clipboard
+    CPlainText* text = CPlainText::NewL();
+    CleanupStack::PushL( text );
+    TInt dataLength = text->PasteFromStoreL( store, dict, KPlainTextPos);   
+    if ( dataLength == 0 )  
+        {
+        User::Leave( KErrNotFound );
+        }       
+    HBufC* hBuf = HBufC::NewL( dataLength );    
+    TPtr buf = hBuf->Des(); 
+    text->Extract( buf, KPlainTextPos, dataLength );
+    CleanupStack::PopAndDestroy( text );
+    CleanupStack::PushL( hBuf );
+    
+    // get the list of allowed characters in phone number editor
+    CAknEdwinState* fepState = ( CAknEdwinState* )iFepState;
+    HBufC* specTable = NULL;        
+    if ( fepState->NumericKeymap() == 
+         EAknEditorAlphanumericNumberModeKeymap )
+        {
+        TInt resId = fepState->SpecialCharacterTableResourceId();
+        if ( resId > 0 )
+            {
+            specTable = iEikonEnv->AllocReadResourceLC( resId );
+            }       
+        }       
+    HBufC* allowChars = iEikonEnv->AllocReadResourceLC( 
+        R_EIK_ALLOWED_STANDARDNUMBERMODEKEYMAP );   
+    
+    // check if the characters are allowed, if one character is not allowed, 
+    // it will not be pasted into phone number editor
+	if ( fepState->CurrentInputMode() != EAknEditorTextInputMode )
+		{
+		TInt pos = 0;
+		TInt index = 0;
+		while ( index < buf.Length() )
+			{
+            pos = allowChars->Locate( buf[index] );     
+			if ( pos == KErrNotFound && specTable && specTable->Length() > 0 )
+				{
+				pos = specTable->Locate( buf[index] );
+				}           
+			if ( pos == KErrNotFound )
+				{
+				buf.Delete( index, 1 );
+				}
+			else
+				{
+				index++;
+				}
+			}
+		if ( buf.Length() == 0 )
+			{
+			User::Leave( KErrNotFound );
+			}
+		}
+    iExtension->iPasteText = HBufC::NewL( buf.Length() );
+    TPtr pasteBuf = iExtension->iPasteText->Des();
+    pasteBuf.Copy( buf );
+    CleanupStack::PopAndDestroy( allowChars );
+    if ( specTable )
+        {
+        CleanupStack::PopAndDestroy( specTable );
+        }   
+    CleanupStack::PopAndDestroy( hBuf );
+    CleanupStack::PopAndDestroy( cb );    
+    }
+
+// --------------------------------------------------------------------------
+// CAknPhoneNumberEditor::CcpuPasteL
+// --------------------------------------------------------------------------
+//
+EXPORT_C void CAknPhoneNumberEditor::CcpuPasteL()
+    {
+    if ( iExtension->iPasteText )
+        {
+        iModel->Paste( iExtension->iPasteText->Des() );
+        DrawNow();
+        }
+    }
+
+// --------------------------------------------------------------------------
+// CAknPhoneNumberEditor::CcpuCanUndo
+// --------------------------------------------------------------------------
+//
+EXPORT_C TBool CAknPhoneNumberEditor::CcpuCanUndo() const
+    {
+    return EFalse;
+    }
+
+// --------------------------------------------------------------------------
+// CAknPhoneNumberEditor::CcpuUndoL
+// --------------------------------------------------------------------------
+//
+EXPORT_C void CAknPhoneNumberEditor::CcpuUndoL()
+    {
+    }
+
+// --------------------------------------------------------------------------
+// CAknPhoneNumberEditor::EnableCcpuSupportL
+// --------------------------------------------------------------------------
+//
+void CAknPhoneNumberEditor::EnableCcpuSupportL( TBool aSupport )
+    {
+    CAknCcpuSupport* ccpu = NULL;
+    CAknEdwinState* edwinState = ( CAknEdwinState* )iFepState;
+    
+    if ( aSupport )
+        {
+        ccpu = new( ELeave ) CAknCcpuSupport( this );
+        ccpu->SetMopParent( this );
+        CleanupStack::PushL( ccpu );
+        ccpu->ConstructL();
+        CleanupStack::Pop( ccpu );
+        if ( edwinState )
+            {
+            edwinState->SetCcpuState( this );                   
+            }
+        }
+    else
+        {       
+        if ( edwinState )
+            {
+            edwinState->SetCcpuState( NULL );                   
+            }
+        }        
+    delete iExtension->iCcpuSupport;
+    iExtension->iCcpuSupport = ccpu;
+    }
+
+// --------------------------------------------------------------------------
+// CAknPhoneNumberEditor::ClipboardL
+// implementate copy and cut
+// --------------------------------------------------------------------------
+//  
+void CAknPhoneNumberEditor::ClipboardL( TBool aIsCopy )
+    {
+    CancelFepTransaction();
+    TInt selectLength = SelectionLength();      
+    if ( selectLength == 0 )
+        {
+        iEikonEnv->InfoMsg( aIsCopy ? 
+            R_EIK_TBUF_NOTHING_TO_COPY : R_EIK_TBUF_NOTHING_TO_CUT );
+        }           
+    else
+        {
+        HBufC* buf = HBufC::NewLC( selectLength );
+        TPtr text = buf->Des();
+        if ( aIsCopy )
+            {
+            iModel->Copy( text );               
+            }
+        else
+            {
+            iModel->Cut( text );
+            DrawNow();
+            }
+        PlaceDataOnClipboardL( text );      
+        CleanupStack::PopAndDestroy( buf );             
+        iEikonEnv->InfoMsg( R_EIK_TBUF_COPIED );
+        if ( iExtension->iCcpuSupport )
+            {
+            iExtension->iCcpuSupport->HandleSelectionChangeL();
+            }           
+        CAknNoteDialog* dlg = new (ELeave) CAknNoteDialog();
+        dlg->SetTimeout( CAknNoteDialog::EShortTimeout );
+        dlg->SetTone( CAknNoteDialog::ENoTone );
+        dlg->ExecuteLD( R_AVKON_NOTE_CONF_COPIED );           
+        }        
+    }
+
+// --------------------------------------------------------------------------
+// CAknPhoneNumberEditor::PlaceDataOnClipboardL
+// --------------------------------------------------------------------------
+//  
+void CAknPhoneNumberEditor::PlaceDataOnClipboardL( const TDesC& aText )
+    {   
+    CClipboard* cb = CClipboard::NewForWritingLC( iCoeEnv->FsSession() );
+    
+    CStreamStore& store = cb->Store();
+    CStreamDictionary& dict = cb->StreamDictionary();
+    
+    CPlainText* text = CPlainText::NewL();
+    CleanupStack::PushL( text );
+    text->InsertL( KPlainTextPos, aText );
+    text->CopyToStoreL( store, dict, KPlainTextPos, aText.Length() );
+    CleanupStack::PopAndDestroy( text );
+    cb->CommitL();
+    
+    CleanupStack::PopAndDestroy( cb );
+    }
+    
+// --------------------------------------------------------------------------
+// CAknPhoneNumberEditor::OpenVKB
+// --------------------------------------------------------------------------
+// 
+EXPORT_C void CAknPhoneNumberEditor::OpenVKB( )
+    {
+    TUint cap = iExtension->iExtendedInputCapabilities->Capabilities();
+    cap &= ~CAknExtendedInputCapabilities::EInputEditorDisableVKB;
+    iExtension->iExtendedInputCapabilities->SetCapabilities( cap );
+    TRAP_IGNORE( ReportAknEdStateEventL( 
+    		     MAknEdStateObserver::EAknActivatePenInputRequest ) );
+    }
+
+// --------------------------------------------------------------------------
+// CAknPhoneNumberEditor::CloseVKB
+// --------------------------------------------------------------------------
+//
+void CAknPhoneNumberEditor::CloseVKB( )
+    {
+    TUint cap = iExtension->iExtendedInputCapabilities->Capabilities();
+    cap |= CAknExtendedInputCapabilities::EInputEditorDisableVKB;
+    iExtension->iExtendedInputCapabilities->SetCapabilities( cap );
+    ReportAknEdStateEventL( MAknEdStateObserver::EAknClosePenInputRequest );
+    }
+
+// --------------------------------------------------------------------------
+// CAknPhoneNumberEditor::ReportAknEdStateEventL
+// --------------------------------------------------------------------------
+//
+void CAknPhoneNumberEditor::ReportAknEdStateEventL( 
+         MAknEdStateObserver::EAknEdwinStateEvent aStateEvent )
+    {
+    CAknEdwinState* edwinState = STATIC_CAST( CAknEdwinState*,State(KNullUid) );
+    if ( edwinState )
+        {                   
+        TRAP_IGNORE( edwinState->ReportAknEdStateEventL( aStateEvent ) );
+        }
+    }
+// --------------------------------------------------------------------------
+// CAknPhoneNumberEditor::AknEditorFlags
+// --------------------------------------------------------------------------
+//
+EXPORT_C TInt CAknPhoneNumberEditor::AknEditorFlags() 
+	{
+	CAknEdwinState* edwinState = STATIC_CAST( CAknEdwinState*,State(KNullUid) ); 	  
+    if ( !edwinState )
+    	{
+    	return 0;
+    	}
+	return edwinState->Flags();	
+	}
+
+
+// End of file