javauis/eswt_akn/org.eclipse.ercp.swt.s60/native/src/swttext.cpp
branchRCL_3
changeset 26 2455ef1f5bbc
child 27 d5e927d5853b
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/javauis/eswt_akn/org.eclipse.ercp.swt.s60/native/src/swttext.cpp	Wed Sep 01 12:33:18 2010 +0100
@@ -0,0 +1,1735 @@
+/*******************************************************************************
+ * 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 <EIKCOCTL.rsg>
+#include <AknUtils.h>
+#include <eikedwin.h>
+#include <AknNumEdwin.h>
+#include <eikfpne.h>
+#include "swttext.h"
+#include "swtcontrolhelper.h"
+#include "swtscrollbar.h"
+#include "swtedwin.h"
+
+#ifdef SYMBIAN_ENABLE_SPLIT_HEADERS
+#include <tagma_internal.h>
+#endif
+
+static const TText KDefaultSecretChar = '*';
+
+#define KInputModesRequiringFeedbackWithSingleChar (EAknEditorTextInputMode | EAknEditorKatakanaInputMode | EAknEditorFullWidthTextInputMode | EAknEditorFullWidthKatakanaInputMode | EAknEditorHiraganaKanjiInputMode | EAknEditorHiraganaInputMode | EAknEditorHalfWidthTextInputMode)
+#define KInputModesRequiringFeedbackWithString (EAknEditorHiraganaInputMode | EAknEditorHiraganaKanjiInputMode)
+
+const TInt KPasswordCharTimeout = 700000; // 700 msecs
+
+
+// ======== MEMBER FUNCTIONS ========
+
+
+// ---------------------------------------------------------------------------
+// CSwtText::CPasswordText::CPasswordText
+// ---------------------------------------------------------------------------
+//
+inline CSwtText::CPasswordText::CPasswordText(
+    const CParaFormatLayer* aParaLayer, const CCharFormatLayer* aCharLayer,
+    CEikEdwin* aEdwin, TBool aPswdEnable)
+        : CGlobalText(aParaLayer, aCharLayer)
+        , iEchoChar(0), iEditor(aEdwin), iClearCharPos(-1), iPswdEnable(aPswdEnable)
+{
+}
+
+// ---------------------------------------------------------------------------
+// CSwtText::CPasswordText::~CPasswordText
+// ---------------------------------------------------------------------------
+//
+CSwtText::CPasswordText::~CPasswordText()
+{
+    delete iTimer;
+    delete iClearText;
+}
+
+// ---------------------------------------------------------------------------
+// CSwtText::CPasswordText::ConstructL
+// ---------------------------------------------------------------------------
+//
+inline void CSwtText::CPasswordText::ConstructL()
+{
+    CGlobalText::ConstructL(ESegmentedStorage, EDefaultTextGranularity);
+
+    iTimer = CPeriodic::NewL(CActive::EPriorityStandard);
+    iClearText = HBufC::NewL(CEditableText::EDefaultTextGranularity);
+}
+
+// ---------------------------------------------------------------------------
+// CSwtText::CPasswordText::NewL
+// ---------------------------------------------------------------------------
+//
+CSwtText::CPasswordText* CSwtText::CPasswordText::NewL(
+    const CParaFormatLayer* aParaLayer,
+    const CCharFormatLayer* aCharLayer, CEikEdwin* aEdwin, TBool aPswdEnable)
+{
+    CPasswordText* self = new(ELeave) CPasswordText(
+        aParaLayer, aCharLayer, aEdwin, aPswdEnable);
+    CleanupStack::PushL(self);
+    self->ConstructL();
+    CleanupStack::Pop(self);
+    return self;
+}
+
+
+// ---------------------------------------------------------------------------
+// CSwtText::CPasswordText::SaveClearTextL
+// We save our clear text. We reallocate if not enough memory.
+// ---------------------------------------------------------------------------
+//
+void CSwtText::CPasswordText::SaveClearTextL(TInt aPos, const TDesC& aBuf)
+{
+    ASSERT(iClearText);
+    TPtr ptr(iClearText->Des());
+
+    TInt totalLength = ptr.Length() + aBuf.Length();
+    //
+    if (totalLength > ptr.MaxLength())
+    {
+        iClearText = iClearText->ReAllocL(totalLength);
+        ptr.Set(iClearText->Des());
+    }
+
+    ptr.Insert(aPos,aBuf);
+}
+
+// ---------------------------------------------------------------------------
+// CSwtText::CPasswordText::Reset
+// ---------------------------------------------------------------------------
+//
+void CSwtText::CPasswordText::Reset()
+{
+    if (iPswdEnable)
+    {
+        if (iTimer->IsActive())
+        { //commit any previous character before deleting or else we
+            // may crash in the timer callback when trying to replace
+            // an uncommited but already deleted char
+            TRAP_IGNORE(DoTimerCallbackL(EFalse));
+        }
+    }
+    // clear local (hidden) copy
+    TPtr ptr = iClearText->Des();
+    ptr.SetLength(0);
+    CGlobalText::Reset();
+}
+
+// ---------------------------------------------------------------------------
+// CSwtText::CPasswordText::InsertL
+// Insert a single character. First we save the character in the clear text by
+// calling SaveClearTextL(). Then if the character is a paragraph delimiter
+// insert a space.Otherwise if we are in alpha mode insert the clear
+// character and start the timer. Otherwise insert the asterisks.
+// ---------------------------------------------------------------------------
+//
+void CSwtText::CPasswordText::InsertL(TInt aPos, const TChar& aChar)
+{
+    TBuf<1> buf;
+    buf.Append(aChar);
+    SaveClearTextL(aPos, buf);
+    if (iPswdEnable)
+    {
+        if (aChar == CEditableText::EParagraphDelimiter)
+        {
+            CGlobalText::InsertL(aPos, ' ');
+        }
+        else if (iEditor->AknEditorCurrentInputMode() &
+                 KInputModesRequiringFeedbackWithSingleChar)
+        {
+            if (iTimer->IsActive() && iClearCharPos != aPos)
+            { //commit any previous character in a different position
+                DoTimerCallbackL(ETrue);
+            }
+            else
+            { //or restart the timer if the char is in the same
+                //position (multi-tap looping)
+                iTimer->Cancel();
+            }
+
+            CGlobalText::InsertL(aPos, aChar);
+            iClearCharPos = aPos;
+            iTimer->Start(KPasswordCharTimeout, KPasswordCharTimeout,
+                          TCallBack(TimerCallback, this));
+        }
+        else
+        {
+            CGlobalText::InsertL(aPos, iEchoChar);
+        }
+    }
+    else
+    {
+        if (iEchoChar)
+        {
+            CGlobalText::InsertL(aPos, iEchoChar);
+        }
+        else
+        {
+            CGlobalText::InsertL(aPos, aChar);
+        }
+    }
+
+}
+
+// ---------------------------------------------------------------------------
+// CSwtText::CPasswordText::InsertL
+// Insert one or more characters. If inserting only one character rely
+// on InsertL() accepting only one char. Otherwise, save the clear text by
+// calling SaveClearTextL(). Then for every character either insert an asterisk
+// or a space if the character is a space delimiter. Note: this method is
+// called at start-up so it makes no sense to show a temporary clear character.
+// ---------------------------------------------------------------------------
+//
+void CSwtText::CPasswordText::InsertL(TInt aPos,const TDesC& aBuf)
+{
+    if (iPswdEnable)
+    {
+
+        if (aBuf.Length() == 1)
+        {
+            CSwtText::CPasswordText::InsertL(aPos, aBuf[0]);
+        }
+        else if (aBuf.Length() > 1 && (iEditor->AknEditorCurrentInputMode() &
+                                       KInputModesRequiringFeedbackWithString))
+        {
+            // When writing in kanji or hiragana input mode, the characters are
+            // entered in sequences. Insert the sequence char by char so that
+            // the user will see the last character temporarily for feedback.
+            for (TInt i = 0; i < aBuf.Length(); i++)
+            {
+                CSwtText::CPasswordText::InsertL(aPos + i, aBuf[i]);
+            }
+        }
+        else
+        {
+            SaveClearTextL(aPos, aBuf);
+
+            for (TInt i = 0; i < aBuf.Length(); i++)
+            {
+                if (aBuf[i] == CEditableText::EParagraphDelimiter)
+                {
+                    CGlobalText::InsertL(aPos + i, ' ');
+                }
+                else
+                {
+                    CGlobalText::InsertL(aPos + i, iEchoChar);
+                }
+            }
+        }
+    }
+    else
+    {
+        if (iEchoChar)
+        {
+            SaveClearTextL(aPos, aBuf);
+            for (TInt i = 0; i < aBuf.Length(); i++)
+            {
+                if (aBuf[i] == CEditableText::EParagraphDelimiter)
+                {
+                    CGlobalText::InsertL(aPos + i, ' ');
+                }
+                else
+                {
+                    CGlobalText::InsertL(aPos + i, iEchoChar);
+                }
+            }
+        }
+        else
+        {
+            for (TInt i = 0; i < aBuf.Length(); i++)
+            {
+                CSwtText::CPasswordText::InsertL(aPos + i, aBuf[i]);
+            }
+        }
+
+    }
+
+}
+
+// ---------------------------------------------------------------------------
+// CSwtText::CPasswordText::SetEchoCharL
+// Support Changin all characters to masked character when we set the
+// SetEchoCharater
+// ---------------------------------------------------------------------------
+//
+void CSwtText::CPasswordText::SetEchoCharL()
+{
+    TInt length = iClearText->Des().Length();
+    if (length > 0)
+    {
+        CGlobalText::DeleteL(0,length);
+        if (iEchoChar)
+        {
+            for (int i = 0; i < length; i++)
+            {
+                CGlobalText::InsertL(i, iEchoChar);
+            }
+        }
+        else
+        {
+            CGlobalText::InsertL(0 , iClearText->Des());
+        }
+        iEditor->NotifyNewFormatL();
+    }
+}
+
+// ---------------------------------------------------------------------------
+// CSwtText::CPasswordText::PasteFromStoreL
+// Support for pasting in the Text with EchoCharacter. The normal insertion
+// mechanism is not used in the paste operation, so it must be handled separately
+// here. This is an overriden method that stores the pasted chars to the local
+// store and puts masked chars (*) to the visible store (in super class).
+// ---------------------------------------------------------------------------
+//
+TInt CSwtText::CPasswordText::PasteFromStoreL(const CStreamStore& aStore,
+        const CStreamDictionary& aDictionary,
+        TInt aPos)
+{
+    // 1. Paste clipboard text (to visible text)
+    TInt numCharsPasted = CGlobalText::PasteFromStoreL(aStore, aDictionary, aPos);
+    // 2. Insert the pasted text to the local clear text store
+    TPtr content(SwtControlHelper::GetClipboardTextContentLC());
+    TPtrC ptr = content.Ptr();
+    SaveClearTextL(aPos, ptr);
+
+    if (iEchoChar)
+    {
+        // 3. Mask the visible text
+        for (int i = 0; i < numCharsPasted; i++)
+        {
+            TPtrC charToProcess = Read(aPos+i, 1);
+            TChar replaceChar   = iEchoChar;
+            if (charToProcess[0] == CEditableText::EParagraphDelimiter)
+            {
+                replaceChar = ' ';
+            }
+            CGlobalText::DeleteL(aPos+i,1);
+            CGlobalText::InsertL(aPos+i, replaceChar);
+        }
+    }
+    if (content.Ptr())
+    {
+        CleanupStack::PopAndDestroy();
+    }
+    return numCharsPasted;
+}
+
+// ---------------------------------------------------------------------------
+// CSwtText::CPasswordText::CopyToStoreL
+// Support for copying Text with EchoCharacter constraint. The normal mechanism
+// is not used in the copy operation, so it must be handled separately here.
+// This is an overriden method that stores the copied chars to the local store
+// and puts masked chars (*) to the visible store (in super class).
+// ---------------------------------------------------------------------------
+//
+void CSwtText::CPasswordText::CopyToStoreL(CStreamStore& aStore,
+        CStreamDictionary& aDictionary,
+        TInt aPos,
+        TInt aLength) const
+{
+    if (!iEchoChar)
+    {
+        // this allow to copy in single line text without
+        // Echo Character set
+        CGlobalText::CopyToStoreL(aStore, aDictionary,
+                                  aPos, aLength);
+    }
+    else
+    {
+        // here we should handle the situation that it shouldn't
+        // delete already existing clipboard contents.
+    }
+}
+
+// ---------------------------------------------------------------------------
+// CSwtText::CPasswordText::Delete
+// Delete one or more chars, this makes sure our clear text stays
+// in sync.
+// ---------------------------------------------------------------------------
+//
+TBool CSwtText::CPasswordText::DeleteL(TInt aPos,TInt aLength)
+{
+    if (iPswdEnable)
+    {
+        if (iTimer->IsActive())
+        { //commit any previous character before deleting or else we
+            // may crash in the timer callback when trying to replace
+            // an uncommited but already deleted char
+            DoTimerCallbackL(EFalse);
+        }
+    }
+    TPtr ptr = iClearText->Des();
+    ptr.Delete(aPos, aLength);
+
+    return CGlobalText::DeleteL(aPos, aLength);
+}
+
+// ---------------------------------------------------------------------------
+// CSwtText::CPasswordText::Extract
+// This method is called by edwin when returning text to the user via
+// a GetText() call. We make sure we return the clear text instead of the
+// masking used by edwin.
+// ---------------------------------------------------------------------------
+//
+void CSwtText::CPasswordText::Extract(TDes& aBuf,TInt aPos) const
+{
+    if (iPswdEnable || iEchoChar)
+    {
+        aBuf.SetLength(0);
+        aBuf.Append(iClearText->Mid(aPos));
+    }
+    else
+    {
+        CGlobalText::Extract(aBuf, aPos);
+    }
+}
+
+// ---------------------------------------------------------------------------
+// CSwtText::CPasswordText::Extract
+// This method is called by edwin when returning text to the user via
+// a GetText() call. We make sure we return the clear text instead of the
+// masking used by edwin.
+// ---------------------------------------------------------------------------
+//
+void CSwtText::CPasswordText::Extract(TDes& aBuf,
+                                      TInt aPos,
+                                      TInt aLength) const
+{
+    if (iPswdEnable || iEchoChar)
+    {
+        aBuf.SetLength(0);
+        aBuf.Append(iClearText->Mid(aPos, aLength));
+    }
+    else
+    {
+        CGlobalText::Extract(aBuf, aPos, aLength);
+    }
+}
+
+// ---------------------------------------------------------------------------
+// CSwtText::CPasswordText::TimerCallbackL
+// ---------------------------------------------------------------------------
+//
+TInt CSwtText::CPasswordText::TimerCallback(TAny* aThis)
+{
+    CPasswordText* self = STATIC_CAST(CPasswordText*, aThis);
+    ASSERT(self);
+
+    TRAPD(err, self->DoTimerCallbackL(ETrue));
+    return err;
+}
+
+// ---------------------------------------------------------------------------
+// CSwtText::CPasswordText::DoTimerCallbackL
+// It is time to remove the temporary clear character. Do a delete at
+// iClearCharPos and then insert an asterisk at this position. Then we need to
+// call something that signals the edwin to update its characters,
+// NotifyNewFormatL() seems to do the job. Note: this is only needed when inse-
+// rting a char from the special char table or when holding a key down so that
+// a number is inserted even if in alpha input mode. Otherwise you do not notice
+// the differece as edwin update its text anyway when commiting a fep transaction
+// after a timeout that seems just about longer than our timeout.
+// ---------------------------------------------------------------------------
+//
+void CSwtText::CPasswordText::DoTimerCallbackL(TBool aNotifyFormat)
+{
+
+    iTimer->Cancel();
+
+    ASSERT(iClearCharPos != -1 && (DocumentLength() > iClearCharPos));
+    // here checking iEchochar is for null character in iEchoChar that does mask
+    // the characters so we dont need to insert or delete.
+    if (iClearCharPos != -1 && (DocumentLength() > iClearCharPos) && iEchoChar)
+    {
+        CGlobalText::DeleteL(iClearCharPos,1);
+        CGlobalText::InsertL(iClearCharPos, iEchoChar);
+
+        if (aNotifyFormat && iEditor->TextView())
+        {
+            iEditor->NotifyNewFormatL();
+        }
+        iEditor->DrawDeferred();
+    }
+}
+
+// CSwtText::~CSwtText
+// ---------------------------------------------------------------------------
+//
+CSwtText::~CSwtText()
+{
+    //iiBufferToVerify.Close();
+}
+
+// ---------------------------------------------------------------------------
+// CSwtText::ConstructL
+// ---------------------------------------------------------------------------
+//
+void CSwtText::ConstructL()
+{
+    CSwtTextBase::ConstructL();
+    TUint aknFlags = 0;
+    // Compute edwin flags from our style
+    TUint flags = CEikEdwin::ESegmentedStorage | CEikEdwin::ELineCursor
+                  | CEikEdwin::EInclusiveSizeFixed | CEikEdwin::ENoAutoSelection
+                  | CEikEdwin::EResizable  | CEikEdwin::EWidthInPixels;
+    if (!(iStyle & KSwtStyleWrap))
+    {
+        flags |= CEikEdwin::ENoWrap;
+    }
+
+    if (iStyle & KSwtStyleReadOnly)
+    {
+        flags |= CEikEdwin::EReadOnly;
+    }
+
+    // Single/multi - line
+    TInt lineCount;
+    if (iStyle & KSwtStyleSingle)
+    {
+        flags |= CEikEdwin::ENoLineOrParaBreaks | CEikEdwin::ENoWrap;
+        lineCount = 1;
+    }
+    else
+    {
+        lineCount = 0;
+    }
+
+    // Construct the editor
+    CSwtEdwin* editor = new(ELeave) CSwtEdwin;
+    SetEditor(editor);
+    editor->ConstructL(flags, 0, ETextLimit, lineCount);
+    editor->SetContainerWindowL(*this);
+
+    if (iStyle & KSwtStyleSingle)
+    {
+        CParaFormatLayer* paraLayer = iEikonEnv->SystemSingleLineParaFormatLayerL();
+        CCharFormatLayer* charLayer = iEikonEnv->SystemCharFormatLayerL();
+        CPasswordText* passwordText = CPasswordText::NewL(
+                                          paraLayer, charLayer, editor, iStyle & KSwtStylePassword);
+        delete editor->Text();
+        // Ownership of passwordText is transferred
+        editor->SetDocumentContentL(*passwordText, CEikEdwin::EUseText);
+
+    }
+    editor->CreateTextViewL();
+    editor->SetDimmed(IsDimmed());
+    editor->AddEdwinObserverL(this);
+
+    ActivateL();
+
+    // Password: default to echo char = '*'
+    if (iStyle & KSwtStylePassword)
+    {
+        ASSERT(iStyle & KSwtStyleSingle);
+        static_cast < CPasswordText* >(Editor().Text())->
+        iEchoChar = KDefaultSecretChar;
+        editor->SetAknEditorCase(EAknEditorLowerCase);
+        editor->SetAknEditorCurrentCase(EAknEditorLowerCase);
+        editor->EnableCcpuSupportL(EFalse);
+        aknFlags |= EAknEditorFlagNoT9;
+        // Based on MIDP constraints, checks if the text is a PASSWORD text
+        TCoeInputCapabilities inputCapabilities = editor->InputCapabilities();
+        if (inputCapabilities != TCoeInputCapabilities::ENone)
+        {
+            CSwtLafFacade::SetPasswordCapability(inputCapabilities);
+        }
+    }
+#ifdef RD_SCALABLE_UI_V2
+    aknFlags |= EAknEditorFlagDeliverVirtualKeyEventsToApplication;
+#endif // RD_SCALABLE_UI_V2
+
+#ifdef RD_JAVA_S60_RELEASE_9_2
+    aknFlags |= EAknEditorFlagEnablePartialScreen;
+#endif
+
+    editor->SetAknEditorFlags(aknFlags);
+
+    // Scrollbars
+    if (iStyle & (KSwtStyleHScroll | KSwtStyleVScroll))
+    {
+        editor->CreatePreAllocatedScrollBarFrameL();
+
+        CEikScrollBarFrame* sbFrame = editor->ScrollBarFrame();
+#ifdef RD_SCALABLE_UI_V2
+        // WARNING!!! The expanded touch area does not move correctly togehter with the scrollbars!
+        sbFrame->SetScrollBarFrameFlags(CEikScrollBarFrame::EDisableExpandedTouchArea);
+#endif // RD_SCALABLE_UI_V2
+
+        sbFrame->CreateDoubleSpanScrollBarsL(EFalse, EFalse);
+        CEikScrollBarFrame::TScrollBarVisibility horizVis =
+            /*( iStyle & KSwtStyleHScroll ) ?
+            CEikScrollBarFrame::EOn : */
+            CEikScrollBarFrame::EOff;
+        CEikScrollBarFrame::TScrollBarVisibility vertVis =
+            (iStyle & KSwtStyleVScroll) ?
+            CEikScrollBarFrame::EOn :
+            CEikScrollBarFrame::EOff;
+        sbFrame->SetScrollBarVisibilityL(horizVis, vertVis);
+    }
+    //To avoid editor cursor to blink
+    //if the user doesnt set size and position
+    editor->SetPosition(TPoint(0,0));
+    editor->SetSize(TSize(0,0));
+    SetAlignmentL();
+    RetrieveDefaultFontL();
+    FixPadding();
+}
+
+// ---------------------------------------------------------------------------
+// CSwtText::NewL
+// ---------------------------------------------------------------------------
+//
+CSwtText* CSwtText::NewL(MSwtDisplay& aDisplay, TSwtPeer aPeer,
+                         MSwtComposite& aParent, TInt aStyle)
+{
+    CSwtText* self = new(ELeave) CSwtText(
+        aDisplay, aPeer, aParent, aStyle);
+    CleanupStack::PushL(self);
+    self->ConstructL();
+    self->InitControlBaseL();
+    CleanupStack::Pop(self);
+    return self;
+}
+
+// ---------------------------------------------------------------------------
+// CSwtText::Draw
+// ---------------------------------------------------------------------------
+//
+void CSwtText::Draw(const TRect& /*aRect*/) const
+{
+    if (GetShell().UrgentPaintControl() == this)
+        return;
+
+    CEikEdwin& editor(Editor());
+    if (editor.TextView() == NULL)
+    {
+        return;
+    }
+
+    // Update editor's visibility, otherwise text will be drawn
+    // when performing clipboard operations on invisible control.
+    const TBool visible = GetVisibleRecursively();
+    if (visible != editor.IsVisible())
+    {
+        editor.MakeVisible(visible);
+    }
+
+    // Update custom clipping, otherwise edwin will draw outside of
+    // its parent control.
+    TRect clipRect(ClipToVisibleRect(editor.TextView()->ViewRect()));
+    if (clipRect != iLastViewVisibleRect)
+    {
+        ((CSwtEdwin*)&editor)->SetClippingRect(clipRect);
+        iLastViewVisibleRect = clipRect;
+    }
+}
+
+// ---------------------------------------------------------------------------
+// CSwtText::ComputeAlignment
+// ---------------------------------------------------------------------------
+//
+CParaFormat::TAlignment CSwtText::ComputeAlignment() const
+{
+    CParaFormat::TAlignment result;
+    const TInt alignment = iStyle  & KSwtAlignmentMask;
+
+    if (alignment == KSwtStyleCenter)
+    {
+        result = CParaFormat::ECenterAlign;
+    }
+    else if (alignment == KSwtStyleTrail)
+    {
+        if ((iStyle & KSwtOrientationMask) == KSwtStyleRightToLeft
+                || AknLayoutUtils::LayoutMirrored())
+        {
+            result = CParaFormat::ELeftAlign;
+        }
+        else
+        {
+            result = CParaFormat::ERightAlign;
+        }
+    }
+    else
+    {
+        ASSERT(alignment == KSwtStyleLead);
+        if ((iStyle & KSwtOrientationMask) == KSwtStyleRightToLeft
+                || AknLayoutUtils::LayoutMirrored())
+        {
+            result = CParaFormat::ERightAlign;
+        }
+        else
+        {
+            result = CParaFormat::ELeftAlign;
+        }
+    }
+
+    return result;
+}
+
+// ---------------------------------------------------------------------------
+// CSwtText::SetAlignmentL
+// ---------------------------------------------------------------------------
+//
+void CSwtText::SetAlignmentL()
+{
+    CParaFormat* paraFormat = CParaFormat::NewL();
+    CleanupStack::PushL(paraFormat);
+    paraFormat->iHorizontalAlignment = ComputeAlignment();
+    TParaFormatMask paraMask;
+    paraMask.SetAttrib(EAttAlignment);
+    static_cast < CGlobalText* >(Editor().Text())->
+    ApplyParaFormatL(paraFormat, paraMask, 0, 0);
+    CleanupStack::PopAndDestroy(paraFormat);
+}
+
+// ---------------------------------------------------------------------------
+// CSwtText::CropToFirstLine
+// ---------------------------------------------------------------------------
+//
+void CSwtText::CropToFirstLine(TDes& aText)
+{
+    const TInt length = aText.Length();
+    const TText* ptr = aText.Ptr();
+    TInt i = 0;
+
+    // As of Unicode 4.0.1 there is only one character in each of the line
+    // or paragraph separator categories. Therefore, if speed was an issue,
+    // the below code could be replaced by a simpler and faster test against
+    // those two characters. The current code, however, is more future proof.
+    for (i = 0; i < length; i++)
+    {
+        const TText ch = ptr[i];
+
+        // CR or LF
+        if (ch == 0x0D || ch == 0x0A)
+        {
+            break;
+        }
+
+        const TChar::TCategory category = TChar(ch).GetCategory();
+        if (category == TChar::EZlCategory
+                || category == TChar::EZpCategory)
+        {
+            break;
+        }
+    }
+
+    aText.SetLength(i);
+}
+
+
+// ---------------------------------------------------------------------------
+// CSwtText::ConvertToUnicodeBreaks
+// ---------------------------------------------------------------------------
+//
+void CSwtText::ConvertToUnicodeBreaks(TDes& aText)
+{
+    const TText KCr = 0x0D; // CR
+    const TText KLf = 0x0A; // LF
+
+    const TInt length = aText.Length();
+    TText* ptr = const_cast < TText* >(aText.Ptr());
+
+    // First loop: just scans for CR & LF and stops at the first occurrence.
+    // This loop is faster than the second one.
+    TInt inputIndex  = 0;
+    for (; inputIndex < length;  ++ inputIndex)
+    {
+        if (ptr[inputIndex] == KCr || ptr[inputIndex] == KLf)
+        {
+            break;
+        }
+    }
+
+    // Second loop: starts at the first CR or LF and does the actual replacement.
+    // It will only be triggered if the first loop didn't reach the end.
+    TText prevChar    = 0;
+    TInt  outputIndex = inputIndex;
+    for (; inputIndex < length;  ++ inputIndex)
+    {
+        TText ch = ptr[inputIndex];
+        if (ch != KCr && ch != KLf)
+        {
+            ptr[outputIndex ++ ] = ch;
+        }
+        else
+        {
+            // Don't replace LF if preceded by CR, just skip it.
+            if (!(ch == KLf && prevChar == KCr))
+            {
+                ptr[outputIndex ++ ] = CEditableText::EParagraphDelimiter;
+            }
+        }
+
+        prevChar = ch;
+    }
+
+    aText.SetLength(outputIndex);
+}
+
+// ---------------------------------------------------------------------------
+// CSwtText::ProcessLineBrakes
+// ---------------------------------------------------------------------------
+//
+void CSwtText::ProcessLineBrakes(TDes& aText) const
+{
+    if (iStyle & KSwtStyleSingle)
+    {
+        CropToFirstLine(aText);
+    }
+    else
+    {
+        ConvertToUnicodeBreaks(aText);
+    }
+}
+
+// ---------------------------------------------------------------------------
+// CSwtText::PostVerifyEventL
+// ---------------------------------------------------------------------------
+//
+void CSwtText::PostVerifyEventL(
+    TInt aStart, TInt aEnd, TDes& aText)
+{
+    iDisplay.PostVerifyEventL(
+        *this, iPeer, aStart, aEnd, aText);
+}
+
+// ---------------------------------------------------------------------------
+// CSwtText::PostVerifyEventL
+// ---------------------------------------------------------------------------
+//
+void CSwtText::PostVerifyEventL(TInt aStart, TInt aEnd, TInt aChar)
+{
+    TBuf<1> charString;
+    charString.Append(aChar);
+    PostVerifyEventL(aStart, aEnd, charString);
+}
+
+// ---------------------------------------------------------------------------
+// CSwtText::SendCharacterL
+// ---------------------------------------------------------------------------
+//
+void CSwtText::SendCharacterL(TText aChar)
+{
+    TKeyEvent keyEvent;
+
+    // For some reason TChar::IsPrint() returns false for line separator and
+    // paragraph separator, so we have to emulate them.
+    if (aChar == CEditableText::EParagraphDelimiter)
+    {
+        keyEvent.iCode = EKeyEnter;
+        keyEvent.iModifiers = 0;
+    }
+    else if (aChar == CEditableText::ELineBreak)
+    {
+        keyEvent.iCode = EKeyEnter;
+        keyEvent.iModifiers = EModifierShift;
+    }
+    else
+    {
+        keyEvent.iCode = aChar;
+        keyEvent.iModifiers = 0;
+    }
+
+    keyEvent.iScanCode = 0;
+    keyEvent.iRepeats = 0;
+    ForwardKeyEventL(keyEvent, EEventKey);
+    iDisplay.PostModifyEventL(iPeer);
+}
+
+// ---------------------------------------------------------------------------
+// CSwtText::HandleResourceChange
+// From CSwtTextBase
+// ---------------------------------------------------------------------------
+//
+void CSwtText::HandleResourceChange(TInt aType)
+{
+    CSwtTextBase::HandleResourceChange(aType);
+
+    if (aType == KEikDynamicLayoutVariantSwitch)
+    {
+        TRAP_IGNORE(
+            TInt topIndex = 0;
+            if (iStyle & KSwtStyleMulti)
+    {
+        // SetOrientationL method changes the TopIndex, we need to save it and set it again.
+        topIndex = GetTopIndexL();
+        }
+        // Update text orientation (left-to-right / right-to-left)
+        SetOrientationL(iStyle & KSwtOrientationMask);
+        if (iStyle & KSwtStyleMulti)
+    {
+        SetTopIndexL(topIndex);
+        }
+        );
+    }
+}
+
+// ---------------------------------------------------------------------------
+// CSwtText::SizeChanged
+// From CCoeControl
+// ---------------------------------------------------------------------------
+//
+void CSwtText::SizeChanged()
+{
+    CSwtTextBase::SizeChanged();
+    Editor().TextLayout()->RestrictScrollToTopsOfLines(EFalse);
+}
+
+// ---------------------------------------------------------------------------
+// CSwtText::OfferKeyEventL
+// From CCoeControl
+// ---------------------------------------------------------------------------
+//
+TKeyResponse CSwtText::OfferKeyEventL(
+    const TKeyEvent& aKeyEvent,
+    TEventCode aType)
+{
+    TBool traversalDoIt = ETrue;
+    CEikEdwin& editor = Editor();
+
+#ifdef RD_SCALABLE_UI_V2
+    // If focus gets changed by keys, iIgnorePointerDown is set to ETrue. We
+    // don't want this since the next pointer event should be ignored only
+    // when focus gets changed by tapping on the screen.
+    iIgnorePointerDown = EFalse;
+#endif //RD_SCALABLE_UI_V2
+
+    switch (aKeyEvent.iCode)
+    {
+    case EKeyEnter:
+        traversalDoIt = iStyle & KSwtStyleSingle;
+        break;
+
+    case EKeyEscape:
+        traversalDoIt = EFalse;
+        break;
+
+    case EKeyTab:
+        traversalDoIt = (iStyle & KSwtStyleMulti)
+                        && (aKeyEvent.iModifiers & ECtrlFuncShiftMask);
+        break;
+
+    case EKeyDownArrow:
+        traversalDoIt = (!(aKeyEvent.iModifiers & EModifierShift))
+                        && (GetCaretLineNumber() == GetLineCount() - 1)
+                        && (GetShell().FindTraversalTargetL(
+                                ESwtTraverseArrowNext, *this));
+        break;
+
+    case EKeyUpArrow:
+        traversalDoIt = (!(aKeyEvent.iModifiers & EModifierShift))
+                        && (GetCaretLineNumber() == 0)
+                        && (GetShell().FindTraversalTargetL(
+                                ESwtTraverseArrowPrevious, *this));
+        break;
+
+    case EKeyLeftArrow:
+    case EKeyRightArrow:
+        traversalDoIt = EFalse;
+        break;
+
+    default:
+        // traversalDoIt remains ETrue
+        break;
+    }
+
+    /*
+     * This is a workaround for issue with traversing between Text if cursor
+     * was on first position and LEFT key was pressed, the event was
+     * consumed somewhere in AknFep. The same problem was in case RIGHT key
+     * and end cursor position. In this case we don't recieve EEventKey, so
+     * we must simulate it.
+     */
+    if (aType == EEventKeyDown)
+    {
+        if (aKeyEvent.iScanCode == EStdKeyLeftArrow &&
+                editor.CursorPos() == 0)
+        {
+            HandleKeyL(aKeyEvent, EEventKey, EFalse);
+        }
+        else if (aKeyEvent.iScanCode == EStdKeyRightArrow &&
+                 editor.CursorPos() == editor.TextLength())
+        {
+            HandleKeyL(aKeyEvent, EEventKey, EFalse);
+        }
+    }
+
+    return HandleKeyL(aKeyEvent, aType, traversalDoIt);
+}
+
+// ---------------------------------------------------------------------------
+// CSwtText::ProcessKeyEventL
+// From MSwtControl
+// ---------------------------------------------------------------------------
+//
+void CSwtText::ProcessKeyEventL(const TKeyEvent& aKeyEvent, TEventCode aType)
+{
+    CEikEdwin& editor = Editor();
+
+    if (aType != EEventKey)
+    {
+        return;
+    }
+
+    // Read - only: CEikEdwin displays a message and leaves. We want the message
+    // but not the leaving, hence the trap.
+    if (iStyle & KSwtStyleReadOnly)
+    {
+        TRAP_IGNORE(ForwardKeyEventL(aKeyEvent, aType));
+        return;
+    }
+
+    // Single - line: enter not consumed, translated to default selection event
+    if ((iStyle & KSwtStyleSingle) && aKeyEvent.iCode == EKeyEnter)
+    {
+        iDisplay.PostDefaultSelectionEventL(iPeer);
+        return;
+    }
+
+    const TInt modifiers = aKeyEvent.iModifiers & ECtrlFuncShiftMask;
+    const TCursorSelection selection(editor.Selection());
+    const TInt selStart = selection.LowerPos();
+    const TInt selEnd = selection.HigherPos();
+    const TInt selLength = selEnd  -  selStart;
+    const TInt length = editor.TextLength();
+    const TInt hotkey = HotKeyL(aKeyEvent);
+
+    // Cut
+    if (hotkey == CEikEdwin::EHotKeyCut)
+    {
+        TText echoChar = static_cast < CPasswordText* >(
+                             Editor().Text())->iEchoChar;
+        if (!(iStyle & KSwtStylePassword) || !(echoChar))
+        {
+            Editor().ClipboardL(CEikEdwin::ECopy);
+            if (selLength != 0)
+            {
+                TPtr text(NULL, 0, 0);
+                PostVerifyEventL(selStart, selEnd, text);
+            }
+        }
+    }
+    // Copy
+    else if (hotkey == CEikEdwin::EHotKeyCopy)
+    {
+        TText echoChar = static_cast < CPasswordText* >(
+                             Editor().Text())->iEchoChar;
+        if (!(iStyle & KSwtStylePassword) || !(echoChar))
+        {
+            editor.ClipboardL(CEikEdwin::ECopy);
+        }
+    }
+    // Paste
+    else if (hotkey == CEikEdwin::EHotKeyPaste)
+    {
+        TPtr content(SwtControlHelper::GetClipboardTextContentLC());
+        if (content.Length() == 0)
+        {
+            // Nothing to paste: CEikEdwin displays a message and leaves. We want
+            // the message but not the leaving, hence the trap.
+            TRAP_IGNORE(ForwardKeyEventL(aKeyEvent, aType));
+        }
+        else
+        {
+            PostVerifyEventL(selStart, selEnd, content);
+        }
+        if (content.Ptr())
+        {
+            CleanupStack::PopAndDestroy();
+        }
+    }
+    // Undo
+    else if (hotkey == CEikEdwin::EHotKeyUndo)
+    {
+        // Do nothing
+    }
+    // Delete
+    else if (aKeyEvent.iCode == EKeyDelete && modifiers == 0)
+    {
+        TPtr text(NULL, 0, 0);
+        if (selLength != 0)
+        {
+            PostVerifyEventL(selStart, selEnd, text);
+        }
+        else if (selection.iCursorPos < length)
+        {
+            PostVerifyEventL(selection.iCursorPos, selection.iCursorPos + 1, text);
+        }
+    }
+    // Backspace
+    else if (aKeyEvent.iCode == EKeyBackspace && modifiers == 0)
+    {
+        TPtr text(NULL, 0, 0);
+        if (selLength != 0)
+        {
+            PostVerifyEventL(selStart, selEnd, text);
+        }
+        else if (selection.iCursorPos > 0)
+        {
+            PostVerifyEventL(selection.iCursorPos - 1, selection.iCursorPos, text);
+        }
+    }
+    // Enter: paragraph separator
+    else if (aKeyEvent.iCode == EKeyEnter && modifiers == 0)
+    {
+        PostVerifyEventL(selStart, selEnd, CEditableText::ELineBreak);
+    }
+    // Shift + Enter: line separator
+    else if (aKeyEvent.iCode == EKeyEnter && (modifiers & EModifierShift))
+    {
+        PostVerifyEventL(selStart, selEnd, CEditableText::ELineBreak);
+    }
+    // Ctrl + Minus: non - breaking hyphen
+    else if (aKeyEvent.iCode == '-' && (modifiers & EModifierCtrl))
+    {
+        PostVerifyEventL(selStart, selEnd, CEditableText::ENonBreakingHyphen);
+    }
+    // Shift + Space: non - breaking space
+    else if (aKeyEvent.iCode == ' ' && (modifiers & EModifierShift))
+    {
+        PostVerifyEventL(selStart, selEnd, CEditableText::ENonBreakingSpace);
+    }
+    // Regular character
+    else if (aKeyEvent.iCode == EKeyTab || TChar(aKeyEvent.iCode).IsPrint())
+    {
+        PostVerifyEventL(selStart, selEnd, aKeyEvent.iCode);
+    }
+    // Other
+    else
+    {
+        ForwardKeyEventL(aKeyEvent, aType);
+    }
+}
+
+// ---------------------------------------------------------------------------
+// CSwtText::Scrollable
+// From MSwtText
+// ---------------------------------------------------------------------------
+//
+MSwtScrollable* CSwtText::Scrollable()
+{
+    return this;
+}
+
+// ---------------------------------------------------------------------------
+// CSwtText::GetTextL
+// From MSwtText
+// ---------------------------------------------------------------------------
+//
+HBufC* CSwtText::GetTextL() const
+{
+    return Editor().GetTextInHBufL();
+}
+
+// ---------------------------------------------------------------------------
+// CSwtText::GetTextRangeL
+// From MSwtText
+// ---------------------------------------------------------------------------
+//
+HBufC* CSwtText::GetTextRangeL(TInt aStart, TInt aEnd) const
+{
+    ASSERT(aStart <=aEnd);
+
+    const TInt length = Editor().TextLength();
+    if (length == 0)
+    {
+        return NULL;
+    }
+
+    TInt pos1 = Max(0,    aStart);
+    TInt pos2 = Min(aEnd, length - 1);
+    TInt count = pos2 - pos1 + 1;
+    if (pos1 >= length || pos2 < 0 || count <= 0)
+    {
+        return NULL;
+    }
+
+    HBufC* buffer = HBufC::NewL(count);
+    TPtr des(buffer->Des());
+    Editor().Text()->Extract(des, pos1, count);
+    return buffer;
+}
+
+// ---------------------------------------------------------------------------
+// CSwtText::SetTextL
+// From MSwtText
+// ---------------------------------------------------------------------------
+//
+TBool CSwtText::SetTextL(TDes& aText)
+{
+    ProcessLineBrakes(aText);
+    return CSwtTextBase::SetTextL(aText);
+}
+
+// ---------------------------------------------------------------------------
+// CSwtText::AppendL
+// From MSwtText
+// ---------------------------------------------------------------------------
+//
+TBool CSwtText::AppendL(TDes& aText)
+{
+    ProcessLineBrakes(aText);
+    return CSwtTextBase::AppendL(aText);
+}
+
+// ---------------------------------------------------------------------------
+// CSwtText::InsertL
+// From MSwtText
+// ---------------------------------------------------------------------------
+//
+TBool CSwtText::InsertL(TDes& aText)
+{
+    ProcessLineBrakes(aText);
+    return CSwtTextBase::InsertL(aText);
+}
+
+// ---------------------------------------------------------------------------
+// CSwtText::GetCharCount
+// From MSwtText
+// ---------------------------------------------------------------------------
+//
+TInt CSwtText::GetCharCount() const
+{
+    return Editor().TextLength();
+}
+
+// ---------------------------------------------------------------------------
+// CSwtText::SetTextLimit
+// From MSwtText
+// ---------------------------------------------------------------------------
+//
+TBool CSwtText::SetTextLimitL(TInt aLimit)
+{
+    iTextLimit = aLimit;
+    return CSwtTextBase::SetLimitL(aLimit);
+}
+
+// ---------------------------------------------------------------------------
+// CSwtText::GetCaretLineNumber
+// From MSwtText
+// ---------------------------------------------------------------------------
+//
+TInt CSwtText::GetCaretLineNumber() const
+{
+    TTmLineInfo info;
+    TPoint origin(TPoint::EUninitialized);
+    TInt width;
+    TInt ascent;
+    TInt descent;
+    TTmDocPos curPos;
+    Editor().TextView()->GetCursorPos(curPos);
+    TTmDocPosSpec curPosSpec(curPos);
+    Editor().TextLayout()->TagmaTextLayout().GetCursor(
+        curPosSpec, ECursorVertical, info, origin, width, ascent, descent);
+    return info.iLineNumber;
+}
+
+// ---------------------------------------------------------------------------
+// CSwtText::GetCaretLocationL
+// From MSwtText
+// ---------------------------------------------------------------------------
+//
+TPoint CSwtText::GetCaretLocationL() const
+{
+    CTextView* textView = Editor().TextView();
+    CTextLayout* layout   = Editor().TextLayout();
+
+    TTmLineInfo info;
+    TPoint curLoc;
+    TInt width;
+    TInt ascent;
+    TInt descent;
+    TTmDocPos curPos;
+    textView->GetCursorPos(curPos);
+    TTmDocPosSpec curPosSpec(curPos);
+    layout->TagmaTextLayout().GetCursor(
+        curPosSpec, ECursorVertical, info, curLoc, width, ascent, descent);
+    TPoint result(TPoint::EUninitialized);
+    layout->GetOrigin(result);
+    result += curLoc;
+    result += textView->ViewRect().iTl;
+    result -= ClientRect().iTl;
+    result.iY += GetTopPixelL();
+    return result;
+}
+
+// ---------------------------------------------------------------------------
+// CSwtText::GetCaretPosition
+// From MSwtText
+// ---------------------------------------------------------------------------
+//
+TInt CSwtText::GetCaretPosition() const
+{
+    return Editor().CursorPos();
+}
+
+// ---------------------------------------------------------------------------
+// CSwtText::GetSelection
+// From MSwtText
+// ---------------------------------------------------------------------------
+//
+TPoint CSwtText::GetSelection() const
+{
+    const TCursorSelection selection(Editor().Selection());
+    return TPoint(selection.LowerPos(), selection.HigherPos());
+}
+
+// ---------------------------------------------------------------------------
+// CSwtText::GetSelectionTextL
+// From MSwtText
+// ---------------------------------------------------------------------------
+//
+HBufC* CSwtText::GetSelectionTextL() const
+{
+    const TCursorSelection selection(Editor().Selection());
+    const TInt length = selection.Length();
+    if (length == 0)
+    {
+        return NULL;
+    }
+
+    HBufC* buffer = HBufC::NewL(length);
+    TPtr des(buffer->Des());
+    Editor().Text()->Extract(des, selection.LowerPos(), length);
+    return buffer;
+}
+
+// ---------------------------------------------------------------------------
+// CSwtText::SetSelectionL
+// From MSwtText
+// ---------------------------------------------------------------------------
+//
+void CSwtText::SetSelectionL(TInt aStart, TInt aEnd)
+{
+    const TInt length = Editor().TextLength();
+    const TInt pos1 = Max(0, Min(aStart, length));
+    const TInt pos2 = Max(0, Min(aEnd, length));
+    const TInt cursor = Min(pos1, pos2);
+    const TInt anchor = Max(pos1, pos2);
+    Editor().SetSelectionL(cursor, anchor);
+    // This is neccessary, since CEikEdwin doesn't really set the selection
+    // until drawing occurs and clipboard operations can be
+    // broken in such a case
+    Editor().TextView()->SetSelectionL(TCursorSelection(cursor, anchor));
+}
+
+// ---------------------------------------------------------------------------
+// CSwtText::ClearSelectionL
+// From MSwtText
+// ---------------------------------------------------------------------------
+//
+void CSwtText::ClearSelectionL()
+{
+    TCursorSelection selection(Editor().Selection());
+    Editor().SetSelectionL(selection.iCursorPos, selection.iCursorPos);
+    Editor().TextView()->SetSelectionL(TCursorSelection(
+                                           selection.iCursorPos, selection.iCursorPos));
+}
+
+// ---------------------------------------------------------------------------
+// CSwtText::SelectAllL
+// From MSwtText
+// ---------------------------------------------------------------------------
+//
+void CSwtText::SelectAllL()
+{
+    const TInt length = Editor().TextLength();
+    Editor().SetSelectionL(length, 0);
+    Editor().TextView()->SetSelectionL(TCursorSelection(length, 0));
+}
+
+// ---------------------------------------------------------------------------
+// CSwtText::ShowSelectionL
+// From MSwtText
+// ---------------------------------------------------------------------------
+//
+void CSwtText::ShowSelectionL()
+{
+    TCursorSelection selection(Editor().Selection());
+    Editor().SetSelectionL(selection.iCursorPos, selection.iAnchorPos);
+}
+
+// ---------------------------------------------------------------------------
+// CSwtText::CopyL
+// From MSwtText
+// ---------------------------------------------------------------------------
+//
+void CSwtText::CopyL()
+{
+    if (!(iStyle & KSwtStylePassword))
+    {
+        Editor().ClipboardL(CEikEdwin::ECopy);
+    }
+}
+
+// ---------------------------------------------------------------------------
+// CSwtText::PasteL
+// From MSwtText
+// ---------------------------------------------------------------------------
+//
+TBool CSwtText::PasteL()
+{
+    TPtrC content(SwtControlHelper::GetClipboardTextContentLC());
+    TInt length = content.Length();
+    if (content.Ptr() != NULL)
+    {
+        CleanupStack::PopAndDestroy(); // content
+    }
+    if (length == 0)
+    {
+        // Nothing to paste: CEikEdwin displays a message and leaves.
+        // We want the message but not the leaving, hence the trap.
+        TRAP_IGNORE(Editor().ClipboardL(CEikEdwin::EPaste));
+        return EFalse;
+    }
+
+    Editor().ClipboardL(CEikEdwin::EPaste);
+    return ETrue;
+}
+
+// ---------------------------------------------------------------------------
+// CSwtText::GetEditable
+// From MSwtText
+// ---------------------------------------------------------------------------
+//
+TBool CSwtText::GetEditable() const
+{
+    return CSwtTextBase::GetEditable();
+}
+
+// ---------------------------------------------------------------------------
+// CSwtText::SetEditable
+// From MSwtText
+// ---------------------------------------------------------------------------
+//
+void CSwtText::SetEditable(TBool aEditable)
+{
+    CSwtTextBase::SetEditable(aEditable);
+}
+
+// ---------------------------------------------------------------------------
+// CSwtText::GetLineCount
+// From MSwtText
+// ---------------------------------------------------------------------------
+//
+TInt CSwtText::GetLineCount() const
+{
+    return Editor().TextLayout()->NumFormattedLines();
+}
+
+// ---------------------------------------------------------------------------
+// CSwtText::GetLineHeightL
+// From MSwtText
+// ---------------------------------------------------------------------------
+//
+TInt CSwtText::GetLineHeightL() const
+{
+    CTextLayout* layout = Editor().TextLayout();
+    TPoint xyPos(TPoint::EUninitialized);
+    layout->DocPosToXyPosL(0, xyPos);
+    TRect lineRect(TRect::EUninitialized);
+    layout->GetLineRect(xyPos.iY, lineRect);
+    return lineRect.Height();
+}
+
+// ---------------------------------------------------------------------------
+// CSwtText::GetTopIndexL
+// From MSwtText
+// ---------------------------------------------------------------------------
+//
+TInt CSwtText::GetTopIndexL() const
+{
+    ASSERT(iStyle & KSwtStyleMulti);
+
+    CTextLayout* layout = Editor().TextLayout();
+
+    // First fully visible line
+    TInt firstLine = layout->FirstLineInBand();
+
+    // Adjust ( if needed ) to return the first partially visible line
+    // FirstCharOnLine() counts lines from 1
+    TInt lineStart = layout->FirstCharOnLine(firstLine + 1);
+    TRect lineRect(layout->GetLineRectL(lineStart, lineStart));
+    if (lineRect.iTl.iY != 0)
+    {
+        --firstLine;
+    }
+
+    return firstLine;
+}
+
+// ---------------------------------------------------------------------------
+// CSwtText::SetTopIndexL
+// From MSwtText
+// ---------------------------------------------------------------------------
+//
+void CSwtText::SetTopIndexL(TInt aIndex)
+{
+    ASSERT(iStyle & KSwtStyleMulti);
+
+    if (aIndex < 0)
+    {
+        aIndex = 0;
+    }
+    Editor().TextView()->SetViewLineAtTopL(aIndex + 1);
+
+    // Update vertical scroll - bar
+    CEikScrollBarFrame* sbFrame = Editor().ScrollBarFrame();
+    if (sbFrame)
+    {
+        CEikScrollBar* vsb = sbFrame->GetScrollBarHandle(
+                                 CEikScrollBar::EVertical);
+        if (vsb)
+        {
+            Editor().HandleScrollEventL(
+                vsb, EEikScrollThumbReleaseVert);
+        }
+    }
+}
+
+// ---------------------------------------------------------------------------
+// CSwtText::GetTopPixelL
+// From MSwtText
+// ---------------------------------------------------------------------------
+//
+TInt CSwtText::GetTopPixelL() const
+{
+    if (iStyle & KSwtStyleSingle)
+    {
+        return 0;
+    }
+
+    CTextLayout* layout = Editor().TextLayout();
+    TInt topLine = layout->FirstLineInBand();
+    TInt lineStart = layout->FirstCharOnLine(topLine + 1);
+    TRect lineRect(layout->GetLineRectL(lineStart, lineStart));
+    TInt lineHeight = lineRect.Height();
+    if (lineRect.iTl.iY != 0)
+    {
+        --topLine;
+    }
+    TInt topPixel = (lineHeight * topLine)  +  lineRect.iTl.iY;
+    return topPixel;
+}
+
+// ---------------------------------------------------------------------------
+// CSwtText::GetEchoChar
+// From MSwtText
+// ---------------------------------------------------------------------------
+//
+TText CSwtText::GetEchoChar() const
+{
+    return static_cast < CPasswordText* >(Editor().Text())->iEchoChar;
+}
+
+// ---------------------------------------------------------------------------
+// CSwtText::SetEchoChar
+// From MSwtText
+// ---------------------------------------------------------------------------
+//
+void CSwtText::SetEchoCharL(TText aEcho)
+{
+    if (aEcho!=0 && !TChar(aEcho).IsPrint())
+    {
+        aEcho = KDefaultSecretChar;
+    }
+    static_cast < CPasswordText* >(Editor().Text())->iEchoChar = aEcho;
+    static_cast < CPasswordText* >(Editor().Text())->SetEchoCharL();
+    Redraw();
+}
+
+// ---------------------------------------------------------------------------
+// CSwtText::SetDoubleClickEnabled
+// From MSwtText
+// ---------------------------------------------------------------------------
+//
+void CSwtText::SetDoubleClickEnabled(TBool /*aEnabled*/)
+{
+    // No pointer, nothing to do
+}
+
+// ---------------------------------------------------------------------------
+// CSwtText::GetOrientation
+// From MSwtText
+// ---------------------------------------------------------------------------
+//
+TInt CSwtText::GetOrientation() const
+{
+    return iStyle & KSwtOrientationMask;
+}
+
+// ---------------------------------------------------------------------------
+// CSwtText::SetOrientationL
+// From MSwtText
+// ---------------------------------------------------------------------------
+//
+void CSwtText::SetOrientationL(TInt aOrientation)
+{
+    ASSERT(aOrientation == KSwtStyleLeftToRight
+           || aOrientation == KSwtStyleRightToLeft);
+    iStyle &= ~KSwtOrientationMask;
+    iStyle |= aOrientation;
+    SetAlignmentL();
+    Editor().HandleTextChangedL();
+}
+
+// ---------------------------------------------------------------------------
+// CSwtText::ProcessVerifiedTextL
+// From MSwtVerifyEventObserver
+// ---------------------------------------------------------------------------
+//
+void CSwtText::ProcessVerifiedTextL(
+    TInt aStart, TInt aEnd, TDes& aText)
+{
+    ProcessLineBrakes(aText);
+    Editor().CancelFepTransaction();
+    const TCursorSelection oldSelection(Editor().Selection());
+
+    // Special treatment for the most common cases, we simply send a key
+    // instead of replacing the text. This helps reduce flicker.
+
+    // Single printable character
+    if (aText.Length() == 1
+            && oldSelection.LowerPos() == aStart
+            && oldSelection.HigherPos() == aEnd)
+    {
+        TText ch = aText[0];
+        if (TChar(ch).IsPrint()
+                || ch == CEditableText::EParagraphDelimiter
+                || ch == CEditableText::ELineBreak)
+        {
+            SendCharacterL(aText[0]);
+            return;
+        }
+    }
+
+    if (aText.Length() == 0 && oldSelection.Length() == 0)
+    {
+        // Delete
+        if (aStart == oldSelection.iCursorPos
+                && aEnd == oldSelection.iCursorPos + 1)
+        {
+            SendCharacterL(EKeyDelete);
+            return;
+        }
+
+        // Backspace
+        if (aStart == oldSelection.iCursorPos - 1
+                && aEnd == oldSelection.iCursorPos)
+        {
+            SendCharacterL(EKeyBackspace);
+            return;
+        }
+    }
+
+    Editor().ClearSelectionL();
+
+    // Delete old range and insert new text
+    CPlainText* plainText = Editor().Text();
+    TInt textLength = plainText->DocumentLength();
+    if (aStart > textLength)
+    {
+        aStart = textLength;
+    }
+    if (aEnd > textLength)
+    {
+        aEnd = textLength;
+    }
+
+    plainText->DeleteL(aStart, aEnd - aStart);
+
+    textLength = aText.Length();
+    if (textLength > 0)
+    {
+        TInt nbExtraChar = ((iTextLimit > 0)
+                            && (iTextLimit < (plainText->DocumentLength() + textLength))) ?
+                           (plainText->DocumentLength() + textLength - iTextLimit) : 0;
+        if (nbExtraChar > 0)
+        {
+            aText.Delete(textLength - nbExtraChar, nbExtraChar);
+            iEikonEnv->InfoMsg(R_EIK_TBUF_MAX_CHARACTERS_REACHED);
+        }
+        plainText->InsertL(aStart, aText);
+    }
+    Editor().HandleTextChangedL();
+    TInt newCursorPos;
+    if (oldSelection.HigherPos()>=aStart && oldSelection.LowerPos()<=aEnd)
+    {
+        newCursorPos=aStart+aText.Length();
+    }
+    else if (oldSelection.iCursorPos>aEnd)
+    {
+        newCursorPos=oldSelection.iCursorPos-(aEnd-aStart)+aText.Length();
+    }
+    else
+    {
+        newCursorPos=oldSelection.iCursorPos;
+    }
+
+    Editor().SetSelectionL(newCursorPos,newCursorPos);
+    iDisplay.PostModifyEventL(iPeer);
+}
+
+
+// ---------------------------------------------------------------------------
+// CSwtText::HandleEdwinEventL
+// From MEikEdwinObserver
+// ---------------------------------------------------------------------------
+//
+void CSwtText::HandleEdwinEventL(CEikEdwin*, TEdwinEvent aEventType)
+{
+    if (aEventType == EEventTextUpdate)
+    {
+        iDisplay.PostModifyEventL(iPeer);
+    }
+}
+
+// ---------------------------------------------------------------------------
+// CSwtText::SetVisibleScrollBar
+// From MEikEdwinObserver
+// ---------------------------------------------------------------------------
+//
+void CSwtText::SetVisibleScrollBar(
+    TInt aStyle, TBool aVisible)
+{
+    // Get frame
+    CEikScrollBarFrame* sbFrame = SbFrame();
+    if (!sbFrame)
+    {
+        return;
+    }
+
+    // Calculate new visibility states
+    if (aStyle & KSwtStyleHScroll)
+    {
+        iHScroll->SetVisible(aVisible);
+    }
+
+    if (aStyle & KSwtStyleVScroll)
+    {
+        iVScroll->SetVisible(aVisible);
+    }
+
+    // Resize Scrollable, as the client area has changed
+    CCoeControl& coeCtrl = CoeControl();
+    coeCtrl.SetSize(coeCtrl.Size());
+
+    // Force a redraw here as some Scrollables do not update the screen after
+    // a scrollbar as been switched on or off.
+    Redraw();
+}
+