javauis/lcdui_akn/lcdui/src/CMIDEdwin.cpp
branchRCL_3
changeset 26 2455ef1f5bbc
child 27 d5e927d5853b
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/javauis/lcdui_akn/lcdui/src/CMIDEdwin.cpp	Wed Sep 01 12:33:18 2010 +0100
@@ -0,0 +1,1488 @@
+/*
+* Copyright (c) 2003-2006 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:  Base class for TextField and TextBox
+*
+*/
+
+
+#include <eikenv.h>
+#include <eikappui.h>
+#include <coecntrl.h>
+// macros for resources
+#include <EIKCOCTL.rsg>
+
+#include <AknUtils.h>
+// usied for playing error sounds when text input
+#include <aknsoundsystem.h>
+#include <aknenv.h>
+// CAknSettingCache used for obtaining input language
+#include <AknSettingCache.h>
+#include <AknIndicatorContainer.h>
+#include <aknEditStateIndicator.h>
+
+#include <applayout.cdl.h>              // LAF
+#include <aknlayoutscalable_apps.cdl.h> // LAF
+#include <aknlayoutscalable_avkon.cdl.h> // LAF
+#include <AknLayoutFont.h>
+// CAknExtendedInputCapabilities for extended input capabilities
+#include <aknextendedinputcapabilities.h>
+
+#include <lcdui.rsg>
+// Avkon dialog for info notes
+#include <aknnotewrappers.h>
+
+// for fetching contacts from phonebook
+// CPbk2StoreConfiguration for contact manager
+#include <CPbk2StoreConfiguration.h>
+// used in CMIDAiwPbk2Client::VPbkSingleContactOperationComplete to retrieving single contact
+#include <MVPbkStoreContact.h>
+// MVPbkContactLinkArray* iFetchedLinks
+#include <CVPbkContactLinkArray.h>
+// used in CMIDAiwPbk2Client::VPbkSingleContactOperationComplete
+#include <MVPbkContactFieldTextData.h>
+// used for open all contact stores
+#include <MVPbkContactStoreList.h>
+// API for iContactManager
+#include <CVPbkContactManager.h>
+
+// aiw used to invoke phonebook
+#include <AiwContactSelectionDataTypes.h>
+
+// phone client API classes for starting phone call
+#include <AiwCommon.h>
+#include <aiwdialdata.h>
+// using AIWDialDataExt::KMaximumPhoneNumberLength
+#include <aiwdialdataext.h>
+
+// loading string from resource
+#include <StringLoader.h>
+
+// FEP CR
+// constants for FEP
+#include <AknFepInternalCRKeys.h>
+#include <centralrepository.h>
+
+#include <j2me/jdebug.h>
+
+#include "CMIDEdwin.h"
+#include "CMIDTextFieldItem.h"
+#include "CMIDComponentFactory.h"
+#include "CMIDUtils.h"
+#include "CMIDUIManager.h"
+
+#undef  TRAP_INSTRUMENTATION_LEAVE
+#define TRAP_INSTRUMENTATION_LEAVE(aResult) DEBUG_INT2("In CMIDEdwin.cpp, trapped method was called at line %D and got exception %D", __LINE__, aResult);
+
+// class CMIDEdwin
+
+void CMIDEdwin::ConstructL(const TDesC& aText,TInt aMaxSize)
+{
+
+    // Set decimal separator according to the current locale.
+    // Note: decimal separators other than ',' and '.' are currently not supported
+    TLocale loc;
+    iDecimalSeparator = loc.DecimalSeparator();
+    if (iDecimalSeparator != ',')
+    {
+        iDecimalSeparator = '.';
+    }
+
+    iEdwinUtils = CMIDEdwinUtils::NewL(this, iDecimalSeparator);
+
+    // if text is invalid according to constraints, throw IllegalArgumentException,
+    // except for a PHONENUMBER which only has the invalid characters removed
+    if ((iConstraints & MMIDTextField::EConstraintMask) != MMIDTextField::EPhoneNumber
+            && !iEdwinUtils->ConstraintsValidForText(aText,iConstraints,ETrue))
+    {
+        User::Leave(KErrArgument);
+    }
+
+    iMaxSize = aMaxSize;
+    if (iDisplayable)
+    {
+        iUIManager = iDisplayable->GetUIManager();
+        SetContainerWindowL(*iDisplayable);
+        SetAknEditorFlags(EAknEditorFlagEnableScrollBars | AknEdwinFlags());
+    }
+    else
+    {
+        iUIManager = iTextFieldItem->GetUIManager();
+        // TextField does not have any displayable yet available (before Form.Append())
+        // and EikEdwin needs to have a proper container window set, otherwise it may crash in singleLineEditor mode
+        CCoeControl::SetContainerWindowL(*(iUIManager->OpenMenuHandlerL()->GetDisplayable()));
+    }
+
+    TBool singleLineEditor = (iConstraints & MMIDTextField::EPassword);
+
+    AknEditUtils::ConstructEditingL(this,                           // aEdwin
+                                    aMaxSize,                      // aEditingSpace
+                                    (singleLineEditor ? 1 : 0),    // aEditingWindow
+                                    EAknEditorCharactersLowerCase, // aCharacterCase
+                                    EAknEditorAlignLeft,           // aJustification
+                                    ETrue,                         // aAllowedToMoveInsertionPoint
+                                    ETrue,                         // aCursorYesNo
+                                    EFalse);                       // aOverflowYesNo
+
+    if (iConstraints & MMIDTextField::EPassword)
+    {
+        iEdwinUserFlags |= CEikEdwin::EUserSuppliedText;
+        CreatePasswordTextL();
+    }
+
+    HBufC* buf = aText.AllocLC();
+    CMIDUtils::MapJavaToETextChars(buf);
+    if ((iConstraints & MMIDTextField::EConstraintMask) == MMIDTextField::EPhoneNumber)
+    {
+        iEdwinUtils->RemoveNonPhoneNumberChars(buf);
+    }
+    CEikEdwin::SetTextL(buf);
+    CreateTextViewL();
+    ProcessModifiers();
+    CleanupStack::PopAndDestroy(buf);
+    SetFEPModeAndCharFormat();
+    AddEdwinObserverL(this);    // see HandleEdwinEventL
+    CreateNonMidletCommandsL();
+
+
+    iUIManager->OpenNaviPaneControllerL()->AddTickerObserverL(this);
+
+    // set the cursor position
+    CEikEdwin::SetCursorPosL(TextLength(), EFalse);
+
+    // Publish MIDP constraints via input capabilities of the CEikEdwin
+    // The information is needed by chinese VKB/HWR system that adjusts its behavior
+    // based on MIDP constraints (most notably by checking if the field is a PASSWORD field).
+    TCoeInputCapabilities inputCapabilities = InputCapabilities();
+    if (inputCapabilities != TCoeInputCapabilities::ENone)
+    {
+        MObjectProvider* mop = inputCapabilities.ObjectProvider();
+        if (mop)
+        {
+            CAknExtendedInputCapabilities* extendedInputCapabilities = NULL;
+            extendedInputCapabilities = mop->MopGetObject(extendedInputCapabilities);
+            if (extendedInputCapabilities)
+            {
+                extendedInputCapabilities->SetMIDPConstraints(iConstraints);
+            }
+        }
+    }
+
+    iThisMultitapKey = 0;   // reset key counter
+    iLastMultitapKey = 0;
+}
+
+CMIDEdwin::CMIDEdwin(
+    TUint aConstraints, MMIDDisplayable* aDisplayable, CMIDTextFieldItem* aTextFieldItem)
+        : iDisplayable(static_cast<CMIDDisplayable*>(aDisplayable)),
+        iTextFieldItem(aTextFieldItem),
+        iConstraints(aConstraints),
+        iStateChanged(EFalse),
+        iKeyEventsPending(EFalse),
+        iInitialCurrentCase(0),
+        iInitialCurrentInputMode(0),
+        iInitialCurrentLanguage(ELangTest)
+{
+}
+
+CMIDEdwin::~CMIDEdwin()
+{
+    //phonebook fetch
+    delete iAiwPbkClient;
+    //edwin utils
+    delete iEdwinUtils;
+    if (iUIManager && iUIManager->GetNaviPaneController())
+    {
+        iUIManager->GetNaviPaneController()->RemoveTickerObserver(this);
+    }
+    RemoveNonMidletCommands();
+}
+
+void CMIDEdwin::DeleteTextL(TInt aOffset,TInt aLength)
+{
+    // get all initial values before deletion
+    TInt oldSize = Size();
+    HBufC* oldText = GetTextInHBufL();
+    CleanupStack::PushL(oldText);
+    // get cursor position before deletion
+    TInt cursorPos = CEikEdwin::CursorPos();
+
+    if (IsReadyToDraw())
+        ClearSelectionL();
+
+    TInt withoutFEPSize = Size();
+    // if size is different then FEP transaction was canceled and some letters
+    // are missing - must work with original text
+    if (withoutFEPSize != oldSize)
+    {
+        CEikEdwin::SetTextL(oldText);
+    }
+
+    //
+    // Do the deletion, then roll back if it leaves invalid text
+    //
+    iText->DeleteL(aOffset,aLength);
+    //
+    TBool valid = iEdwinUtils->ConstraintsValidForText(Read(), iConstraints, ETrue);
+    if (!valid)
+    {
+        CEikEdwin::SetTextL(oldText);
+    }
+    CleanupStack::PopAndDestroy(oldText);
+
+    HandleTextChangedL();
+    if (IsReadyToDraw())
+        SetSelectionL(aOffset,aOffset);
+
+    if (!valid)
+    {
+        User::Leave(KErrArgument);
+    }
+
+    // Handle cursor moving
+    // Cursor is in the middle of delete area
+    if ((cursorPos > aOffset) && (cursorPos < (aOffset + aLength)))
+    {
+        CEikEdwin::SetCursorPosL(aOffset, EFalse);
+    }
+    // cursor is on the right side of delete area
+    else if (cursorPos > (aOffset + aLength))
+    {
+        TInt newPosition = cursorPos - aLength;
+        if (newPosition < 0)
+        {
+            newPosition = 0;
+        }
+        CEikEdwin::SetCursorPosL(newPosition, EFalse);
+    }
+    // cursor is on the left side of delete area
+    else
+    {
+        CEikEdwin::SetCursorPosL(cursorPos, EFalse);
+    }
+}
+
+void CMIDEdwin::SetTextL(const TDesC& aText)
+{
+    // if text is invalid according to constraints, throw IllegalArgumentException,
+    //  except for a PHONENUMBER which only has the invalid characters removed
+    if ((iConstraints & MMIDTextField::EConstraintMask) == MMIDTextField::EPhoneNumber)
+    {
+    }
+    else if (!iEdwinUtils->ConstraintsValidForText(aText, iConstraints, ETrue))
+    {
+        User::Leave(KErrArgument);
+    }
+
+    HBufC* buf = iEdwinUtils->ConvertToLocalizedLC(aText, iConstraints);
+
+    if (IsNumberConversionNeeded())
+    {
+        TPtr ptr = buf->Des();
+        AknTextUtils::LanguageSpecificNumberConversion(ptr);
+    }
+
+    if ((iConstraints & MMIDTextField::EConstraintMask) == MMIDTextField::EPhoneNumber)
+    {
+        iEdwinUtils->RemoveNonPhoneNumberChars(buf);
+    }
+    CEikEdwin::SetTextL(buf);
+    HandleTextChangedL();
+    CleanupStack::PopAndDestroy(buf);
+
+    // move cursor to end of the new text
+    CEikEdwin::SetCursorPosL(TextLength(), EFalse);
+}
+
+/** The first part of this method validates existing text + new text.
+Then it carries on with text insertion. */
+void CMIDEdwin::InsertTextL(const TDesC& aText, TInt aPosition)
+{
+    //VALIDATE EXISTING TEXT
+    HBufC* temp = NULL;
+    if ((iConstraints & MMIDTextField::EConstraintMask) == MMIDTextField::EDecimal)
+    {
+        // Convert decimal content to unlocalized form before testing validity
+        // of insertion.
+        temp = GetTextInHBufL();
+        if (temp)
+        {
+            CleanupStack::PushL(temp);
+            iEdwinUtils->ConvertFromLocalizedDecimal(temp);
+        }
+    }
+
+    if (aPosition < 0)
+        aPosition = 0;
+
+    TInt size = TextLength();
+    if (aPosition > size)
+        aPosition = size;
+
+    // if text is invalid according to constraints, throw IllegalArgumentException,
+    //  except for a PHONENUMBER which only has the invalid characters removed
+    if ((iConstraints & MMIDTextField::EConstraintMask) == MMIDTextField::EPhoneNumber)
+    {
+    }
+    else if (!iEdwinUtils->ConstraintsValidForInsertedTextL((temp ? temp->Des() : Read()), aText, aPosition, iConstraints, ETrue))
+    {
+        User::Leave(KErrArgument);
+    }
+    if (temp)
+    {
+        CleanupStack::PopAndDestroy(temp);
+        temp = NULL;
+    }
+    //
+    //TEXT INSERTION STARTS HERE
+    if (IsReadyToDraw())
+    {
+        ClearSelectionL();
+    }
+
+    temp = iEdwinUtils->ConvertToLocalizedLC(aText, iConstraints);
+
+
+    if (IsNumberConversionNeeded())
+    {
+        TPtr ptr = temp->Des();
+        AknTextUtils::LanguageSpecificNumberConversion(ptr);
+    }
+
+    if ((iConstraints & MMIDTextField::EConstraintMask) == MMIDTextField::EPhoneNumber)
+    {
+        iEdwinUtils->RemoveNonPhoneNumberChars(temp);
+    }
+    iText->InsertL(aPosition, temp->Des());
+
+    HandleTextChangedL();
+
+    // Get the cursor position and move it forward along with inserter characters, if
+    // characters were inserted on the left side of the cursor.
+    TInt cursorPos = CEikEdwin::CursorPos();
+    TInt numberOfAddedCharacters = TextLength() - size;
+
+    if (cursorPos >= aPosition)
+    {
+        if ((cursorPos + numberOfAddedCharacters) < iMaxSize)
+        {
+            CEikEdwin::SetCursorPosL(cursorPos + numberOfAddedCharacters, EFalse);
+        }
+    }
+
+    UpdateTextCapacityIndicatorValueL();
+
+    CleanupStack::PopAndDestroy(temp);
+}
+
+/** Not used in current implementation; functionality
+    provided in CMIDEdwinControl and CMIDTextFieldItem
+   */
+void CMIDEdwin::SetConstraintsL(TUint /*aConstraints*/)
+{
+}
+
+void CMIDEdwin::SetTextWithNewConstraintsL(HBufC* aText)
+{
+    // If the current contents of the TextBox do not match the new constraints,the
+    // contents are set to empty, except for a PHONENUMBER which only has the
+    // invalid characters removed. Otherwise, set the text as given.
+    if ((iConstraints & MMIDTextField::EConstraintMask) == MMIDTextField::EPhoneNumber)
+    {
+        iEdwinUtils->RemoveNonPhoneNumberChars(aText);
+        CEikEdwin::SetTextL(aText);
+    }
+    else if (!iEdwinUtils->ConstraintsValidForText(aText->Des(), iConstraints & MMIDTextField::EConstraintMask, ETrue))
+    {
+        CEikEdwin::SetTextL(&KNullDesC);
+    }
+    else
+    {
+        CEikEdwin::SetTextL(aText);
+    }
+    HandleTextChangedL();
+}
+
+
+TInt CMIDEdwin::SetMaxSizeL(TInt aMaxSize)
+{
+    TInt size = TextLength();
+    if (aMaxSize < size)
+    {
+        DeleteTextL(aMaxSize,size-aMaxSize);
+    }
+    iMaxSize = aMaxSize;
+    SetTextLimit(iMaxSize);
+    return iMaxSize;
+}
+
+TInt CMIDEdwin::GetMaxSize()
+{
+    return iMaxSize;
+}
+
+
+TInt CMIDEdwin::Size()
+{
+    TRAP_IGNORE(ResetNumericContentL());
+    return TextLength();
+}
+
+TInt CMIDEdwin::GetCaretPosition()
+{
+    TRAP_IGNORE(ResetNumericContentL());
+    return CursorPos();
+}
+
+/** For a NUMERIC TextBox, clear the contents if the "displayed contents" are
+    in a state that is not valid "actual contents" for the current constraints.
+*/
+void CMIDEdwin::ResetNumericContentL()
+{
+    if ((iConstraints & MMIDTextField::EConstraintMask) == MMIDTextField::ENumeric)
+    {
+        HBufC* buf = GetTextInHBufL();
+        if (buf != NULL)
+        {
+            CleanupStack::PushL(buf);
+            if (!iEdwinUtils->ConstraintsValidForText(buf->Des(), iConstraints, ETrue))
+            {
+                (buf->Des()).SetLength(0);
+                CEikEdwin::SetTextL(buf);
+            }
+            CleanupStack::PopAndDestroy(buf);
+        }
+    }
+}
+
+HBufC* CMIDEdwin::GetTextL()
+{
+    HBufC* buf = GetTextInHBufL();
+    if (!buf)
+    {
+        buf = HBufC::NewL(0);
+    }
+    // convert decimal from localized to MIDlet-visible representation
+    if ((iConstraints & MMIDTextField::EConstraintMask) == MMIDTextField::EDecimal)
+    {
+        iEdwinUtils->ConvertFromLocalizedDecimal(buf);
+    }
+
+    if (IsNumberConversionNeeded())
+    {
+        TPtr ptr = buf->Des();
+        AknTextUtils::ConvertDigitsTo(ptr, EDigitTypeWestern);
+    }
+
+    if (!iEdwinUtils->ConstraintsValidForText(buf->Des(), iConstraints, ETrue))
+    {
+        // The "displayed contents" of the TextBox may be in a state that is
+        // not valid "actual contents" for the current constraints; in that
+        // case, return an empty string and clear the TextBox contents.
+        (buf->Des()).SetLength(0);
+        CEikEdwin::SetTextL(buf);
+    }
+    else
+    {
+        // Otherwise, return a copy of the contents where newlines etc. are
+        // mapped to their Java representations.
+        CMIDUtils::MapETextToJavaChars(buf);
+    }
+    return buf;
+}
+
+
+void CMIDEdwin::CreatePasswordTextL()
+{
+    CGlobalText* oldGText = STATIC_CAST(CGlobalText*,iText);
+    CPasswordBoxGlobalText* text=new(ELeave) CPasswordBoxGlobalText
+    (oldGText->GlobalParaFormatLayer(),oldGText->GlobalCharFormatLayer(),*this);
+    CleanupStack::PushL(text);
+    text->ConstructL();
+    CleanupStack::Pop(text);
+
+    delete iText;
+    iText = NULL;
+
+    SetDocumentContentL(*text,CEikEdwin::EUseText);
+}
+
+/**
+ * Need to recreate TextView here such that it uses the right window
+ */
+void CMIDEdwin::SetContainerWindowL(const CCoeControl& aContainer)
+{
+    SetObserver(this); //Prevent MCoeControlObserver::EEventStateChanged going to Form
+
+    CEikEdwin::SetContainerWindowL(aContainer);
+}
+
+TKeyResponse CMIDEdwin::OfferKeyEventL(const TKeyEvent& aKeyEvent,TEventCode aType)
+{
+    // store the key pressed last time, used for warning beeps while reaching size limit
+    if (aType == EEventKeyDown)
+    {
+        iLastMultitapKey = iThisMultitapKey;
+        iThisMultitapKey = aKeyEvent.iScanCode;
+    }
+
+    if (aType == EEventKeyDown)
+    {
+        iKeyEventsPending = ETrue;
+    }
+    else if (aType == EEventKeyUp)
+    {
+        iKeyEventsPending = EFalse;
+    }
+    //
+    // Post ItemStateChangedEvent before a command is delivered to the Form's CommandListener
+    //
+    TUint scanCode = aKeyEvent.iScanCode;
+    TBool losingFocus = EFalse;
+
+    CMIDMenuHandler* menuHandler = iUIManager->GetMenuHandler();
+    // Enter Key
+    //
+    //TextFieldItem
+    if (iTextFieldItem)
+    {
+        // QWERTY and VKB Enter Key
+        if (scanCode == EStdKeyEnter && aType == EEventKeyDown && !useEnterKey)
+        {
+            useEnterKey=true;
+        }
+        if ((scanCode ==    EStdKeyEnter && aType == EEventKeyUp && useEnterKey) ||
+                (aType == EEventKey && aKeyEvent.iCode == EKeyEnter))
+            //TextFieldItem with NUMERIC,DECIMAL and PHONENUMBER constraint
+            if (IsConstraintSet(MMIDTextField::ENumeric) ||
+                    IsConstraintSet(MMIDTextField::EDecimal) ||
+                    IsConstraintSet(MMIDTextField::ENumeric + MMIDTextField::EPassword))
+            {
+                useEnterKey=false;
+                //Activate default command
+                if (iTextFieldItem->DefaultCommand())
+                {
+                    menuHandler->ProcessCommandL(
+                        iTextFieldItem->CommandList()->CommandOffset() +
+                        iTextFieldItem->CommandList()->FindCommandIndex(iTextFieldItem->DefaultCommand()));
+                }
+                // Show ctx menu or activate command
+                else
+                {
+                    menuHandler->ShowMenuL(CMIDMenuHandler::EOkMenu);
+                    if (menuHandler->MenuItemsCount() <= 1)
+                        menuHandler->ProcessCommandL(iTextFieldItem->CommandList()->CommandOffset());
+                }
+
+                return EKeyWasConsumed;
+
+            }
+            else
+            {
+                //TextFieldItem with PHONENUMBER constraint
+                if (IsConstraintSet(MMIDTextField::EPhoneNumber) ||
+                        IsConstraintSet(MMIDTextField::EPhoneNumber + MMIDTextField::EPassword))
+                {
+                    useEnterKey = false;
+                    //Activate default command
+                    if (iTextFieldItem->DefaultCommand())
+                    {
+                        menuHandler->ProcessCommandL(
+                            iTextFieldItem->CommandList()->CommandOffset() +
+                            iTextFieldItem->CommandList()->FindCommandIndex(iTextFieldItem->DefaultCommand()));
+                    }
+                    // Show options menu or activate command
+                    else
+                    {
+                        menuHandler->ShowMenuL(CMIDMenuHandler::EOkMenu);
+                        if (menuHandler->MenuItemsCount() == 1)
+                        {
+                            menuHandler->ProcessCommandL(iTextFieldItem->CommandList()->CommandOffset());
+                        }
+                    }
+                    return EKeyWasConsumed;
+                }
+                else
+                {
+                    //TextFieldItem with ANY,PASSWORD  constraint
+                    if (iConstraints == MMIDTextField::EPassword)
+                    {
+                        useEnterKey=false;
+                        //Activate default command
+                        if (iTextFieldItem->DefaultCommand())
+                        {
+                            menuHandler->ProcessCommandL(
+                                iTextFieldItem->CommandList()->CommandOffset() +
+                                iTextFieldItem->CommandList()->FindCommandIndex(iTextFieldItem->DefaultCommand()));
+                        }
+                        // Show options menu or activate command
+                        else
+                        {
+                            menuHandler->ShowMenuL(CMIDMenuHandler::EOkMenu);
+                            if (menuHandler->MenuItemsCount() == 1)
+                            {
+                                menuHandler->ProcessCommandL(
+                                    iTextFieldItem->CommandList()->CommandOffset());
+                            }
+                        }
+                        return EKeyWasConsumed;
+
+                    }
+
+                }
+            }
+        if (aKeyEvent.iCode ==  EKeyEnter && aType == EEventKey)
+        {
+            //TextFieldItem with EMAILADDR constraint
+            if (IsConstraintSet(MMIDTextField::EMailAddr) ||
+                    IsConstraintSet(MMIDTextField::EUrl))
+            {
+                //Show menu or activate command
+                if (!iTextFieldItem->DefaultCommand())
+                {
+                    menuHandler->ShowMenuL(CMIDMenuHandler::EOkMenu);
+                    if (menuHandler->MenuItemsCount() <= 1)
+                    {
+                        menuHandler->ProcessCommandL(
+                            iTextFieldItem->CommandList()->CommandOffset());
+                    }
+                    return EKeyWasConsumed;
+                }
+
+            }
+        }
+    }
+    // End Enter Key
+    //
+
+    //
+    // keyboard menu
+    //
+    switch (scanCode)
+    {
+    case EStdKeyF1:
+    case EStdKeyMenu:
+        losingFocus=ETrue;
+    }
+    //
+    // Pause the ticker for five sec if # key received
+    if (aKeyEvent.iScanCode == EStdKeyHash && !IsReadOnly()) //0x7f
+    {
+        iUIManager->OpenNaviPaneControllerL()->PauseTickerL(TICKER_PAUSE_INTERVAL, this);
+    }
+    //
+    // Non keyboard zoom,menu,etc.
+    //
+    if (scanCode>=ESpecialKeyBase && scanCode<(ESpecialKeyBase+ESpecialKeyCount))
+        losingFocus=ETrue;
+    //
+    // CBA buttons:
+    //
+    if (scanCode>=EStdKeyDevice0 && scanCode<=EStdKeyDeviceF)
+        losingFocus=ETrue;
+    //
+    if (iTextFieldItem && losingFocus && iStateChanged)
+    {
+        iTextFieldItem->HandleControlEventL(this,MCoeControlObserver::EEventStateChanged);
+        iStateChanged=EFalse;
+    }
+
+    // ignore up and down arrows on PASSWORD TextField to avoid funny behaviour
+    // with line breaks
+    if (iDisplayable && (iConstraints & MMIDTextField::EPassword)
+            && (aKeyEvent.iCode == EKeyDownArrow || aKeyEvent.iCode == EKeyUpArrow))
+    {
+        return EKeyWasConsumed;
+    }
+
+    // when pressing the send key on a phonenumber-type box, call the number
+#ifdef RD_SCALABLE_UI_V2
+    if ((aType == EEventKey) && (scanCode == EStdKeyYes))
+#else
+    if ((aType == EEventKeyUp) && (scanCode == EStdKeyYes))
+#endif // RD_SCALABLE_UI_V2
+    {
+        if ((iConstraints & MMIDTextField::EConstraintMask) == MMIDTextField::EPhoneNumber)
+        {
+            CreatePhoneCallL();
+            return EKeyWasConsumed;
+        }
+    }
+
+#ifdef RD_SCALABLE_UI_V2
+    if ((aType == EEventKey) && (iConstraints & MMIDTextField::EPassword)
+#else
+    if ((aType == EEventKeyDown) && (iConstraints & MMIDTextField::EPassword)
+#endif // RD_SCALABLE_UI_V2
+            && iTextFieldItem) // type == TextField
+    {
+        static_cast<CPasswordBoxGlobalText*>(iText)->RejectNextKey(scanCode == EStdKeyEnter);
+    }
+
+#ifdef RD_SCALABLE_UI_V2
+    if (IsConstraintSet(MMIDTextField::ENumeric) && (aType == EEventKey || aType == EEventKeyUp) && !IsReadOnly() &&
+#else
+    if (IsConstraintSet(MMIDTextField::ENumeric) && (aType == EEventKeyUp) && !IsReadOnly() &&
+#endif // RD_SCALABLE_UI_V2
+            ((scanCode==EStdKeyNkpAsterisk) || (scanCode == EStdKeyMinus) || (scanCode==EStdKeyNkpMinus) || (scanCode == 0x2A) || (scanCode == 0x2D) ||
+             (TChar(aKeyEvent.iCode) == TChar('-') && scanCode != EStdKeyMinus)))
+    {
+        HandleMinusCharEventL(EEventTextUpdate);
+        CEikEdwin::ReportEdwinEventL(EEventTextUpdate);
+        UpdateTextCapacityIndicatorValueL();
+        return EKeyWasConsumed;
+    }
+
+    //handling of qwerty keypad "-" or "." pressing in Decimal mode
+#ifdef RD_SCALABLE_UI_V2
+    if (IsConstraintSet(MMIDTextField::EDecimal) && (aType == EEventKey) && !IsReadOnly() &&
+#else
+    if (IsConstraintSet(MMIDTextField::EDecimal) && (aType == EEventKeyUp) && !IsReadOnly() &&
+#endif // RD_SCALABLE_UI_V2
+            ((scanCode==EStdKeyMinus) || (scanCode==EStdKeyFullStop)))
+    {
+        CPlainText* res = CEikEdwin::Text();
+        TInt textLength = CEikEdwin::TextLength();
+        if (scanCode == EStdKeyMinus && textLength < iMaxSize)
+        {
+            res->InsertL(CEikEdwin::CursorPos(), KMinusChar);
+        }
+        else if (scanCode == EStdKeyFullStop && textLength < iMaxSize)
+        {
+            res->InsertL(CEikEdwin::CursorPos(), KFullStopChar);
+        }
+
+        HandleTextChangedL(); // notify editor about the text changes
+        CEikEdwin::ReportEdwinEventL(EEventTextUpdate);
+        TInt cursorPos = CEikEdwin::CursorPos();
+
+        if (CEikEdwin::TextLength() < iMaxSize)
+        {
+            CEikEdwin::SetCursorPosL(cursorPos + 1, EFalse);
+        }
+        else if (cursorPos == (iMaxSize - 1) && cursorPos == textLength &&
+                 (scanCode == EStdKeyFullStop || scanCode == EStdKeyMinus))
+        {
+            CEikEdwin::SetCursorPosL(iMaxSize, EFalse);
+        }
+    }
+    //Error tone playing case1:
+    //Play error tone if TextBox/TextField is read-only or maximum length has been reached.
+    //Here is handling of keys 0...9 for full keyboard and itu-t, but NOT virtual keyboard.
+    if (aType == EEventKeyDown
+            && ((scanCode >= KKeyQwerty0 && scanCode <= KKeyQwerty9)
+                || scanCode == EStdKeyHash
+                || scanCode == EStdKeyNkpAsterisk
+                || scanCode == KMidpKeyNkpAsteriskHW))
+    {
+        if ((scanCode == EStdKeyNkpAsterisk || scanCode == KMidpKeyNkpAsteriskHW)
+                && !IsReadOnly() && IsConstraintSet(MMIDTextField::ENumeric))
+        {
+            //Do nothing here in case of minus char toggle
+        }
+        else if (IsReadOnly())
+        {
+            iAvkonAppUi->KeySounds()->PlaySound(EAvkonSIDErrorTone);
+            UpdateTextCapacityIndicatorValueL();
+            return EKeyWasConsumed;
+        }
+
+        // All possible sources of warning beep are separated to be easy to read
+        else if (TextLength() >= iMaxSize)
+        {
+            TInt ret = KErrNone;
+            TInt inputModeValue = AknEditorCurrentInputMode();
+            if (inputModeValue != EAknEditorTextInputMode)
+            {
+                iAvkonAppUi->KeySounds()->PlaySound(EAvkonSIDErrorTone);
+                UpdateTextCapacityIndicatorValueL();
+                return EKeyWasConsumed;
+            }
+
+            TInt aknRepositoryValue = 0;
+            CRepository* aknFepRepository = NULL;
+            TRAP(ret, aknFepRepository = CRepository::NewL(KCRUidAknFep));
+            if ((ret != KErrNone) || (!aknFepRepository))
+            {
+                // if we cannot get the repository (something is wrong), play nothing
+                UpdateTextCapacityIndicatorValueL();
+                return EKeyWasConsumed;
+            }
+            aknFepRepository->Get(KAknFepPredTxtFlag, aknRepositoryValue);
+
+            delete aknFepRepository;
+            aknFepRepository = NULL;
+
+            if (aknRepositoryValue == 1)    // 1 means the predictive input is on
+            {
+                iAvkonAppUi->KeySounds()->PlaySound(EAvkonSIDErrorTone);
+                UpdateTextCapacityIndicatorValueL();
+                return EKeyWasConsumed;
+            }
+            // now only nonpredictive textinput is left
+            if (iThisMultitapKey != iLastMultitapKey) // different key tapped -> no multitap
+            {
+                iAvkonAppUi->KeySounds()->PlaySound(EAvkonSIDErrorTone);
+                UpdateTextCapacityIndicatorValueL();
+                iThisMultitapKey = 0;
+                iLastMultitapKey = 0;
+                return EKeyWasConsumed;
+            }
+        }
+    }
+
+    if (aType != EEventKey && aKeyEvent.iScanCode != EStdKeyApplication0)
+    {
+        UpdateTextCapacityIndicatorValueL();
+        return EKeyWasConsumed;
+    }
+
+
+    TKeyResponse response = EKeyWasNotConsumed;
+
+    // Error tone playing case2:
+    // Play error tone if TextBox/TextField is read-only or maximum length has been reached.
+    // Here is handling of full keyboard keys(NOT 0...9) and all virtual keyboard keys
+    // (camera and menu key not included).
+    // (Note: Virtual keyboard sends only EEventKey type events, not up or down events)
+    // (Note: Error tone is played when there is no text to be replaced i.e. no text has been painted)
+    if (!iEdwinUtils->IsNavigationKey(aKeyEvent) && !iEdwinUtils->IsHotKeyL(aKeyEvent, iCoeEnv) && aKeyEvent.iCode != EKeyYes &&
+            (!iKeyEventsPending || (scanCode < KKeyQwerty0  || scanCode > KKeyQwerty9)) &&
+            (aKeyEvent.iCode != EKeyApplication0 && scanCode != EStdKeyApplication0 &&
+             aKeyEvent.iCode != EKeyApplication19 && scanCode != EStdKeyApplication19))
+    {
+        if (IsReadOnly() || (TextLength() >= iMaxSize && aKeyEvent.iCode != EKeyBackspace))
+        {
+            //SelectionLength() > 0 if text has been selected/painted
+            if (SelectionLength() == 0)
+            {
+                iAvkonAppUi->KeySounds()->PlaySound(EAvkonSIDErrorTone);
+            }
+            response = CEikEdwin::OfferKeyEventL(aKeyEvent,aType);
+            UpdateTextCapacityIndicatorValueL();
+            return response;
+        }
+    }
+
+    TBool valid = EFalse;
+    //
+    if (iEdwinUtils->IsNavigationKey(aKeyEvent) || iEdwinUtils->IsHotKeyL(aKeyEvent, iCoeEnv))
+    {
+        HBufC* oldText = GetTextInHBufL();
+        CleanupStack::PushL(oldText);
+        TCursorSelection sel = Selection();
+        //
+        response = CEikEdwin::OfferKeyEventL(aKeyEvent,aType);
+        valid = iEdwinUtils->ConstraintsValidForText(iText?Read():TPtrC(),iConstraints,EFalse);
+        //
+        if (!valid)
+        {
+            CEikEdwin::SetTextL(oldText);
+            HandleTextChangedL();
+            SetSelectionL(sel.iCursorPos,sel.iAnchorPos);
+            response = EKeyWasConsumed;
+        }
+        //
+        CleanupStack::PopAndDestroy(oldText);
+        UpdateTextCapacityIndicatorValueL();
+        return response;
+    }
+    else
+    {
+        TBuf<1> key;
+        key.Append(TChar(aKeyEvent.iCode));
+        valid = iEdwinUtils->ConstraintsValidForInsertedTextL(iText?Read():TPtrC(), key, CursorPos(), iConstraints, EFalse);
+        if (valid)
+        {
+            if (iTextFieldItem && (aKeyEvent.iCode == EKeyEnter) &&
+                    (((iConstraints & MMIDTextField::EConstraintMask) !=  MMIDTextField::EAny) ||
+                     (iConstraints & MMIDTextField::EPassword)))
+            {//enter key for NON ANY or ANY | PASSWORD editors
+                return EKeyWasNotConsumed; //must do command triggering in this case
+            }
+
+            response = CEikEdwin::OfferKeyEventL(aKeyEvent,aType);
+            UpdateTextCapacityIndicatorValueL();
+        }
+        else
+        {
+            // If minus char was entered in full querty editor mode
+            if (IsConstraintSet(MMIDTextField::EDecimal) &&
+                    (aType == EEventKey) && !IsReadOnly() &&
+                    (TChar(aKeyEvent.iCode) == TChar('-') && scanCode != EStdKeyMinus))
+            {
+                CPlainText* res = CEikEdwin::Text();
+
+                if (res && TChar(aKeyEvent.iCode) == TChar('-') &&
+                        TextLength() < iMaxSize)
+                {
+                    TInt textLength = TextLength();
+                    res->InsertL(GetCaretPosition(), KMinusChar);
+                    HandleTextChangedL(); // notify editor about the text changes
+                    CEikEdwin::ReportEdwinEventL(EEventTextUpdate);
+                    TInt cursorPos = GetCaretPosition();
+
+                    if (TextLength() < iMaxSize)
+                    {
+                        CEikEdwin::SetCursorPosL(GetCaretPosition() + 1, EFalse);
+                    }
+                    else if (cursorPos == (iMaxSize - 1) && cursorPos == textLength)
+
+                    {
+                        CEikEdwin::SetCursorPosL(iMaxSize, EFalse);
+                    }
+                }
+            }
+
+        }
+        return response;
+    }
+}
+
+void CMIDEdwin::FocusChanged(TDrawNow aDrawNow)
+{
+    CEikEdwin::FocusChanged(aDrawNow);
+    TBool isFocused = IsFocused();
+    TInt  ret = KErrNone;
+
+    // in case of TextFieldItem iDisplayable is not valid do not use it.
+    if (!iDisplayable && iTextFieldItem->Form() == NULL)
+    {
+        return;
+    }
+
+    if (!IsReadOnly())
+    {
+        if (isFocused)
+        {
+            TRAP(
+                ret,
+                iUIManager->OpenNaviPaneControllerL()->PauseTickerL(TICKER_PAUSE_INTERVAL, this));
+        }
+        else
+        {
+            TRAP(
+                ret,
+                iUIManager->OpenNaviPaneControllerL()->PauseTickerL(0, this));
+        }
+    }
+    //
+    // Post ItemStateChangedEvent if focus moves away
+    //
+    if (iTextFieldItem && !isFocused && (iStateChanged))
+    {
+        TRAP(ret,iTextFieldItem->HandleControlEventL(this,MCoeControlObserver::EEventStateChanged));
+        iStateChanged=EFalse;
+    }
+
+    // Show text input indicator is the last thing we want to do
+    TRAP(ret,UpdateTextCapacityIndicatorValueL());
+}
+
+void CMIDEdwin::HandleControlEventL(CCoeControl* /*aControl*/,TCoeEvent aEventType)
+{
+    switch (aEventType)
+    {
+    case MCoeControlObserver::EEventStateChanged:
+        iStateChanged=ETrue;
+        break;
+    default:
+        break;
+    }
+}
+
+void CMIDEdwin::ProcessModifiers()
+{
+    // set general edwin attributes according to TextBox constraints
+    SetReadOnly(iConstraints & MMIDTextField::EUneditable);
+}
+
+void CMIDEdwin::HandleMinusCharEventL(TEdwinEvent aEventType)
+{
+
+    if ((aEventType == EEventTextUpdate) && ((iConstraints & MMIDTextField::EConstraintMask) == MMIDTextField::ENumeric))
+    {
+        ClearSelectionL();
+        CPlainText* res = CEikEdwin::Text();
+        TBuf<1> firstChar;
+        if (CEikEdwin::TextLength() != 0)
+        {
+            res->Extract(firstChar,  0, 1);
+        }
+        TInt cursorPos = CEikEdwin::CursorPos();
+        //toggle '-' char in the first position
+        TInt pos = firstChar.Locate(TChar('-'));
+        if (pos == KErrNotFound)
+        {
+            if (CEikEdwin::TextLength() < iMaxSize)
+            {
+                res->InsertL(0, KMinusChar);
+                cursorPos++;
+            }
+            else
+            {
+                //play error sound if text limit is to be exceeded
+                iAvkonAppUi->KeySounds()->PlaySound(EAvkonSIDErrorTone);
+            }
+        }
+        else
+        {
+            TBool deletion = res->DeleteL(0,1);
+            if (cursorPos >= 1)
+            {
+                cursorPos--;
+            }
+        }
+        HandleTextChangedL(); // notify editor about the text changes
+        CEikEdwin::SetCursorPosL(cursorPos, EFalse);
+    }
+}
+
+void CMIDEdwin::HandleEdwinEventL(CEikEdwin* aEdwin, TEdwinEvent aEventType)
+{
+    if (iTextFieldItem && aEventType == MEikEdwinObserver::EEventTextUpdate)
+    {
+        // notify Java that text has changed with itemStateChanged()
+        iTextFieldItem->HandleControlEventL(aEdwin, MCoeControlObserver::EEventStateChanged);
+    }
+
+    if (aEventType == MEikEdwinObserver::EEventTextUpdate)
+    {
+        // handles clearing multitap counter
+        if ((iLastMultitapKey != 0) && (iLastMultitapKey != iThisMultitapKey))
+        {
+            iLastMultitapKey = 0;
+        }
+        else
+        {
+            iThisMultitapKey = 0;
+            iLastMultitapKey = 0;
+        }
+
+        TBool textChanged = EFalse;
+
+        // in DECIMAL mode, don't allow changes that would result
+        // in an illegal string;
+        //  1) if there is a minus, it must be the first character
+        //  2) there can be at most one decimal separator
+        if ((iConstraints &
+                MMIDTextField::EConstraintMask) == MMIDTextField::EDecimal)
+        {
+            HBufC* res = NULL;
+            TRAPD(err, { res = GetTextInHBufL();});
+            if (err != KErrNone || !res)
+            {
+                return;
+            }
+            CleanupStack::PushL(res);
+
+            TInt illegalCharPos = -1;
+            TPtr16 ptr = res->Des();
+            TInt minusPos = ptr.LocateReverse(TChar('-'));
+            TInt endCursorPos = CEikEdwin::CursorPos();
+
+            // check if minus sign is inserted on incorrect place
+            // (not at the beginning)
+            if ((minusPos != KErrNotFound) && (minusPos != 0))
+            {
+                // check if minus sign isn't inserted twice
+                if (minusPos != ptr.Locate(TChar('-')))
+                {
+                    illegalCharPos = minusPos;
+                }
+                // insert minus char at the beginning of decimal field
+                else
+                {
+                    ptr.Delete(minusPos, 1);
+                    ptr.Insert(0, KMinusChar);
+                    minusPos = 0;
+                    CEikEdwin::SetTextL(res);
+                    textChanged = ETrue;
+                }
+            }
+
+            TInt pointPosL = ptr.Locate(iDecimalSeparator);
+            TInt pointPosR = ptr.LocateReverse(iDecimalSeparator);
+            TInt cursorPos = CEikEdwin::CursorPos();
+            if ((minusPos != KErrNotFound) && (pointPosL == 0))
+            {
+                illegalCharPos = pointPosL;
+            }
+            else if (pointPosL != pointPosR)
+            {
+                illegalCharPos = pointPosR;
+            }
+
+            // if minus or dot/comma char is displayed more than once
+            if (illegalCharPos >= 0)
+            {
+                // deleting second minus or dot/comma char
+                // and set cursor position on the right place
+                ptr.Delete(illegalCharPos, 1);
+                CEikEdwin::SetTextL(res);
+                textChanged = ETrue;
+                if (cursorPos >= 1)
+                {
+                    if (cursorPos == illegalCharPos)
+                    {
+                        cursorPos--;
+                    }
+                    endCursorPos = cursorPos;
+                }
+            }
+            CEikEdwin::SetCursorPosL(endCursorPos, EFalse);
+            CleanupStack::Pop(res);
+            delete res;
+        }
+        else if (((iConstraints &
+                   MMIDTextField::EConstraintMask) == MMIDTextField::EMailAddr)||
+                 ((iConstraints &
+                   MMIDTextField::EConstraintMask) == MMIDTextField::EUrl))
+        {
+            HBufC* res = NULL;
+            TRAPD(err, { res = GetTextL();});
+            if (err != KErrNone || !res)
+            {
+                return;
+            }
+            CleanupStack::PushL(res);
+
+            // In EMAIL and URL mode, don't allow changes that would result
+            // in an illegal string; if there is '/n' or '/f', and line breaks
+            // are not supported, chars need to be changed to space
+            // SetText function before actual text change checks if line
+            // breaks are not supported
+            TPtr16 text = res->Des();
+            TInt tmpPos;
+
+            if ((text.Locate(TChar('\n'))) >=0 ||
+                    (text.Locate(TChar('\f'))) >=0)
+            {
+                tmpPos = CEikEdwin::CursorPos();
+                SetTextL(*res);
+                CEikEdwin::SetCursorPosL(tmpPos, EFalse);
+            }
+
+            textChanged = ETrue;
+            CleanupStack::Pop(res);
+            delete res;
+        }
+
+        // if there were any modifications the text is updated
+        if (textChanged)
+        {
+            HandleTextChangedL();
+        }
+    }
+
+
+}
+
+void CMIDEdwin::SetInitialInputModeL(const TDesC& aCharacterSubset)
+{
+    iEdwinUtils->SetInitialInputModeL(aCharacterSubset,
+                                      iConstraints,
+                                      iInitialCurrentCase,
+                                      iInitialCurrentInputMode,
+                                      iInitialCurrentLanguage);
+
+    TUint constraint = iConstraints & MMIDTextField::EConstraintMask;
+
+    // Set permitted case modes for TextBox in lowercase or uppercase mode.
+    if (aCharacterSubset.Compare(KMidpUppercaseLatin) == 0 ||
+            aCharacterSubset.Compare(KMidpLowercaseLatin) == 0)
+    {
+        //Setting permited case mode for TextField in ANY do panic
+        //when TextField loses focus.
+        if (iTextFieldItem && iConstraints == MMIDTextField::EAny)
+        {
+            return;
+        }
+        // MIDP_UPPERCASE_LATIN or MIDP_LOWERCASE_LATIN are ignored if
+        // INITIAL_CAPS_SENTENCE or INITIAL_CAPS_WORD modifier in ANY.
+        if (!(iConstraints & MMIDTextField::EInitialCapsWordSentence ||
+                iConstraints & MMIDTextField::EInitialCapsWord) ||
+                constraint != MMIDTextField::EAny)
+        {
+            // If initial input mode is uppercase or lowercase then permit
+            // only explicit case mode changes, automatic changes are not
+            // allowed.
+            SetAknEditorPermittedCaseModes(EAknEditorUpperCase |
+                                           EAknEditorLowerCase);
+        }
+    }
+    else
+    {
+        SetAknEditorPermittedCaseModes(EAknEditorAllCaseModes);
+    }
+
+}
+
+
+TBool CMIDEdwin::IsNumberConversionNeeded()
+{
+    return iEdwinUtils->IsNumberConversionNeeded(GetConstraints());
+}
+
+void CMIDEdwin::SetFEPModeAndCharFormat()
+{
+    iEdwinUtils->SetFEPModeAndCharFormat(iConstraints, this);
+}
+
+/** Create non-midlet commands according to the constraints and add them
+to either the displayable or to the item. Commands will be processed in ProcessCommandL(). */
+void CMIDEdwin::CreateNonMidletCommandsL()
+{
+    if (((iConstraints & MMIDTextField::EConstraintMask) == MMIDTextField::EPhoneNumber) && !(iConstraints & MMIDTextField::EUneditable))
+    {
+        AddCommandToEdwinL(R_MIDP_PB_FETCH_NUMBER_SHORT_COMMAND_TEXT, R_MIDP_PB_FETCH_NUMBER_COMMAND_TEXT, CMIDEdwinUtils::EMenuCommandFetchPhoneNumber);
+        AddCommandToEdwinL(R_MIDP_CREATE_CALL_SHORT_COMMAND_TEXT, R_MIDP_CREATE_CALL_COMMAND_TEXT, CMIDEdwinUtils::EMenuCommandCreatePhoneCall);
+    }
+
+    if (((iConstraints & MMIDTextField::EConstraintMask) == MMIDTextField::EPhoneNumber) && (iConstraints & MMIDTextField::EUneditable))
+    {
+        AddCommandToEdwinL(R_MIDP_CREATE_CALL_SHORT_COMMAND_TEXT, R_MIDP_CREATE_CALL_COMMAND_TEXT, CMIDEdwinUtils::EMenuCommandCreatePhoneCall);
+    }
+
+    if (((iConstraints & MMIDTextField::EConstraintMask) == MMIDTextField::EMailAddr) && !(iConstraints & MMIDTextField::EUneditable))
+    {
+        AddCommandToEdwinL(R_MIDP_PB_FETCH_EMAIL_SHORT_COMMAND_TEXT, R_MIDP_PB_FETCH_EMAIL_COMMAND_TEXT, CMIDEdwinUtils::EMenuCommandFetchEmailAddress);
+    }
+}
+
+/**
+Creates and adds new command to edwin based on shot & long label resource ids
+and other parameters.
+*/
+void CMIDEdwin::AddCommandToEdwinL(TInt aCommandResIdShort,
+                                   TInt aCommandResIdLong,
+                                   TInt aCommandId)
+{
+    TBuf<64> shortLabel;
+    iEikonEnv->ReadResourceL(shortLabel, aCommandResIdShort);
+    TBuf<64> longLabel;
+    iEikonEnv->ReadResourceL(longLabel, aCommandResIdLong);
+
+
+    MMIDCommand* cmd = CMIDCommand::NewL(shortLabel, longLabel, MMIDCommand::EItem, 0, aCommandId);
+    CleanupStack::PushL(cmd);
+
+    STATIC_CAST(CMIDCommand*,cmd)->SetObserver(this);
+
+    AddCommandToEdwinL(*cmd);
+    CleanupStack::Pop(cmd);
+}
+
+/**
+Creates and adds new command to edwin, short label is the same as long label.
+*/
+void CMIDEdwin::AddCommandToEdwinL(TInt aCommandResId, TInt aCommandId)
+{
+    AddCommandToEdwinL(aCommandResId, aCommandResId, aCommandId);
+}
+
+/** This method is called from the destructor and removes
+    the commands added by CreateNonMidletCommandsL(). To do
+    this we examine cmds on the list (either of the displayable
+    or the item as applicable) and remove those whose observer is us.
+    */
+void CMIDEdwin::RemoveNonMidletCommands()
+{
+    CMIDCommandList* list = NULL;
+    if (iDisplayable)
+    {
+        list = STATIC_CAST(CMIDDisplayable*, iDisplayable)->MainCommandList();
+    }
+    else if (iTextFieldItem)
+    {
+        list = STATIC_CAST(CMIDTextFieldItem*, iTextFieldItem)->CommandList();
+    }
+
+    if (!list)
+    {
+        return;
+    }
+
+    for (TInt i = 0; i < list->Count(); i++)
+    {
+        CMIDCommand* cmd = list->At(i).iCommand;
+        if (cmd && (cmd->Observer() == this))
+        {
+            list->Remove(cmd);
+            cmd->Dispose();
+            i--;
+        }
+    }
+}
+
+/** Process non-midlet commands according to their unique negative id. See
+MMIDCommandObserver, FetchFromPhoneBoolL() and CreateNonMidletCommandsL(). */
+TBool CMIDEdwin::ProcessCommandL(CMIDCommand* aCommand)
+{
+    ASSERT(aCommand);
+    TBool ret = EFalse;
+
+    switch (aCommand->Id())
+    {
+    case CMIDEdwinUtils::EMenuCommandFetchPhoneNumber:
+        // for fetching data from phonebook
+        if (!iAiwPbkClient)
+        {
+            iAiwPbkClient = CMIDAiwPbk2Client::NewL(*this);
+        }
+        iAiwPbkClient->FetchFromPhoneBookL(EAiwPhoneNumberSelect);
+        ret = ETrue;
+        break;
+    case CMIDEdwinUtils::EMenuCommandFetchEmailAddress:
+        // for fetching data from phonebook
+        if (!iAiwPbkClient)
+        {
+            iAiwPbkClient = CMIDAiwPbk2Client::NewL(*this);
+        }
+        iAiwPbkClient->FetchFromPhoneBookL(EAiwEMailSelect);
+        ret = ETrue;
+        break;
+    case CMIDEdwinUtils::EMenuCommandCreatePhoneCall:
+        CreatePhoneCallL();
+        ret = ETrue;
+        break;
+    default:
+        break;
+    }
+
+    return ret;
+}
+
+void CMIDEdwin::CreatePhoneCallL()
+{
+    iEdwinUtils->CreatePhoneCallL(TextLength(), CCoeEnv::Static()->WsSession(), this);
+}
+
+/** From MTickerObserver: If the ticker is showing disable the displaying of
+edit indicators in the navi pane.  **/
+void CMIDEdwin::TickerShowing(TBool aShowing)
+{
+    TInt flags = aShowing ? EAknEditorFlagNoEditIndicators | AknEdwinFlags() :
+                 ~EAknEditorFlagNoEditIndicators & AknEdwinFlags();
+
+    SetAknEditorFlags(flags);
+}
+
+void CMIDEdwin::HandleCurrentL(TBool aActivate)
+{
+    // when becoming the current Displayable, set editor input mode
+    // to the one set by SetInitialInputModeL
+    if (aActivate &&
+            ((iConstraints & MMIDTextField::EConstraintMask) == MMIDTextField::EAny ||
+             (iConstraints & MMIDTextField::EConstraintMask) == MMIDTextField::EMailAddr ||
+             (iConstraints & MMIDTextField::EConstraintMask) == MMIDTextField::EUrl))
+    {
+        if (iInitialCurrentLanguage)
+        {
+            SetAknEditorLocalLanguage(iInitialCurrentLanguage);
+            if (iInitialCurrentInputMode == 0)
+            {
+                // clears any number mode used previously
+                SetAknEditorCurrentInputMode(EAknEditorNullInputMode);
+            }
+        }
+
+        if (iInitialCurrentInputMode)
+        {
+            SetAknEditorCurrentInputMode(iInitialCurrentInputMode);
+        }
+
+        if (iInitialCurrentCase)
+        {
+            TInt initialCurrentCase = iInitialCurrentCase;
+            if ((iConstraints & MMIDTextField::EPassword ||
+                    iConstraints & MMIDTextField::EMailAddr ||
+                    iConstraints & MMIDTextField::EUrl) &&
+                    iInitialCurrentCase == EAknEditorTextCase)
+            {
+                // Text case is not used in passwords, emailaddrs and urls
+                initialCurrentCase = EAknEditorLowerCase;
+            }
+            SetAknEditorCurrentCase(initialCurrentCase);
+            SetAknEditorCase(initialCurrentCase);
+        }
+    }
+    if (aActivate)
+    {
+        UpdateTextCapacityIndicatorValueL();
+    }
+}
+
+/** Update the text capacity indicator if we have focus and are not read only.*/
+void CMIDEdwin::UpdateTextCapacityIndicatorValueL()
+{
+    TBool isActive = iDisplayable ? iDisplayable->IsActive() :
+                     (iTextFieldItem->Form() ? iTextFieldItem->Form()->CurrentDisplayable().IsActive() : EFalse);
+
+    if (IsFocused() && isActive && !(iConstraints & MMIDTextField::EUneditable))
+    {
+        // Navi pane controller is opened on constructor phase so it should exists
+        iUIManager->OpenNaviPaneControllerL()->UpdateTextInputIndicatorL(
+            iMaxSize - TextLength());
+        iDisplayingCapacityIndic = ETrue;
+    }
+    else if (iDisplayingCapacityIndic)
+    {
+        // Navi pane controller is opened on constructor phase so it should exists
+        iUIManager->OpenNaviPaneControllerL()->UpdateTextInputIndicatorL(-1);
+        iDisplayingCapacityIndic = EFalse;
+    }
+}
+
+/** Updates capacity indicator when text is pasted. */
+void CMIDEdwin::HandleTextPastedL(TInt aStartPos,TInt& aLength)
+{
+    // When TextBox field is NUMERIC, PHONENUMBER or DECIMAL new line
+    // characters if exists in copied text must be filtered out before pasting
+
+    if ((IsConstraintSet(MMIDTextField::ENumeric) ||
+            IsConstraintSet(MMIDTextField::EPhoneNumber) ||
+            IsConstraintSet(MMIDTextField::EDecimal)) != EFalse)
+    {
+        HBufC* hbuf = GetTextInHBufL();
+        TPtr strPtr = hbuf->Des();
+        TInt firstPos = strPtr.Find(KLineSeparator);
+
+        if (firstPos != KErrNotFound)
+        {
+            CleanupStack::PushL(hbuf);
+            while (firstPos != KErrNotFound)
+            {
+                strPtr.Delete(firstPos, KLineSeparator().Length());
+                firstPos = strPtr.Find(KLineSeparator);
+            }
+            CEikEdwin::SetTextL(hbuf);
+            CleanupStack::Pop(hbuf);
+        }
+        delete hbuf;
+    }
+    UpdateTextCapacityIndicatorValueL();
+    CEikEdwin::HandleTextPastedL(aStartPos, aLength);
+}
+
+TPtrC CMIDEdwin::Read() const
+{
+    if (iConstraints & MMIDTextField::EPassword)
+    {
+        return static_cast<CPasswordBoxGlobalText*>(iText)->ClearText();
+    }
+    else
+    {
+        return iText->Read(0,TextLength());
+    }
+}