javauis/eswt_akn/org.eclipse.ercp.swt.s60/native/src/swttextbase.cpp
branchRCL_3
changeset 66 2455ef1f5bbc
child 71 d5e927d5853b
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/javauis/eswt_akn/org.eclipse.ercp.swt.s60/native/src/swttextbase.cpp	Wed Sep 01 12:33:18 2010 +0100
@@ -0,0 +1,1443 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2010 Nokia Corporation and/or its subsidiary(-ies).
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     Nokia Corporation - S60 implementation
+ *******************************************************************************/
+
+
+#include <eikedwin.h>
+#include <txtglobl.h>
+#include <EIKCOCTL.rsg>
+#include <AknsUtils.h>
+#include <swtlaffacade.h>
+#include <AknUtils.h>
+#include <AknDef.h>
+#ifdef RD_JAVA_S60_RELEASE_9_2
+#include <AknPriv.hrh>
+#endif
+#include <aknappui.h>
+#include <akntouchpane.h>
+#include "swtscrollbar.h"
+#include "swtfont.h"
+#include "swttextbase.h"
+#include "swtcaptionedcontrol.h"
+
+#ifdef SYMBIAN_ENABLE_SPLIT_HEADERS
+#include <uikon/eikdefconst.h>
+#endif
+
+// ======== MEMBER FUNCTIONS ========
+
+
+// ---------------------------------------------------------------------------
+// CSwtTextBase::CSwtTextBase
+// ---------------------------------------------------------------------------
+//
+CSwtTextBase::CSwtTextBase(
+    MSwtDisplay& aDisplay,
+    TSwtPeer aPeer,
+    MSwtComposite& aParent,
+    TInt aStyle)
+        : ASwtScrollableBase(aDisplay, aPeer, &aParent, aStyle)
+{
+}
+
+// ---------------------------------------------------------------------------
+// CSwtTextBase::~CSwtTextBase
+// ---------------------------------------------------------------------------
+//
+CSwtTextBase::~CSwtTextBase()
+{
+    // Own
+    delete iEditor;
+    iEditor = NULL;
+    delete iIndicator;
+    iIndicator = NULL;
+
+    // Not own.
+    if (iDefaultFont)
+    {
+        iDefaultFont->RemoveRef();
+        iDefaultFont = NULL;
+    }
+
+    if (iCharFormatLayer)
+    {
+        delete iCharFormatLayer;
+        iCharFormatLayer = NULL;
+    }
+}
+
+// ---------------------------------------------------------------------------
+// CSwtTextBase::ConstructL
+// ---------------------------------------------------------------------------
+//
+void CSwtTextBase::ConstructL()
+{
+    CCoeControl& coeParent = iParent->Control()->CoeControl();
+    SetContainerWindowL(coeParent);
+    CSwtEditIndicatorRedictor* redirector = MopGetObject(redirector);
+    if (redirector)
+    {
+        iIndicator = CSwtEditIndicator::NewL(CoeControl());
+    }
+    CCoeControl::MakeVisible(coeParent.IsVisible());
+    CCoeControl::SetDimmed(coeParent.IsDimmed());
+    SetComponentsToInheritVisibility(ETrue);
+
+    // Although the background is drawn already natively, this fixes
+    // problems with srollbar back when custom back color set.
+    SetBackground(this);
+}
+
+// ---------------------------------------------------------------------------
+// CSwtTextBase::SetEditor
+// ---------------------------------------------------------------------------
+//
+void CSwtTextBase::SetEditor(CEikEdwin* aEditor)
+{
+    ASSERT(!iEditor);
+    iEditor = aEditor;
+}
+
+#if defined( RD_SCALABLE_UI_V2)
+
+// ---------------------------------------------------------------------------
+// CSwtTextBase::InputCapabilities
+// ---------------------------------------------------------------------------
+//
+TCoeInputCapabilities CSwtTextBase::InputCapabilities() const
+{
+    // Override CCoeControl behaviour to provide MCoeCaptionRetrieverForFep.
+    const TCoeInputCapabilities& capabilities = CAknControl::InputCapabilities();
+
+    return TCoeInputCapabilities(capabilities.Capabilities(),
+                                 capabilities.FepAwareTextEditor(),
+                                 (MCoeCaptionRetrieverForFep*)this);
+}
+
+// ---------------------------------------------------------------------------
+// CSwtTextBase::GetCaptionForFep
+// ---------------------------------------------------------------------------
+//
+void CSwtTextBase::GetCaptionForFep(TDes& aCaption) const
+{
+    // If we are inside a CaptionedControl, return the CaptionedControl text.
+    // It will be shown in thumb keypad
+    MSwtCaptionedControl* captionedControl = iParent->Control()->CaptionedControlInterface();
+
+    if (captionedControl)
+    {
+        const TDesC* text = captionedControl->GetText();
+
+        if (!text)
+        {
+            aCaption = KNullDesC;
+        }
+        else
+        {
+            const TInt maximumLength = aCaption.MaxLength();
+
+            if (text->Length() > maximumLength)
+            {
+                aCaption = text->Left(maximumLength);
+            }
+            else
+            {
+                aCaption = *text;
+            }
+        }
+    }
+    else
+    {
+        aCaption=KNullDesC;
+    }
+}
+
+void CSwtTextBase::MCoeCaptionRetrieverForFep_Reserved_1()
+{}
+
+void CSwtTextBase::MCoeCaptionRetrieverForFep_Reserved_2()
+{}
+
+#endif //RD_SCALABLE_UI_V2
+
+// ---------------------------------------------------------------------------
+// CSwtTextBase::RetrieveDefaultFontL
+// ---------------------------------------------------------------------------
+//
+void CSwtTextBase::RetrieveDefaultFontL()
+{
+    ASSERT(iEditor);
+
+    if (iDefaultFont)
+    {
+        iDefaultFont->RemoveRef();
+        iDefaultFont = NULL;
+    }
+
+    // Not same but similar to DateEditor's font. Height most probably be same.
+    iDefaultFont = CSwtFont::NewL(iDisplay.Device(), *AknLayoutUtils::FontFromId(
+                                      CSwtLafFacade::GetFontId(CSwtLafFacade::EFont2MidpTextPaneT1Font, 0, 0), NULL));
+
+    if (!iFont)
+    {
+        // to avoid the default font of CEikEdwin
+        ProcessFontUpdateL();
+    }
+}
+
+
+// ---------------------------------------------------------------------------
+// CSwtTextBase::ProcessFontUpdate
+// ---------------------------------------------------------------------------
+//
+void CSwtTextBase::ProcessFontUpdateL()
+{
+    TCharFormat charFormat;
+    TCharFormatMask charMask;
+
+    charFormat.iFontSpec = GetFont()->Font().FontSpecInTwips();
+    charMask.SetAttrib(EAttFontTypeface);
+    charMask.SetAttrib(EAttFontHeight);
+
+    if (charFormat.iFontSpec.iFontStyle.StrokeWeight() == EStrokeWeightBold)
+    {
+        charMask.SetAttrib(EAttFontStrokeWeight);
+    }
+
+    if (charFormat.iFontSpec.iFontStyle.Posture() == EPostureItalic)
+    {
+        charMask.SetAttrib(EAttFontPosture);
+    }
+
+    TRgb color(0);
+    TInt err(KErrNone);
+
+    if (HasHighlight())
+    {
+        err = AknsUtils::GetCachedColor(AknsUtils::SkinInstance()
+                                        , color
+                                        , KAknsIIDQsnTextColors
+                                        , KHighlightedTextColor);
+        if (err == KErrNone)
+        {
+            charFormat.iFontPresentation.iTextColor = color;
+            charMask.SetAttrib(EAttColor);
+        }
+    }
+    else if (iTextColor)
+    {
+        charFormat.iFontPresentation.iTextColor = GetForeground();
+        charMask.SetAttrib(EAttColor);
+    }
+    else
+    {
+        err = AknsUtils::GetCachedColor(AknsUtils::SkinInstance()
+                                        , color
+                                        , KAknsIIDQsnTextColors
+                                        , KNonHighlightedTextColor);
+        if (err == KErrNone)
+        {
+            charFormat.iFontPresentation.iTextColor = color;
+            charMask.SetAttrib(EAttColor);
+        }
+    }
+
+    if (iStyle & KSwtStyleSingle)
+    {
+        CCharFormatLayer* charFormatLayer = CCharFormatLayer::NewL(charFormat, charMask);
+        // we are using CGlobalText for Single line. So SetGlobalCharFormat for Global text
+        static_cast<CGlobalText*>(iEditor->Text())->SetGlobalCharFormat(charFormatLayer);
+        if (iCharFormatLayer)
+        {
+            delete iCharFormatLayer;
+        }
+        iCharFormatLayer = charFormatLayer;
+    }
+    else
+    {
+        CCharFormatLayer* charFormatLayer = CCharFormatLayer::NewL(charFormat, charMask);
+        // SetCharFormatLayer is for EText and RichText
+        iEditor->SetCharFormatLayer(charFormatLayer);
+    }
+}
+
+// ---------------------------------------------------------------------------
+// CSwtTextBase::SetBackgroundL
+// ---------------------------------------------------------------------------
+//
+void CSwtTextBase::SetBackgroundL(const MSwtColor* aColor)
+{
+    ASwtControlBase::DoSetBackgroundL(aColor);
+    TRgb color(aColor ? aColor->RgbValue() :
+               iDisplay.CoeEnv()->Color(EColorControlBackground));
+    if (iEditor)
+    {
+        // Outside text view
+        iEditor->SetBackgroundColorL(color);
+
+        // Inside text view, outside paragraphs
+        iEditor->TextView()->SetBackgroundColor(color);
+
+        // Inside paragraphs
+        CParaFormat* paraFormat = new(ELeave) CParaFormat();
+        CleanupStack::PushL(paraFormat);
+        paraFormat->iFillColor = color;
+        TParaFormatMask paraMask;
+        paraMask.SetAttrib(EAttFillColor);
+        static_cast<CGlobalText*>(iEditor->Text())->ApplyParaFormatL(
+            paraFormat, paraMask, 0, iEditor->TextLength());
+        CleanupStack::PopAndDestroy(paraFormat);
+    }
+    Redraw();
+}
+
+// ---------------------------------------------------------------------------
+// CSwtTextBase::SetForegroundL
+// ---------------------------------------------------------------------------
+//
+void CSwtTextBase::SetForegroundL(const MSwtColor* aColor)
+{
+    ASwtControlBase::DoSetForegroundL(aColor);
+
+    iTextColor = ETrue;
+    if (!aColor)
+    {
+        iTextColor = EFalse;
+    }
+    else if (iEditor)
+    {
+        TCharFormat charFormat;
+        TCharFormatMask charMask;
+        charFormat.iFontPresentation.iTextColor = aColor->RgbValue();
+        charMask.SetAttrib(EAttColor);
+        static_cast<CGlobalText*>(iEditor->Text())->
+        ApplyCharFormatL(charFormat, charMask, 0, iEditor->TextLength());
+    }
+
+    UpdateTextColor();
+    Redraw();
+}
+
+void CSwtTextBase::SetBounds(const TRect& aRect)
+{
+    // Divert the job to UiUtils if this is an editor open for split view editing.
+    MSwtUiUtils& utils = iDisplay.UiUtils();
+    if (utils.SplitInputView() == this)
+    {
+        utils.SetSplitInputViewSize(aRect.Size());
+        SetLocation(aRect.iTl);
+    }
+    else
+    {
+        ASwtScrollableBase::SetBounds(aRect);
+    }
+}
+
+void CSwtTextBase::SetWidgetSize(const TSize& aSize)
+{
+    // Divert the job to UiUtils if this is an editor open for split view editing.
+    MSwtUiUtils& utils = iDisplay.UiUtils();
+    if (utils.SplitInputView() == this)
+    {
+        utils.SetSplitInputViewSize(aSize);
+    }
+    else
+    {
+        ASwtScrollableBase::SetWidgetSize(aSize);
+    }
+}
+
+TSwtPeer CSwtTextBase::Dispose()
+{
+    // Close VKB.
+    if (iEditor->IsFocused())
+    {
+        CCoeFep* fep = iDisplay.CoeEnv()->Fep();
+        if (fep)
+        {
+            fep->HandleDestructionOfFocusedItem();
+        }
+    }
+    return ASwtScrollableBase::Dispose();
+}
+
+TInt CSwtTextBase::PressBackgroundPolicy() const
+{
+    return EPressBackground;
+}
+
+void CSwtTextBase::UpdateTextColor()
+{
+    if (iEditor)
+    {
+        TCharFormat charFormat;
+        TCharFormatMask charMask;
+        TRgb color(0);
+        TInt err(KErrNone);
+
+        if (HasHighlight())
+        {
+            // Highlighted foreground color, overrides all others.
+            err = AknsUtils::GetCachedColor(AknsUtils::SkinInstance()
+                                            , color
+                                            , KAknsIIDQsnTextColors
+                                            , KHighlightedTextColor);
+            if (err == KErrNone)
+            {
+                charFormat.iFontPresentation.iTextColor = color;
+            }
+        }
+        else if (iTextColor)
+        {
+            // Custom foreground color, overrides the default.
+            charFormat.iFontPresentation.iTextColor = GetForeground();
+        }
+        else
+        {
+            // Default foreground color.
+            err = AknsUtils::GetCachedColor(AknsUtils::SkinInstance()
+                                            , color
+                                            , KAknsIIDQsnTextColors
+                                            , KNonHighlightedTextColor);
+            if (err == KErrNone)
+            {
+                charFormat.iFontPresentation.iTextColor = color;
+            }
+        }
+
+        charMask.SetAttrib(EAttColor);
+        TRAP_IGNORE(static_cast<CGlobalText*>(iEditor->Text())->
+                    ApplyCharFormatL(charFormat, charMask, 0, iEditor->TextLength()));
+    }
+}
+
+void CSwtTextBase::HandleHighlightChange()
+{
+    UpdateTextColor();
+}
+
+// ---------------------------------------------------------------------------
+// CSwtTextBase::ComputeDelta
+// ---------------------------------------------------------------------------
+//
+TSize CSwtTextBase::ComputeDelta() const
+{
+    ASSERT(iEditor);
+
+    // Retrieve the various margins & borders
+    TInt labels = 0;
+    TInt cursor = 0;
+    iEditor->TextView()->MarginWidths(labels, cursor);
+    const TSize borderDelta(iEditor->Border().SizeDelta());
+    const TSize marginDelta(iEditor->Margins().SizeDelta());
+    const TSize ownBorderDelta(BorderSizeDelta());
+
+    // The scrollbars
+    const TSize sbDelta(SbOuterRect(TRect()).Size());
+
+    // Add them all up
+    // Note that marginDelta.iWidth is counted twice because CEikEdwin also
+    // counts it twice ( in LayoutWidth(), margins are substracted from
+    // ViewRect().Width() whereas this is already done when computing
+    // ViewRect().Width() ). So this is a workaround to avoid unwanted
+    // wrapping because of this defect in CEikEdwin.
+    TSize totalDelta(ownBorderDelta.iWidth + borderDelta.iWidth
+                     + 2 * marginDelta.iWidth  + sbDelta.iWidth
+                     + labels + cursor + KEikDefaultCursorWidth,
+                     ownBorderDelta.iHeight + borderDelta.iHeight
+                     + marginDelta.iHeight + sbDelta.iHeight);
+    if (iIndicator)
+    {
+        totalDelta.iHeight += KSWTEditIndicatorHeight;
+    }
+    return totalDelta;
+}
+
+// ---------------------------------------------------------------------------
+// CSwtTextBase::HotKeyL
+// ---------------------------------------------------------------------------
+//
+TInt CSwtTextBase::HotKeyL(const TKeyEvent& aKeyEvent) const
+{
+    ASSERT(iEditor);
+
+    if (!(aKeyEvent.iModifiers & EModifierCtrl)
+            || (aKeyEvent.iCode >= 100)
+            || (aKeyEvent.iCode == ' '))
+    {
+        return -1;
+    }
+
+    HBufC* hkBuf;
+    if (aKeyEvent.iModifiers & EModifierShift)
+    {
+        hkBuf = iCoeEnv->AllocReadResourceL(R_EIK_EDWIN_SHIFT_CTRL_HOTKEYS);
+    }
+    else
+    {
+        hkBuf = iCoeEnv->AllocReadResourceL(R_EIK_EDWIN_CTRL_HOTKEYS);
+    }
+    TInt hotkey = hkBuf->Locate(TChar(aKeyEvent.iCode + 'a' - 1));
+    delete hkBuf;
+    return hotkey;
+}
+
+// ---------------------------------------------------------------------------
+// CSwtTextBase::SetEditable
+// ---------------------------------------------------------------------------
+//
+void CSwtTextBase::SetEditable(TBool aEditable)
+{
+    // Update the style accordingly
+    if (aEditable)
+    {
+        iStyle &= ~KSwtStyleReadOnly;
+    }
+    else
+    {
+        iStyle |= KSwtStyleReadOnly;
+    }
+
+    iEditor->SetReadOnly(!aEditable);
+    iEditor->SetFocus(IsFocused());
+}
+
+// ---------------------------------------------------------------------------
+// CSwtTextBase::SetTextL
+// ---------------------------------------------------------------------------
+//
+TBool CSwtTextBase::SetTextL(const TDesC& aText)
+{
+    // This must be called before querying the length or selection as it can
+    // remove the char that is just being typed.
+    iEditor->CancelFepTransaction();
+
+    // Get the remaining editing space available in editor if text limit set,
+    // and return if no available space.
+    TInt editorTextLen = iEditor->TextLength();
+    TInt availableLen = KErrNotFound;
+    if (iTextLimit)
+    {
+        ASSERT(editorTextLen <= iTextLimit);
+        availableLen = iTextLimit;
+        if (availableLen <= 0)
+        {
+            return EFalse;
+        }
+    }
+
+
+    // Clear selection if any
+    iEditor->ClearSelectionL();
+
+    // If a text limit is set, append as much as the available space permits,
+    // otherwise append the entire text.
+    TInt textToInsertLen = aText.Length();
+    if (availableLen != KErrNotFound
+            && textToInsertLen > availableLen)
+    {
+        TPtrC des = aText.Left(availableLen);
+        iEditor->SetTextL(&des);
+    }
+    else
+    {
+        iEditor->SetTextL(&aText);
+    }
+    iEditor->HandleTextChangedL();
+
+
+    // Restore carret
+    iEditor->SetSelectionL(0, 0);
+
+    /* Workaround for junit tests. Copy and paste functions crash, when
+     * Text is not visible. There is some optimalization in CEikEdwin,
+     * that updates selection (and cursos position) after Text is drawn.
+     */
+    iEditor->TextView()->SetSelectionL(TCursorSelection(0, 0));
+
+    return ETrue;
+}
+
+// ---------------------------------------------------------------------------
+// CSwtTextBase::AppendL
+// ---------------------------------------------------------------------------
+//
+TBool CSwtTextBase::AppendL(const TDesC& aText)
+{
+    ASSERT(iEditor);
+
+    // This must be called before querying the length or selection as it can
+    // remove the char that is just being typed.
+    iEditor->CancelFepTransaction();
+
+    // Get the remaining editing space available in editor if text limit set,
+    // and return if no available space.
+    TInt textToInsertLen = aText.Length();
+    TInt editorTextLen = iEditor->TextLength();
+    TInt availableLen = KErrNotFound;
+    if (iTextLimit)
+    {
+        ASSERT(editorTextLen <= iTextLimit);
+        availableLen = iTextLimit - editorTextLen;
+        if (availableLen <= 0)
+        {
+            return EFalse;
+        }
+    }
+
+    // Clear selection if any
+    iEditor->ClearSelectionL();
+
+    // If a text limit is set, append as much as the available space permits,
+    // otherwise append the entire text.
+    CPlainText* plainText = iEditor->Text();
+    if (availableLen != KErrNotFound
+            && textToInsertLen > availableLen)
+    {
+        plainText->InsertL(editorTextLen, aText.Left(availableLen));
+    }
+    else
+    {
+        plainText->InsertL(editorTextLen, aText);
+    }
+    iEditor->HandleTextChangedL();
+
+    // Restore carret
+    editorTextLen = iEditor->TextLength();
+    iEditor->SetSelectionL(editorTextLen, editorTextLen);
+
+    return ETrue;
+}
+
+// ---------------------------------------------------------------------------
+// CSwtTextBase::InsertL
+// ---------------------------------------------------------------------------
+//
+TBool CSwtTextBase::InsertL(const TDesC& aText)
+{
+    ASSERT(iEditor);
+
+    // This must be called before querying the length or selection as it can
+    // remove the char that is just being typed.
+    iEditor->CancelFepTransaction();
+
+    const TCursorSelection selection(iEditor->Selection());
+    const TInt selStart = selection.LowerPos();
+    TInt textToInsertLen = aText.Length();
+
+    // Return if there is nothing to delete
+    if (textToInsertLen == 0 && selection.Length() == 0)
+    {
+        return EFalse;
+    }
+
+    iEditor->ClearSelectionL();
+    // Update selection to be sure selection is valid after text removal
+    iEditor->SetSelectionL(selStart, selStart);
+    iEditor->TextView()->SetSelectionL(TCursorSelection(selStart, selStart));
+
+    // Remove selected text
+    CPlainText* plainText = iEditor->Text();
+    plainText->DeleteL(selStart, selection.Length());
+
+    // Get the remaining editing space available in editor if text limit set,
+    // and return if no available space.
+    TInt editorTextLen = iEditor->TextLength();
+    TInt availableLen = KErrNotFound;
+    if (iTextLimit)
+    {
+        ASSERT(editorTextLen <= iTextLimit);
+        availableLen = iTextLimit - editorTextLen;
+        if (availableLen <= 0)
+        {
+            return EFalse;
+        }
+    }
+
+    // If a text limit is set, append as much as the available space permits,
+    // otherwise insert the entire text.
+    if (availableLen != KErrNotFound
+            && textToInsertLen > availableLen)
+    {
+        plainText->InsertL(selStart, aText.Left(availableLen));
+        textToInsertLen = availableLen;
+    }
+    else
+    {
+        plainText->InsertL(selStart, aText);
+    }
+
+    iEditor->HandleTextChangedL();
+
+    // Restore carret
+    TInt newCaretPos = Min(selStart + textToInsertLen,
+                           iEditor->TextLength());
+    iEditor->SetSelectionL(newCaretPos, newCaretPos);
+
+    return ETrue;
+}
+
+// ---------------------------------------------------------------------------
+// CSwtTextBase::CutL
+// ---------------------------------------------------------------------------
+//
+TBool CSwtTextBase::CutL()
+{
+    ASSERT(iEditor);
+
+    if (iEditor->Selection().Length() == 0)
+    {
+        return EFalse;
+    }
+    iEditor->ClipboardL(CEikEdwin::ECut);
+    return ETrue;
+}
+
+// ---------------------------------------------------------------------------
+// CSwtTextBase::SetLimit
+// ---------------------------------------------------------------------------
+//
+TBool CSwtTextBase::SetLimitL(TInt aLimit)
+{
+    ASSERT(iEditor);
+    ASSERT(aLimit);
+
+    const TCursorSelection selection(iEditor->Selection());
+    const TInt selStart = selection.LowerPos();
+
+    // This should be enough but it's not.
+    // iEditor->SetTextLimit( aLimit );
+    iTextLimit = aLimit;
+
+    // Clear selection.
+    iEditor->ClearSelectionL();
+
+    // Ensure that the editor's text is not longer than the limit just set.
+    TInt editorTextLen = iEditor->TextLength();
+    if (editorTextLen > iTextLimit)
+    {
+        CPlainText* plainText = iEditor->Text();
+        plainText->DeleteL(iTextLimit, editorTextLen - iTextLimit);
+        iEditor->HandleTextChangedL();
+    }
+    iEditor->SetTextLimit(aLimit);
+    // Not allowed to have failed here.
+    editorTextLen = iEditor->TextLength();
+    ASSERT(editorTextLen <= iTextLimit);
+
+    // Ensure cursor is at the most at the end of the new text.
+    if (selStart > editorTextLen)
+    {
+        iEditor->SetSelectionL(editorTextLen, editorTextLen);
+    }
+
+    return ETrue;
+}
+
+// ---------------------------------------------------------------------------
+// CSwtTextBase::ForwardKeyEventL
+// NOTE: FEP may deliver the key events directly to CEikEdwin!
+// ---------------------------------------------------------------------------
+//
+void CSwtTextBase::ForwardKeyEventL(
+    const TKeyEvent& aKeyEvent, TEventCode aType)
+{
+    ASSERT(iEditor);
+    TInt cursorPos = Editor().TextView()->Selection().iCursorPos;
+    TInt textLen = Editor().TextLength();
+
+    iEditor->OfferKeyEventL(aKeyEvent, aType);
+
+    // This is called, because when FepManager is notified first time,
+    // there are no changes in editor yet. Editor is updated later,
+    // after verification on java side. So now FepManager must be notified
+    // again to get a right information about changes.
+    iDisplay.CoeEnv()->InputCapabilitiesChanged();
+
+    // CEikEdwin doesn't loop when cursor is end or begining of Text
+    //if edwin is readonly. this is workaround to fix.
+    if ((iStyle & KSwtStyleReadOnly))
+    {
+        switch (aKeyEvent.iCode)
+        {
+        case EKeyLeftArrow:
+            if (!(aKeyEvent.iModifiers & EModifierShift)
+                    && (cursorPos == 0))
+            {
+                Editor().SetSelectionL(textLen , textLen);
+            }
+            break;
+
+        case EKeyRightArrow:
+            if (!(aKeyEvent.iModifiers & EModifierShift)
+                    && (cursorPos == textLen))
+            {
+                Editor().SetSelectionL(0, 0);
+            }
+            break;
+
+        default:
+            break;
+        }
+    }
+}
+
+// ---------------------------------------------------------------------------
+// CSwtTextBase::CountComponentControls
+// From CCoeControl
+// ---------------------------------------------------------------------------
+//
+TInt CSwtTextBase::CountComponentControls() const
+{
+    TInt componentCount = 0;
+    if (iEditor)
+    {
+        componentCount++;
+        if (iIndicator)
+        {
+            componentCount++;
+        }
+    }
+    return componentCount;
+}
+
+// ---------------------------------------------------------------------------
+// CSwtTextBase::ComponentControl
+// From CCoeControl
+// ---------------------------------------------------------------------------
+//
+CCoeControl* CSwtTextBase::ComponentControl(TInt aIndex) const
+{
+    ASSERT(iEditor);
+    if (aIndex == 1 && iIndicator)
+    {
+        return iIndicator->IndicatorContainer();
+    }
+    return iEditor;
+}
+
+// ---------------------------------------------------------------------------
+// CSwtTextBase::MakeVisible
+// From CCoeControl
+// ---------------------------------------------------------------------------
+//
+void CSwtTextBase::MakeVisible(TBool aVisible)
+{
+    const TBool oldVisibility = IsVisible();
+    if ((aVisible && oldVisibility) || (!aVisible && !oldVisibility))
+    {
+        return;
+    }
+
+    // Close VKB. Do it here instead of FocusChange to avoid split input flicker.
+    if (iEditor->IsFocused() && !aVisible)
+    {
+        CCoeFep* fep = iDisplay.CoeEnv()->Fep();
+        if (fep)
+        {
+            fep->HandleDestructionOfFocusedItem();
+        }
+    }
+
+    CCoeControl::MakeVisible(aVisible);
+    if (iEditor)
+    {
+        iEditor->MakeVisible(aVisible);
+
+        // Forward the new visibility to the scroll-bars
+        CEikScrollBarFrame* sbFrame = iEditor->ScrollBarFrame();
+        if (sbFrame)
+        {
+            //Update scrollbars
+            TRAP_IGNORE(iEditor->UpdateScrollBarsL());
+            const TInt count = sbFrame->CountComponentControls();
+            for (TInt i = 0; i < count; ++i)
+            {
+                sbFrame->ComponentControl(i)->MakeVisible(aVisible);
+            }
+        }
+    }
+
+    FocusabilityChanged();
+}
+
+// ---------------------------------------------------------------------------
+// CSwtTextBase::SetDimmed
+// From CCoeControl
+// ---------------------------------------------------------------------------
+//
+void CSwtTextBase::SetDimmed(TBool aDimmed)
+{
+    // Close VKB. Do it here instead of FocusChange to avoid split input flicker.
+    if (iEditor->IsFocused() && aDimmed)
+    {
+        CCoeFep* fep = iDisplay.CoeEnv()->Fep();
+        if (fep)
+        {
+            fep->HandleDestructionOfFocusedItem();
+        }
+    }
+
+    CCoeControl::SetDimmed(aDimmed);
+    if (iEditor)
+    {
+        iEditor->SetDimmed(aDimmed);
+    }
+    FocusabilityChanged();
+}
+
+// ---------------------------------------------------------------------------
+// CSwtTextBase::HandleResourceChange
+// From CCoeControl
+// ---------------------------------------------------------------------------
+//
+void CSwtTextBase::HandleResourceChange(TInt aType)
+{
+    TRAP_IGNORE(SwtHandleResourceChangeL(aType));
+}
+
+// ---------------------------------------------------------------------------
+// CSwtTextBase::SwtHandleResourceChangeL
+// ---------------------------------------------------------------------------
+//
+void CSwtTextBase::SwtHandleResourceChangeL(TInt aType)
+{
+    CCoeControl::HandleResourceChange(aType);
+
+    if (aType == KAknsMessageSkinChange || aType == KEikDynamicLayoutVariantSwitch)
+    {
+        // The highlight color will be updated from ProcessFontUpdateL()
+
+        if (!iFont)
+        {
+            RetrieveDefaultFontL(); // ProcessFontUpdateL() will get called also.
+        }
+        else
+        {
+            ProcessFontUpdateL();
+        }
+    }
+#ifdef RD_JAVA_S60_RELEASE_9_2
+    else if (aType == KAknSplitInputEnabled)
+    {
+        const MSwtShell* activeShell = iDisplay.UiUtils().GetActiveShell();
+        if (activeShell && activeShell->FocusControl() == this)
+        {
+            iDisplay.UiUtils().SetSplitInputEditor(this);
+        }
+    }
+#endif
+}
+
+// ---------------------------------------------------------------------------
+// CSwtTextBase::FixPadding
+// ---------------------------------------------------------------------------
+//
+void CSwtTextBase::FixPadding()
+{
+    Editor().SetBorderViewMargins(iDisplay.UiUtils().InlineReferencePadding());
+}
+
+// ---------------------------------------------------------------------------
+// CSwtTextBase::HandlePointerEventL
+// From CCoeControl
+// ---------------------------------------------------------------------------
+//
+#ifdef RD_SCALABLE_UI_V2
+void CSwtTextBase::HandlePointerEventL(const TPointerEvent& aPointerEvent)
+{
+    // Scrollbar tap
+    CEikScrollBarFrame* sbFrame = iEditor->ScrollBarFrame();
+    CEikScrollBar* vsb = sbFrame ? sbFrame->GetScrollBarHandle(CEikScrollBar::EVertical) : NULL;
+
+    TBool hit = ETrue;
+
+#ifdef RD_JAVA_S60_RELEASE_9_2
+    TBool isActiveSplitEditor = iDisplay.UiUtils().SplitInputEditor() == this;
+    hit = Rect().Contains(aPointerEvent.iPosition);
+    TBool pressed = iPressed;
+#endif
+
+    // Check if we should start scrollbar grabbing
+    if (aPointerEvent.iType == TPointerEvent::EButton1Down)
+    {
+        if (vsb && vsb->Rect().Contains(aPointerEvent.iPosition))
+        {
+            iVScrollBarGrabsPointerEvents = ETrue;
+        }
+#ifdef RD_JAVA_S60_RELEASE_9_2
+        else
+        {
+            iPressed = !isActiveSplitEditor;
+        }
+#endif
+    }
+
+    // Deliver event to scrollbar
+    if (iVScrollBarGrabsPointerEvents && vsb)
+    {
+        vsb->HandlePointerEventL(aPointerEvent);
+    }
+
+    TBool forward(EFalse);
+    TPointerEvent pointerEvent(aPointerEvent);
+
+    // Edwin tap. Button1Up after the long tap is not forwarded to the editor
+    if (!(aPointerEvent.iType == TPointerEvent::EButton1Up
+            && (iDisplay.RevertPointerEvent() || !hit))
+            && !iVScrollBarGrabsPointerEvents
+            && !iIgnorePointerDown)
+    {
+        // If clicking on margins, move the pointer event.
+        TRect viewRect(iEditor->TextView()->ViewRect());
+        TRect viewRectWithoutMargins(viewRect);
+        viewRectWithoutMargins.Shrink(2, 2);    // well inside the edges
+
+        // EButtonRepeat and EDrag events should not be moved to viewRect
+        // This enables to scroll text, when dragging outside of the text
+        const TBool moveEventToViewRect =
+            aPointerEvent.iType != TPointerEvent::EButtonRepeat
+            && aPointerEvent.iType != TPointerEvent::EDrag;
+
+        // Checking if event is in area between margins and borders
+        // When so then moving event to the rect without margins
+        if (moveEventToViewRect ||
+                (viewRect.Contains(aPointerEvent.iPosition) &&
+                 !viewRectWithoutMargins.Contains(aPointerEvent.iPosition)))
+        {
+            if (pointerEvent.iPosition.iX < viewRectWithoutMargins.iTl.iX)
+            {
+                pointerEvent.iPosition.iX = viewRectWithoutMargins.iTl.iX;
+            }
+            if (pointerEvent.iPosition.iY < viewRectWithoutMargins.iTl.iY)
+            {
+                pointerEvent.iPosition.iY = viewRectWithoutMargins.iTl.iY;
+            }
+            if (pointerEvent.iPosition.iX > viewRectWithoutMargins.iBr.iX)
+            {
+                pointerEvent.iPosition.iX = viewRectWithoutMargins.iBr.iX;
+            }
+            if (pointerEvent.iPosition.iY > viewRectWithoutMargins.iBr.iY)
+            {
+                pointerEvent.iPosition.iY = viewRectWithoutMargins.iBr.iY;
+            }
+        }
+
+        forward = ETrue;
+    }
+
+    // Stop scrollbar grabbing
+    if (aPointerEvent.iType == TPointerEvent::EButton1Up)
+    {
+        iVScrollBarGrabsPointerEvents = EFalse;
+#ifdef RD_JAVA_S60_RELEASE_9_2
+        iPressed = EFalse;
+#endif
+    }
+#ifdef RD_JAVA_S60_RELEASE_9_2
+    else if (aPointerEvent.iType == TPointerEvent::EDrag)
+    {
+        iPressed = hit && !iVScrollBarGrabsPointerEvents && !isActiveSplitEditor;
+    }
+
+    if (pressed != iPressed)
+    {
+        GetShell().UpdateHighlight(ETrue); // draw now
+    }
+#endif
+
+#ifndef RD_JAVA_S60_RELEASE_9_2
+    // We got a pointer event, so any subsequent events should not be ignored.
+    iIgnorePointerDown = EFalse;
+#endif // RD_JAVA_S60_RELEASE_9_2
+
+    // Forwarding this late due to splitview + pressed flicker issues.
+    if (forward)
+    {
+        iEditor->HandlePointerEventL(pointerEvent);
+    }
+
+    PostMouseEventL(aPointerEvent);
+}
+#else //RD_SCALABLE_UI_V2
+void CSwtTextBase::HandlePointerEventL(
+    const TPointerEvent& /*aPointerEvent*/)
+{
+}
+#endif //RD_SCALABLE_UI_V2
+
+// ---------------------------------------------------------------------------
+// CSwtTextBase::FocusChanged
+// From CCoeControl
+// ---------------------------------------------------------------------------
+//
+void CSwtTextBase::FocusChanged(TDrawNow aDrawNow)
+{
+    if (iEditor)
+    {
+        TRAP_IGNORE(iEditor->UpdateScrollBarsL());
+    }
+
+    if (iEditor)
+    {
+        if (iIndicator)
+        {
+            if (!IsFocused())
+                iIndicator->SetState(EStateNone);
+        }
+
+        iEditor->SetFocus(IsFocused());
+    }
+
+    HandleFocusChanged(aDrawNow);
+}
+
+// ---------------------------------------------------------------------------
+// CSwtTextBase::PositionChanged
+// From CCoeControl
+// ---------------------------------------------------------------------------
+//
+void CSwtTextBase::PositionChanged()
+{
+    if (!iEditor)
+    {
+        return;
+    }
+
+    // The size of scrollbars are set to ( 0,0 )
+    // to be correctly updated in editor.
+    CEikScrollBarFrame* sbFrame = SbFrame();
+    if (sbFrame)
+    {
+        CEikScrollBar* verticalScrollBar = sbFrame->
+                                           GetScrollBarHandle(CEikScrollBar::EVertical);
+        if (verticalScrollBar)
+        {
+            verticalScrollBar->SetSize(TSize(0, 0));
+        }
+        CEikScrollBar* horizScrollBar = sbFrame->
+                                        GetScrollBarHandle(CEikScrollBar::EHorizontal);
+        if (horizScrollBar)
+        {
+            horizScrollBar->SetSize(TSize(0, 0));
+        }
+    }
+
+    //Position indicator
+    TRect editorRect(SbInnerRect(BorderInnerRect()));
+
+    if (iIndicator)
+    {
+        const TPoint indPos(iPosition.iX + GetBorderWidth(),
+                            iPosition.iY + GetBorderWidth());
+        iIndicator->IndicatorContainer()->SetPosition(indPos);
+        editorRect.SetRect(TPoint(editorRect.iTl.iX,
+                                  indPos.iY + KSWTEditIndicatorHeight), editorRect.iBr);
+    }
+
+    // We have to call CEikEdwin::SetRect() to update the location
+    // of the editor member on the screen.
+    if (AknLayoutUtils::LayoutMirrored())
+    {
+        iEditor->SetAlignment(EAknEditorAlignRight);
+        const TSize sbDelta(SbOuterRect(TRect()).Size());
+        editorRect.iTl.iX += sbDelta.iWidth;
+    }
+
+    iEditor->SetRect(editorRect);
+    HandlePositionChanged();
+
+    // Notify change to UiUtils if this is an editor open for split view editing.
+    MSwtUiUtils& utils = iDisplay.UiUtils();
+    if (utils.SplitInputView() == this)
+    {
+        utils.AdjustSplitInputShellPos();
+    }
+}
+
+// ---------------------------------------------------------------------------
+// CSwtTextBase::SizeChanged
+// From CCoeControl
+// ---------------------------------------------------------------------------
+//
+void CSwtTextBase::SizeChanged()
+{
+    if (!iEditor)
+    {
+        return;
+    }
+    const TSize sbDelta(SbOuterRect(TRect()).Size());
+    const TSize ownBorderDelta(BorderSizeDelta());
+    if (AknLayoutUtils::LayoutMirrored())
+    {
+        iEditor->SetAlignment(EAknEditorAlignRight);
+    }
+    if (iIndicator)
+    {
+        const TSize indicatorSize(
+            BorderInnerRect().Size().iWidth,
+            KSWTEditIndicatorHeight);
+        iIndicator->IndicatorContainer()->SetSize(indicatorSize);
+        TSize editorSize = iSize - sbDelta - ownBorderDelta;
+        editorSize.iHeight -= indicatorSize.iHeight;
+        iEditor->SetSize(editorSize);
+    }
+    else
+    {
+        iEditor->SetSize(iSize - sbDelta - ownBorderDelta);
+    }
+
+    if (HasBorderStyle())
+    {
+        iEditor->SetPosition(BorderInnerRect().iTl);
+    }
+
+    HandleSizeChanged();
+}
+
+// ---------------------------------------------------------------------------
+// CSwtTextBase::MopSupplyObject
+// From CCoeControl
+// ---------------------------------------------------------------------------
+//
+TTypeUid::Ptr CSwtTextBase::MopSupplyObject(TTypeUid aId)
+{
+    if (iIndicator && aId.iUid == MAknEditingStateIndicator::ETypeId)
+    {
+        return aId.MakePtr(static_cast<MAknEditingStateIndicator*>(iIndicator));
+    }
+    TTypeUid::Ptr id = ASwtControlBase::SwtMopSupplyObject(aId);
+
+    if (id.Pointer() == NULL)
+    {
+        return CCoeControl::MopSupplyObject(aId);
+    }
+    else
+    {
+        return id;
+    }
+}
+
+// ---------------------------------------------------------------------------
+// CSwtTextBase::CoeControl
+// From MSwtControl
+// ---------------------------------------------------------------------------
+//
+CCoeControl& CSwtTextBase::CoeControl()
+{
+    return *this;
+}
+
+// ---------------------------------------------------------------------------
+// CSwtTextBase::CoeControl
+// From MSwtControl
+// ---------------------------------------------------------------------------
+//
+const CCoeControl& CSwtTextBase::CoeControl() const
+{
+    return *this;
+}
+
+// ---------------------------------------------------------------------------
+// CSwtTextBase::SetSwtFocus
+// From MSwtControl
+// ---------------------------------------------------------------------------
+//
+TBool CSwtTextBase::SetSwtFocus(TInt aReason /*=KSwtFocusByApi*/)
+{
+#ifndef RD_JAVA_S60_RELEASE_9_2
+    iIgnorePointerDown = EFalse;
+    if (IsFocusControl())
+    {
+        return ETrue;
+    }
+    iIgnorePointerDown = aReason == KSwtFocusByPointer;
+#endif // RD_JAVA_S60_RELEASE_9_2
+    return ASwtControlBase::SetSwtFocus(aReason);
+}
+
+// ---------------------------------------------------------------------------
+// CSwtTextBase::ClientRect
+// From MSwtControl
+// ---------------------------------------------------------------------------
+//
+TRect CSwtTextBase::ClientRect() const
+{
+    TRect rect(ASwtScrollableBase::ClientRect());
+    if (iIndicator)
+    {
+        rect.iTl.iY = iIndicator->IndicatorContainer()->Rect().iBr.iY;
+    }
+    return rect;
+}
+
+// ---------------------------------------------------------------------------
+// CSwtTextBase::SetFontL
+// From MSwtControl
+// ---------------------------------------------------------------------------
+//
+void CSwtTextBase::SetFontL(const MSwtFont* aFont)
+{
+    ASwtControlBase::DoSetFontL(aFont);
+
+    // Set the font in the edwin
+    if (iEditor)
+    {
+        ProcessFontUpdateL();
+        iEditor->HandleTextChangedL();
+    }
+
+    Redraw();
+}
+
+// ---------------------------------------------------------------------------
+// CSwtTextBase::ComputeSizeL
+// From MSwtControl
+// ---------------------------------------------------------------------------
+//
+TSize CSwtTextBase::ComputeSizeL(TInt aWHint, TInt aHHint)
+{
+    if (!iEditor)
+    {
+        // iEditor could be null if the CSwtTextBase is contained in a
+        // CaptionedControl.
+        return TSize(0, 0);
+    }
+
+    if (aWHint != KSwtDefault && aHHint != KSwtDefault)
+    {
+        return TSize(aWHint, aHHint);
+    }
+
+    const TSize delta(ComputeDelta());
+    const TInt maxWidth = KMaxTInt - delta.iWidth;
+
+    TSize prefSize(TSize::EUninitialized);
+
+    CTextView*   textView = iEditor->TextView();
+    CTextLayout* layout   = const_cast<CTextLayout*>(textView->Layout());
+
+    if (aWHint == KSwtDefault)
+    {
+        layout->SetWrapWidth(maxWidth);
+    }
+    else
+    {
+        layout->SetWrapWidth(aWHint);
+    }
+
+    TViewYPosQualifier yPosQualifier;
+    yPosQualifier.SetFillScreen();
+    yPosQualifier.SetMakeLineFullyVisible();
+    textView->HandleGlobalChangeNoRedrawL(yPosQualifier);
+    TInt formatedHeight = layout->FormattedHeightInPixels();
+
+    // if width is free, no effect for wraping. that is swt implementation
+    if (aWHint == KSwtDefault)
+    {
+        layout->GetMinimumSizeL(maxWidth, prefSize);
+    }
+    else
+    {
+        // if width is fixed, height is free
+        // if wrapping is on, the Height should be heights of all lines that all
+        // characters fit in vertically ( note: VSrolling shouldn't be there )
+        // if wrap is off, the Height should be heights of all lines and
+        // HScrolling if any of  the line width is bigger than given width
+        layout->GetMinimumSizeL(aWHint, prefSize);
+        prefSize.iHeight = formatedHeight;
+    }
+
+    prefSize += delta;
+
+    if (aWHint != KSwtDefault)
+    {
+        prefSize.iWidth = aWHint;
+    }
+    if (aHHint != KSwtDefault)
+    {
+        prefSize.iHeight = aHHint;
+    }
+
+    return prefSize;
+}
+
+// ---------------------------------------------------------------------------
+// CSwtTextBase::IsKeyUsed
+// From MSwtControl
+// ---------------------------------------------------------------------------
+//
+TBool CSwtTextBase::IsKeyUsed(TUint aKeyCode) const
+{
+    // A text uses the Backspace and OK keys
+    if (aKeyCode == EKeyBackspace)
+    {
+        return ETrue;
+    }
+    else if (aKeyCode == EKeyOK)
+    {
+        return EFalse;
+    }
+    return ETrue;
+}
+
+// ---------------------------------------------------------------------------
+// CSwtTextBase::CanDrawOutsideRect
+// Needed for drawing the scrollbars in multi line texts!
+// From MSwtControl
+// ---------------------------------------------------------------------------
+//
+TBool CSwtTextBase::CanDrawOutsideRect() const
+{
+    return ETrue;
+}
+
+// ---------------------------------------------------------------------------
+// CSwtTextBase::DefaultFont
+// From ASwtControlBase
+// ---------------------------------------------------------------------------
+//
+const MSwtFont& CSwtTextBase::DefaultFont() const
+{
+    ASSERT(iDefaultFont);
+    return *iDefaultFont;
+
+}
+
+// ---------------------------------------------------------------------------
+// CSwtTextBase::SbFrame
+// From ASwtScrollableBase
+// ---------------------------------------------------------------------------
+//
+CEikScrollBarFrame* CSwtTextBase::SbFrame() const
+{
+    return (iEditor!=NULL) ? iEditor->ScrollBarFrame() : NULL;
+}
+
+// ---------------------------------------------------------------------------
+// CSwtListBase::HandleScrollEventL
+// From MEikScrollBarObserver
+// ---------------------------------------------------------------------------
+//
+#ifdef RD_SCALABLE_UI_V2
+void CSwtTextBase::HandleScrollEventL(
+    CEikScrollBar* aScrollBar,
+    TEikScrollEvent aEventType)
+{
+    iEditor->HandleScrollEventL(aScrollBar, aEventType);
+    ASwtScrollableBase::HandleScrollEventL(aScrollBar, aEventType);
+}
+#else //RD_SCALABLE_UI_V2
+void CSwtTextBase::HandleScrollEventL(
+    CEikScrollBar*,
+    TEikScrollEvent)
+{
+}
+#endif //RD_SCALABLE_UI_V2