javauis/lcdui_akn/lcdui/src/CMIDTextEditorEdwin.cpp
branchRCL_3
changeset 19 04becd199f91
child 23 98ccebc37403
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/javauis/lcdui_akn/lcdui/src/CMIDTextEditorEdwin.cpp	Tue Apr 27 16:30:29 2010 +0300
@@ -0,0 +1,1526 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Defines a custom editor window for Text editor component.
+*
+*/
+
+
+// INTERNAL INCLUDES
+#include "CMIDTextEditorEdwin.h"
+#include "CMIDEdwinUtils.h"
+#include "CMIDTextEditorEdwinCustomDraw.h"
+#include "CMIDEditingStateIndicator.h"
+
+// EXTERNAL INCLUDES
+#include <MMIDTextEditor.h> // MMIDTextEditorObserver
+#include <aknextendedinputcapabilities.h>
+#include <AknSettingCache.h>
+#include <eikedwob.h>
+#include <j2me/jdebug.h>
+
+const TInt KColorOpaque = 255;
+const TInt KCharMinus   = 0x2d;
+
+// ---------------------------------------------------------------------------
+// CMIDTextEditorEdwin::CMIDTextEditorEdwin
+// ---------------------------------------------------------------------------
+//
+CMIDTextEditorEdwin::CMIDTextEditorEdwin(CMIDEdwinUtils& aEdwinUtils)
+        : CEikEdwin(),
+        iMultiline(EFalse),
+        iCursorPosForAction(KErrNotFound),
+        iEdwinUtils(aEdwinUtils)
+{
+    DEBUG("CMIDTextEditorEdwin::CMIDTextEditorEdwin +");
+
+    // Set margins to zero
+    TMargins8 margins;
+    margins.SetAllValuesTo(0);
+    SetBorderViewMargins(margins);
+    // Set layout
+    CAknEnv::Static()->GetCurrentLayoutId(iDirection);
+    // Set visible content height
+    iVisibleContentHeight = 0;
+    // Set border to zero
+    SetBorder(TGulBorder::ENone);
+    SetFocusing(ETrue);
+    DEBUG("CMIDTextEditorEdwin::CMIDTextEditorEdwin -");
+}
+
+// ---------------------------------------------------------------------------
+// CMIDTextEditorEdwin::~CMIDTextEditorEdwin
+// ---------------------------------------------------------------------------
+//
+CMIDTextEditorEdwin::~CMIDTextEditorEdwin()
+{
+    DEBUG("CMIDTextEditorEdwin::~CMIDTextEditorEdwin");
+}
+
+// ---------------------------------------------------------------------------
+// CMIDTextEditorEdwin::ConstructL
+// (other items were commented in the header file)
+// ---------------------------------------------------------------------------
+//
+void CMIDTextEditorEdwin::ConstructL(
+    TInt aEdwinFlags,
+    TInt aWidthInChars,
+    TInt aTextLimit,
+    TInt aNumberOfLines)
+{
+    DEBUG("CMIDTextEditorEdwin::ConstructL +");
+
+    CEikEdwin::ConstructL(
+        aEdwinFlags, aWidthInChars, aTextLimit, aNumberOfLines);
+
+    // Supress all background drawing of CEikEdwin so that this editor
+    // can draw the correct custom color to the background.
+    SetSuppressBackgroundDrawing(ETrue);
+
+    // No background control context. This way it is possible to change the
+    // background color of the text editor. By default, it is white.
+    SetSkinBackgroundControlContextL(NULL);
+
+    // Observer events in the editor. Note that this must be done in order
+    // to avoid resulting incorrect content in numeric and decimal editors
+    SetEdwinObserver(this);
+
+    // To have the line where cursor is properly displayed.
+    if (iLayout)
+    {
+        iLayout->RestrictScrollToTopsOfLines(EFalse);
+    }
+
+    DEBUG("CMIDTextEditorEdwin::ConstructL -");
+}
+
+// ---------------------------------------------------------------------------
+// CMIDTextEditorEdwin::OfferKeyEventL
+// (other items were commented in the header file)
+// ---------------------------------------------------------------------------
+//
+TKeyResponse CMIDTextEditorEdwin::OfferKeyEventL(
+    const TKeyEvent& aKeyEvent,
+    TEventCode aType)
+{
+    DEBUG_INT("CMIDTextEditorEdwin::OfferKeyEventL +, aType=%d", aType);
+
+    TKeyResponse response = EKeyWasNotConsumed;
+
+    if ((aType == EEventKey) &&
+            (aKeyEvent.iCode == EKeyEnter) &&
+            (!iMultiline ||
+             iConstraints & MMIDTextField::EPassword ||
+             !IsConstraintSet(MMIDTextField::EAny)))
+    {
+        // Enter key for single-line editor, password and other than any
+        // editors is simply passed on.
+        DEBUG("CMIDTextEditorEdwin::OfferKeyEventL -, ignoring enter");
+
+        return response;
+    }
+
+    // Offer key event to editor window if it is set focused and visible.
+    // If the editor is set hidden, OfferKeyEventL will update the content
+    // in the editor and draw it. So the editor content CANNOT be modified
+    // if it is not visible and focused.
+    if (IsFocused() && IsVisible())
+    {
+        DEBUG("CMIDTextEditorEdwin::OfferKeyEventL, focused=true");
+
+        // Edwin does not report cursor movements with text updates
+        // Store the current position here for future use.
+        iCursorPosForAction = CursorPos();
+
+        // Try handling special characters.
+        response = HandleSpecialKeyEventsL(aKeyEvent, aType);
+
+        // Not handled, try with CEikEdwin
+        if (response == EKeyWasNotConsumed)
+        {
+            // Old text is needed if the new content is not valid for the
+            // given set of constraints. This validation is made because
+            // CEikEdwin and FEP seem to input text that is not always
+            // valid for the given Java-specific constraints. No very
+            // optimized solution to allocate heap here but at least this
+            // solution is bulletproof and prevents illegal contents.
+            // This also prevents that the implementation does not ignore
+            // special characters such as navigation and hotkeys.
+            HBufC* oldContent = GetTextInHBufL();
+
+            CleanupStack::PushL(oldContent);
+
+            response = CEikEdwin::OfferKeyEventL(aKeyEvent, aType);
+
+            // Validate new content and undo if not valid.
+            if (!iEdwinUtils.ConstraintsValidForText(
+                        Read(), iConstraints, EFalse))
+            {
+                CEikEdwin::SetTextL(oldContent);
+                // Notify about text change.
+                HandleTextChangedL();
+                // Restore cursor's original position.
+                SetCursorPosL(iCursorPosForAction, EFalse);
+            }
+
+            CleanupStack::PopAndDestroy(oldContent);
+        }
+
+        // Update current selection.
+        iSelection = Selection();
+
+        // Draw now so that background gets updated. Otherwise the
+        // content may not be updated (e.g. cursor may be visible
+        // if a line is deleted from the editor.
+        // Transparency needs whole redraw of the editor's content.
+        if (IsTransparent())
+        {
+            iParent->DrawNow(Rect());
+        }
+        else
+        {
+            DrawDeferred();
+        }
+    }
+
+    DEBUG("CMIDTextEditorEdwin::OfferKeyEventL -");
+
+    return response;
+}
+
+// ---------------------------------------------------------------------------
+// CMIDTextEditorEdwin::Traverse
+// (other items were commented in the header file)
+// ---------------------------------------------------------------------------
+//
+TBool CMIDTextEditorEdwin::Traverse(const TKeyEvent& aEvent)
+{
+    TInt cursorPos = CursorPos();
+    TBool traverse = EFalse;
+
+    if ((aEvent.iCode == EKeyDownArrow) ||
+            (aEvent.iScanCode == EStdKeyDownArrow))
+    {
+        if (TextLength() == cursorPos)
+        {
+            traverse = ETrue;
+        }
+
+    }
+    else if ((aEvent.iCode == EKeyUpArrow) ||
+             (aEvent.iScanCode == EStdKeyUpArrow))
+    {
+        if (cursorPos == 0)
+        {
+            traverse = ETrue;
+        }
+
+    }
+
+    return traverse;
+}
+// ---------------------------------------------------------------------------
+// CMIDTextEditorEdwin::Draw
+// (other items were commented in the header file)
+// ---------------------------------------------------------------------------
+//
+void CMIDTextEditorEdwin::Draw(const TRect& aRect) const
+{
+    DEBUG("CMIDTextEditorEdwin::Draw +");
+
+    // Part of transparency workaround. Set drawing active.
+    iDrawInvoked = ETrue;
+
+    // Background color is drawn before other content.
+    // Note that in order this to work, the background drawing of CEikEdwin
+    // needs to be suppressed. Custom drawer cannot be used due to flickering
+    // problems. Currently it just handles the selection color.
+    CWindowGc& gc = SystemGc();
+
+    // Draw background with alpha.
+    gc.SetBrushColor(iBackgroundColor);
+    gc.Clear(aRect);
+
+    // Now draw the content of the editor.
+    CEikEdwin::Draw(aRect);
+
+    // Part of transparency workaround. Set drawing not active.
+    iDrawInvoked = EFalse;
+
+    if (iObserver)
+    {
+        iObserver->NotifyInputAction(
+            MMIDTextEditorObserver::EActionPaintRequest);
+    }
+    DEBUG("CMIDTextEditorEdwin::Draw -");
+}
+
+// ---------------------------------------------------------------------------
+// CMIDTextEditorEdwin::DrawOngoing
+// Part of transparency workaround. Returns the current draw status
+// of this editor window.
+// ---------------------------------------------------------------------------
+//
+TBool CMIDTextEditorEdwin::DrawOngoing() const
+{
+    return iDrawInvoked;
+}
+
+// ---------------------------------------------------------------------------
+// CMIDTextEditorEdwin::Redraw
+// Part of transparency workaround. Returns the current draw status
+// of this editor window.
+// ---------------------------------------------------------------------------
+//
+void CMIDTextEditorEdwin::Redraw() const
+{
+    // Do not redraw if draw is already ongoing.
+    if (iDrawInvoked || !iParent)
+    {
+        return;
+    }
+
+    // If the editor has a transaprent background, the parent
+    // needs to be redrawn in that case. Note that DrawNow
+    // is not applicable here because this is used from the
+    // custom draw which may invoke this method during CTextView
+    // redraw causing a panic to occur.
+    if (IsTransparent())
+    {
+        iParent->DrawDeferred();
+    }
+    else
+    {
+        // No transparency. Draw this control only.
+        DrawDeferred();
+    }
+}
+
+// ---------------------------------------------------------------------------
+// CMIDTextEditorEdwin::IsTransparent
+// (other items were commented in the header file)
+// ---------------------------------------------------------------------------
+//
+TBool CMIDTextEditorEdwin::IsTransparent() const
+{
+    return (iBackgroundColor.Alpha() < KColorOpaque);
+}
+
+// ---------------------------------------------------------------------------
+// CMIDTextEditorEdwin::FocusChanged
+// (other items were commented in the header file)
+// ---------------------------------------------------------------------------
+//
+void CMIDTextEditorEdwin::FocusChanged(TDrawNow aDrawNow)
+{
+    DEBUG("CMIDTextEditorEdwin::FocusChanged +");
+
+    CEikEdwin::FocusChanged(aDrawNow);
+
+    // Apply initial input mode change when the editor has been focused.
+    // Note that initial input mode change must be applied only when
+    // an editing session starts (according to MIDP specification).
+    // See CMIDEdwin::HandleCurrentL()
+
+    if (IsFocused() &&
+            (IsConstraintSet(MMIDTextField::EAny) ||
+             IsConstraintSet(MMIDTextField::EMailAddr) ||
+             IsConstraintSet(MMIDTextField::EUrl)))
+    {
+        // Set current language.
+        if (iInitialCurrentLanguage)
+        {
+            DEBUG("CMIDTextEditorEdwin::FocusChanged, \
+applying current language");
+
+            SetAknEditorLocalLanguage(iInitialCurrentLanguage);
+
+            if (iInitialCurrentInputMode == 0)
+            {
+                DEBUG("CMIDTextEditorEdwin::FocusChanged, null input mode");
+
+                // Clears any number mode used previously
+                SetAknEditorCurrentInputMode(EAknEditorNullInputMode);
+            }
+        }
+
+        // Set current input mode.
+        if (iInitialCurrentInputMode)
+        {
+            DEBUG("CMIDTextEditorEdwin::FocusChanged, \
+applying current input mode");
+
+            SetAknEditorCurrentInputMode(iInitialCurrentInputMode);
+        }
+
+        // Set current case.
+        if (iInitialCurrentCase)
+        {
+            DEBUG("CMIDTextEditorEdwin::FocusChanged, \
+applying current case");
+
+            TInt initialCurrentCase = iInitialCurrentCase;
+
+            if ((iConstraints & MMIDTextField::EPassword ||
+                    IsConstraintSet(MMIDTextField::EMailAddr) ||
+                    IsConstraintSet(MMIDTextField::EUrl)) &&
+                    iInitialCurrentCase == EAknEditorTextCase)
+            {
+                // Text case is not used in passwords, emailaddrs and urls
+                initialCurrentCase = EAknEditorLowerCase;
+            }
+
+            SetAknEditorCurrentCase(initialCurrentCase);
+            SetAknEditorCase(initialCurrentCase);
+        }
+    }
+
+    DEBUG("CMIDTextEditorEdwin::FocusChanged -");
+}
+
+// ---------------------------------------------------------------------------
+// CMIDTextEditorEdwin::PositionChanged
+// (other items were commented in the header file)
+// ---------------------------------------------------------------------------
+//
+void CMIDTextEditorEdwin::PositionChanged()
+{
+    DEBUG("CMIDTextEditorEdwin::PositionChanged +");
+
+    CCoeControl::PositionChanged();
+
+    // Text view may have not been created yet.
+    if (iTextView)
+    {
+        // Adjust the view rect to the text view
+        iTextView->SetViewRect(Rect());
+    }
+
+    DEBUG("CMIDTextEditorEdwin::PositionChanged -");
+}
+
+// ---------------------------------------------------------------------------
+// CMIDTextEditorEdwin::PositionChanged
+// (other items were commented in the header file)
+// ---------------------------------------------------------------------------
+//
+void CMIDTextEditorEdwin::OverrideColorL(TInt aLogicalColor, TRgb aColor)
+{
+    CCoeControl::OverrideColorL(aLogicalColor, aColor);
+
+    if (aLogicalColor == EColorControlBackground)
+    {
+        iBackgroundColor = aColor;
+    }
+
+    // Suppress background drawing if the editor is transparent.
+    SetSuppressBackgroundDrawing(IsTransparent());
+}
+
+// ---------------------------------------------------------------------------
+// CMIDTextEditorEdwin::CreateCustomDrawL
+// (other items were commented in the header file)
+// ---------------------------------------------------------------------------
+//
+CLafEdwinCustomDrawBase* CMIDTextEditorEdwin::CreateCustomDrawL()
+{
+    DEBUG("CMIDTextEditorEdwin::CreateCustomDrawL +");
+
+    // First create the parent custom draw that handles the drawing of
+    // text and other related components.
+    const MFormCustomDraw* customDraw = CEikEdwin::CreateCustomDrawL();
+
+    // Create text editor specific custom draw that handles the
+    // setting of selection color.
+    CLafEdwinCustomDrawBase* ret = new(ELeave)CMIDTextEditorEdwinCustomDraw(
+        iEikonEnv->LafEnv(), *customDraw, *this);
+
+    DEBUG("CMIDTextEditorEdwin::CreateCustomDrawL -");
+
+    return ret;
+}
+
+// ---------------------------------------------------------------------------
+// CMIDTextEditorEdwin::HandleTextPastedL
+// (other items were commented in the header file)
+// ---------------------------------------------------------------------------
+//
+void CMIDTextEditorEdwin::HandleTextPastedL(TInt aStartPos, TInt& aLength)
+{
+    DEBUG_INT2(
+        "CMIDTextEditorEdwin::HandleTextPastedL +, aStartPos=%d, aLength=%d",
+        aStartPos, aLength);
+
+    HBufC* content = GetTextInHBufL(); // May return NULL
+    if (!content)
+    {
+        // For guaranteeing that this method does not crash in any case.
+        return;
+    }
+
+    CleanupStack::PushL(content);
+
+    // Check that the pasted text is valid for the given set of constraints.
+    if (!iEdwinUtils.ConstraintsValidForText(
+                content->Des(), iConstraints, ETrue))
+    {
+        DEBUG("CMIDTextEditorEdwin::HandleTextPastedL, \
+constraints not valid");
+
+        // Remove pasted content from the text and set it back.
+        iText->DeleteL(aStartPos, aLength);
+        // Notify about the change.
+        HandleTextChangedL();
+    }
+    // Convert breaks if needed if constraints that do not allow line breaks.
+    // Note that numeric, decimal and phonenumber do not allow line breaks
+    // and are checked before this so no need to check here again.
+    else if (!IsWrapEnabled() ||
+             iConstraints & MMIDTextField::EPassword  ||
+             IsConstraintSet(MMIDTextField::EUrl) ||
+             IsConstraintSet(MMIDTextField::EMailAddr))
+    {
+        DEBUG("CMIDTextEditorEdwin::HandleTextPastedL, \
+cropping to single line");
+
+        TPtr ptr = content->Des();
+        iEdwinUtils.CropToSingleLine(ptr);
+        CEikEdwin::SetTextL(content);
+        // Notify about content change.
+        HandleTextChangedL();
+    }
+
+    CleanupStack::PopAndDestroy(content);
+
+    DEBUG("CMIDTextEditorEdwin::HandleTextPastedL -");
+}
+
+// ---------------------------------------------------------------------------
+// CMIDTextEditorEdwin::HandleTextChangedL
+// (other items were commented in the header file)
+// ---------------------------------------------------------------------------
+//
+void CMIDTextEditorEdwin::HandleTextChangedL()
+{
+    DEBUG("CMIDTextEditorEdwin::HandleTextChangedL +");
+
+    // Call edwin's method to format the text and redraw.
+    CEikEdwin::HandleTextChangedL();
+
+    // Report edwin event.
+    ReportEdwinEventL(MEikEdwinObserver::EEventTextUpdate);
+
+    DEBUG("CMIDTextEditorEdwin::HandleTextChangedL -");
+}
+
+// ---------------------------------------------------------------------------
+// CMIDTextEditorEdwin::HandleResourceChangeL
+// (other items were commented in the header file)
+// ---------------------------------------------------------------------------
+//
+void CMIDTextEditorEdwin::HandleResourceChange(TInt aType)
+{
+    // Notification about language change
+    if (aType == KEikInputLanguageChange)
+    {
+        if (iObserver)
+        {
+            TInt event = MMIDTextEditorObserver::EActionLanguageChange;
+            TAknLayoutId currentLayoutId;
+            CAknEnv::Static()->GetCurrentLayoutId(currentLayoutId);
+            if (iDirection != currentLayoutId)
+            {
+                iDirection = currentLayoutId;
+                event |= MMIDTextEditorObserver::EActionDirectionChange;
+            }
+            iObserver->NotifyInputAction(event);
+        }
+    }
+}
+
+// ---------------------------------------------------------------------------
+// CMIDTextEditorEdwin::HandleEdwinEventL
+// (other items were commented in the header file)
+// ---------------------------------------------------------------------------
+//
+void CMIDTextEditorEdwin::HandleEdwinEventL(
+    CEikEdwin* /*aEdwin*/,
+    TEdwinEvent aEventType)
+{
+    DEBUG_INT("CMIDTextEditorEdwin::HandleEdwinEventL +, aEventType=%d",
+              aEventType);
+
+    if (aEventType == EEventTextUpdate && (
+                IsConstraintSet(MMIDTextField::EDecimal) ||
+                IsConstraintSet(MMIDTextField::ENumeric)))
+    {
+        // Do not report events if the content was invalid.
+        if (RemoveInvalidNumericContentL())
+        {
+            return;
+        }
+    }
+
+    // Notify observer if set.
+    if (iObserver)
+    {
+        switch (aEventType)
+        {
+        case EEventNavigation:
+        {
+            TInt event = MMIDTextEditorObserver::EActionCaretMove;
+            TInt newVisiblecontentHeight = VisibleContentPosition();
+
+            // Check if cursor has moved. This must be done because
+            // currently edwin does not report cursor position movement
+            // when text is changed due to user input.
+            if ((iVisibleContentHeight != newVisiblecontentHeight) &&
+                    (iCursorPosForAction != CursorPos()))
+            {
+                event |= MMIDTextEditorObserver::EActionScrollbarChange;
+                // Reported, reset here to avoid multiple notifications.
+                iVisibleContentHeight = newVisiblecontentHeight;
+            }
+
+            iObserver->NotifyInputAction(event);
+            break;
+        }
+        case EEventFormatChanged: // Fallthrough
+        case EEventTextUpdate:
+        {
+            TInt event = MMIDTextEditorObserver::EActionContentChange;
+
+            // Check if cursor has moved. This must be done because
+            // currently edwin does not report cursor position movement
+            // when text is changed due to user input.
+            if (iCursorPosForAction != KErrNotFound &&
+                    iCursorPosForAction != CursorPos())
+            {
+                event |= MMIDTextEditorObserver::EActionCaretMove;
+                // Reported, reset here to avoid multiple notifications.
+                iCursorPosForAction = KErrNotFound;
+            }
+
+            iObserver->NotifyInputAction(event);
+            break;
+        }
+        case EEventScroll:
+        {
+            break;
+        }
+        default:
+        {
+            // Not handled.
+            break;
+        }
+        }
+    }
+
+    DEBUG("CMIDTextEditorEdwin::HandleEdwinEventL -");
+}
+
+// ---------------------------------------------------------------------------
+// CMIDTextEditorEdwin::HandlePointerEventL
+// (other items were commented in the header file)
+// ---------------------------------------------------------------------------
+//
+#ifdef RD_SCALABLE_UI_V2
+void CMIDTextEditorEdwin::HandlePointerEventL(
+    const TPointerEvent &aPointerEvent)
+{
+    DEBUG("CMIDTextEditorEdwin::HandlePointerEventL +");
+    if (AknLayoutUtils::PenEnabled())
+    {
+        CEikEdwin::HandlePointerEventL(aPointerEvent);
+    }
+    DEBUG("CMIDTextEditorEdwin::HandlePointerEventL -");
+}
+#endif // RD_SCALABLE_UI_V2
+
+
+// ---------------------------------------------------------------------------
+// CMIDTextEditorEdwin::HandleSpecialKEyEventsL
+// (other items were commented in the header file)
+// ---------------------------------------------------------------------------
+//
+TKeyResponse CMIDTextEditorEdwin::HandleSpecialKeyEventsL(
+    const TKeyEvent& aKeyEvent,
+    TEventCode aType)
+{
+    DEBUG("CMIDTextEditorEdwin::HandleSpecialKeyEventsL +");
+
+    TKeyResponse response = EKeyWasNotConsumed;
+
+    // Do not handle anything if text's maximum lenght has been reached
+    // or if the editor is set to read only state.
+    if (TextLength() >= MaxLength() || IsReadOnly())
+    {
+        DEBUG("CMIDTextEditorEdwin::HandleSpecialKeyEventsL -, \
+max size reached");
+
+        return response;
+    }
+
+    TUint sc = aKeyEvent.iScanCode;
+
+    DEBUG_INT2("CMIDTextEditorEdwin::HandleSpecialKeyEventsL, \
+scanCode=0x%x, iConstraints=0x%x", sc, iConstraints);
+
+    TBool dec = IsConstraintSet(MMIDTextField::EDecimal);
+    TBool num = IsConstraintSet(MMIDTextField::ENumeric);
+
+    // Try to handle minus and full stop characters separately.
+    // Other than EEventKey events are ignored.
+
+    if ((dec || num) &&
+            (aType == EEventKey) &&
+            (sc == EStdKeyMinus || sc == EStdKeyNkpMinus ||
+             sc == EStdKeyFullStop || sc == EStdKeyNkpFullStop ||
+             sc == EStdKeyNkpAsterisk || sc == KMidpKeyNkpAsteriskHW))
+    {
+        DEBUG("CMIDTextEditorEdwin::HandleSpecialKeyEventsL, \
+handling special");
+
+        TInt cursorPos = CursorPos();
+        TPtrC content = Read();
+
+        // Toggle minus character. Decimal editor uses SCT so do not toggle
+        // from asterisk key in that case.
+        if ((sc == EStdKeyMinus || sc == EStdKeyNkpMinus) ||
+                ((sc == EStdKeyNkpAsterisk || sc == KMidpKeyNkpAsteriskHW)
+                 && num))
+        {
+            DEBUG("CMIDTextEditorEdwin::HandleSpecialKeyEventsL, \
+toggle minus");
+
+            if (content.Find(KMinusChar) == KErrNotFound)
+            {
+                iText->InsertL(0, KMinusChar);
+                cursorPos++;
+            }
+            else
+            {
+                iText->DeleteL(0, 1);
+                cursorPos--;
+            }
+
+            HandleTextChangedL();
+            ReportEdwinEventL(MEikEdwinObserver::EEventTextUpdate);
+            SetCursorPosL(cursorPos, EFalse);
+
+            response = EKeyWasConsumed;
+        }
+        else if (dec && (sc == EStdKeyFullStop ||
+                         sc == EStdKeyNkpFullStop))
+        {
+            TLocale locale;
+            TChar decimalSeparator(locale.DecimalSeparator());
+
+            if (content.Locate(decimalSeparator) == KErrNotFound)
+            {
+                DEBUG("CMIDTextEditorEdwin::HandleSpecialKeyEventsL, \
+inserting full stop");
+
+                // Insert full stop sign into to cursor's current position.
+                iText->InsertL(cursorPos, decimalSeparator);
+                HandleTextChangedL();
+                ReportEdwinEventL(MEikEdwinObserver::EEventTextUpdate);
+                SetCursorPosL(cursorPos + 1, EFalse);
+
+                response = EKeyWasConsumed;
+            }
+        }
+    }
+
+    DEBUG_INT("CMIDTextEditorEdwin::HandleSpecialKeyEventsL - response=%d",
+              response);
+
+    return response;
+}
+
+// ---------------------------------------------------------------------------
+// CMIDTextEditorEdwin::SetTopParent
+// (other items are commented in the header file)
+// ---------------------------------------------------------------------------
+//
+void CMIDTextEditorEdwin::SetTopParent(CCoeControl* aControl)
+{
+    iParent = aControl;
+}
+
+// ---------------------------------------------------------------------------
+// CMIDTextEditorEdwin::SetObserver
+// (other items are commented in the header file)
+// ---------------------------------------------------------------------------
+//
+void CMIDTextEditorEdwin::SetObserver(MMIDTextEditorObserver* aObserver)
+{
+    DEBUG("CMIDTextEditorEdwin::SetObserver +");
+
+    iObserver = aObserver;
+
+    DEBUG("CMIDTextEditorEdwin::SetObserver -");
+}
+
+// ---------------------------------------------------------------------------
+// CMIDTextEditorEdwin::SetEditingStateIndicator
+// (other items were commented in the header file)
+// ---------------------------------------------------------------------------
+//
+void CMIDTextEditorEdwin::SetEditingStateIndicator(
+    CMIDEditingStateIndicator* aIndicator)
+{
+    DEBUG("CMIDTextEditorEdwin::SetEditingStateIndicator +");
+
+    // Indicator can be set to NULL.
+    iIndicator = aIndicator;
+
+    DEBUG("CMIDTextEditorEdwin::SetEditingStateIndicator -");
+}
+
+// ---------------------------------------------------------------------------
+// CMIDTextEditorEdwin::SetConstraintsL
+// (other items were commented in the header file)
+// ---------------------------------------------------------------------------
+//
+void CMIDTextEditorEdwin::SetConstraintsL(TUint aConstraints)
+{
+    DEBUG("CMIDTextEditorEdwin::SetConstraintsL +");
+
+    // Note that this method cannot be 100% leave-safe due to the current
+    // CEikEdwin implementation.
+
+    __ASSERT_DEBUG(iText, User::Invariant());
+
+    // Apply document content.
+    CGlobalText* newText = NULL;
+    CGlobalText* oldText = static_cast< CGlobalText* >(iText);
+
+    const CParaFormatLayer* paraFormatLayer =
+        oldText->GlobalParaFormatLayer();
+
+    const CCharFormatLayer* charFormatLayer =
+        oldText->GlobalCharFormatLayer();
+
+    TBool enableCcpuSupport = ETrue;
+
+    // Create password text if mode is password (non-restrictive).
+    if (aConstraints & MMIDTextField::EPassword)
+    {
+        DEBUG(
+            "CMIDTextEditorEdwin::SetConstraintsL, creating password text");
+
+        // Password editors must not use CCPU support according to
+        // S60 Editing specification.
+        enableCcpuSupport = EFalse;
+
+        CPasswordBoxGlobalText* text = new(ELeave)CPasswordBoxGlobalText(
+            paraFormatLayer, charFormatLayer, *this);
+
+        CleanupStack::PushL(text);
+        text->ConstructL();
+        CleanupStack::Pop(text);
+
+        newText = text;
+    }
+    else // Default, no password.
+    {
+        // Use default global text in the editor.
+        newText = CGlobalText::NewL(paraFormatLayer, charFormatLayer);
+    }
+
+    CleanupStack::PushL(newText);
+    SetDocumentContentL(newText);
+
+    // Disable or enable CCPU support here.
+    EnableCcpuSupportL(enableCcpuSupport);
+
+    // Store constraints here. Rest of the method is leave-safe
+    // and RestoreDefaultInputState uses the capabilities.
+    iConstraints = aConstraints;
+
+    // Restore default input state before making any modifications. This
+    // ensures that the next input constraints are set correctly and
+    // that the previous constraints do not affect on the new input modes.
+    // This should be done in CMIDEdwinUtils::SetFEPModeAndCharFormat()
+    // but it does not reset all the necessary input parameters.
+    RestoreDefaultInputState();
+
+    // Set uneditable if set as current mode.
+    SetReadOnly(aConstraints & MMIDTextField::EUneditable);
+
+    // Use edwin utils to set the FEP mode and character format.
+    iEdwinUtils.SetFEPModeAndCharFormat(aConstraints, this);
+
+    // Publish MIDP constraints via input capabilities of CEikEdwin.
+    CAknExtendedInputCapabilities* caps = AknInputCaps();
+    if (caps)
+    {
+        DEBUG(
+            "CMIDTextEditorEdwin::SetConstraintsL, setting MIDP constaints");
+
+        caps->SetMIDPConstraints(aConstraints);
+    }
+
+    // CMIDEdwinUtils modify the multiline state of the editor
+    // thus it needs the be set again here. Passwords are always
+    // single line editors.
+    if (!(aConstraints & MMIDTextField::EPassword))
+    {
+        SetWordWrapL(iMultiline);
+    }
+    else
+    {
+        SetWordWrapL(EFalse);
+    }
+    CleanupStack::Pop(newText);
+
+    DEBUG("CMIDTextEditorEdwin::SetConstraintsL +");
+}
+
+// ---------------------------------------------------------------------------
+// CMIDTextEditorEdwin::SetInitialInputModeL
+// (other items were commented in the header file)
+// ---------------------------------------------------------------------------
+//
+void CMIDTextEditorEdwin::SetInitialInputModeL(
+    const TDesC& aCharacterSubset)
+{
+    DEBUG_STR(
+        "CMIDTextEditorEdwin::SetInitialInputModeL +, aCharacterSubset=%S",
+        aCharacterSubset);
+
+    // Set initial input mode. Note that the change is performed
+    // after the next editing session starts. See MIDP specification.
+    // See CMIDEdwin::SetInitialInputModeL
+
+    iEdwinUtils.SetInitialInputModeL(
+        aCharacterSubset,
+        iConstraints,
+        iInitialCurrentCase,
+        iInitialCurrentInputMode,
+        iInitialCurrentLanguage);
+
+    // Set permitted case modes for edwin in lowercase or uppercase mode.
+    if (aCharacterSubset.Compare(KMidpUppercaseLatin) == 0 ||
+            aCharacterSubset.Compare(KMidpLowercaseLatin) == 0)
+    {
+        DEBUG("CMIDTextEditorEdwin::SetInitialInputModeL, latin");
+
+        // 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) ||
+                !IsConstraintSet(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);
+    }
+
+    DEBUG("CMIDTextEditorEdwin::SetInitialInputModeL -");
+}
+
+// ---------------------------------------------------------------------------
+// CMIDTextEditorEdwin::RestoreDefaultInputState
+// (other items were commented in the header file)
+// ---------------------------------------------------------------------------
+//
+void CMIDTextEditorEdwin::RestoreDefaultInputState()
+{
+    DEBUG("CMIDTextEditorEdwin::RestoreEdwinDefaultInputState +");
+
+    // Restore the default input state. It is not possible to directly
+    // call CAknEditorState object from CEikEdwin since it is currently
+    // used internally only. The default state set here is the same
+    // that is set when CAknEditorState is constructed. See
+    // CAknEditorState::CAknEditorState in aknedsts.cpp for details.
+
+    SetAknEditorCase(EAknEditorTextCase);
+    SetAknEditorPermittedCaseModes(EAknEditorAllCaseModes);
+    SetAknEditorFlags(EAknEditorFlagDefault);
+    SetAknEditorSpecialCharacterTable(KErrNotFound);
+    SetAknEditorInputMode(EAknEditorTextInputMode);
+    SetAknEditorAllowedInputModes(EAknEditorAllInputModes);
+    SetAknEditorCurrentInputMode(EAknEditorTextInputMode);
+    SetAknEditorCurrentCase(EAknEditorTextCase);
+    SetAknEditorNumericKeymap(EAknEditorAlphanumericNumberModeKeymap);
+    SetAknEditorLocalLanguage(
+        CAknEnv::Static()->SettingCache().InputLanguage());
+
+    // Enable SCT in other than numeric editors. Note that asterisk toggles
+    // the minus character so the SCT must not be enabled because of that.
+    if (!IsConstraintSet(MMIDTextField::ENumeric))
+    {
+        CAknExtendedInputCapabilities* caps = AknInputCaps();
+        if (caps)
+        {
+            DEBUG("CMIDTextEditorEdwin::RestoreEdwinDefaultInputState,\
+ disable SCT");
+
+            caps->SetCapabilities(
+                caps->Capabilities() &
+                ~CAknExtendedInputCapabilities::EDisableSCT);
+        }
+    }
+
+    // Reset initial input mode also.
+    iInitialCurrentCase = 0;
+    iInitialCurrentInputMode = 0;
+    iInitialCurrentLanguage = ELangTest;
+
+    DEBUG("CMIDTextEditorEdwin::RestoreEdwinDefaultInputState -");
+}
+
+// ---------------------------------------------------------------------------
+// CMIDTextEditorEdwin::SetCursorPosL
+// (other items were commented in the header file)
+// ---------------------------------------------------------------------------
+//
+void CMIDTextEditorEdwin::SetCursorPosL(
+    TInt aCursorPosition,
+    TBool aSelect)
+{
+    DEBUG_INT("CMIDTextEditorEdwin::SetCursorPosL +, aCursorPosition=%d",
+              aCursorPosition);
+
+    // Set cursor if the editor has a valid parent.
+    if (IsInitialized())
+    {
+        CEikEdwin::SetCursorPosL(aCursorPosition, aSelect);
+    }
+    // Do not deliver event if the position actually does not change.
+    else if (CursorPos() != aCursorPosition)
+    {
+        // Event has to be delivered to the registered observer
+        // even if the editor window has not been initialized.
+        ReportEdwinEventL(MEikEdwinObserver::EEventNavigation);
+    }
+
+    if (aSelect)
+    {
+        // CEikEdwin does not store selection if not initialized.
+        // Store it in order to avoid errors when setting selection
+        // before parent is stored.
+        iSelection.SetSelection(iCursorPosition, aCursorPosition);
+    }
+    else // Clear selection.
+    {
+        iSelection.SetSelection(0, 0);
+    }
+
+    // Editor window does not know the position yet because it has not
+    // been activated. Store the position to a member variable. Note that
+    // this must be set when the editor is activated.
+    // Cursor needs to be stored all the time because change of the
+    // parent object may cause the cursor to be changed in CEikEdwin.
+    iCursorPosition = aCursorPosition;
+
+    DEBUG("CMIDTextEditorEdwin::SetCursorPosL -");
+}
+
+// ---------------------------------------------------------------------------
+// CMIDTextEditorEdwin::CursorPos
+// (other items are commented in the header file)
+// ---------------------------------------------------------------------------
+//
+TInt CMIDTextEditorEdwin::CursorPos() const
+{
+    DEBUG("CMIDTextEditorEdwin::CursorPos +");
+
+    // The control may have not been initialized yet (i.e. SetParentL has
+    // not been called). Do not get cursor position in that case because
+    // it crashes due to missing text view in the CEikEdwin.
+    TInt cursorPosition(
+        (IsInitialized() ? CEikEdwin::CursorPos() : iCursorPosition));
+
+    DEBUG_INT("CMIDTextEditorEdwin::CursorPos -, cursorPosition=%d",
+              cursorPosition);
+
+    return cursorPosition;
+}
+
+// ---------------------------------------------------------------------------
+// CMIDTextEditorEdwin::Selection
+// (other items were commented in the header file)
+// ---------------------------------------------------------------------------
+//
+TCursorSelection CMIDTextEditorEdwin::Selection()
+{
+    DEBUG("CMIDTextEditorEdwin::Selection +");
+
+    TCursorSelection selection(iSelection);
+
+    // Selection is not returned correctly if the editor has not been
+    // initialized.
+    if (IsInitialized())
+    {
+        selection = CEikEdwin::Selection();
+    }
+
+    DEBUG("CMIDTextEditorEdwin::Selection -");
+
+    return selection;
+}
+
+// ---------------------------------------------------------------------------
+// CMIDTextEditorEdwin::SetWordWrapL
+// (other items were commented in the header file)
+// ---------------------------------------------------------------------------
+//
+void CMIDTextEditorEdwin::SetWordWrapL(TBool aWrapIsOn)
+{
+    DEBUG_INT("CMIDTextEditorEdwin::SetWordWrapL +, aWrapIsOn=%d",
+              aWrapIsOn);
+
+    // CEikEdwin crashes when setting word wrap before it
+    // has a valid container window. Multiline state is set
+    // in InitializeL() method again when called.
+    if (IsInitialized())
+    {
+        CEikEdwin::SetWordWrapL(aWrapIsOn);
+
+        // Apply line and paragraph breaks.
+        if (!aWrapIsOn)
+        {
+            AddFlagToUserFlags(CEikEdwin::ENoLineOrParaBreaks);
+        }
+        else
+        {
+            RemoveFlagFromUserFlags(CEikEdwin::ENoLineOrParaBreaks);
+        }
+    }
+
+    iMultiline = aWrapIsOn;
+
+    DEBUG("CMIDTextEditorEdwin::SetCursorPosL -");
+}
+
+// ---------------------------------------------------------------------------
+// CMIDTextEditorEdwin::IsWrapEnabled
+// (other items were commented in the header file)
+// ---------------------------------------------------------------------------
+//
+TBool CMIDTextEditorEdwin::IsWrapEnabled() const
+{
+    return iMultiline;
+}
+
+// ---------------------------------------------------------------------------
+// CMIDTextEditorEdwin::SetSize
+// (other items were commented in the header file)
+// ---------------------------------------------------------------------------
+//
+void CMIDTextEditorEdwin::SetSize(TInt aWidth, TInt aHeight)
+{
+    DEBUG("CMIDTextEditorEdwin::SetSize +");
+
+    // Set the width of the editor window. Note that EWidthInPixels is set
+    // so this method uses the parameter as pixels instead of chars.
+    CalculateWidth(aWidth);
+    // Set minimum and maximum height to the same value.
+    SetMinimumHeight(aHeight);
+    SetMaximumHeight(aHeight);
+
+    TSize size(aWidth, aHeight);
+    // Set size of the UI control if container has been set. Otherwise
+    // this will panic the editor window at some point.
+    if (IsInitialized())
+    {
+        CCoeControl::SetSize(size);
+    }
+
+    // Store the size for later use when set parent has been called.
+    iSize = size;
+
+    DEBUG("CMIDTextEditorEdwin::SetSize -");
+}
+
+// ---------------------------------------------------------------------------
+// CMIDTextEditorEdwin::Size
+// (other items were commented in the header file)
+// ---------------------------------------------------------------------------
+//
+TSize CMIDTextEditorEdwin::Size() const
+{
+    DEBUG("CMIDTextEditorEdwin::Size +");
+
+    TSize size(iSize);
+
+    // Check if editor has been initialized.
+    if (IsInitialized())
+    {
+        size = CCoeControl::Size();
+    }
+
+    DEBUG("CMIDTextEditorEdwin::Size -");
+
+    return size;
+}
+
+// ---------------------------------------------------------------------------
+// CMIDTextEditorEdwin::IsInitialized
+// (other items were commented in the header file)
+// ---------------------------------------------------------------------------
+//
+TBool CMIDTextEditorEdwin::IsInitialized() const
+{
+    DEBUG_INT("CMIDTextEditorEdwin::IsInitialized, iInitialized=%d",
+              iInitialized);
+
+    // Currently, the text editor is considered as constructed when the text
+    // view has been created and the editor window has been activated.
+    return iInitialized;
+}
+
+// ---------------------------------------------------------------------------
+// CMIDTextEditorEdwin::InitializeL
+// (other items were commented in the header file)
+// ---------------------------------------------------------------------------
+//
+void CMIDTextEditorEdwin::InitializeL()
+{
+    DEBUG("CMIDTextEditorEdwin::InitializeL +");
+
+    if (!iInitialized)
+    {
+        CreateTextViewL();
+        ActivateL();
+
+        // Set colors here in order to avoid crash when parent
+        // has not been set by CMIDTextEditor.
+        SetBackgroundColorL(iBackgroundColor);
+        iTextView->SetBackgroundColor(iBackgroundColor);
+
+        // Set selection set before initialization.
+        CEikEdwin::SetCursorPosL(iCursorPosition, EFalse);
+
+        // Selection overrides cursor's position
+        if (iSelection.Length() > 0)
+        {
+            CEikEdwin::SetCursorPosL(iSelection.LowerPos(), EFalse);
+            CEikEdwin::SetCursorPosL(iSelection.HigherPos(), ETrue);
+        }
+
+        // By default, editor is unfocused and not visible. Note
+        // that hide and show cannot be called before set parent.
+        SetFocus(EFalse);
+        MakeVisible(EFalse);
+        // Apply current size.
+        CCoeControl::SetSize(iSize);
+        iInitialized = true;
+        // Apply current multiline status. iInitialized must be true here.
+        SetWordWrapL(iMultiline);
+    }
+
+    DEBUG("CMIDTextEditorEdwin::InitializeL -");
+}
+
+// ---------------------------------------------------------------------------
+// CMIDTextEditorEdwin::Uninitialize
+// (other items were commented in the header file)
+// ---------------------------------------------------------------------------
+//
+void CMIDTextEditorEdwin::Uninitialize()
+{
+    DEBUG("CMIDTextEditorEdwin::Uninitialize +");
+
+    if (iInitialized)
+    {
+        // Remove focus and hide the editor.
+        SetFocus(EFalse);
+        MakeVisible(EFalse);
+        // Store cursor's current position.
+        iCursorPosition = CEikEdwin::CursorPos();
+
+        iInitialized = false;
+        iParent = NULL;
+    }
+
+    DEBUG("CMIDTextEditorEdwin::Uninitialize -");
+}
+
+// ---------------------------------------------------------------------------
+// CMIDTextEditorEdwin::EditorWindowHeight
+// (other items were commented in the header file)
+// ---------------------------------------------------------------------------
+//
+TInt CMIDTextEditorEdwin::EditorWindowHeight() const
+{
+    DEBUG("CMIDTextEditorEdwin::EditorWindowHeight +");
+
+    TInt minimumHeight = iSize.iHeight;
+    if (iNumberOfLines == 0)
+    {
+        if (MinimumHeight() > 0)
+        {
+            minimumHeight = MinimumHeight();
+        }
+    }
+    else
+    {
+        minimumHeight = (LineHeight() * iNumberOfLines)
+                        + iBorder.SizeDelta().iHeight
+                        + iMargins.iTop
+                        + iMargins.iBottom;
+    }
+
+    DEBUG_INT("CMIDTextEditorEdwin::EditorWindowHeight - , height=%d",
+              minimumHeight);
+
+    return minimumHeight;
+}
+
+// ---------------------------------------------------------------------------
+// CMIDTextEditorEdwin::NumberOfLines
+// (other items were commented in the header file)
+// ---------------------------------------------------------------------------
+//
+TInt CMIDTextEditorEdwin::NumberOfLines() const
+{
+    __ASSERT_DEBUG(iLayout, User::Invariant());
+
+    return iLayout->NumFormattedLines();
+}
+
+// ---------------------------------------------------------------------------
+// CMIDTextEditorEdwin::LineHeight
+// (other items were commented in the header file)
+// ---------------------------------------------------------------------------
+//
+TInt CMIDTextEditorEdwin::LineHeight() const
+{
+    __ASSERT_DEBUG(iLayout, User::Invariant());
+
+    TInt lineHeight = iLayout->FormattedHeightInPixels();
+    const TInt docLength = iLayout->DocumentLength();
+    if (docLength > 0)
+    {
+        const TInt numFormattedLines = iLayout->NumFormattedLines();
+        lineHeight = lineHeight / numFormattedLines;
+    }
+
+    return lineHeight;
+}
+
+// ---------------------------------------------------------------------------
+// CMIDTextEditorEdwin::VisibleContentPosition
+// (other items were commented in the header file)
+// ---------------------------------------------------------------------------
+//
+TInt CMIDTextEditorEdwin::VisibleContentPosition() const
+{
+    DEBUG("CMIDTextEditorEdwin::VisibleContentPosition +");
+
+    __ASSERT_DEBUG(iLayout, User::Invariant());
+
+    DEBUG_INT("CMIDTextEditorEdwin::VisibleContentPosition -, pos=%d",
+              iLayout->PixelsAboveBand());
+
+    return iLayout->PixelsAboveBand();
+}
+
+// ---------------------------------------------------------------------------
+// CMIDTextEditorEdwin::Read
+// (other items were commented in the header file)
+// ---------------------------------------------------------------------------
+//
+const TPtrC CMIDTextEditorEdwin::Read() const
+{
+    if (iConstraints & MMIDTextField::EPassword)
+    {
+        return static_cast< CPasswordBoxGlobalText* >(iText)->ClearText();
+    }
+
+    return iText->Read(0, TextLength());
+}
+
+// ---------------------------------------------------------------------------
+// CMIDTextEditorEdwin::MopSupplyObject
+// (other items were commented in the header file)
+// ---------------------------------------------------------------------------
+//
+TTypeUid::Ptr CMIDTextEditorEdwin::MopSupplyObject(TTypeUid aId)
+{
+    // Try supplying custom indicator.
+    TTypeUid::Ptr id((
+                         iIndicator ? iIndicator->SupplyIndicatorMopObject(aId)
+                         : TTypeUid::Null()));
+
+    // Indicator was not supplied. Try supplying from CEikEdwin.
+    if (!(id.Pointer()))
+    {
+        return CEikEdwin::MopSupplyObject(aId);
+    }
+
+    return id;
+}
+
+// ---------------------------------------------------------------------------
+// CMIDTextEditorEdwin::SetDocumentContentL
+// (other items were commented in the header file)
+// ---------------------------------------------------------------------------
+//
+void CMIDTextEditorEdwin::SetDocumentContentL(CGlobalText* aText)
+{
+    DEBUG("CMIDTextEditorEdwin::SetDocumentContentL +");
+
+    // Even though the method takes a reference in it, the ownership
+    // is still transferred to CEikEdwin. And current iText is simply
+    // left ignored. Store it locally and delete after successful
+    // operation
+    CPlainText* temp = iText;
+    TRAPD(err, CEikEdwin::SetDocumentContentL(
+              *aText, CEikEdwin::EUseText));
+
+    if (err != KErrNone)
+    {
+        // Failed but the ownership was transferred... State has been changed
+        // but we avoid leaking any memory at this point which is better.
+        // Restore the text back. This is not bulletproof, but leaves
+        // the text state as it was before trying to set the new text.
+        delete iText;
+        iText = temp;
+        User::Leave(err);
+    }
+
+    // Everything went fine. Delete the old iText.
+    delete temp;
+
+    DEBUG("CMIDTextEditorEdwin::SetDocumentContentL -");
+}
+
+// ---------------------------------------------------------------------------
+// CMIDTextEditorEdwin::AknInputCaps
+// (other items were commented in the header file)
+// ---------------------------------------------------------------------------
+//
+CAknExtendedInputCapabilities* CMIDTextEditorEdwin::AknInputCaps() const
+{
+    CAknExtendedInputCapabilities* caps = NULL;
+
+    TCoeInputCapabilities inputCapabilities = InputCapabilities();
+    if (inputCapabilities != TCoeInputCapabilities::ENone)
+    {
+        DEBUG("CMIDTextEditorEdwin::AknInputCaps, editor has input caps");
+
+        // Get input capabilities object provider.
+        MObjectProvider* provider = inputCapabilities.ObjectProvider();
+        if (provider)
+        {
+            DEBUG(
+                "CMIDTextEditorEdwin::AknInputCaps, object provider found");
+
+            // MopGetObjects needs a reference to a pointer to an object
+            // of a type that is to be retrieved. NULL is OK here.
+            caps = provider->MopGetObject(caps);
+        }
+    }
+
+    return caps;
+}
+
+// ---------------------------------------------------------------------------
+// CMIDTextEditorEdwin::RemoveInvalidNumericContentL
+// (other items were commented in the header file)
+// ---------------------------------------------------------------------------
+//
+TBool CMIDTextEditorEdwin::RemoveInvalidNumericContentL()
+{
+    DEBUG("CMIDTextEditorEdwin::RemoveInvalidNumericContentL +");
+
+    TBool textChanged = EFalse;
+    TPtrC content = Read();
+
+    // Handle content change in numeric and decimal editors if the
+    // content is not valid for the given set of constraints.
+    if (!iEdwinUtils.ConstraintsValidForText(content, iConstraints, ETrue))
+    {
+        DEBUG("CMIDTextEditorEdwin::RemoveInvalidNumericContentL, \
+content not valid");
+
+        TLocale locale;
+        TChar decimal(locale.DecimalSeparator());
+        TChar minus(KCharMinus);
+
+        TInt cursorPos = CursorPos();
+        TInt minusPos = content.Locate(minus);
+        TInt decimalPos = content.Locate(decimal);
+
+        // Validate that minus character has been entered correctly
+        // First cases in which there is only minus and separator.
+        if (content.Length() == 1 &&
+                ((decimalPos == 0) || (minusPos == 0)))
+        {
+            iText->DeleteL(0, 1);
+            cursorPos = 0;
+        }
+        else if (content.Length() == 2 &&
+                 ((minusPos == 0) && (decimalPos == 1)))
+        {
+            iText->DeleteL(0, 2);
+            cursorPos = 0;
+        }
+        else
+        {
+            // Other cases. Minus and decimal somewhere in the content.
+            if (minusPos != KErrNotFound)
+            {
+                // The first is valid. Remove all other minus chars.
+                minusPos = content.LocateReverse(minus);
+                while (minusPos != 0 && minusPos != KErrNotFound)
+                {
+                    iText->DeleteL(minusPos, 1);
+                    minusPos = content.LocateReverse(minus);
+                    cursorPos--;
+                }
+            }
+
+            // Decimal position may have changed.
+            decimalPos = content.Locate(decimal);
+
+            if (decimalPos != KErrNotFound)
+            {
+                // The first is valid. Remove all other separators.
+                TInt secondPos = content.LocateReverse(decimal);
+                while (secondPos != decimalPos)
+                {
+                    iText->DeleteL(secondPos, 1);
+                    secondPos = content.LocateReverse(decimal);
+                    cursorPos--;
+                }
+            }
+        }
+
+        // Do not report event again so call base class' method.
+        CEikEdwin::HandleTextChangedL();
+        // Restore cursor's original position.
+        SetCursorPosL(cursorPos, EFalse);
+        textChanged = ETrue;
+    }
+
+    DEBUG_INT(
+        "CMIDTextEditorEdwin::RemoveInvalidNumericContentL -, textChanged=%d",
+        textChanged);
+
+    return textChanged;
+}
+
+// End of file