uifw/EikStd/coctlsrc/EIKEDWIN.CPP
changeset 0 2f259fa3e83a
child 4 8ca85d2f0db7
child 14 3320e4e6e8bb
equal deleted inserted replaced
-1:000000000000 0:2f259fa3e83a
       
     1 /*
       
     2 * Copyright (c) 1997-1999 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 #include <s32mem.h>
       
    20 #include <s32file.h>
       
    21 #include <s32std.h>
       
    22 #include <fldinfo.h>
       
    23 #include <basched.h>
       
    24 #include <baclipb.h>
       
    25 #include <txtglobl.h>
       
    26 #include <eikdef.h>
       
    27 #include <fldbase.h>
       
    28 #ifndef SYMBIAN_ENABLE_SPLIT_HEADERS
       
    29 #include <txtrich.h>
       
    30 #else
       
    31 #include <txtrich.h>
       
    32 #include <txtclipboard.h>
       
    33 #include <uikon/eikdefmacros.h>
       
    34 #include <uikon/eikenvinterface.h> 
       
    35 #endif
       
    36 #include <txtfmlyr.h>
       
    37 #include <txtfrmat.h>
       
    38 #include <frmtview.h>
       
    39 #include <barsread.h>
       
    40 #include <coecobs.h>
       
    41 #include <coemain.h>
       
    42 #include <eikedwin.pan>
       
    43 #include <eikpanic.h>
       
    44 #include <uikon.hrh>
       
    45 #include <gulutil.h>
       
    46 #include <eikenv.h>
       
    47 #include <eikedwin.h>
       
    48 #include <eikcoctl.rsg>
       
    49 #include <avkon.rsg>
       
    50 #include <gulcolor.h>
       
    51 #include <eikirfty.h>
       
    52 #include "LAFEDWIN.H"
       
    53 #include <lafmain.h>
       
    54 #include <uiklaf/private/lafenv.h>
       
    55 #include <aknedsts.h>
       
    56 #include <frmtlay.h>
       
    57 #include <tagma.h>
       
    58 #include <eiksvdef.h>
       
    59 #include <AknUtils.h>
       
    60 #include <fepipext.h>
       
    61 #include <aknedformaccessor.h>
       
    62 #include <coemop.h>
       
    63 #include <AknSettingCache.h>
       
    64 #include <aknenv.h>
       
    65 #include <AknDef.h>
       
    66 #include <AknsDrawUtils.h>
       
    67 #include "aknedwincustomdrawprivate.h"
       
    68 #include "aknedwindrawingmodifier.h"
       
    69 #include "FromCursorModifierUtils.h"
       
    70 
       
    71 #include <AknTasHook.h>
       
    72 #include <FormCursorModifier.h>
       
    73 #include <formcursormodifierint.h>
       
    74 #include <biditext.h>
       
    75 #include <bidivisual.h>
       
    76 #include <AknBidiTextUtils.h>
       
    77 
       
    78 #include "aknedwinphysicshandler.h"
       
    79 #include "AknEdwinFormExtendedInterfaceProvider.h"
       
    80 #include "AknNoMatchesIndicatorInlineTextSource.h"
       
    81 #include "AknPhoneNumberInlineTextSource.h"
       
    82 #include "AknRichTextPhoneNumberInlineTextSource.h"
       
    83 #include "AknCompositeInlineTextSource.h"
       
    84 #include <featmgr.h>
       
    85 #include <aknconsts.h>
       
    86 #include <AknPictographInterface.h>
       
    87 #include <aknappui.h>
       
    88 #include <jplangutil.h>
       
    89 #include <AknSgcc.h>
       
    90 #include <AknLayoutFont.h>
       
    91 #include <aknlayoutscalable_avkon.cdl.h>
       
    92 #include <aknextendedinputcapabilities.h>
       
    93 #include <PUAcodes.hrh>
       
    94 #include <AknFepInternalCRKeys.h> // KAknFepHashKeySelection
       
    95 #include <eikrted.h>
       
    96 #include <NumberGroupingCRKeys.h>
       
    97 #include <aknpointereventsuppressor.h>
       
    98 #include <aknnotedialog.h>
       
    99 #include <AknFepGlobalEnums.h>
       
   100 
       
   101 #include "smileymanager.h"
       
   102 #include "smileycustomwrap.h"
       
   103 #include <touchfeedback.h>
       
   104 
       
   105 GLDEF_C void Panic(TEikEdwinPanic aPanic)
       
   106     {
       
   107     _LIT(KPanicCat,"EIKON-EDWIN");
       
   108     User::Panic(KPanicCat,aPanic);
       
   109     }
       
   110 
       
   111 // For neutral character protection 
       
   112 enum 
       
   113     {
       
   114     EEikEdwinLeftToRightMark = 0x200E,
       
   115     EEikEdwinRightToLeftMark = 0x200F 
       
   116     };
       
   117 
       
   118 _LIT(KEikEdwinLeftToRightMark, "\x200E" );  // LRM
       
   119 _LIT(KEikEdwinRightToLeftMark, "\x200F" );  // RLM
       
   120 
       
   121 // Used by neutral protection code to extract small chunks of the editor at a time 
       
   122 // while searching for strong characters.
       
   123 const TInt KLengthAtATime(3);
       
   124 
       
   125 // Constants for controlling the switching between band and full document formatting
       
   126 const TInt KFullFormattingUpperThreshold=2000;      // Default initial value
       
   127 const TInt KPartialFormattingLowerThreshold=1900;   // Default initial value
       
   128 // This should be consistent with the difference between the two default limits:
       
   129 const TInt KFormattingThresholdGap=100; 
       
   130 // This should be significantly bigger than KFormattingThresholdGap (and certainly > 0):
       
   131 const TInt KMinimumPartialFormattingLength=400; 
       
   132 const TInt KMinimumFullFormattingLength=KMinimumPartialFormattingLength+KFormattingThresholdGap;
       
   133 
       
   134 // Unicode sign for S60 "enter" symbol
       
   135 const TInt KDownwardsArrowWithTipLeftwards  = 0x21B2;
       
   136 const TInt KDownwardsArrowWithTipRightwards = 0x21B3;
       
   137 
       
   138 // Unicode for euro sign
       
   139 const TInt KEuroSign = 0x20AC;
       
   140 const TInt KSegmSize = 1024;
       
   141 
       
   142 
       
   143 
       
   144 const TInt KNormalAnimPlayTimes = 2;
       
   145 const TInt KInfiniteAnimPlayTimes = 0x7ffff;
       
   146 const TInt KAdditionalPixels = 0x400;
       
   147 
       
   148 const TInt KFullFormatLengthForSmiley = 5000;
       
   149 
       
   150 //
       
   151 // class CEikEdwin::CUndoBuffer
       
   152 //
       
   153 
       
   154 class CEikEdwin::CUndoBuffer : public CBase
       
   155     {
       
   156 public:
       
   157     static CUndoBuffer* NewL();
       
   158     ~CUndoBuffer();
       
   159     CBufStore& Store() const;
       
   160     CStreamDictionary& Dictionary() const;
       
   161     TCursorSelection NewText() const;
       
   162     void SetNewText(const TCursorSelection& aSelection);
       
   163     TInt OldCursorPos() const;
       
   164     void SetOldCursorPos(TInt aPos);
       
   165 private:
       
   166     void ConstructL();
       
   167 private:
       
   168     CBufStore* iStore;
       
   169     CStreamDictionary* iDictionary;
       
   170     TCursorSelection iNewText;
       
   171     TInt iOldCursorPos;
       
   172     };
       
   173 
       
   174 CEikEdwin::CUndoBuffer* CEikEdwin::CUndoBuffer::NewL()
       
   175     { // static
       
   176     CUndoBuffer* self=new(ELeave) CUndoBuffer;
       
   177     CleanupStack::PushL(self);
       
   178     self->ConstructL();
       
   179     CleanupStack::Pop();  // self
       
   180     return self;
       
   181     }
       
   182 
       
   183 CEikEdwin::CUndoBuffer::~CUndoBuffer()
       
   184     {
       
   185     delete iStore;
       
   186     delete iDictionary;
       
   187     }
       
   188 
       
   189 void CEikEdwin::CUndoBuffer::ConstructL()
       
   190     {
       
   191     iStore=CBufStore::NewL(512);
       
   192     iDictionary=CStreamDictionary::NewL();
       
   193     }
       
   194 
       
   195 CBufStore& CEikEdwin::CUndoBuffer::Store() const
       
   196     {return *iStore;}
       
   197 CStreamDictionary& CEikEdwin::CUndoBuffer::Dictionary() const
       
   198     {return *iDictionary;}
       
   199 TCursorSelection CEikEdwin::CUndoBuffer::NewText() const
       
   200     {return iNewText;}
       
   201 void CEikEdwin::CUndoBuffer::SetNewText(const TCursorSelection& aSelection)
       
   202     {iNewText=aSelection;}
       
   203 TInt CEikEdwin::CUndoBuffer::OldCursorPos() const
       
   204     {return iOldCursorPos;}
       
   205 void CEikEdwin::CUndoBuffer::SetOldCursorPos(TInt aPos)
       
   206     {iOldCursorPos=aPos;}
       
   207 
       
   208 void CEikEdwin::CEikEdwinExtension::TAknEdwinPictographDrawer::DrawPictographArea()
       
   209     {
       
   210     }
       
   211 
       
   212 //
       
   213 // class CEikEdwinFepSupport
       
   214 //
       
   215 
       
   216 NONSHARABLE_CLASS(CEikEdwinFepSupport) : public CBase, public MCoeFepAwareTextEditor, public MCoeFepAwareTextEditor_Extension1, public TCoeInputCapabilities::MCoeFepSpecificExtensions
       
   217     {
       
   218     friend class CEikEdwin;
       
   219 public:
       
   220     static CEikEdwinFepSupport* New(CEikEdwin& aEdwin);
       
   221     virtual ~CEikEdwinFepSupport();
       
   222     TBool IsHandledByFepL(TPointerEvent::TType aType, TUint aModifiers, TInt aDocumentPosition);
       
   223     /**
       
   224     * Set the input capabilities in the edwin fep support object. A copy of the input capabilities
       
   225     * is maintained in and owned by the fep support; 
       
   226     *
       
   227     * @param aInputCapabilities     Reference to desired input capabilities object
       
   228     */
       
   229     void SetInputCapabilitiesL(const TCoeInputCapabilities& aInputCapabilities);
       
   230     const TCoeInputCapabilities* InputCapabilities() const;
       
   231     void ConstructStateHolder();
       
   232     // from MCoeFepAwareTextEditor_Extension1
       
   233     void SetStateTransferingOwnershipL(CState* aState, TUid aTypeSafetyUid);
       
   234     CState* State(TUid aTypeSafetyUid); // this function does *not* transfer ownership
       
   235 
       
   236 private:
       
   237     enum TPointerState
       
   238         {
       
   239         EPointerIsUp,
       
   240         EPointerIsDownStartingInsideInlineText,
       
   241         EPointerIsDownStartingOutsideInlineText
       
   242         };
       
   243     struct SPointerEventInInlineText
       
   244         {
       
   245         inline SPointerEventInInlineText(TPointerEvent::TType aType, TUint aModifiers, TInt aPositionInInlineText) :iType(aType), iModifiers(aModifiers), iPositionInInlineText(aPositionInInlineText) {}
       
   246         TPointerEvent::TType iType;
       
   247         TUint iModifiers;
       
   248         TInt iPositionInInlineText;
       
   249         };
       
   250 private:
       
   251     CEikEdwinFepSupport(CEikEdwin& aEdwin);
       
   252     void UpdateTextViewAfterChangeInInlineTextL(TBool aParagraphContainingStartPositionOfInlineTextHasChangedFormat,TInt aNumberOfCharactersSuccessfullyDeleted,TInt aNumberOfCharactersSuccessfullyInserted,TInt aError);
       
   253     void UpdateTextViewAfterChangeInInlineTextL(TBool aParagraphContainingStartPositionOfInlineTextHasChangedFormat,TInt aNumberOfCharactersSuccessfullyDeleted,TInt aNumberOfCharactersSuccessfullyInserted,TInt aError,TInt aSelectionAnchorPosition);
       
   254     void ResetInternalState();
       
   255 
       
   256     // from MCoeFepAwareTextEditor
       
   257     virtual void StartFepInlineEditL(const TDesC& aInitialInlineText, TInt aPositionOfInsertionPointInInlineText, TBool aCursorVisibility, const MFormCustomDraw* aCustomDraw, MFepInlineTextFormatRetriever& aInlineTextFormatRetriever, MFepPointerEventHandlerDuringInlineEdit& aPointerEventHandlerDuringInlineEdit);
       
   258     virtual void UpdateFepInlineTextL(const TDesC& aNewInlineText, TInt aPositionOfInsertionPointInInlineText);
       
   259     virtual void SetInlineEditingCursorVisibilityL(TBool aCursorVisibility);
       
   260     virtual void CancelFepInlineEdit();
       
   261     virtual TInt DocumentLengthForFep() const;
       
   262     virtual TInt DocumentMaximumLengthForFep() const;
       
   263     virtual void SetCursorSelectionForFepL(const TCursorSelection& aCursorSelection);
       
   264     virtual void GetCursorSelectionForFep(TCursorSelection& aCursorSelection) const;
       
   265     virtual void GetEditorContentForFep(TDes& aEditorContent, TInt aDocumentPosition, TInt aLengthToRetrieve) const; // must cope with aDocumentPosition being outside the range 0 to DocumentLengthForFep()
       
   266     virtual void GetFormatForFep(TCharFormat& aFormat, TInt aDocumentPosition) const;
       
   267     virtual void GetScreenCoordinatesForFepL(TPoint& aLeftSideOfBaseLine, TInt& aHeight, TInt& aAscent, TInt aDocumentPosition) const;
       
   268     virtual void DoCommitFepInlineEditL();
       
   269     virtual MCoeFepAwareTextEditor_Extension1* Extension1(TBool& aSetToTrue);
       
   270     virtual void MCoeFepAwareTextEditor_Reserved_2();
       
   271     // from MCoeFepAwareTextEditor_Extension1
       
   272 //  virtual void SetStateTransferingOwnershipL(CState* aState, TUid aTypeSafetyUid);
       
   273 //  virtual CState* State(TUid aTypeSafetyUid);
       
   274     virtual void StartFepInlineEditL(TBool& aSetToTrue, const TCursorSelection& aCursorSelection, const TDesC& aInitialInlineText, TInt aPositionOfInsertionPointInInlineText, TBool aCursorVisibility, const MFormCustomDraw* aCustomDraw, MFepInlineTextFormatRetriever& aInlineTextFormatRetriever, MFepPointerEventHandlerDuringInlineEdit& aPointerEventHandlerDuringInlineEdit);
       
   275     virtual void SetCursorType(TBool& aSetToTrue, const TTextCursor& aTextCursor);
       
   276     virtual void MCoeFepAwareTextEditor_Extension1_Reserved_3();
       
   277     virtual void MCoeFepAwareTextEditor_Extension1_Reserved_4();
       
   278     // from TCoeInputCapabilities::MCoeFepSpecificExtensions
       
   279     virtual TBool IsValidCharacter(TInt aChar);
       
   280     virtual void MCoeFepSpecificExtensions_Reserved_1();
       
   281     virtual void MCoeFepSpecificExtensions_Reserved_2();
       
   282 
       
   283 
       
   284 private:
       
   285     CEikEdwin& iEdwin;
       
   286     TCursorSelection iOriginalSelection;
       
   287     TInt iPositionOfInsertionPointInDocument;
       
   288     TInt iPositionOfInlineTextInDocument;
       
   289     TInt iLengthOfInlineText;
       
   290 public: 
       
   291     const MFormCustomDraw* iOldCustomDraw; // does not own anything
       
   292     MTouchFeedback* iFeedback;
       
   293     TBool iSelectionIsCancel;
       
   294     TInt iMoveThumbFeedbackNeeded;
       
   295 private:    
       
   296     MFepPointerEventHandlerDuringInlineEdit* iPointerEventHandlerDuringInlineEdit; // does not own anything
       
   297     SPointerEventInInlineText iLastPointerEventInInlineText;
       
   298     TPointerState iPointerState;
       
   299     TCoeInputCapabilities* iInputCapabilities;
       
   300     CState* iState;
       
   301     TUid iStateTypeSafetyUid;
       
   302     TInt iCharsDeleted;
       
   303     TInt iCharsInserted;
       
   304     TBool iShowCursor;
       
   305     };
       
   306 
       
   307 CEikEdwinFepSupport* CEikEdwinFepSupport::New(CEikEdwin& aEdwin)
       
   308     {
       
   309     return new CEikEdwinFepSupport(aEdwin);
       
   310     }
       
   311 
       
   312 CEikEdwinFepSupport::~CEikEdwinFepSupport()
       
   313     {
       
   314     delete iInputCapabilities;
       
   315     delete iState;
       
   316     }
       
   317 
       
   318 TBool CEikEdwinFepSupport::IsHandledByFepL(TPointerEvent::TType aType,TUint aModifiers,TInt aDocumentPosition)
       
   319     {
       
   320     if (iPositionOfInlineTextInDocument>=0)
       
   321         {
       
   322         __ASSERT_DEBUG((iOriginalSelection.iCursorPos>=0) && (iOriginalSelection.iAnchorPos>=0) && (iPositionOfInsertionPointInDocument>=0) && (iPositionOfInlineTextInDocument>=0) && (iLengthOfInlineText>=0) && (iPointerEventHandlerDuringInlineEdit!=NULL),Panic(EEikPanicBadInlineEditingState1));
       
   323         const TInt positionOfFirstCharacterInDocumentAfterInlineText=iPositionOfInlineTextInDocument+iLengthOfInlineText;
       
   324         switch (aType)
       
   325             {
       
   326         case TPointerEvent::EDrag:
       
   327         case TPointerEvent::EButton1Up:
       
   328             if (iPointerState!=EPointerIsUp)
       
   329                 {
       
   330                 break;
       
   331                 }
       
   332             // fall through (only will do this if no preceding TPointerEvent::EButton1Down occurred, either initially or since the previous TPointerEvent::EButton1Up event)
       
   333         case TPointerEvent::EButton1Down:
       
   334             if ((aDocumentPosition>=iPositionOfInlineTextInDocument) && (aDocumentPosition<=positionOfFirstCharacterInDocumentAfterInlineText))
       
   335                 {
       
   336                 iPointerState=EPointerIsDownStartingInsideInlineText;
       
   337                 }
       
   338             else
       
   339                 {
       
   340                 iPointerState=EPointerIsDownStartingOutsideInlineText;
       
   341                 }
       
   342             break;
       
   343 #if defined(__GCC32__)
       
   344         default:
       
   345             break;
       
   346 #endif
       
   347             }
       
   348         const TBool pointerIsDownStartingInsideInlineText=(iPointerState==EPointerIsDownStartingInsideInlineText);
       
   349         if (aType==TPointerEvent::EButton1Up)
       
   350             {
       
   351             iPointerState=EPointerIsUp;
       
   352             }
       
   353         if (pointerIsDownStartingInsideInlineText)
       
   354             {
       
   355             if (aDocumentPosition<iPositionOfInlineTextInDocument)
       
   356                 {
       
   357                 aDocumentPosition=iPositionOfInlineTextInDocument;
       
   358                 }
       
   359             if (aDocumentPosition>positionOfFirstCharacterInDocumentAfterInlineText)
       
   360                 {
       
   361                 aDocumentPosition=positionOfFirstCharacterInDocumentAfterInlineText;
       
   362                 }
       
   363             const TInt positionInInlineText=aDocumentPosition-iPositionOfInlineTextInDocument;
       
   364             if ((aType!=iLastPointerEventInInlineText.iType) || (aModifiers!=iLastPointerEventInInlineText.iModifiers) || (positionInInlineText!=iLastPointerEventInInlineText.iPositionInInlineText))
       
   365                 {
       
   366                 iLastPointerEventInInlineText.iType=aType;
       
   367                 iLastPointerEventInInlineText.iModifiers=aModifiers;
       
   368                 iLastPointerEventInInlineText.iPositionInInlineText=positionInInlineText;
       
   369                 iPointerEventHandlerDuringInlineEdit->HandlePointerEventInInlineTextL(aType,aModifiers,positionInInlineText);
       
   370                 }
       
   371             return ETrue;
       
   372             }
       
   373         }
       
   374 #if defined(_DEBUG)
       
   375     else
       
   376         {
       
   377         __ASSERT_DEBUG((iOriginalSelection.iCursorPos<0) && (iOriginalSelection.iAnchorPos<0) && (iPositionOfInsertionPointInDocument<0) && (iPositionOfInlineTextInDocument<0) && (iLengthOfInlineText<0) && (iOldCustomDraw==NULL) && (iPointerEventHandlerDuringInlineEdit==NULL),Panic(EEikPanicBadInlineEditingState2));
       
   378         }
       
   379 #endif
       
   380     return EFalse;
       
   381     }
       
   382 
       
   383 // This method treats the input capabilities slightly oddly in order to avoid re-allocation of Heap
       
   384 void CEikEdwinFepSupport::SetInputCapabilitiesL(const TCoeInputCapabilities& aInputCapabilities)
       
   385     {
       
   386     if (iInputCapabilities==NULL)
       
   387         {
       
   388         iInputCapabilities=new(ELeave) TCoeInputCapabilities(aInputCapabilities); // copy constructor
       
   389         }
       
   390     else
       
   391         {
       
   392         *iInputCapabilities=aInputCapabilities;  // Structure copy. OK for T class.
       
   393         }
       
   394     }
       
   395 
       
   396 const TCoeInputCapabilities* CEikEdwinFepSupport::InputCapabilities() const
       
   397     {
       
   398     return iInputCapabilities;
       
   399     }
       
   400 
       
   401 void CEikEdwinFepSupport::ConstructStateHolder()
       
   402     {
       
   403     iState = new CAknEdwinState(STATIC_CAST(MEikCcpuEditor*, &iEdwin));
       
   404     if (iState)
       
   405         static_cast<CAknEdwinState*>(iState)->SetObjectProvider(&iEdwin);
       
   406     }
       
   407 
       
   408 #pragma warning (disable: 4355) // warning disabled: "'this' : used in base member initializer list"
       
   409 CEikEdwinFepSupport::CEikEdwinFepSupport(CEikEdwin& aEdwin)
       
   410     :iEdwin(aEdwin),
       
   411      iOriginalSelection(-1,-1),
       
   412      iPositionOfInsertionPointInDocument(-1),
       
   413      iPositionOfInlineTextInDocument(-1),
       
   414      iLengthOfInlineText(-1),
       
   415      iOldCustomDraw(NULL),
       
   416      iFeedback(MTouchFeedback::Instance()),
       
   417      iSelectionIsCancel(EFalse),
       
   418      iMoveThumbFeedbackNeeded(EFalse),
       
   419      iPointerEventHandlerDuringInlineEdit(NULL),
       
   420      iLastPointerEventInInlineText((TPointerEvent::TType)-1,0,0),
       
   421      iPointerState(EPointerIsUp),
       
   422      iInputCapabilities(NULL)
       
   423     {
       
   424     __DECLARE_NAME(_S("CEikEdwinFepSupport"));
       
   425     }
       
   426 
       
   427 #pragma warning (default: 4355) // warning disabled: "assignment within conditional expression"
       
   428 
       
   429 void CEikEdwinFepSupport::UpdateTextViewAfterChangeInInlineTextL(TBool aParagraphContainingStartPositionOfInlineTextHasChangedFormat,TInt aNumberOfCharactersSuccessfullyDeleted,TInt aNumberOfCharactersSuccessfullyInserted,TInt aError)
       
   430     {
       
   431     UpdateTextViewAfterChangeInInlineTextL(aParagraphContainingStartPositionOfInlineTextHasChangedFormat,aNumberOfCharactersSuccessfullyDeleted,aNumberOfCharactersSuccessfullyInserted,aError,iPositionOfInsertionPointInDocument);
       
   432     }
       
   433 
       
   434 void CEikEdwinFepSupport::UpdateTextViewAfterChangeInInlineTextL(TBool aParagraphContainingStartPositionOfInlineTextHasChangedFormat,TInt aNumberOfCharactersSuccessfullyDeleted,TInt aNumberOfCharactersSuccessfullyInserted,TInt aError,TInt aSelectionAnchorPosition)
       
   435     {
       
   436     TCursorSelection select( iPositionOfInsertionPointInDocument, aSelectionAnchorPosition );
       
   437     iEdwin.iTextView->SetPendingSelection( select );    
       
   438     
       
   439     select.iAnchorPos = iPositionOfInlineTextInDocument;
       
   440     select.iCursorPos = select.iAnchorPos + aNumberOfCharactersSuccessfullyInserted;
       
   441     if ( iEdwin.iEdwinExtension->iSmiley )
       
   442         { 
       
   443         TInt textChange( aNumberOfCharactersSuccessfullyInserted - aNumberOfCharactersSuccessfullyDeleted );
       
   444         if ( textChange == 0 )
       
   445             {
       
   446             if ( iCharsDeleted < aNumberOfCharactersSuccessfullyDeleted )
       
   447                 {
       
   448                 iEdwin.iEdwinExtension->iSmiley->HandleDeleteL( iPositionOfInlineTextInDocument,
       
   449                         aNumberOfCharactersSuccessfullyDeleted - iCharsDeleted );
       
   450                 iCharsDeleted = aNumberOfCharactersSuccessfullyDeleted;
       
   451                 }
       
   452             if ( iCharsInserted < aNumberOfCharactersSuccessfullyInserted )
       
   453                 {
       
   454                 iEdwin.iEdwinExtension->iSmiley->HandleInsertL( 
       
   455                         iPositionOfInlineTextInDocument, 
       
   456                         ( aNumberOfCharactersSuccessfullyInserted - iCharsInserted ) );
       
   457                 iCharsInserted = aNumberOfCharactersSuccessfullyInserted;
       
   458                 }
       
   459             }
       
   460         else
       
   461             {
       
   462             if ( textChange > 0 )
       
   463                 {
       
   464                 iEdwin.iEdwinExtension->iSmiley->HandleInsertL( 
       
   465                     select.iAnchorPos + aNumberOfCharactersSuccessfullyDeleted, 
       
   466                     textChange );
       
   467                 }
       
   468             else if ( textChange < 0 )
       
   469                 {
       
   470                 iEdwin.iEdwinExtension->iSmiley->HandleDeleteL( aSelectionAnchorPosition,
       
   471                     textChange * -1 );
       
   472                 }
       
   473             }
       
   474         }
       
   475     iEdwin.iTextView->HandleInsertDeleteL( select, aNumberOfCharactersSuccessfullyDeleted,
       
   476         aParagraphContainingStartPositionOfInlineTextHasChangedFormat );
       
   477     User::LeaveIfError(aError);
       
   478     iEdwin.SetScrollBarsL();
       
   479     iEdwin.DoReportEventL(MCoeControlObserver::EEventStateChanged);
       
   480     if (aParagraphContainingStartPositionOfInlineTextHasChangedFormat)
       
   481         {
       
   482         iEdwin.ReportEdwinEventL(MEikEdwinObserver::EEventFormatChanged);
       
   483         }    
       
   484     }
       
   485 
       
   486 void CEikEdwinFepSupport::ResetInternalState()
       
   487     {
       
   488     iOriginalSelection.SetSelection(-1,-1);
       
   489     iPositionOfInsertionPointInDocument=-1;
       
   490     iPositionOfInlineTextInDocument=-1;
       
   491     iLengthOfInlineText=-1;
       
   492     iOldCustomDraw=NULL;
       
   493     iPointerEventHandlerDuringInlineEdit=NULL;
       
   494     }
       
   495 
       
   496 
       
   497 void CEikEdwinFepSupport::StartFepInlineEditL(
       
   498       const TDesC& aInitialInlineText,
       
   499       TInt aPositionOfInsertionPointInInlineText,
       
   500       TBool aCursorVisibility,
       
   501       const MFormCustomDraw* aCustomDraw,
       
   502       MFepInlineTextFormatRetriever& aInlineTextFormatRetriever,
       
   503       MFepPointerEventHandlerDuringInlineEdit& aPointerEventHandlerDuringInlineEdit)
       
   504     {
       
   505     __ASSERT_ALWAYS(iPositionOfInlineTextInDocument<0,Panic(EEikPanicBadInlineEditingState3)); // assert that we're not currently inline editing
       
   506     __ASSERT_DEBUG((iOriginalSelection.iCursorPos<0) && (iOriginalSelection.iAnchorPos<0) && (iPositionOfInsertionPointInDocument<0) && (iPositionOfInlineTextInDocument<0) && (iLengthOfInlineText<0) && (iOldCustomDraw==NULL) && (iPointerEventHandlerDuringInlineEdit==NULL),Panic(EEikPanicBadInlineEditingState4));
       
   507     iEdwin.PerformRecordedOperationL();
       
   508     CCoeEnv::Static()->ForEachFepObserverCall(FepObserverHandleStartOfTransactionL);
       
   509     iEdwin.SetKeyboardRepeatRate(KAknEditorKeyboardRepeatRate);
       
   510     iEdwin.CheckNotReadOnlyL();
       
   511     iEdwin.iEdwinExtension->iInlineEditing = ETrue;
       
   512     iShowCursor = aCursorVisibility;
       
   513     CAknEdwinState* state( iEdwin.EditorState() );
       
   514     state->SetInlineEditSpan( TCursorSelection( 0, 0 ) );
       
   515     const TCursorSelection selection=iEdwin.Selection();
       
   516     iOriginalSelection=selection;
       
   517     iPositionOfInsertionPointInDocument=selection.iCursorPos;
       
   518     iPositionOfInlineTextInDocument=selection.LowerPos();
       
   519     iPointerEventHandlerDuringInlineEdit=&aPointerEventHandlerDuringInlineEdit;
       
   520     TBool paragraphContainingStartPositionOfInlineTextHasChangedFormat=EFalse;
       
   521     TInt numberOfCharactersSuccessfullyDeleted=0;
       
   522     TInt numberOfCharactersSuccessfullyInserted=0;
       
   523     // handle extended highlights
       
   524 
       
   525 /* 
       
   526 WARNING.  do not insert any leaving function calls after the iEdwin.iText->StartFepInlineEditL unless they are trapped
       
   527 as this will call update-state problems.
       
   528 */
       
   529     TRAPD(error,
       
   530         {
       
   531         iEdwin.iTextView->ClearSelectionL();
       
   532         iEdwin.iText->StartFepInlineEditL(paragraphContainingStartPositionOfInlineTextHasChangedFormat,numberOfCharactersSuccessfullyDeleted,numberOfCharactersSuccessfullyInserted,iPositionOfInsertionPointInDocument,iPositionOfInlineTextInDocument+aPositionOfInsertionPointInInlineText,aInitialInlineText,iPositionOfInlineTextInDocument,selection.Length(),aInlineTextFormatRetriever);//);
       
   533         });
       
   534     if (error != KErrNone)
       
   535         { // cancel inline editing...
       
   536         ResetInternalState();
       
   537         User::LeaveIfError(error);
       
   538         }
       
   539     iLengthOfInlineText=numberOfCharactersSuccessfullyInserted;
       
   540     iOldCustomDraw=iEdwin.iLayout->CustomDraw();
       
   541     if (aCustomDraw)
       
   542         iEdwin.iLayout->SetCustomDraw(aCustomDraw);
       
   543 /*
       
   544 The scheme for this component is as follows:
       
   545 There are 3 levels of call to StartFepInlineEdit (from FEP to here, to CEditable)
       
   546 As each level contains its' own state to decide which mode it is in, complex issues arise upon a leave.
       
   547 
       
   548 Basically, if there is a leave, then all three levels must NOT be in inline edit mode.
       
   549 There are a number of possible ways of achieving this, but the simplest and most efficient has been 
       
   550 chosen here.  The method which changes the state must occur after the last leaving call in that method
       
   551 (NB if the state-changing method itself leaves, then this is ok).  That is to say "as soon as the lowest
       
   552 level has entered inline edit mode, all three levels are committed to inline edit mode, as they cannot 
       
   553 leave after this point".
       
   554 
       
   555 Therefore, the two calls below are deliberately trapped (as if they leave it does not matter) 
       
   556 */
       
   557 
       
   558     TRAP_IGNORE(
       
   559         {
       
   560         UpdateTextViewAfterChangeInInlineTextL(paragraphContainingStartPositionOfInlineTextHasChangedFormat,numberOfCharactersSuccessfullyDeleted,numberOfCharactersSuccessfullyInserted,error);
       
   561         iEdwin.SetCursorVisibilityL(aCursorVisibility);
       
   562         });
       
   563     }
       
   564 
       
   565 void CEikEdwinFepSupport::UpdateFepInlineTextL(const TDesC& aNewInlineText,TInt aPositionOfInsertionPointInInlineText)
       
   566     {
       
   567     __ASSERT_ALWAYS(iPositionOfInlineTextInDocument>=0,Panic(EEikPanicBadInlineEditingState5)); // assert that we're currently inline editing
       
   568     __ASSERT_DEBUG((iOriginalSelection.iCursorPos>=0) && (iOriginalSelection.iAnchorPos>=0) && (iPositionOfInsertionPointInDocument>=0) && (iPositionOfInlineTextInDocument>=0) && (iLengthOfInlineText>=0) && (iPointerEventHandlerDuringInlineEdit!=NULL),Panic(EEikPanicBadInlineEditingState6));
       
   569     TBool paragraphContainingStartPositionOfInlineTextHasChangedFormat=EFalse;
       
   570     TInt numberOfCharactersSuccessfullyDeleted=0;
       
   571     TInt numberOfCharactersSuccessfullyInserted=0;
       
   572     TRAPD(error,iEdwin.iText->UpdateFepInlineTextL(paragraphContainingStartPositionOfInlineTextHasChangedFormat,numberOfCharactersSuccessfullyDeleted,numberOfCharactersSuccessfullyInserted,iPositionOfInsertionPointInDocument,iPositionOfInlineTextInDocument+aPositionOfInsertionPointInInlineText,aNewInlineText));
       
   573     iLengthOfInlineText=numberOfCharactersSuccessfullyInserted;
       
   574     UpdateTextViewAfterChangeInInlineTextL(paragraphContainingStartPositionOfInlineTextHasChangedFormat,numberOfCharactersSuccessfullyDeleted,numberOfCharactersSuccessfullyInserted,error);
       
   575     iEdwin.ReportEdwinEventL( MEikEdwinObserver::EEventTextUpdate );
       
   576     }
       
   577 
       
   578 void CEikEdwinFepSupport::SetInlineEditingCursorVisibilityL(TBool aCursorVisibility)
       
   579     {
       
   580     __ASSERT_ALWAYS(iPositionOfInlineTextInDocument>=0,Panic(EEikPanicBadInlineEditingState7)); // assert that we're currently inline editing
       
   581     __ASSERT_DEBUG((iOriginalSelection.iCursorPos>=0) && (iOriginalSelection.iAnchorPos>=0) && (iPositionOfInsertionPointInDocument>=0) && (iPositionOfInlineTextInDocument>=0) && (iLengthOfInlineText>=0) && (iPointerEventHandlerDuringInlineEdit!=NULL),Panic(EEikPanicBadInlineEditingState8));
       
   582     iEdwin.SetCursorVisibilityL(aCursorVisibility);
       
   583     iShowCursor = aCursorVisibility;
       
   584     }
       
   585 
       
   586 void CEikEdwinFepSupport::CancelFepInlineEdit()
       
   587     {
       
   588     if (iPositionOfInlineTextInDocument>=0)
       
   589         {
       
   590         __ASSERT_DEBUG((iOriginalSelection.iCursorPos>=0) && (iOriginalSelection.iAnchorPos>=0) && (iPositionOfInsertionPointInDocument>=0) && (iPositionOfInlineTextInDocument>=0) && (iLengthOfInlineText>=0) && (iPointerEventHandlerDuringInlineEdit!=NULL),Panic(EEikPanicBadInlineEditingState11));
       
   591         iEdwin.iEdwinExtension->iInlineEditing = EFalse;
       
   592         iCharsInserted = 0;
       
   593         iCharsDeleted = 0;
       
   594         TBool paragraphContainingStartPositionOfInlineTextHasChangedFormat;
       
   595         TInt numberOfCharactersSuccessfullyDeleted( 0 );
       
   596         TInt numberOfCharactersSuccessfullyInserted( 0 );
       
   597         iEdwin.iText->CancelFepInlineEdit(paragraphContainingStartPositionOfInlineTextHasChangedFormat,numberOfCharactersSuccessfullyDeleted,numberOfCharactersSuccessfullyInserted,iPositionOfInsertionPointInDocument,iOriginalSelection.iCursorPos);
       
   598         TRAP_IGNORE(
       
   599             {
       
   600             UpdateTextViewAfterChangeInInlineTextL( 
       
   601                 paragraphContainingStartPositionOfInlineTextHasChangedFormat, 
       
   602                 numberOfCharactersSuccessfullyDeleted, 
       
   603                 numberOfCharactersSuccessfullyInserted, KErrNone, 
       
   604                 iOriginalSelection.iAnchorPos );
       
   605             if ( iEdwin.IsFocused() )
       
   606                 {
       
   607                 iEdwin.SetCursorVisibilityL( ETrue );
       
   608                 }
       
   609             });        
       
   610         iEdwin.iLayout->SetCustomDraw(iOldCustomDraw);
       
   611         ResetInternalState();
       
   612         if ( numberOfCharactersSuccessfullyDeleted || numberOfCharactersSuccessfullyInserted )
       
   613             {
       
   614             TRAP_IGNORE( iEdwin.ReportEdwinEventL( MEikEdwinObserver::EEventTextUpdate ) );
       
   615             }
       
   616         }
       
   617 #if defined(_DEBUG)
       
   618     else
       
   619         {
       
   620         __ASSERT_DEBUG((iOriginalSelection.iCursorPos<0) && (iOriginalSelection.iAnchorPos<0) && (iPositionOfInsertionPointInDocument<0) && (iPositionOfInlineTextInDocument<0) && (iLengthOfInlineText<0) && (iOldCustomDraw==NULL) && (iPointerEventHandlerDuringInlineEdit==NULL),Panic(EEikPanicBadInlineEditingState12));
       
   621         }
       
   622 #endif
       
   623     }
       
   624 
       
   625 TInt CEikEdwinFepSupport::DocumentLengthForFep() const
       
   626     {
       
   627     return iEdwin.TextLength();
       
   628     }
       
   629 
       
   630 TInt CEikEdwinFepSupport::DocumentMaximumLengthForFep() const
       
   631     {
       
   632     return iEdwin.iTextLimit;
       
   633     }
       
   634 
       
   635 void CEikEdwinFepSupport::SetCursorSelectionForFepL(const TCursorSelection& aCursorSelection)
       
   636     {
       
   637     TInt cursorPos( aCursorSelection.iCursorPos );
       
   638     TInt anchorPos( aCursorSelection.iAnchorPos );
       
   639     if ( iEdwin.IsSmileyEnabled() )
       
   640         {  
       
   641         CSmileyManager* smiley( iEdwin.iEdwinExtension->iSmiley );
       
   642         TInt oldPos = ( cursorPos == anchorPos ) ? iEdwin.CursorPos() : anchorPos; 
       
   643         smiley->HandleSetCursor( oldPos, cursorPos );       
       
   644         if ( aCursorSelection.iCursorPos == aCursorSelection.iAnchorPos )
       
   645             {
       
   646             anchorPos = cursorPos;
       
   647             }
       
   648         else
       
   649             {
       
   650             smiley->HandleSetCursor( cursorPos, anchorPos );
       
   651             }
       
   652         }
       
   653 	iEdwin.SetSelectionL( cursorPos, anchorPos );
       
   654     iEdwin.ReportEdwinEventL(MEikEdwinObserver::EEventNavigation);
       
   655     }
       
   656 
       
   657 void CEikEdwinFepSupport::GetCursorSelectionForFep(TCursorSelection& aCursorSelection) const
       
   658     {
       
   659     aCursorSelection=iEdwin.Selection();
       
   660     }
       
   661 
       
   662 void CEikEdwinFepSupport::GetEditorContentForFep(TDes& aEditorContent,TInt aDocumentPosition,TInt aLengthToRetrieve) const
       
   663     {
       
   664     TInt length( Min( aLengthToRetrieve, iEdwin.TextLength() - aDocumentPosition ) );
       
   665     iEdwin.iText->Extract( aEditorContent, aDocumentPosition, length );
       
   666     if ( iEdwin.IsSmileyEnabled() )
       
   667         {
       
   668         CSmileyManager* smiley( iEdwin.iEdwinExtension->iSmiley );
       
   669         CAknEdwinState* state( iEdwin.EditorState() );
       
   670         if ( state )
       
   671             {
       
   672             TCursorSelection inlineText( state->CurrentInlineEditSpan() );
       
   673             if ( aDocumentPosition >= inlineText.LowerPos() && 
       
   674                 aDocumentPosition + length <= inlineText.HigherPos() )
       
   675                 {
       
   676                 iEdwin.iEdwinExtension->iSmiley->ConvertTextForSmileyL(
       
   677                     aDocumentPosition, aEditorContent, EFalse );
       
   678                 }
       
   679             }
       
   680         TBool prevIsCode( EFalse );
       
   681         for ( TInt i( 0 ); i < length; i++ )
       
   682             {
       
   683             if ( aEditorContent[i] == CSmileyManager::KCompensateChar )
       
   684                 {
       
   685                 if ( i == 0 )
       
   686                     {
       
   687                     prevIsCode = ( CSmileyManager::IsSmileyCode( 
       
   688                         smiley->SmileyCodeByPos( aDocumentPosition ) ) );
       
   689                     }
       
   690                 if ( prevIsCode )
       
   691                     {
       
   692                     aEditorContent[i] = CSmileyManager::KPlaceHolder;
       
   693                     }
       
   694                 }
       
   695             else
       
   696                 {
       
   697                 prevIsCode = CSmileyManager::IsSmileyCode( aEditorContent[i] );
       
   698                 }
       
   699             }
       
   700         }
       
   701     }
       
   702 
       
   703 void CEikEdwinFepSupport::GetFormatForFep(TCharFormat& aFormat,TInt aDocumentPosition) const
       
   704     {
       
   705     TCharFormatMask notUsed;
       
   706     STATIC_CAST(CGlobalText*,iEdwin.iText)->GetCharFormat(aFormat,notUsed,aDocumentPosition,(aDocumentPosition==iEdwin.TextLength())? 0: 1);
       
   707     }
       
   708 
       
   709 void CEikEdwinFepSupport::GetScreenCoordinatesForFepL(TPoint& aLeftSideOfBaseLine,TInt& aHeight,TInt& aAscent,TInt aDocumentPosition) const
       
   710     {
       
   711     aDocumentPosition %= ( iEdwin.iText->DocumentLength() + 1 );    
       
   712     iEdwin.iTextView->DocPosToXyPosL(aDocumentPosition,aLeftSideOfBaseLine);
       
   713     aLeftSideOfBaseLine+=iEdwin.DrawableWindow()->InquireOffset(iEdwin.iCoeEnv->RootWin()); // make position "absolute" (i.e. not relative to the window that iEdwin is using) - note that *any* group window can be passed into InquireOffset to return the desired result, it doesn't have to be an ancestor of the window being used by iEdwin (i.e. this line of code does *not* make the assumption that iEdwin is (even indirectly) attached to iCoeEnv->RootWin())
       
   714     iEdwin.iLayout->GetCharacterHeightAndAscentL(aDocumentPosition,aHeight,aAscent);
       
   715     }
       
   716 
       
   717 MCoeFepAwareTextEditor_Extension1* CEikEdwinFepSupport::Extension1(TBool& aSetToTrue)
       
   718     {
       
   719     aSetToTrue=ETrue;
       
   720     return STATIC_CAST(MCoeFepAwareTextEditor_Extension1*, this);
       
   721     }
       
   722 
       
   723 void CEikEdwinFepSupport::DoCommitFepInlineEditL()
       
   724     {
       
   725     __ASSERT_ALWAYS(iPositionOfInlineTextInDocument>=0,Panic(EEikPanicBadInlineEditingState9)); // assert that we're currently inline editing
       
   726     __ASSERT_DEBUG((iOriginalSelection.iCursorPos>=0) && (iOriginalSelection.iAnchorPos>=0) && (iPositionOfInsertionPointInDocument>=0) && (iPositionOfInlineTextInDocument>=0) && (iLengthOfInlineText>=0) && (iPointerEventHandlerDuringInlineEdit!=NULL),Panic(EEikPanicBadInlineEditingState10));
       
   727     iEdwin.iEdwinExtension->iInlineEditing = EFalse;
       
   728     iCharsInserted = 0;
       
   729     iCharsDeleted = 0;
       
   730     TBool paragraphContainingStartPositionOfInlineTextHasChangedFormat=EFalse;
       
   731     TInt numberOfCharactersSuccessfullyDeleted=0;
       
   732     TInt numberOfCharactersSuccessfullyInserted=0;
       
   733     TRAPD(error1,iEdwin.iText->CommitFepInlineEditL(paragraphContainingStartPositionOfInlineTextHasChangedFormat,numberOfCharactersSuccessfullyDeleted,numberOfCharactersSuccessfullyInserted,iPositionOfInsertionPointInDocument,iPositionOfInsertionPointInDocument));
       
   734     TRAPD(error2,UpdateTextViewAfterChangeInInlineTextL(paragraphContainingStartPositionOfInlineTextHasChangedFormat,numberOfCharactersSuccessfullyDeleted,numberOfCharactersSuccessfullyInserted,error1));
       
   735     TCursorSelection select( iPositionOfInlineTextInDocument + 
       
   736         numberOfCharactersSuccessfullyInserted, iPositionOfInlineTextInDocument );
       
   737     if (iEdwin.iUndoStore!=NULL)
       
   738         {
       
   739         iEdwin.iUndoStore->SetNewText( select );
       
   740         }    
       
   741     if ( iEdwin.IsSmileyEnabled() )
       
   742         {
       
   743         CAknEdwinState* state( iEdwin.EditorState() );
       
   744         TCursorSelection inlineSpan( state->CurrentInlineEditSpan() );
       
   745         if ( inlineSpan.Length() == 0 || iShowCursor )
       
   746             {
       
   747             iEdwin.ConvertTextForSmileyL( select, ETrue , EFalse );            
       
   748             CSmileyManager* smiley( iEdwin.iEdwinExtension->iSmiley );
       
   749             TInt docPos( iEdwin.CursorPos() );
       
   750             smiley->HandleSetCursor( select.iAnchorPos, docPos );
       
   751             if ( docPos != select.iCursorPos )
       
   752                 {
       
   753                 TBool isSelected( iEdwin.SelectionLength() > 0 );
       
   754                 iEdwin.SetCursorPosL( docPos, isSelected );
       
   755                 if ( isSelected )
       
   756                     {
       
   757                     iEdwin.HandleSelectionForSmiley( iEdwin.Selection() );
       
   758                     }
       
   759                 }
       
   760             iEdwin.SetAmountToFormatL( EFalse, ETrue );
       
   761             iEdwin.DrawDeferred();
       
   762             }
       
   763         }
       
   764     iOriginalSelection.SetSelection(-1,-1);
       
   765     iPositionOfInsertionPointInDocument=-1;
       
   766     iPositionOfInlineTextInDocument=-1;
       
   767     iLengthOfInlineText=-1;
       
   768     iEdwin.iLayout->SetCustomDraw(iOldCustomDraw);
       
   769     iOldCustomDraw=NULL;
       
   770     iPointerEventHandlerDuringInlineEdit=NULL;
       
   771     iEdwin.ReportEdwinEventL( MEikEdwinObserver::EEventTextUpdate );
       
   772     User::LeaveIfError(error2);
       
   773     }
       
   774 
       
   775 /*MCoeFepAwareTextEditor_Extension1* CEikEdwinFepSupport::Extension1(TBool& aSetToTrue)
       
   776     {
       
   777     aSetToTrue=ETrue;
       
   778     return this;
       
   779     }
       
   780 */
       
   781 void CEikEdwinFepSupport::MCoeFepAwareTextEditor_Reserved_2()
       
   782     {
       
   783     }
       
   784 
       
   785 void CEikEdwinFepSupport::SetStateTransferingOwnershipL(CState* aState, TUid aTypeSafetyUid)
       
   786     {
       
   787     MEikCcpuEditor* currentCcpuState=STATIC_CAST(CAknEdwinState*, State(KNullUid))->CcpuState();
       
   788     MObjectProvider* currentObjectProvider=STATIC_CAST(CAknEdwinState*, State(KNullUid))->ObjectProvider();
       
   789     delete iState;
       
   790     iState=aState;
       
   791     STATIC_CAST(CAknEdwinState*, State(KNullUid))->SetCcpuState(currentCcpuState);
       
   792     STATIC_CAST(CAknEdwinState*, State(KNullUid))->SetObjectProvider(currentObjectProvider);
       
   793     iStateTypeSafetyUid.iUid=aTypeSafetyUid.iUid;
       
   794     }
       
   795 
       
   796 MCoeFepAwareTextEditor_Extension1::CState* CEikEdwinFepSupport::State(TUid aTypeSafetyUid)
       
   797     {
       
   798     if (aTypeSafetyUid.iUid==iStateTypeSafetyUid.iUid)
       
   799         {
       
   800         return iState;
       
   801         }
       
   802     return NULL;
       
   803     }
       
   804 
       
   805 void CEikEdwinFepSupport::StartFepInlineEditL(
       
   806         TBool& aSetToTrue, 
       
   807         const TCursorSelection& aCursorSelection, 
       
   808         const TDesC& aInitialInlineText, 
       
   809         TInt aPositionOfInsertionPointInInlineText, 
       
   810         TBool aCursorVisibility, 
       
   811         const MFormCustomDraw* aCustomDraw, 
       
   812         MFepInlineTextFormatRetriever& aInlineTextFormatRetriever, 
       
   813         MFepPointerEventHandlerDuringInlineEdit& aPointerEventHandlerDuringInlineEdit)
       
   814     {
       
   815     aSetToTrue=ETrue;
       
   816     iEdwin.PerformRecordedOperationL();
       
   817     TBool selectionVisible = iEdwin.iTextView->SelectionVisible();
       
   818     if (selectionVisible)
       
   819     	iEdwin.SetSelectionVisibilityL(EFalse);
       
   820     SetCursorSelectionForFepL(aCursorSelection);
       
   821 
       
   822     StartFepInlineEditL(aInitialInlineText, aPositionOfInsertionPointInInlineText, aCursorVisibility, aCustomDraw, aInlineTextFormatRetriever, aPointerEventHandlerDuringInlineEdit);
       
   823     if (selectionVisible)
       
   824     	iEdwin.SetSelectionVisibilityL(ETrue);
       
   825     }
       
   826 
       
   827 void CEikEdwinFepSupport::SetCursorType(TBool& /*aSetToTrue*/, const TTextCursor& aTextCursor)
       
   828     {
       
   829     TRAP_IGNORE( iEdwin.iTextView->SetCursorWidthTypeL( aTextCursor.iType ) );
       
   830     }
       
   831 
       
   832 void CEikEdwinFepSupport::MCoeFepAwareTextEditor_Extension1_Reserved_3()
       
   833     {
       
   834     }
       
   835 
       
   836 void CEikEdwinFepSupport::MCoeFepAwareTextEditor_Extension1_Reserved_4()
       
   837     {
       
   838     }
       
   839 
       
   840 TBool CEikEdwinFepSupport::IsValidCharacter(TInt aChar)
       
   841     {
       
   842     if (aChar == CEditableText::EParagraphDelimiter && 
       
   843         (iEdwin.UserFlags() & CEikEdwin::ENoLineOrParaBreaks))
       
   844         return EFalse;
       
   845 
       
   846     if ((aChar==EKeyEnter || aChar==CEditableText::EParagraphDelimiter) && iEdwin.iEdwinInternalFlags & CEikEdwin::EHasOneLineOnly)
       
   847         return EFalse;
       
   848     /*
       
   849     if (iEdwin.OnlyASCIIChars() && aChar > 0xFF && aChar != KPuaCodeSpaceSymbol)
       
   850         return EFalse;
       
   851     */
       
   852     
       
   853     if ( !iEdwin.IsValidChar( aChar ) )
       
   854         {
       
   855         return EFalse;
       
   856         }
       
   857         
       
   858     return ETrue;
       
   859     }
       
   860 
       
   861 
       
   862 void CEikEdwinFepSupport::MCoeFepSpecificExtensions_Reserved_1()
       
   863     {
       
   864     }
       
   865 
       
   866 void CEikEdwinFepSupport::MCoeFepSpecificExtensions_Reserved_2()
       
   867     {
       
   868     }
       
   869 
       
   870 
       
   871 //
       
   872 //  CEikEdwinExtension
       
   873 //
       
   874 CEikEdwin::CEikEdwinExtension* CEikEdwin::CEikEdwinExtension::NewL(CEikEdwin* aEdwin)
       
   875     {   
       
   876     CEikEdwinExtension* self = new (ELeave) CEikEdwinExtension();
       
   877     CleanupStack::PushL(self);
       
   878     self->ConstructL(aEdwin);
       
   879     CleanupStack::Pop();  // self
       
   880     return self;
       
   881     }
       
   882 
       
   883 CEikEdwin::CEikEdwinExtension::~CEikEdwinExtension()
       
   884     {  
       
   885     delete iPhysicsHandler;
       
   886     
       
   887     // Stop listening CenRep.
       
   888     if (iCenRepNotifyHandler)
       
   889         {
       
   890         iCenRepNotifyHandler->StopListening();
       
   891         }
       
   892     delete iCenRepNotifyHandler;
       
   893     delete iCenRep;
       
   894 
       
   895     delete iFormAccessor;
       
   896     delete iFormCursorModifier;
       
   897     delete iFormExtendedInterfaceProvider;
       
   898     delete iPictographInterface;
       
   899     delete iExtendedInputCapabilities;
       
   900     delete iPtSuppressor;
       
   901     if( iDestroyedPtr )
       
   902         {
       
   903         // Mark the object as destroyed.
       
   904         *iDestroyedPtr = ETrue;
       
   905         iDestroyedPtr = NULL;
       
   906         }
       
   907     delete iSmiley;
       
   908     delete iSmileyWrap;
       
   909     }
       
   910 
       
   911 EXPORT_C CAknEdwinFormAccessor* CEikEdwin::CEikEdwinExtension::FormAccessor() const
       
   912     {
       
   913     return iFormAccessor;
       
   914     }
       
   915 
       
   916 EXPORT_C void CEikEdwin::CEikEdwinExtension::SetFormAccessor(CAknEdwinFormAccessor* aFormAccessor)
       
   917     {
       
   918     iFormAccessor = aFormAccessor;
       
   919     }
       
   920 
       
   921 EXPORT_C void CEikEdwin::CEikEdwinExtension::SetScrollBarSetter(CIdle* aScrollBarSetter)
       
   922     {
       
   923     iSetScrollBar=aScrollBarSetter;
       
   924     }
       
   925 
       
   926 EXPORT_C CIdle* CEikEdwin::CEikEdwinExtension::ScrollBarSetter()
       
   927     {
       
   928     return iSetScrollBar;
       
   929     }
       
   930 
       
   931 EXPORT_C const TAvkonEditorCustomWrap& CEikEdwin::CEikEdwinExtension::TextWrapper()
       
   932     {
       
   933     return iTextWrapper;
       
   934     }
       
   935 
       
   936 EXPORT_C CFormCursorModifier* CEikEdwin::CEikEdwinExtension::FormCursorModifier() const
       
   937     {
       
   938     return iFormCursorModifier;
       
   939     }
       
   940 
       
   941 void CEikEdwin::CEikEdwinExtension::SetSkinBackgroundControlContext( MAknsControlContext* aBackgroundControlContext)
       
   942     {
       
   943     iSkinBackgroundControlContext = aBackgroundControlContext;
       
   944     iFlags.Set(ESkinBackgroundControlContextHasBeenSetIndex);
       
   945     }
       
   946 
       
   947 MAknsControlContext* CEikEdwin::CEikEdwinExtension::SkinBackgroundControlContext() const
       
   948     {
       
   949     return iSkinBackgroundControlContext;
       
   950     }
       
   951 
       
   952 TBool CEikEdwin::CEikEdwinExtension::SkinBackgroundControlContextHasBeenSet() const
       
   953     {
       
   954     return iFlags[ESkinBackgroundControlContextHasBeenSetIndex];
       
   955     }
       
   956 
       
   957 void CEikEdwin::CEikEdwinExtension::SetAlignment(TInt aAlignment)
       
   958     {
       
   959     iAlignment = aAlignment;
       
   960     TUint capabilities = iExtendedInputCapabilities->Capabilities();
       
   961     capabilities &= ~( CAknExtendedInputCapabilities::KAknEditorAlignMask );
       
   962     switch( iAlignment )
       
   963         {
       
   964         case EAknEditorAlignCenter:
       
   965             capabilities |= 
       
   966                 CAknExtendedInputCapabilities::EInputEditorAlignCenter;
       
   967             break;
       
   968         case EAknEditorAlignLeft:
       
   969             capabilities |= 
       
   970                 CAknExtendedInputCapabilities::EInputEditorAlignLeft;
       
   971             break;
       
   972         case EAknEditorAlignRight:
       
   973             capabilities |= 
       
   974                 CAknExtendedInputCapabilities::EInputEditorAlignRight;
       
   975             break;
       
   976         case EAknEditorAlignBidi:
       
   977             capabilities |= 
       
   978                 CAknExtendedInputCapabilities::EInputEditorAlignBidi;
       
   979             break;
       
   980         default:
       
   981             break;
       
   982         }
       
   983     iExtendedInputCapabilities->SetCapabilities( capabilities );
       
   984     }
       
   985 
       
   986 TInt CEikEdwin::CEikEdwinExtension::CurrentAlignment() const
       
   987     {
       
   988     return iAlignment;
       
   989     }
       
   990 
       
   991 void CEikEdwin::CEikEdwinExtension::SetSuppressBackgroundDrawing( TBool aSuppress )
       
   992     {
       
   993     iFlags.Assign( ESuppressBackgroundDrawing, aSuppress );
       
   994     }
       
   995 
       
   996 TBool CEikEdwin::CEikEdwinExtension::IsBackgroundDrawingSuppressed() const
       
   997     {
       
   998     return iFlags[ESuppressBackgroundDrawing];
       
   999     }
       
  1000 
       
  1001 void CEikEdwin::CEikEdwinExtension::SetPictoCallBack( TCallBack& aCallBack )
       
  1002     {
       
  1003     iPictoCallBack = aCallBack;
       
  1004     }
       
  1005 
       
  1006 const TCallBack& CEikEdwin::CEikEdwinExtension::PictoCallBack() const
       
  1007     {
       
  1008     return iPictoCallBack;
       
  1009     }
       
  1010 
       
  1011 CEikEdwin::CEikEdwinExtension::CEikEdwinExtension() :
       
  1012     iAlignment(EAknEditorAlignBidi),
       
  1013     iSkinIdForText(KErrNotFound),
       
  1014     iUpperFullFormattingLength(KFullFormattingUpperThreshold),
       
  1015     iTempCursorPos( KErrNotFound ),
       
  1016     iTempAnchorPos( KErrNotFound ),
       
  1017     iThumbPos( KErrNotFound ),
       
  1018     iEdwin( NULL ),
       
  1019     iPhysicsHandler( NULL )
       
  1020     {
       
  1021     }
       
  1022 
       
  1023 void CEikEdwin::CEikEdwinExtension::ConstructL(CEikEdwin* aEdwin)
       
  1024     {
       
  1025     iEdwin = aEdwin;
       
  1026     iFormAccessor = new (ELeave) CAknEdwinFormAccessor(aEdwin);
       
  1027     iFormCursorModifier = CFormCursorModifier::NewL(aEdwin->TextView(), aEdwin->TextLayout());
       
  1028     iPictographInterface = CAknPictographInterface::NewL( *aEdwin, iPictographDrawer );
       
  1029     iExtendedInputCapabilities = CAknExtendedInputCapabilities::NewL();
       
  1030     iPtSuppressor = CAknPointerEventSuppressor::NewL();
       
  1031 
       
  1032     // Start listening a CenRep key indicating whether hash key selection is active.
       
  1033     TRAPD(err, iCenRep = CRepository::NewL(KCRUidAknFep));
       
  1034     if (err == KErrNone)
       
  1035         {
       
  1036         iCenRepNotifyHandler = CCenRepNotifyHandler::NewL(*this,
       
  1037             *iCenRep,
       
  1038             CCenRepNotifyHandler::EIntKey,
       
  1039             KAknFepClearDirection);
       
  1040 
       
  1041         iCenRepNotifyHandler->StartListeningL();
       
  1042         iCenRep->Get(KAknFepClearDirection, iClearDirection);
       
  1043         }
       
  1044     iSmileyWrap = new ( ELeave ) CSmileyCustomWrap;
       
  1045     }
       
  1046 
       
  1047 void CEikEdwin::CEikEdwinExtension::CreateFormExtendedInterfaceProviderIfNeededL()
       
  1048     {
       
  1049     if ( !iFormExtendedInterfaceProvider )
       
  1050         iFormExtendedInterfaceProvider = CAknEdwinFormExtendedInterfaceProvider::NewL();
       
  1051     }
       
  1052 
       
  1053 CAknEdwinFormExtendedInterfaceProvider* CEikEdwin::CEikEdwinExtension::FormExtendedInferfaceProvider( ) const
       
  1054     {
       
  1055     return iFormExtendedInterfaceProvider;
       
  1056     }
       
  1057 
       
  1058 void CEikEdwin::CEikEdwinExtension::CreatePurePhoneNumberFormatterL( CTextLayout& /*aLayout*/, const CPlainText& aText )
       
  1059     {
       
  1060     CreateFormExtendedInterfaceProviderIfNeededL();
       
  1061 
       
  1062     if ( !iPhoneNumberFormatter )
       
  1063         {
       
  1064         CAknPhoneNumberInlineTextSource* phoneNumberFormatter = 
       
  1065             CAknPlainPhoneNumberInlineTextSource::NewL( aText );
       
  1066         CleanupStack::PushL( phoneNumberFormatter );
       
  1067         iFormExtendedInterfaceProvider->
       
  1068             CompositeInlineTextSource().InstallInlineTextSourceL( phoneNumberFormatter );
       
  1069         CleanupStack::Pop( phoneNumberFormatter );
       
  1070         iPhoneNumberFormatter = phoneNumberFormatter;
       
  1071         }
       
  1072     }
       
  1073 
       
  1074 
       
  1075 void CEikEdwin::CEikEdwinExtension::CreateNoMatchesIndicatorFormatterL( CTextLayout& aLayout )
       
  1076     {
       
  1077     CreateFormExtendedInterfaceProviderIfNeededL();
       
  1078 
       
  1079     if ( !iNoMatchesIndicatorFormatter )
       
  1080         {
       
  1081         CAknNoMatchesIndicatorInlineTextSource* noMatchesIndicatorFormatter = CAknNoMatchesIndicatorInlineTextSource::NewL( aLayout );
       
  1082         CleanupStack::PushL( noMatchesIndicatorFormatter );
       
  1083         iFormExtendedInterfaceProvider->CompositeInlineTextSource().InstallInlineTextSourceL( noMatchesIndicatorFormatter );
       
  1084         CleanupStack::Pop( noMatchesIndicatorFormatter );
       
  1085         iNoMatchesIndicatorFormatter = noMatchesIndicatorFormatter;
       
  1086         }
       
  1087     }
       
  1088 
       
  1089 
       
  1090 void CEikEdwin::CEikEdwinExtension::CreateRichTextPhoneNumberFormatterL( CTextLayout& /*aTextLayout*/, const CRichText& aText )
       
  1091     {
       
  1092     CreateFormExtendedInterfaceProviderIfNeededL();
       
  1093 
       
  1094     if ( !iPhoneNumberFormatter )
       
  1095         {
       
  1096         CAknRichTextPhoneNumberInlineTextSource* phoneNumberFormatter = 
       
  1097             CAknRichTextPhoneNumberInlineTextSource::NewL( aText );
       
  1098         CleanupStack::PushL( phoneNumberFormatter );
       
  1099         iFormExtendedInterfaceProvider->
       
  1100             CompositeInlineTextSource().InstallInlineTextSourceL( phoneNumberFormatter );
       
  1101         CleanupStack::Pop( phoneNumberFormatter );
       
  1102         iPhoneNumberFormatter = phoneNumberFormatter;
       
  1103         }
       
  1104 
       
  1105     }
       
  1106 
       
  1107 CAknInlineTextSource* CEikEdwin::CEikEdwinExtension::InlineTextSource() const
       
  1108     {
       
  1109     CAknEdwinFormExtendedInterfaceProvider* provider = FormExtendedInferfaceProvider();
       
  1110     if ( provider )
       
  1111         return &(provider->CompositeInlineTextSource());
       
  1112     else
       
  1113         return NULL;
       
  1114     }
       
  1115 
       
  1116 CAknPictographInterface* CEikEdwin::CEikEdwinExtension::PictographInterface() const
       
  1117     {
       
  1118     return iPictographInterface;
       
  1119     }
       
  1120 
       
  1121 TInt CEikEdwin::CEikEdwinExtension::ClearDirection() const
       
  1122     {
       
  1123     return iClearDirection;
       
  1124     }
       
  1125 
       
  1126 void CEikEdwin::CEikEdwinExtension::HandleNotifyInt(TUint32 aId, TInt aNewValue)
       
  1127     {
       
  1128     if (aId == KAknFepClearDirection)
       
  1129         {
       
  1130         iClearDirection = (TBool)aNewValue;
       
  1131         }
       
  1132     }
       
  1133 
       
  1134 // ---------------------------------------------------------------------------
       
  1135 // CEikEdwin::CEikEdwinExtension::EnableKineticScrollingL
       
  1136 // ---------------------------------------------------------------------------
       
  1137 //   
       
  1138 void CEikEdwin::CEikEdwinExtension::EnableKineticScrollingL()
       
  1139     {
       
  1140     iFlags.Set( EKineticScrollingEnabled );
       
  1141     EnablePhysicsL();
       
  1142     }
       
  1143 
       
  1144 // ---------------------------------------------------------------------------
       
  1145 // CEikEdwin::CEikEdwinExtension::EnablePhysicsL
       
  1146 // ---------------------------------------------------------------------------
       
  1147 //   
       
  1148 void CEikEdwin::CEikEdwinExtension::EnablePhysicsL()
       
  1149     {
       
  1150     if ( iFlags.IsSet( EKineticScrollingEnabled )
       
  1151         && !iPhysicsHandler && iEdwin->DrawableWindow() )
       
  1152         {
       
  1153         iPhysicsHandler = CAknEdwinPhysicsHandler::NewL( *iEdwin );
       
  1154         
       
  1155         InitPhysicsL();   
       
  1156         if ( iEdwin->iLayout )
       
  1157             {
       
  1158             iEdwin->iLayout->RestrictScrollToTopsOfLines( EFalse );
       
  1159             }
       
  1160         }
       
  1161     }
       
  1162 
       
  1163 // ---------------------------------------------------------------------------
       
  1164 // CEikEdwin::CEikEdwinExtension::InitPhysicsL
       
  1165 // ---------------------------------------------------------------------------
       
  1166 //   
       
  1167 void CEikEdwin::CEikEdwinExtension::InitPhysicsL()
       
  1168     {
       
  1169     if ( iPhysicsHandler )
       
  1170         {
       
  1171         if ( iEdwin->iTextView )
       
  1172             {
       
  1173             iPhysicsHandler->SetViewRect( iEdwin->AdjustedViewRect() );
       
  1174             }
       
  1175         iPhysicsHandler->InitPhysicsL();
       
  1176         }
       
  1177     }
       
  1178 
       
  1179 //
       
  1180 // class CEikEdwin
       
  1181 //
       
  1182 
       
  1183 
       
  1184 const TInt KPointerRepeatRate=50000;
       
  1185 // const TInt KBlockDeleteWarningSize=300; // minimum block delete that will elicit a query
       
  1186 
       
  1187 EXPORT_C CEikEdwin::~CEikEdwin()
       
  1188     {
       
  1189     AKNTASHOOK_REMOVE();
       
  1190     if ( iEdwinFepSupport )
       
  1191         {
       
  1192         CAknEdwinState* edwinState = STATIC_CAST( CAknEdwinState*, iEdwinFepSupport->State(KNullUid) );
       
  1193         if ( edwinState )
       
  1194             {                   
       
  1195             TRAP_IGNORE( edwinState->ReportAknEdStateEventL( MAknEdStateObserver::EAknEdwinDestroy ) );
       
  1196             }
       
  1197         }
       
  1198     SetKeyboardRepeatRate(KAknStandardKeyboardRepeatRate);
       
  1199     delete iCcpuSupport;
       
  1200     delete iCustomDrawer;
       
  1201     delete iEdwinFepSupport;
       
  1202 
       
  1203     if (!(iEdwinUserFlags&EKeepDocument))
       
  1204         delete iText;
       
  1205     delete iTextView;
       
  1206     delete iLayout;
       
  1207     if (iEdwinExtension)
       
  1208         {
       
  1209         delete iEdwinExtension->ScrollBarSetter();
       
  1210         }
       
  1211     delete iEdwinExtension;
       
  1212     delete iSBFrame;
       
  1213     delete iUndoStore;
       
  1214     delete iObserverArray;
       
  1215 #ifdef _DEBUG
       
  1216     TRAPD(err, SetVirtualCursorStateL(EFalse)); //should never leave
       
  1217     __ASSERT_DEBUG(err==KErrNone,Panic(EEikPanicVirtualCursorLeaveNotExpected));
       
  1218 #else
       
  1219     TRAP_IGNORE(SetVirtualCursorStateL(EFalse)); //should never leave
       
  1220 #endif // _DEBUG
       
  1221     
       
  1222     delete iCharFormatLayer;
       
  1223     delete iParaFormatLayer;
       
  1224     }
       
  1225 
       
  1226 EXPORT_C CEikEdwin::CEikEdwin()
       
  1227     : iZoomFactor(iEikonEnv->ScreenDevice()),
       
  1228     iAvgCharsPerLine(1)
       
  1229     {
       
  1230     __DECLARE_NAME(_S("CEikEdwin"));
       
  1231     LafEdwin::GetDefaultBorder(iBorder);
       
  1232     iMargins=LafEdwin::Margins();
       
  1233     BuildEdwinFepSupport();
       
  1234     iParaFormatLayer = NULL;
       
  1235     iCharFormatLayer = NULL;
       
  1236 
       
  1237     TRAPD(err, iEdwinExtension = CEikEdwinExtension::NewL(this));
       
  1238     if (err == KErrNone)
       
  1239         {
       
  1240         if (EditorState())
       
  1241             EditorState()->SetFormAccessor(iEdwinExtension->FormAccessor());
       
  1242         
       
  1243         iEdwinExtension->iExtendedInputCapabilities->SetEditorType(
       
  1244             CAknExtendedInputCapabilities::EEdwinBased );
       
  1245         }
       
  1246     AKNTASHOOK_ADD( this, "CEikEdwin" );
       
  1247     }
       
  1248 
       
  1249 EXPORT_C CEikEdwin::CEikEdwin(const TGulBorder& aBorder)
       
  1250     : CEikBorderedControl(aBorder),
       
  1251     iZoomFactor(iEikonEnv->ScreenDevice()),
       
  1252     iAvgCharsPerLine(1)
       
  1253     {
       
  1254     __DECLARE_NAME(_S("CEikEdwin"));
       
  1255     iMargins=LafEdwin::Margins();
       
  1256     BuildEdwinFepSupport();
       
  1257     iParaFormatLayer = NULL;
       
  1258     iCharFormatLayer = NULL;
       
  1259 
       
  1260     TRAPD(err, iEdwinExtension = CEikEdwinExtension::NewL(this));
       
  1261     if (err == KErrNone)
       
  1262         {
       
  1263         if (EditorState())
       
  1264             EditorState()->SetFormAccessor(iEdwinExtension->FormAccessor());
       
  1265         
       
  1266         iEdwinExtension->iExtendedInputCapabilities->SetEditorType(
       
  1267             CAknExtendedInputCapabilities::EEdwinBased );
       
  1268         }
       
  1269     AKNTASHOOK_ADD( this, "CEikEdwin" );
       
  1270     }
       
  1271 
       
  1272 void CEikEdwin::BuildEdwinFepSupport()
       
  1273     {
       
  1274     iEdwinFepSupport=CEikEdwinFepSupport::New(*this); // don't leave
       
  1275     if (iEdwinFepSupport)
       
  1276         {
       
  1277         iEdwinFepSupport->ConstructStateHolder();
       
  1278         if (!iEdwinFepSupport->State(KNullUid))
       
  1279             {
       
  1280             delete iEdwinFepSupport;
       
  1281             iEdwinFepSupport = NULL;
       
  1282             }
       
  1283         }
       
  1284     }
       
  1285 
       
  1286 EXPORT_C void CEikEdwin::ConstructFromResourceL(TResourceReader& aReader)
       
  1287     {
       
  1288     iEdwinUserFlags=iEdwinUserFlags | aReader.ReadInt32();
       
  1289     CalculateWidth(aReader.ReadInt16());
       
  1290     iNumberOfLines=aReader.ReadInt16();
       
  1291     iTextLimit=aReader.ReadInt16();
       
  1292     ReadAknResourceL(aReader);
       
  1293     BaseConstructL();
       
  1294     }
       
  1295 
       
  1296 
       
  1297 EXPORT_C TInt CEikEdwin::AknEdwinFlags() const
       
  1298     {
       
  1299     if (iEdwinFepSupport && iEdwinFepSupport->State(KNullUid))
       
  1300         return STATIC_CAST(CAknEdwinState*, iEdwinFepSupport->State(KNullUid))->Flags();
       
  1301     else
       
  1302         return 0;
       
  1303     }
       
  1304 
       
  1305 EXPORT_C void CEikEdwin::BaseConstructL()
       
  1306     {
       
  1307     if (iEdwinUserFlags&EEdwinAlternativeWrapping)
       
  1308         SetAvkonWrap(EFalse); 
       
  1309     else
       
  1310         SetAvkonWrap(ETrue); // added to make changes in Edwin spacing work. 
       
  1311     if (iEdwinUserFlags&EUserSuppliedText)
       
  1312         {
       
  1313         if (iNumberOfLines)
       
  1314             {
       
  1315             TInt height = iNumberOfLines*iEikonEnv->NormalFont()->HeightInPixels()+iBorder.SizeDelta().iHeight
       
  1316                             +iMargins.iTop+iMargins.iBottom;
       
  1317             SetEdwinHeight(height);
       
  1318             }
       
  1319         }
       
  1320     else
       
  1321         {
       
  1322         CheckIfEdwinIsResizable();
       
  1323         CParaFormatLayer* paraFormatLayer = (iEdwinInternalFlags&EHasOneLineOnly)
       
  1324                             ? iEikonEnv->SystemSingleLineParaFormatLayerL()
       
  1325                             : iEikonEnv->SystemParaFormatLayerL();
       
  1326         
       
  1327         SetParaFormatLayer(paraFormatLayer->CloneL());
       
  1328         SetCharFormatLayer(iEikonEnv->SystemCharFormatLayerL()->CloneL());
       
  1329         
       
  1330         CreateTextAndLayoutL(iParaFormatLayer,iCharFormatLayer);
       
  1331         }
       
  1332 
       
  1333     EnableCcpuSupportL(ETrue);
       
  1334     if (AknEdwinFlags()&EAknEditorFlagEnableScrollBars)
       
  1335         {
       
  1336         CEikScrollBarFrame* scrollFrame = CreatePreAllocatedScrollBarFrameL();
       
  1337         scrollFrame->SetScrollBarVisibilityL(CEikScrollBarFrame::EOff, CEikScrollBarFrame::EAuto);
       
  1338         scrollFrame->SetScrollBarFrameFlags(CEikScrollBarFrame::EVVisible);
       
  1339         }
       
  1340     SetVKBStatus();
       
  1341     }
       
  1342 
       
  1343 EXPORT_C void CEikEdwin::SetCharFormatLayer(CCharFormatLayer* aCharFormatLayer)
       
  1344     {
       
  1345     ASSERT(aCharFormatLayer);
       
  1346     if (iCharFormatLayer)
       
  1347         {
       
  1348         // copy all the format attributes of the new layer, apply to the already
       
  1349         // existing format layer, then delete the one passed in (this function was taking ownership)
       
  1350         // This avoids a problem with ETEXT and CRichText, where CGlobalText::iGlobalCharFormatLayer
       
  1351         // cannot be changed.
       
  1352         if (!(iCharFormatLayer->IsIdentical(aCharFormatLayer,EFalse)))
       
  1353             {
       
  1354             TRAP_IGNORE(MakeCharFormatLayerMatchL(aCharFormatLayer));
       
  1355             }
       
  1356         delete aCharFormatLayer;
       
  1357         }
       
  1358     else
       
  1359         {
       
  1360         iCharFormatLayer = aCharFormatLayer;
       
  1361         if (STATIC_CAST(CGlobalText*, Text()))
       
  1362             {
       
  1363             STATIC_CAST(CGlobalText*, Text())->SetGlobalCharFormat(iCharFormatLayer);
       
  1364             }
       
  1365         }
       
  1366     }
       
  1367 
       
  1368 EXPORT_C void CEikEdwin::SetParaFormatLayer(CParaFormatLayer* aParaFormatLayer)
       
  1369     {
       
  1370     ASSERT(aParaFormatLayer);
       
  1371     if (iParaFormatLayer)
       
  1372         {
       
  1373         // copy all the format attributes of the new layer, apply to the already
       
  1374         // existing format layer, then delete the one passed in (this function was taking ownership)
       
  1375         // This avoids a problem with ETEXT and CRichText, where CGlobalText::iGlobalCharFormatLayer
       
  1376         // cannot be changed.
       
  1377         if (!(iParaFormatLayer->IsIdentical(aParaFormatLayer,EFalse)))
       
  1378             {
       
  1379             TRAP_IGNORE(MakeParaFormatLayerMatchL(aParaFormatLayer));
       
  1380             }
       
  1381         delete aParaFormatLayer;
       
  1382         }
       
  1383     else
       
  1384         {
       
  1385         iParaFormatLayer = aParaFormatLayer;
       
  1386         if (STATIC_CAST(CGlobalText*, Text()))
       
  1387             {
       
  1388             STATIC_CAST(CGlobalText*, Text())->SetGlobalParaFormat(iParaFormatLayer);
       
  1389             }
       
  1390         }
       
  1391     }
       
  1392 
       
  1393 void CEikEdwin::MakeCharFormatLayerMatchL(CCharFormatLayer* aCharFormatLayer)
       
  1394     {
       
  1395     ASSERT(aCharFormatLayer);
       
  1396     TCharFormat newCharFormat;
       
  1397     aCharFormatLayer->SenseEffective(newCharFormat);
       
  1398     TCharFormat currentCharFormat;
       
  1399     iCharFormatLayer->SenseEffective(currentCharFormat);
       
  1400     if (!currentCharFormat.IsEqual(newCharFormat))
       
  1401         {
       
  1402         TCharFormatMask newCharFormatMask;
       
  1403         newCharFormatMask.SetAll();
       
  1404         iCharFormatLayer->SetL(newCharFormat,newCharFormatMask);
       
  1405         }
       
  1406     }
       
  1407 
       
  1408 void CEikEdwin::MakeParaFormatLayerMatchL(CParaFormatLayer* aParaFormatLayer)
       
  1409     {
       
  1410     ASSERT(aParaFormatLayer);
       
  1411     CParaFormat* newParaFormat=CParaFormat::NewLC();
       
  1412     CParaFormat* currentParaFormat=CParaFormat::NewLC();
       
  1413     aParaFormatLayer->SenseEffectiveL(newParaFormat);
       
  1414     iParaFormatLayer->SenseEffectiveL(currentParaFormat);
       
  1415     if (!currentParaFormat->IsEqual(*newParaFormat))
       
  1416         {
       
  1417         TParaFormatMask newParaFormatMask;
       
  1418         newParaFormatMask.SetAll();
       
  1419         iParaFormatLayer->SetL(newParaFormat,newParaFormatMask);
       
  1420         }
       
  1421     CleanupStack::PopAndDestroy(2); // currentParaFormat,newParaFormat
       
  1422     }
       
  1423 
       
  1424 EXPORT_C void CEikEdwin::SetSkinBackgroundControlContextL(  MAknsControlContext* aBackgroundControlContext )
       
  1425     {
       
  1426     CheckEdwinExtensionL(); // checks if iEdwinExtension is NULL and constucts it if it is
       
  1427     iEdwinExtension->SetSkinBackgroundControlContext( aBackgroundControlContext );
       
  1428     }
       
  1429 
       
  1430 MAknsControlContext* CEikEdwin::SkinBackgroundControlContext() const
       
  1431     {
       
  1432     MAknsControlContext* context = NULL;
       
  1433     if ( SkinEnabled() ) // Otherwise null is returned
       
  1434         {
       
  1435         if ( iEdwinExtension )
       
  1436             context = iEdwinExtension->SkinBackgroundControlContext();
       
  1437         // if context is still null we still may return a context, but it has to be from env.
       
  1438         if ( !context )
       
  1439             context = AknsDrawUtils::ControlContext( this );
       
  1440         }
       
  1441     return context;
       
  1442     }
       
  1443 
       
  1444 TBool CEikEdwin::SkinEnabled() const
       
  1445     {
       
  1446     TBool enabled( ETrue );
       
  1447     // return EFalse only if the background control context has been set by API
       
  1448     // and the value set is NULL
       
  1449     if ( iEdwinExtension )
       
  1450         {
       
  1451         if (iEdwinExtension->SkinBackgroundControlContextHasBeenSet() )
       
  1452             if ( !(iEdwinExtension->SkinBackgroundControlContext()) ) // do not use Edwin method here; would cause recursion
       
  1453                 enabled = EFalse;
       
  1454         }
       
  1455     return enabled;
       
  1456     }
       
  1457 
       
  1458 
       
  1459 void CEikEdwin::UpdateCache(TInt aId)
       
  1460     {
       
  1461     CAknSettingCache& cache = CAknEnv::Static()->SettingCache();
       
  1462     cache.Update(aId);
       
  1463     }
       
  1464 
       
  1465 void CEikEdwin::DrawTextView() const
       
  1466     {
       
  1467     if ( IsReadyToDraw() )
       
  1468         {
       
  1469         TRect rect = iTextView->ViewRect();    
       
  1470         Window().Invalidate( rect );
       
  1471         ActivateGc();
       
  1472         Window().BeginRedraw( rect );
       
  1473         TrappedDraw( iTextView->ViewRect() );
       
  1474         Window().EndRedraw();
       
  1475         DeactivateGc();
       
  1476         }
       
  1477     }
       
  1478 
       
  1479 /**
       
  1480 * This routine performs draws in the area around the text view. Most of the work is to drive the 
       
  1481 * custom drawer if present.
       
  1482 *
       
  1483 */
       
  1484 void CEikEdwin::DrawBackgroundAroundTextView( CWindowGc& gc, 
       
  1485                                              const TRect& aOuterRect, 
       
  1486                                              const TRect& aInnerRect, 
       
  1487                                              const TRgb& aBackgroundColor ) const
       
  1488     {
       
  1489     // Skins support
       
  1490     if ( iCustomDrawer )
       
  1491         {
       
  1492         TPoint point(aInnerRect.iTl); // Text layout upper left.
       
  1493         TZoomFactor map(iZoomFactor);
       
  1494 
       
  1495         // This returns the rectangle actually used. Not used here
       
  1496         TRect drawn;
       
  1497 
       
  1498         TRect rect=aOuterRect;
       
  1499         rect.iBr.iY=aInnerRect.iTl.iY;
       
  1500         iCustomDrawer->DrawBackground(
       
  1501             MFormCustomDraw::TParam( gc, map, point, rect ), aBackgroundColor, drawn);
       
  1502         rect.iBr.iY=aOuterRect.iBr.iY;
       
  1503         rect.iTl.iY=aInnerRect.iBr.iY;
       
  1504         iCustomDrawer->DrawBackground(
       
  1505             MFormCustomDraw::TParam( gc, map, point, rect ), aBackgroundColor, drawn);
       
  1506         rect=aInnerRect;
       
  1507         rect.iTl.iX=aOuterRect.iTl.iX;
       
  1508         rect.iBr.iX=aInnerRect.iTl.iX;
       
  1509         iCustomDrawer->DrawBackground(
       
  1510             MFormCustomDraw::TParam( gc, map, point, rect ), aBackgroundColor, drawn);
       
  1511         rect.iTl.iX=aInnerRect.iBr.iX;
       
  1512         rect.iBr.iX=aOuterRect.iBr.iX;
       
  1513         iCustomDrawer->DrawBackground(
       
  1514             MFormCustomDraw::TParam( gc, map, point, rect ), aBackgroundColor, drawn);
       
  1515         }
       
  1516     else 
       
  1517         {
       
  1518         // Draws with a null pen but solid brush
       
  1519         DrawUtils::ClearBetweenRects(gc,aOuterRect,aInnerRect);
       
  1520         }
       
  1521 
       
  1522     }
       
  1523 
       
  1524 EXPORT_C CLafEdwinCustomDrawBase* CEikEdwin::CreateCustomDrawL()
       
  1525     {
       
  1526     // If we have a text view, then use the constructor that sets it
       
  1527     CAknEdwinCustomDrawPrivate* customDrawer;
       
  1528     if ( iTextView )
       
  1529         {
       
  1530         CWindowGc& sysGc = SystemGc();
       
  1531         customDrawer = CAknEdwinCustomDrawPrivate::NewL(iEikonEnv->LafEnv(),*this, iTextView, &sysGc);
       
  1532         }
       
  1533     else
       
  1534         customDrawer = CAknEdwinCustomDrawPrivate::NewL(iEikonEnv->LafEnv(),*this);
       
  1535 
       
  1536     return customDrawer;
       
  1537     }
       
  1538 
       
  1539 void CEikEdwin::DoCreateCustomDrawL()
       
  1540     {
       
  1541 
       
  1542     if (!(iEdwinUserFlags&ENoCustomDraw))
       
  1543         {
       
  1544         if (!iCustomDrawer || iTextView )
       
  1545             {
       
  1546             TBool oldCustomDraw = EFalse;
       
  1547             
       
  1548             if ( iEdwinFepSupport )
       
  1549                 {
       
  1550                 oldCustomDraw = ( iEdwinFepSupport->iOldCustomDraw && iEdwinFepSupport->iOldCustomDraw == iCustomDrawer );
       
  1551                 }
       
  1552 
       
  1553             delete iCustomDrawer;
       
  1554             iCustomDrawer = 0;
       
  1555             iLayout->SetCustomDraw(0);
       
  1556             iCustomDrawer=CreateCustomDrawL();
       
  1557             
       
  1558             if ( oldCustomDraw )
       
  1559                 {
       
  1560                 iEdwinFepSupport->iOldCustomDraw = iCustomDrawer;
       
  1561                 }
       
  1562             }
       
  1563         }
       
  1564     if (!iCustomDrawer)
       
  1565         { // create a non-Avkon custom drawer that just does colour schemes
       
  1566         iCustomDrawer=CLafEdwinCustomDrawBase::NewL(iEikonEnv->LafEnv(),*this);
       
  1567         }
       
  1568 
       
  1569     iLayout->SetCustomDraw(iCustomDrawer);
       
  1570     }
       
  1571 
       
  1572 /**
       
  1573  * @internal
       
  1574  */
       
  1575 EXPORT_C void CEikEdwin::CreateTextAndLayoutL(CParaFormatLayer* aParaFormatLayer,CCharFormatLayer* aCharFormatLayer)
       
  1576     {
       
  1577     CancelFepTransaction();
       
  1578     CEditableText::TDocumentStorage storage=(iEdwinUserFlags&ESegmentedStorage)?
       
  1579                                 CEditableText::ESegmentedStorage: CEditableText::EFlatStorage;
       
  1580     TInt granularity = (iTextLimit != 0 && iTextLimit+2 < CEditableText::EDefaultTextGranularity)
       
  1581                         ? iTextLimit+2
       
  1582                         : CEditableText::EDefaultTextGranularity;
       
  1583     CGlobalText* globalText = (iEdwinInternalFlags&ERichText)
       
  1584                         ? CRichText::NewL(aParaFormatLayer,aCharFormatLayer,storage,granularity)
       
  1585                         : CGlobalText::NewL(aParaFormatLayer,aCharFormatLayer,storage,granularity);
       
  1586     iText=globalText;
       
  1587     CreateLayoutL(globalText);
       
  1588     SetHeightForNumOfLinesL();
       
  1589     DoCreateCustomDrawL();
       
  1590     if ( iEdwinExtension->iSmiley )
       
  1591         {
       
  1592         TextLayout()->SetCustomWrap( iEdwinExtension->iSmileyWrap );
       
  1593         }
       
  1594     }
       
  1595 
       
  1596 EXPORT_C void CEikEdwin::CheckEdwinExtensionL()
       
  1597     {
       
  1598     User::LeaveIfNull(EditorState());
       
  1599     if (!iEdwinExtension)
       
  1600         {
       
  1601         iEdwinExtension = CEikEdwinExtension::NewL(this);
       
  1602         EditorState()->SetFormAccessor(iEdwinExtension->FormAccessor());
       
  1603         }
       
  1604     }
       
  1605 
       
  1606 
       
  1607 EXPORT_C CEikEdwin::CEikEdwinExtension* CEikEdwin::EdwinExtension()
       
  1608     {
       
  1609     return iEdwinExtension;
       
  1610     }
       
  1611 
       
  1612 
       
  1613 EXPORT_C void CEikEdwin::ConstructL(TInt aEdwinFlags,TInt aWidthInChars,TInt aTextLimit,TInt aNumberOfLines)
       
  1614     {
       
  1615     iEdwinUserFlags |= aEdwinFlags;    
       
  1616     CalculateWidth(aWidthInChars);
       
  1617     iTextLimit=aTextLimit;
       
  1618     iNumberOfLines=aNumberOfLines;
       
  1619     BaseConstructL();
       
  1620     }
       
  1621 
       
  1622 EXPORT_C void CEikEdwin::SetEdwinObserver(MEikEdwinObserver* aEdwinObserver)
       
  1623     {
       
  1624     iEdwinObserver=aEdwinObserver;
       
  1625     }
       
  1626 
       
  1627 /**
       
  1628  * Add an observer of standard edwin events.  May be called any number of times and
       
  1629  * is independant of calls to SetEdwinObserver.
       
  1630  */
       
  1631 EXPORT_C void CEikEdwin::AddEdwinObserverL(MEikEdwinObserver* aEdwinObserver)
       
  1632     {
       
  1633     if (!iObserverArray)
       
  1634         iObserverArray=new(ELeave) CArrayPtrFlat<MEikEdwinObserver>(1);
       
  1635     iObserverArray->AppendL(aEdwinObserver);
       
  1636     }
       
  1637 
       
  1638 /**
       
  1639  * Removes aEdwinObserver form the list of observers.  Does nothing if aEdwinObserver isn't an observer.
       
  1640  */
       
  1641 EXPORT_C void CEikEdwin::RemoveEdwinObserver(MEikEdwinObserver* aEdwinObserver)
       
  1642     {
       
  1643     if (iObserverArray)
       
  1644         {
       
  1645         const TInt count=iObserverArray->Count();
       
  1646         for (TInt ii=0;ii<count;ii++)
       
  1647             {
       
  1648             if ((*iObserverArray)[ii]==aEdwinObserver)
       
  1649                 {
       
  1650                 iObserverArray->Delete(ii);
       
  1651                 break;
       
  1652                 }
       
  1653             }
       
  1654         if (iObserverArray->Count()==0)
       
  1655             {
       
  1656             delete iObserverArray;
       
  1657             iObserverArray=NULL;
       
  1658             }
       
  1659         }
       
  1660     }
       
  1661 
       
  1662 EXPORT_C void CEikEdwin::SetDocumentContentL(CGlobalText& aText,TSetContent aContent)
       
  1663     {
       
  1664     __ASSERT_DEBUG(&aText,Panic(EEikPanicNullPointer));
       
  1665     CancelFepTransaction();
       
  1666     if (aContent==ECopyText)
       
  1667         CopyDocumentContentL(aText,*((CGlobalText*)iText));
       
  1668     else
       
  1669         {
       
  1670         iText=&aText; // relies on any existing iText having been deleted by the caller
       
  1671         if (iEdwinInternalFlags&ERichText)
       
  1672             {
       
  1673             static_cast<CRichText*>(iText)->SetEditObserver(this);
       
  1674             TInt startPos=0;
       
  1675             TInt length=iText->DocumentLength();
       
  1676             static_cast<CRichText*>(iText)->ParseText(startPos,length,ETrue);
       
  1677             }
       
  1678         if (iLayout)
       
  1679             iLayout->SetLayDoc(&aText);
       
  1680         else
       
  1681             CreateLayoutL(&aText);
       
  1682         DoCreateCustomDrawL();
       
  1683         }
       
  1684     CheckRemovePictures(0,iText->DocumentLength());
       
  1685     CheckValidityOfChars(0,iText->DocumentLength());
       
  1686     SetAmountToFormatL(ETrue); // performs format
       
  1687     }
       
  1688 
       
  1689 EXPORT_C void CEikEdwin::CopyDocumentContentL(CGlobalText& aInText,CGlobalText& aOutText)
       
  1690     {
       
  1691     __ASSERT_DEBUG(&aInText,Panic(EEikPanicNullPointer));
       
  1692     __ASSERT_DEBUG(&aOutText,Panic(EEikPanicNullPointer));
       
  1693     aOutText.Reset();
       
  1694     CBufStore* store=CBufStore::NewLC(1024);
       
  1695     TStreamId streamId=aInText.StoreL(*store);
       
  1696     aOutText.RestoreL(*store,streamId);
       
  1697     RStoreWriteStream paraWriteStream;
       
  1698     TStreamId paraStreamId=paraWriteStream.CreateLC(*store);
       
  1699     (aInText.GlobalParaFormatLayer())->ExternalizeL(paraWriteStream);
       
  1700     CleanupStack::PopAndDestroy(); // paraStreamId
       
  1701     RStoreReadStream paraReadStream;
       
  1702     paraReadStream.OpenLC(*store,paraStreamId);
       
  1703     ((CParaFormatLayer*)(aOutText.GlobalParaFormatLayer()))->InternalizeL(paraReadStream);
       
  1704     CleanupStack::PopAndDestroy(); // paraReadStream
       
  1705     RStoreWriteStream charWriteStream;
       
  1706     TStreamId charStreamId=charWriteStream.CreateLC(*store);
       
  1707     (aInText.GlobalCharFormatLayer())->ExternalizeL(charWriteStream);
       
  1708     CleanupStack::PopAndDestroy(); // charStreamId
       
  1709     RStoreReadStream charReadStream;
       
  1710     charReadStream.OpenLC(*store,charStreamId);
       
  1711     ((CCharFormatLayer*)(aOutText.GlobalCharFormatLayer()))->InternalizeL(charReadStream);
       
  1712     CleanupStack::PopAndDestroy(2); // store and charReadStream
       
  1713     }
       
  1714 
       
  1715 EXPORT_C void CEikEdwin::CalculateWidth(TInt aWidthInChars)
       
  1716     {
       
  1717     const CFont* font=iEikonEnv->NormalFont();
       
  1718     iSize.iWidth=aWidthInChars;
       
  1719     if (!(iEdwinUserFlags&EWidthInPixels))
       
  1720         iSize.iWidth*=(iEdwinInternalFlags&ENumericCharacters? font->WidthZeroInPixels(): font->MaxNormalCharWidthInPixels());
       
  1721     iSize.iWidth+=iBorder.SizeDelta().iWidth+CursorWidth()+LineCursorWidth()+iMargins.iLeft+iMargins.iRight;
       
  1722     }
       
  1723 
       
  1724 void CEikEdwin::SetHeightForNumOfLinesL()
       
  1725     {
       
  1726     if (iNumberOfLines==0)
       
  1727         return;
       
  1728     iLayout->SetImageDeviceMap(iZoomFactor);
       
  1729     iLayout->FormatBandL();
       
  1730     TInt lineHeight = iLayout->FormattedHeightInPixels();
       
  1731     TInt edwinHeight = iNumberOfLines*lineHeight;
       
  1732     edwinHeight += iBorder.SizeDelta().iHeight+iMargins.iTop+iMargins.iBottom;
       
  1733     SetEdwinHeight(edwinHeight);
       
  1734     }
       
  1735 
       
  1736 EXPORT_C TKeyResponse CEikEdwin::OfferKeyEventL(const TKeyEvent& aKeyEvent,TEventCode aType)
       
  1737     {
       
  1738     if (aType!=EEventKey)
       
  1739         return EKeyWasNotConsumed;
       
  1740     TKeyEvent keyEvent = aKeyEvent;
       
  1741     LafEdwin::MapKeyEvent(keyEvent, aType);
       
  1742     return DoOfferKeyEventL(keyEvent, aType);
       
  1743     }
       
  1744 
       
  1745 TKeyResponse CEikEdwin::DoOfferKeyEventL(const TKeyEvent& aKeyEvent,TEventCode /*aType*/)
       
  1746     {
       
  1747     TInt code=aKeyEvent.iCode;
       
  1748     if ( code == EKeyLeftUpArrow || code == EKeyRightUpArrow)
       
  1749         {
       
  1750         code = EKeyUpArrow;
       
  1751         }
       
  1752     else if ( code == EKeyLeftDownArrow || code == EKeyRightDownArrow)
       
  1753         {
       
  1754         code = EKeyDownArrow;
       
  1755         }
       
  1756     const TCursorSelection selection=Selection();
       
  1757     const TInt selectionLength=selection.Length();
       
  1758     TInt cursorPos=CursorPos();
       
  1759     const TInt docLength=iText->DocumentLength();
       
  1760 
       
  1761 /*
       
  1762 if a 1 line editor, 
       
  1763 and the key is an up/down 
       
  1764 and not holding shift, 
       
  1765  => ignore the key.
       
  1766 */
       
  1767     if (
       
  1768         (iEdwinInternalFlags&EHasOneLineOnly)&&
       
  1769         (code==EKeyUpArrow || code==EKeyDownArrow) &&
       
  1770         (!(aKeyEvent.iModifiers&EModifierShift))
       
  1771         )
       
  1772         {
       
  1773         SetVirtualCursorStateL(EFalse);
       
  1774         return EKeyWasNotConsumed;
       
  1775         }
       
  1776     if (selectionLength==0)
       
  1777         {
       
  1778         if (code==EKeyLeftArrow || code==EKeyRightArrow || code==EKeyBackspace)
       
  1779             SetKeyboardRepeatRate(KAknEditorKeyboardRepeatRate);
       
  1780         else
       
  1781             SetKeyboardRepeatRate(KAknStandardKeyboardRepeatRate);
       
  1782 
       
  1783         TBool consume=ETrue;
       
  1784         TPoint cursorPoint;
       
  1785         if (iLayout->PosInBand(cursorPos,cursorPoint))
       
  1786             {
       
  1787             TPoint pos;
       
  1788 /* 
       
  1789 The following cases were added to stop Up/Down cursors moving the insert point to the
       
  1790 start/end of lines in the case of first/last line.  
       
  1791 However, we should only do this if there is not a shift held down, as otherwise it
       
  1792 is a selection operation
       
  1793 */
       
  1794             if (!(aKeyEvent.iModifiers&EModifierShift))
       
  1795                 {
       
  1796                 if (
       
  1797                     code==EKeyUpArrow && 
       
  1798                     iLayout->FirstDocPosFullyInBand()==0 &&
       
  1799                     iLayout->PosInBand(0,pos) && 
       
  1800                     pos.iY == cursorPoint.iY
       
  1801                     )
       
  1802                     {
       
  1803                     if (cursorPos == 0 || iNumberOfLines == 1)
       
  1804                         { 
       
  1805                         consume = EFalse;
       
  1806                         } 
       
  1807                     }
       
  1808                 if (consume && code==EKeyDownArrow)
       
  1809                     {
       
  1810                     if (iLayout->PosInBand(docLength,pos))
       
  1811                         {
       
  1812                         if (pos.iY == cursorPoint.iY)
       
  1813                             {
       
  1814                             if (cursorPos == TextLength() || iNumberOfLines == 1)
       
  1815                                 {
       
  1816                                 consume = EFalse;
       
  1817                                 }
       
  1818                             }
       
  1819                         }
       
  1820                     }
       
  1821                 }
       
  1822             }
       
  1823         if (!consume)
       
  1824             {
       
  1825             SetVirtualCursorStateL(EFalse);
       
  1826             return EKeyWasNotConsumed;
       
  1827             }
       
  1828         }
       
  1829     if (iEdwinUserFlags&EDisplayOnly)
       
  1830         return EKeyWasConsumed;
       
  1831     if ( iEdwinExtension->iDrawInvoked == CEikEdwinExtension::ENotDraw )
       
  1832         {
       
  1833         PerformRecordedOperationL();
       
  1834         }
       
  1835     const TInt modifiers=aKeyEvent.iModifiers;
       
  1836     TBool navigation=EFalse;
       
  1837     TBool formatChange=EFalse;
       
  1838     TBool select=modifiers&EModifierShift;
       
  1839     if ( select )
       
  1840         {        
       
  1841         CEikButtonGroupContainer* cba( CEikButtonGroupContainer::Current() );
       
  1842         if ( cba )
       
  1843             {            
       
  1844             TInt copyPos( cba->PositionById( EAknFepSoftkeyStartCopy ) );
       
  1845             TInt cutPos( cba->PositionById( EAknFepSoftkeyStartCut ) );
       
  1846             if ( copyPos != KErrNotFound || cutPos != KErrNotFound )
       
  1847                 {
       
  1848                 select = EFalse;
       
  1849                 }
       
  1850             }
       
  1851         }
       
  1852     TBool magnify=modifiers&EModifierCtrl;
       
  1853     const TInt oldLength=iText->DocumentLength();
       
  1854     if (magnify && ( code == EKeyF18 || ( code<100 && code!=' ' ) ) )////!!! magic number
       
  1855         {
       
  1856         TClipboardFunc clipboardFunc=ENoClipboard;
       
  1857         TBuf<24> buf;
       
  1858         if (select)
       
  1859             iCoeEnv->ReadResourceL(buf,R_EIK_EDWIN_SHIFT_CTRL_HOTKEYS);
       
  1860         else
       
  1861             iCoeEnv->ReadResourceL(buf,R_EIK_EDWIN_CTRL_HOTKEYS);
       
  1862         TInt ret=buf.Locate(TChar(code+'a'-1));        
       
  1863         if ( code == EKeyF18 )
       
  1864             {
       
  1865             ret = aKeyEvent.iScanCode;
       
  1866             }
       
  1867         switch (ret)
       
  1868             {
       
  1869         case EHotKeyCut:
       
  1870         case EEikCmdEditCut:
       
  1871             CheckNotReadOnlyL();
       
  1872             clipboardFunc=ECut;
       
  1873             formatChange=ETrue;
       
  1874             break;
       
  1875         case EHotKeyCopy:
       
  1876         case EEikCmdEditCopy:
       
  1877             clipboardFunc=ECopy;
       
  1878             break;
       
  1879         case EHotKeyPaste:
       
  1880             CheckNotReadOnlyL();
       
  1881             clipboardFunc=EPaste;
       
  1882             formatChange=ETrue;
       
  1883             break;
       
  1884         case EHotKeyUndo:
       
  1885             UndoL();
       
  1886             return EKeyWasConsumed;
       
  1887         case EHotKeyFind:
       
  1888             if (iEdwinInternalFlags&EHasOneLineOnly)
       
  1889                 return EKeyWasConsumed; 
       
  1890             if (!TextLength())
       
  1891                 iEikonEnv->InfoMsg(R_EIK_TBUF_NO_TEXT);
       
  1892             else if (!FindL(NULL))
       
  1893                 iEikonEnv->InfoMsg(R_EIK_TBUF_TEXT_NOT_FOUND);
       
  1894             else
       
  1895                 navigation=ETrue;
       
  1896             break;
       
  1897         case EHotKeyInsertChar:
       
  1898             RunCharMapDialogL();
       
  1899             return EKeyWasConsumed;
       
  1900         default:
       
  1901             ;
       
  1902             }
       
  1903         if (clipboardFunc>ENoClipboard)
       
  1904             {
       
  1905             ClipboardL(clipboardFunc);
       
  1906             return EKeyWasConsumed;
       
  1907             }
       
  1908 
       
  1909         // Select all
       
  1910         TChar ctrlStripped( code + 'a' - 1 );
       
  1911         if ( ctrlStripped == TChar('a') ) // ctrl-a is 0x01
       
  1912             {
       
  1913             SelectAllL();
       
  1914             return EKeyWasConsumed;
       
  1915             }
       
  1916         }
       
  1917     TKeyResponse ret=EKeyWasConsumed;
       
  1918     TBool reportChange=EFalse;
       
  1919     TBool formatHasChanged;
       
  1920     TInt charEditType=CTextLayout::EFCharacterInsert;
       
  1921     switch (code)
       
  1922         {
       
  1923     case EKeyPageUp:
       
  1924     case EKeyPageDown:
       
  1925         if (magnify)
       
  1926             SetCursorPosL((code==EKeyPageUp)? 0: TextLength(),select);
       
  1927         else
       
  1928             MoveCursorL((code==EKeyPageUp)? TCursorPosition::EFPageUp: TCursorPosition::EFPageDown, select);
       
  1929         if(CursorPos()==cursorPos && ((cursorPos==0 && code==EKeyPageUp) ||
       
  1930             (cursorPos==TextLength() && code==EKeyPageDown)))
       
  1931             SetVirtualCursorStateL(EFalse);
       
  1932         CancelInsertCharFormat();
       
  1933         navigation=ETrue;
       
  1934         break;
       
  1935     case EKeyHome:
       
  1936     case EKeyEnd:
       
  1937         {
       
  1938         const TBool cancelFormat=!((code==EKeyHome && selection.iCursorPos==0) ||
       
  1939                             (code==EKeyEnd && selection.iCursorPos==docLength));
       
  1940         if (magnify)
       
  1941             SetCursorPosL((code==EKeyHome? 0 : docLength),select);
       
  1942         else
       
  1943             MoveCursorL((code==EKeyHome)? TCursorPosition::EFLineBeg: TCursorPosition::EFLineEnd, select);
       
  1944         if (cancelFormat)
       
  1945             {
       
  1946             CancelInsertCharFormat();
       
  1947             navigation=ETrue;
       
  1948             }
       
  1949         else if(selection.Length()==0)
       
  1950             SetVirtualCursorStateL(EFalse);
       
  1951         break;
       
  1952         }
       
  1953     case EKeyUpArrow:
       
  1954     case EKeyDownArrow:
       
  1955         {
       
  1956         // Cancelformat should be true unless the key is stuck at the maximum/minimum position.
       
  1957         // Unfortunately the following code is not bidi: 
       
  1958         const TBool cancelFormat=!((code==EKeyUpArrow && selection.iCursorPos==0) ||
       
  1959                             (code==EKeyDownArrow && selection.iCursorPos==docLength));
       
  1960         if (selectionLength && !select)
       
  1961             CancelSelectionL(code==EKeyUpArrow? EStart: EEnd);
       
  1962         else
       
  1963             {
       
  1964             if (magnify)
       
  1965                 MoveCursorToChunkStartL(select,EChunkPara,(code==EKeyUpArrow)? EStart: EEnd);
       
  1966             else if (IsReadOnly() && (iEdwinUserFlags&EAvkonDisableCursor))
       
  1967                 ret = ScrollReadOnlyNoCursorDisplayL(code);
       
  1968             else
       
  1969                 MoveCursorL((code==EKeyUpArrow)? TCursorPosition::EFLineUp: TCursorPosition::EFLineDown, select);
       
  1970             }
       
  1971         if (cancelFormat)
       
  1972             {
       
  1973             CancelInsertCharFormat();
       
  1974             navigation=ETrue;
       
  1975             }
       
  1976         else if(selectionLength==0 && ((cursorPos==0 && code==EKeyUpArrow) ||
       
  1977             (cursorPos==TextLength() && code==EKeyDownArrow)))
       
  1978             SetVirtualCursorStateL(EFalse); // This logic not Bidi either...in
       
  1979         break;
       
  1980         }
       
  1981     case EKeyLeftArrow:
       
  1982     case EKeyRightArrow:
       
  1983         { 
       
  1984         if (iEdwinFepSupport && iEdwinFepSupport->State(KNullUid)) 
       
  1985             if  (STATIC_CAST(CAknEdwinState*, iEdwinFepSupport->State(KNullUid))->Flags()&EAknEditorFlagNoLRNavigation)
       
  1986                 return EKeyWasNotConsumed;      
       
  1987 
       
  1988         // This logic is to determine key/position situations that are not causing navigation. 
       
  1989         // All REAL navigation should set the cancelFormat flag. 
       
  1990         // However, In Series 60, all left/right keys navigate somewhere because of end-start looping.
       
  1991         // (In fact the right left keys causing document end to start looping do not even get here. Done in FEP)
       
  1992         TBool cancelFormat(ETrue);
       
  1993 
       
  1994         if (selectionLength && !select)
       
  1995             CancelSelectionL(code==EKeyLeftArrow? EStart: EEnd);
       
  1996         else
       
  1997             {
       
  1998             if (magnify)
       
  1999                 MoveCursorToChunkStartL(select,EChunkWord,(code==EKeyLeftArrow)? EStart: EEnd);
       
  2000             else
       
  2001                 MoveCursorL((code==EKeyLeftArrow)? TCursorPosition::EFLeft: TCursorPosition::EFRight, select);
       
  2002             }
       
  2003         if (cancelFormat)
       
  2004             {
       
  2005             CancelInsertCharFormat();
       
  2006             navigation=ETrue;
       
  2007             }
       
  2008         else if(selectionLength==0 && ((cursorPos==0 && code==EKeyLeftArrow) ||
       
  2009             (cursorPos==TextLength() && code==EKeyRightArrow)))
       
  2010             SetVirtualCursorStateL(EFalse);
       
  2011         break;
       
  2012         }
       
  2013     case EKeyEscape:
       
  2014         if (selectionLength)
       
  2015             iTextView->CancelSelectionL();
       
  2016         break;
       
  2017     case EKeyBackspace:
       
  2018         if (magnify && !(modifiers&EModifierPureKeycode))
       
  2019             break; // prevent Ctrl-H deleting
       
  2020     case EKeyDelete:
       
  2021         {
       
  2022         if (iEdwinExtension)
       
  2023             {
       
  2024             if (iEdwinExtension->ClearDirection() > 0)
       
  2025                 {
       
  2026                 if (code == EKeyBackspace)
       
  2027                     {
       
  2028                     if (!selectionLength
       
  2029                      && cursorPos != docLength)
       
  2030                         {
       
  2031                         code = EKeyDelete;
       
  2032                         }
       
  2033                     }
       
  2034                 else if (code == EKeyDelete && !select)
       
  2035                     {
       
  2036                     code = EKeyBackspace;
       
  2037                     }
       
  2038                 }
       
  2039             }
       
  2040 
       
  2041         // In case of pressing BS-key or Delete-key with shift-key,
       
  2042         // Change from BS(or Delete) to Delete(or BS)
       
  2043         if (select)
       
  2044             {
       
  2045             code = (code==EKeyBackspace)? EKeyDelete : EKeyBackspace;
       
  2046             }
       
  2047 
       
  2048         TBuf<2> newText; // Used for neutral protection
       
  2049         CheckNotReadOnlyL();
       
  2050 
       
  2051         TCursorSelection toDelete;
       
  2052         TBool deleteSelection = EFalse;
       
  2053         TBool replaceSelection = EFalse;
       
  2054         TBool forwardProtectionNeeded = EFalse;
       
  2055 
       
  2056         if (selectionLength)
       
  2057             {
       
  2058             toDelete = selection;
       
  2059             deleteSelection = ETrue;
       
  2060             SetSelectionL(toDelete.iCursorPos, toDelete.iAnchorPos);
       
  2061             }
       
  2062         else // no selection
       
  2063             {
       
  2064             //convert visible codes to original text strings.
       
  2065             if ( ConvertSmileyForDeleteL( cursorPos, ( code == EKeyBackspace ) ) )
       
  2066                 {
       
  2067                 return EKeyWasConsumed;
       
  2068                 }
       
  2069             if (code==EKeyDelete)
       
  2070                 toDelete = iTextView->GetForwardDeletePositionL();
       
  2071             else if (code==EKeyBackspace)
       
  2072                 {
       
  2073                 TInt cursorPos = CursorPos();
       
  2074                 if ( cursorPos > 0 )
       
  2075                     {
       
  2076                     TPtrC ptr(iText->Read(cursorPos-1)); 
       
  2077                     TInt glyphToDelete = ptr[0];
       
  2078                     if (  (glyphToDelete >= 0x0E01) && (glyphToDelete <= 0x0E5B) 
       
  2079 //                       #ifdef RD_HINDI
       
  2080                        || (glyphToDelete >= 0x0900) && (glyphToDelete <= 0x097F) //unicode code range for Devanagari. 
       
  2081 //                       #endif //RD_HINDI
       
  2082                        )
       
  2083                         {
       
  2084                         toDelete = TCursorSelection(cursorPos, cursorPos-1);
       
  2085                         }
       
  2086                     else
       
  2087                         {
       
  2088                         toDelete = iTextView->GetBackwardDeletePositionL();
       
  2089                         }
       
  2090                     }
       
  2091                 else
       
  2092                     toDelete = iTextView->GetBackwardDeletePositionL();                
       
  2093                 }
       
  2094 
       
  2095             if (toDelete.Length() > 1 )
       
  2096                 { // => we have some invisible characters to delete
       
  2097                 SetSelectionL(toDelete.iCursorPos, toDelete.iAnchorPos);
       
  2098                 deleteSelection = ETrue;
       
  2099                 }
       
  2100             // Neutral charcter protection
       
  2101             // Copy selection to descriptor
       
  2102             if ( EditorSupportsNeutralProtection() )
       
  2103                 {
       
  2104                 if ( NeedsNeutralProtection( toDelete.LowerPos(), toDelete.Length(), newText, forwardProtectionNeeded ) )
       
  2105                     replaceSelection = ETrue;
       
  2106                 }
       
  2107             }
       
  2108 
       
  2109         if (deleteSelection && !replaceSelection ) // delete select, but no neutral protection
       
  2110             {
       
  2111             DeleteHighlightL(formatHasChanged,code==EKeyBackspace);
       
  2112             const TInt lower=toDelete.LowerPos();
       
  2113             const TCursorSelection sel(lower,lower);
       
  2114             iTextView->SetPendingSelection(sel);
       
  2115             iTextView->HandleInsertDeleteL(sel,toDelete.Length(),formatHasChanged);
       
  2116             reportChange=ETrue;
       
  2117             }
       
  2118         else if ( replaceSelection ) // All neutral protection cases 
       
  2119             {
       
  2120             if ( !deleteSelection ) // selection has not been set yet
       
  2121                 SetSelectionL(toDelete.iCursorPos, toDelete.iAnchorPos);
       
  2122             TInt cursorPosInNewText = newText.Length(); // after neutral protection character(s)
       
  2123             if (forwardProtectionNeeded) // back it up if one was forward protecting
       
  2124                 cursorPosInNewText--; 
       
  2125             ReplaceSelectionWithTextL( newText, cursorPosInNewText, formatHasChanged ); 
       
  2126             reportChange=ETrue;
       
  2127             formatChange=formatHasChanged;
       
  2128             }
       
  2129         else // !deleteSelection  and !replaceSelection => Legacy single character delete
       
  2130             {
       
  2131             TInt pos=-1;
       
  2132             if (code==EKeyDelete)
       
  2133                 pos=cursorPos;
       
  2134             else if (code==EKeyBackspace)
       
  2135                 {
       
  2136                 pos=cursorPos;
       
  2137                 --pos;
       
  2138                 }
       
  2139             TBool isPicture=EFalse;
       
  2140             if (pos>=0)
       
  2141                 {
       
  2142                 TPtrC text=iText->Read(pos,1); // look at the single character
       
  2143                 if (text[0]==CEditableText::EPictureCharacter)
       
  2144                     {
       
  2145                     if (!iEikonEnv->QueryWinL(R_EIK_CONFIRM_DELETE_OBJECT_TITLE))
       
  2146                         return EKeyWasConsumed;
       
  2147                     isPicture=ETrue;
       
  2148                     }
       
  2149                 }
       
  2150 
       
  2151             TBool doDelete=EFalse;
       
  2152             if (code==EKeyBackspace)
       
  2153                 {
       
  2154                 charEditType=CTextLayout::EFLeftDelete;
       
  2155                 if (cursorPos>0)
       
  2156                     {
       
  2157                     doDelete=ETrue;
       
  2158                     --cursorPos;
       
  2159                     }
       
  2160                 }
       
  2161             else
       
  2162                 {
       
  2163                 charEditType=CTextLayout::EFRightDelete;
       
  2164                 if (cursorPos<TextLength())
       
  2165                     doDelete=ETrue;
       
  2166                 }
       
  2167             if (doDelete)
       
  2168                 {
       
  2169                 TCursorSelection selection=(isPicture? TCursorSelection(cursorPos,cursorPos+1) : TCursorSelection(cursorPos,cursorPos));
       
  2170                 DeleteL(formatHasChanged,selection,code==EKeyBackspace,isPicture);
       
  2171                 if (!isPicture)
       
  2172                     ClearUndo();
       
  2173                 iTextView->HandleCharEditL(charEditType,formatHasChanged);
       
  2174                 reportChange=ETrue;
       
  2175                 formatChange=formatHasChanged;
       
  2176                 }
       
  2177             }
       
  2178         if ( reportChange && iEdwinExtension->iSmiley )
       
  2179             {
       
  2180             ConvertTextForSmileyL( TCursorSelection( cursorPos, cursorPos ), 
       
  2181                 ETrue );          
       
  2182             if ( deleteSelection || replaceSelection )
       
  2183                 {
       
  2184                 SetCursorPosL( cursorPos, EFalse );
       
  2185                 }
       
  2186             }
       
  2187         }
       
  2188         break;
       
  2189     case '-':
       
  2190         if (select|magnify)
       
  2191             code=CEditableText::ENonBreakingHyphen;
       
  2192         goto InChar;
       
  2193     case EKeySpace:
       
  2194         if (select)
       
  2195             code=CEditableText::ENonBreakingSpace;
       
  2196         goto InChar;
       
  2197     case EKeyEnter:
       
  2198         if ( iEdwinUserFlags & ENoLineOrParaBreaks )
       
  2199             {       
       
  2200             return EKeyWasConsumed;
       
  2201             }
       
  2202         CheckNotReadOnlyL();
       
  2203         if (iEdwinInternalFlags&EHasOneLineOnly)
       
  2204             break;
       
  2205         code=(select? CEditableText::ELineBreak : CEditableText::EParagraphDelimiter);
       
  2206         if (code == CEditableText::EParagraphDelimiter)
       
  2207             NewParagraphL();
       
  2208         charEditType=(select? CTextLayout::EFCharacterInsert : CTextLayout::EFParagraphDelimiter);
       
  2209         goto TestMagnify;
       
  2210     case EKeyTab:
       
  2211         code=CEditableText::ETabCharacter;
       
  2212         // Tab characters are disabled in all editors
       
  2213         // because copy/paste and column/formattedcell listboxes
       
  2214         // do not work well and any tab characters in the
       
  2215         // strings will cause crashes in _all_ applications.
       
  2216         // (implements tabulator section in default event
       
  2217         // actions spec which says tab is inactive.)
       
  2218         if (!(iEdwinUserFlags&EAvkonTabsEnabled))
       
  2219             break;
       
  2220 TestMagnify:
       
  2221         if (magnify && !(modifiers&EModifierPureKeycode))
       
  2222             break; // prevent eg Ctrl-I inserting a tab
       
  2223         goto InChar;
       
  2224     default:
       
  2225         if (code>=ENonCharacterKeyBase || !TChar(code).IsPrint() || (!IsValidChar(code)))
       
  2226             {
       
  2227             ret=EKeyWasNotConsumed;
       
  2228             break;
       
  2229             }
       
  2230 InChar: CheckNotReadOnlyL();
       
  2231         TChar character(code);
       
  2232         if ( selectionLength && IsValidNumericCharL(character) )
       
  2233             {
       
  2234             TInt pos=DeleteHighlightL(formatHasChanged);
       
  2235             TRAPD(err,iText->InsertL(pos,character));
       
  2236             if ( iEdwinExtension->iSmiley )
       
  2237                 {
       
  2238                 iEdwinExtension->iSmiley->HandleInsertL( pos, 1 );
       
  2239                 ConvertTextForSmileyL( TCursorSelection( pos, pos ), ETrue );
       
  2240                 }
       
  2241             TCursorSelection selection=iTextView->Selection();
       
  2242             if (err==KErrNone && iUndoStore)
       
  2243                 iUndoStore->SetNewText(TCursorSelection(selection.LowerPos(),selection.LowerPos()+1));
       
  2244             TCursorSelection pending;
       
  2245             pending.iCursorPos=selection.LowerPos()+1;
       
  2246             pending.iAnchorPos=pending.iCursorPos;
       
  2247             iTextView->SetPendingSelection(pending);
       
  2248             selection=pending;
       
  2249             --selection.iAnchorPos;
       
  2250             iTextView->HandleInsertDeleteL(selection,selectionLength,formatHasChanged);
       
  2251             User::LeaveIfError(err);
       
  2252             reportChange=ETrue;
       
  2253             formatChange=formatHasChanged;
       
  2254             break;
       
  2255             }
       
  2256         if ( (!iTextLimit || TextLength()<iTextLimit) && IsValidNumericCharL(character) )
       
  2257             {
       
  2258             iText->InsertL(CursorPos(),character);
       
  2259             ClearUndo();
       
  2260             if ( iEdwinExtension->iSmiley )
       
  2261                 {
       
  2262                 TInt cursorPos( CursorPos() );
       
  2263                 iEdwinExtension->iSmiley->HandleInsertL( cursorPos, 1 );
       
  2264                 ConvertTextForSmileyL( TCursorSelection( cursorPos, cursorPos ), 
       
  2265                     ETrue );
       
  2266                 }
       
  2267             iTextView->HandleCharEditL(charEditType);
       
  2268             reportChange=ETrue;
       
  2269             }
       
  2270         else
       
  2271             {
       
  2272             ClearUndo();
       
  2273             CEikonEnv::Beep();
       
  2274             iEikonEnv->InfoMsg(R_EIK_TBUF_MAX_CHARACTERS_REACHED);
       
  2275             }
       
  2276         }
       
  2277     if (reportChange)
       
  2278         {
       
  2279         ReportEdwinEventL( MEikEdwinObserver::EEventTextUpdate );
       
  2280         DoReportEventL( MCoeControlObserver::EEventStateChanged );
       
  2281         if ( iEdwinExtension->iSmiley )
       
  2282             {            
       
  2283             TInt docPos( CursorPos() );
       
  2284             iEdwinExtension->iSmiley->HandleSetCursor( docPos, 
       
  2285                 docPos );
       
  2286             if ( docPos != CursorPos() )
       
  2287                 {
       
  2288                 SetCursorPosL( docPos, SelectionLength() > 0 );
       
  2289                 }
       
  2290             }
       
  2291         }
       
  2292     if (navigation)
       
  2293         { 
       
  2294         iEdwinExtension->iThumbPos = KErrNotFound;
       
  2295         ReportEdwinEventL(MEikEdwinObserver::EEventNavigation);
       
  2296         }
       
  2297     if (formatChange)
       
  2298         ReportEdwinEventL(MEikEdwinObserver::EEventFormatChanged);
       
  2299     if (NeedToChangeFormattingModeL()) 
       
  2300         SetAmountToFormatL();
       
  2301     UpdateScrollBarsL();
       
  2302     return ret;
       
  2303     }
       
  2304     
       
  2305 TKeyResponse CEikEdwin::ScrollReadOnlyNoCursorDisplayL(TUint aKeyCode)
       
  2306     {
       
  2307     __ASSERT_DEBUG(iTextView,Panic(EEikPanicEdwinNoView));
       
  2308     TCursorPosition::TMovementType move = (aKeyCode==EKeyUpArrow)? TCursorPosition::EFLineUp: TCursorPosition::EFLineDown;
       
  2309     // attempt to scroll the display, but prevent blank lines being added to the end
       
  2310     if (iTextView->ScrollDisplayL(move, CTextLayout::EFDisallowScrollingBlankSpace))
       
  2311         {
       
  2312         // make the cursor stay on the screen by matching its movement to the scrolling
       
  2313         MoveCursorL(move, EFalse);
       
  2314         return EKeyWasConsumed;
       
  2315         }
       
  2316     return EKeyWasNotConsumed;
       
  2317     }
       
  2318 
       
  2319 
       
  2320 void CEikEdwin::ReplaceSelectionWithTextL( const TDesC& aNewText,
       
  2321                                           TInt aPositionOfCursorInNewText,
       
  2322                                           TBool& aFormatHasChanged )
       
  2323     {
       
  2324     CheckNotReadOnlyL(); // leaves if readonly
       
  2325 
       
  2326     // The selection length is preserved as it is used in the HandleInsertDeleteL at the bottom
       
  2327     TInt deletedChars = iTextView->Selection().Length();
       
  2328 
       
  2329     // Just return if the new text minus the old text does not fit
       
  2330     if (iTextLimit && (TextLength() - deletedChars + aNewText.Length() > iTextLimit ) )
       
  2331         return;
       
  2332 
       
  2333     // Delete the selected text from the buffer; 
       
  2334     TCursorSelection selToDelete = iTextView->Selection();
       
  2335     TInt pos = selToDelete.iAnchorPos;
       
  2336     if ( selToDelete.Length() )
       
  2337         {
       
  2338         pos=DeleteHighlightL(aFormatHasChanged);
       
  2339         }
       
  2340 
       
  2341     // Insert new text.
       
  2342     // This is trapped so that we can get by with one call to HandleInsertDeleteL.
       
  2343     // However, we need to ensure that HandleInsertDeleteL is called at least after
       
  2344     // a non-leaving DeleteHighlightL. 
       
  2345     TInt newTextLength = 0; // if the following leaves, handling will be as if newText has length 0
       
  2346     TRAPD(err,iText->InsertL(pos,aNewText) );
       
  2347     if ( err == KErrNone )
       
  2348         newTextLength = aNewText.Length(); 
       
  2349 
       
  2350     // New selection to be passed to HandleInsertDeleteL.  Span the new text 
       
  2351     TCursorSelection selection(pos + newTextLength, pos); // Note, cursor pos is first parameter
       
  2352 
       
  2353     // Some undo stuff; unused in S60
       
  2354     if (err==KErrNone && iUndoStore)
       
  2355         iUndoStore->SetNewText(selection);
       
  2356 
       
  2357     // Following code is to set up for SetPendingSelection which dictates where the selection/cursor
       
  2358     // will be after the operation. Zero length selection dictated by aPositionOfCursorInNewText
       
  2359     TCursorSelection pending;
       
  2360     pending.iAnchorPos = selection.LowerPos() + Min( newTextLength, aPositionOfCursorInNewText);
       
  2361     pending.iCursorPos = pending.iAnchorPos;
       
  2362 
       
  2363     iTextView->SetPendingSelection(pending);
       
  2364 /*
       
  2365 Set up for the call for textview to handle the changed content
       
  2366 @param aSelection The start and new length of the changed block. 
       
  2367 @param aDeletedChars The number of deleted characters. 
       
  2368 @param aFormatChanged ETrue if text is to be reformatted from the start of the
       
  2369 paragraph the cursor was on before the edit, EFalse if from the start of the
       
  2370 line the cursor was on before the edit.
       
  2371 @return The number of pixels scrolled horizontally and vertically. ( Ignored )
       
  2372 */
       
  2373     (void)iTextView->HandleInsertDeleteL( selection, deletedChars, aFormatHasChanged);
       
  2374     User::LeaveIfError(err);
       
  2375     }
       
  2376 
       
  2377 EXPORT_C void* CEikEdwin::ExtensionInterface( TUid /*aInterface*/ )
       
  2378     {
       
  2379     return NULL;
       
  2380     }
       
  2381 
       
  2382 EXPORT_C void CEikEdwin::HandlePointerEventL(const TPointerEvent& aPointerEvent)
       
  2383     {
       
  2384     if ( iEdwinFepSupport )
       
  2385          {
       
  2386          CAknEdwinState* edwinState =
       
  2387              STATIC_CAST( CAknEdwinState*,
       
  2388              iEdwinFepSupport->State(KNullUid) );
       
  2389 
       
  2390          if ( edwinState && ( edwinState->Flags() & EAknEditorFlagChinesePopup ) )
       
  2391              {
       
  2392              return;
       
  2393              }
       
  2394          }
       
  2395     
       
  2396     if ( iEdwinExtension->iDrawInvoked == CEikEdwinExtension::ENotDraw )
       
  2397         {
       
  2398         PerformRecordedOperationL();
       
  2399         }
       
  2400     TCursorSelection selectionBefore = iTextView->Selection();
       
  2401     if (IsDimmed())
       
  2402         {
       
  2403         // IMHO, dimmed editor should not handle events
       
  2404         return;
       
  2405         }
       
  2406 
       
  2407     TBool kineticScrollingEnabled( KineticScrollingEnabled() );
       
  2408     if ( iEdwinExtension )
       
  2409         {
       
  2410         TPoint pos = aPointerEvent.iPosition;
       
  2411         
       
  2412         CAknExtendedInputCapabilities::
       
  2413             MAknEventObserver::TPointerEventReceivedParams params;
       
  2414 
       
  2415         if ( kineticScrollingEnabled &&
       
  2416             aPointerEvent.iType == TPointerEvent::EButton1Down )
       
  2417             {
       
  2418             iEdwinExtension->iPhysicsHandler->InitKineticScrolling(
       
  2419                 aPointerEvent.iPosition );
       
  2420             }
       
  2421 
       
  2422         params.iPointerEvent = aPointerEvent;
       
  2423         TTmPosInfo2 posInfo;
       
  2424         if(iTextView->FindXyPosL(pos, posInfo, NULL)) // not interested in the line
       
  2425             {
       
  2426             params.iDocPos = posInfo.iDocPos.iPos;   
       
  2427             }
       
  2428         else // Need to call this method for the case where the pen is beyond the last line of text
       
  2429             {
       
  2430             params.iDocPos = iTextView->XyPosToDocPosL( pos );
       
  2431             }
       
  2432         
       
  2433         /** The local @c destroyed variable keeps track of the object destroyed state. */
       
  2434         TBool destroyed = EFalse;
       
  2435         iEdwinExtension->iDestroyedPtr = &destroyed;
       
  2436         TRAP_IGNORE (
       
  2437             iEdwinExtension->iExtendedInputCapabilities->ReportEventL(
       
  2438                 CAknExtendedInputCapabilities::MAknEventObserver::EPointerEventReceived,
       
  2439                 &params );
       
  2440               )
       
  2441         if ( !destroyed )
       
  2442             {
       
  2443             iEdwinExtension->iDestroyedPtr = NULL;
       
  2444             }
       
  2445         else
       
  2446             {
       
  2447             return;
       
  2448             }
       
  2449         }
       
  2450 
       
  2451     // Kinetic scrolling related code begins
       
  2452  
       
  2453     if ( kineticScrollingEnabled )
       
  2454         {      
       
  2455         // This FEP related code block needs to perform only if EDisplayOnly
       
  2456         // flag was NOT SET to match to old functionality.
       
  2457         // In original code we returned here if EDisplayOnly was set.
       
  2458         // Now we have to continue (but skip this block of code)
       
  2459         // because kinetic scrolling is supported also in editors
       
  2460         // with EDisplayOnly flag and this is handled later in the code.
       
  2461         
       
  2462         const TCursorSelection selection( iTextView->Selection() );
       
  2463         const TPoint pointerPos( aPointerEvent.iPosition );
       
  2464 
       
  2465         if ( !( iEdwinUserFlags & EDisplayOnly ) )
       
  2466             {
       
  2467             if ( IsFocused() )
       
  2468                 {
       
  2469                 CancelFepTransaction();
       
  2470                 }
       
  2471             if ( iEdwinFepSupport && iCoeEnv->Fep() )
       
  2472                 {
       
  2473                 TPoint tempPos( pointerPos );
       
  2474                 const TInt documentPosition =
       
  2475                     iTextView->XyPosToDocPosL( tempPos );
       
  2476                     
       
  2477                 if ( iEdwinFepSupport->IsHandledByFepL( aPointerEvent.iType,
       
  2478                     aPointerEvent.iModifiers, documentPosition ) )
       
  2479                     {
       
  2480                     return;
       
  2481                     }                   
       
  2482                 }
       
  2483             }
       
  2484         
       
  2485         TBool shouldReturn( EFalse );
       
  2486         iEdwinExtension->iPhysicsHandler->HandleKineticScrolling(
       
  2487             aPointerEvent, shouldReturn );
       
  2488         
       
  2489         if ( shouldReturn )
       
  2490             {
       
  2491             return;
       
  2492             }
       
  2493      
       
  2494         } // physics enabled
       
  2495 
       
  2496     // Kinetic scrolling related code ends
       
  2497      
       
  2498     // Display only mode, don't handle selection but return here.
       
  2499     if ( iEdwinUserFlags & EDisplayOnly )
       
  2500         {
       
  2501         return;
       
  2502         }
       
  2503     
       
  2504     const TCursorSelection selection( iTextView->Selection() );
       
  2505     const TPoint pointerPos( aPointerEvent.iPosition );
       
  2506     
       
  2507     // Kinetic scrolling not enabled
       
  2508     if ( !kineticScrollingEnabled )
       
  2509         {
       
  2510         if ( IsFocused() )
       
  2511             {
       
  2512             CancelFepTransaction();
       
  2513             }
       
  2514         if ( iEdwinFepSupport != NULL )
       
  2515             {
       
  2516             if ( iEdwinFepSupport != NULL )
       
  2517                 {
       
  2518                 // an optimization so that iTextView->XyPosToDocPosL is not
       
  2519                 // called unnecessarily, since it needs to be called again,
       
  2520                 // after CancelFepTransaction has been called
       
  2521                 if (iCoeEnv->Fep()!=NULL) 
       
  2522                     {
       
  2523                     TPoint tempPos( pointerPos );
       
  2524                     const TInt documentPosition =
       
  2525                         iTextView->XyPosToDocPosL( tempPos );
       
  2526                     if ( iEdwinFepSupport->IsHandledByFepL( aPointerEvent.iType,
       
  2527                         aPointerEvent.iModifiers, documentPosition))
       
  2528                         {
       
  2529                         return;
       
  2530                         }
       
  2531                     }
       
  2532                 }
       
  2533             } 
       
  2534         } // Kinetic scrolling not enabled  
       
  2535     
       
  2536     if ( iEdwinExtension->iPtSuppressor->SuppressPointerEvent( aPointerEvent ) )
       
  2537         {
       
  2538         return;
       
  2539         }
       
  2540     if ( IsFocused() )
       
  2541         {
       
  2542         CancelFepTransaction();
       
  2543         }
       
  2544     TInt newCursorPos; // initialized a couple of lines below
       
  2545     {
       
  2546     TPoint tempPos(pointerPos); // the parameter to iTextView->XyPosToDocPosL gets stomped over, so copy pointerPos into a temporary TPoint object - the curly braces give this object a short lifetime
       
  2547     TTmPosInfo2 posInfo;
       
  2548     // newCursorPos needs to be initialised *after* CancelFepTransaction has been called, as CancelFepTransaction 
       
  2549     // may have changed the contents of the document by cancelling an inline edit, and in particular it may have made 
       
  2550     // the document shorter
       
  2551     if(iTextView->FindXyPosL(tempPos, posInfo, NULL)) // not interested in the line
       
  2552         {
       
  2553         newCursorPos = posInfo.iDocPos.iPos; // Gives correct value when pen is on right hand part of the character
       
  2554         }
       
  2555     else // Need to call this method for the case where the pen is beyond the last line of text
       
  2556         {
       
  2557         newCursorPos=iTextView->XyPosToDocPosL(tempPos); 
       
  2558         }
       
  2559     }
       
  2560     TBool select=(aPointerEvent.iModifiers&EModifierShift);
       
  2561     TBool navigation=EFalse;
       
  2562     switch (aPointerEvent.iType)
       
  2563         {
       
  2564     case TPointerEvent::EButton1Down:
       
  2565         {
       
  2566         SetVirtualCursorStateL(ETrue);
       
  2567         iLastPointerDocPos=CursorPos();
       
  2568         iLastPointerAnchorPos=selection.iAnchorPos;
       
  2569         if (iTextView->ViewRect().Contains(pointerPos))
       
  2570             iEdwinInternalFlags|=ELeftDownInViewRect;
       
  2571         else
       
  2572             return;
       
  2573         if (aPointerEvent.iModifiers&EModifierCtrl)
       
  2574             iEdwinInternalFlags|=EDragDouble;
       
  2575         else
       
  2576             iEdwinInternalFlags&=(~EDragDouble);
       
  2577 
       
  2578         if (iEdwinInternalFlags&EDragDouble)
       
  2579             {
       
  2580             TInt startPos,length;
       
  2581             GetWordInfo(newCursorPos,startPos,length);
       
  2582             SetSelectionL(startPos+length,startPos);
       
  2583             }
       
  2584         else
       
  2585             {
       
  2586             if ( iEdwinUserFlags & CEikEdwin::EAvkonDisableCursor )
       
  2587                 {
       
  2588                 iEdwinExtension->iTempCursorPos = newCursorPos;
       
  2589                 iEdwinExtension->iTempSelect = select;
       
  2590                 if ( selection.Length() > 0 && !select )
       
  2591                     {
       
  2592                     ClearSelectionL();
       
  2593                     iEdwinFepSupport->iSelectionIsCancel = ETrue;
       
  2594                     }
       
  2595                 }
       
  2596             else
       
  2597                 {
       
  2598                 CAknEdwinState* edwinState = STATIC_CAST( CAknEdwinState*, iEdwinFepSupport->State( KNullUid ) );
       
  2599                 iEdwinExtension->iRecordCursor = newCursorPos;
       
  2600                 // If touch input opened or no selection, set the new position. Otherwise record current position.
       
  2601                 if ( !( selection.iCursorPos != selection.iAnchorPos 
       
  2602                         && !( edwinState->Flags() & EAknEditorFlagTouchInputModeOpened  ) ) 
       
  2603                     || (iEdwinUserFlags & EAvkonDisableVKB ) || 
       
  2604                     ( iEdwinExtension->iExtendedInputCapabilities->Capabilities() & CAknExtendedInputCapabilities::EInputEditorQwertyInputActive ) )
       
  2605                     {                 
       
  2606                     EnableRateScrolling( ETrue );
       
  2607                     SetCursorPosL( newCursorPos, select );
       
  2608                     EnableRateScrolling( EFalse );
       
  2609                     
       
  2610                     // when point at the bottom line ,if it is not the last line CTextview will scroll up
       
  2611                     // one line. So we record if it scroll and record current point DocPos
       
  2612                     TPoint testPos = aPointerEvent.iPosition;  
       
  2613                     if ( newCursorPos != iTextView->XyPosToDocPosL( testPos ) )
       
  2614                         {
       
  2615                         iEdwinExtension->iRecordScroll = ETrue;
       
  2616                         iEdwinExtension->iRecordCursor = iTextView->XyPosToDocPosL( testPos );
       
  2617                         }
       
  2618                     else
       
  2619                         {
       
  2620                         iEdwinExtension->iRecordScroll = EFalse;    
       
  2621                         }
       
  2622                     }                
       
  2623                 }
       
  2624             }
       
  2625         break;
       
  2626         }
       
  2627     case TPointerEvent::EButtonRepeat:
       
  2628     case TPointerEvent::EDrag:
       
  2629     case TPointerEvent::EButton1Up:
       
  2630         {
       
  2631         iEdwinFepSupport->iMoveThumbFeedbackNeeded = ETrue;        
       
  2632         if (!(iEdwinInternalFlags&ELeftDownInViewRect))
       
  2633             return;
       
  2634         if ( aPointerEvent.iType == TPointerEvent::EDrag && 
       
  2635             ( iEdwinUserFlags & CEikEdwin::EAvkonDisableCursor ) &&
       
  2636             ( iEdwinExtension->iTempCursorPos != KErrNotFound ) )
       
  2637             {
       
  2638             SetCursorPosL( iEdwinExtension->iTempCursorPos,
       
  2639                 iEdwinExtension->iTempSelect );
       
  2640             iEdwinExtension->iTempCursorPos = KErrNotFound;
       
  2641             }
       
  2642         if ( aPointerEvent.iType == TPointerEvent::EButton1Up )
       
  2643             {
       
  2644             if (!iEdwinExtension->iScrollRect.IsEmpty())
       
  2645                 {
       
  2646                 TPoint point;
       
  2647                 TextLayout()->PosInBand(newCursorPos, point);
       
  2648                 TInt yPos = point.iY;
       
  2649                 TRect lineRect;
       
  2650                 TextLayout()->GetLineRect(yPos, lineRect);                      
       
  2651                 lineRect.iTl += Position();
       
  2652                 lineRect.iBr += Position();
       
  2653 
       
  2654 
       
  2655                 if (!(iEdwinExtension->iScrollRect.Contains(lineRect.iTl) || iEdwinExtension->iScrollRect.Contains(lineRect.iBr)))
       
  2656                     {
       
  2657                     TInt y = (iEdwinExtension->iScrollRect.iTl.iY + iEdwinExtension->iScrollRect.iBr.iY) / 2;
       
  2658                     if (lineRect.iTl.iY > y)
       
  2659                         { // Scroll up (cursor is down)
       
  2660                         TInt num = -1;
       
  2661                         TRAP_IGNORE( iTextView->ScrollDisplayLinesL(num));
       
  2662                         }
       
  2663                     else
       
  2664                         { // Scroll down (cursor is up)
       
  2665                         TInt num = 1;
       
  2666                         TRAP_IGNORE( iTextView->ScrollDisplayLinesL(num));
       
  2667                         }
       
  2668                     }
       
  2669                 }
       
  2670 
       
  2671             const TInt newAnchorPos=selection.iAnchorPos;
       
  2672             if (newCursorPos!=iLastPointerDocPos || newAnchorPos!=iLastPointerAnchorPos)
       
  2673                 navigation=ETrue;
       
  2674             iLastPointerDocPos=newCursorPos;
       
  2675             iLastPointerAnchorPos=newAnchorPos;
       
  2676             iEdwinInternalFlags&=(~ELeftDownInViewRect);
       
  2677 
       
  2678             // We can't open cut-copy-paste menu if dragging started
       
  2679             if ( IsReadOnly() && IsSelectionVisible() && !( kineticScrollingEnabled
       
  2680                 && iEdwinExtension->iPhysicsHandler->DraggingStarted() ) )
       
  2681                 {
       
  2682                 iEdwinFepSupport->iFeedback->InstantFeedback(
       
  2683                                                          this,
       
  2684                                                          ETouchFeedbackPopUp,
       
  2685                                                          ETouchFeedbackVibra,
       
  2686                                                          aPointerEvent );
       
  2687                 TRAP_IGNORE (
       
  2688                     iEdwinExtension->iExtendedInputCapabilities->ReportEventL(
       
  2689                         CAknExtendedInputCapabilities::MAknEventObserver::EOpenStylusMenuCcpu,
       
  2690                         NULL );
       
  2691                       )
       
  2692                 }
       
  2693             
       
  2694             if ( iEdwinFepSupport && 
       
  2695                  iTextView->ViewRect().Contains( pointerPos ) )
       
  2696                 {
       
  2697                 CAknEdwinState* edwinState =
       
  2698                     STATIC_CAST( CAknEdwinState*,
       
  2699                     iEdwinFepSupport->State(KNullUid) );
       
  2700 
       
  2701                 if ( kineticScrollingEnabled )
       
  2702                     {                  
       
  2703                     if ( !IsReadOnly() && !iEdwinExtension->iDragging &&
       
  2704                         !iEdwinExtension->iPhysicsHandler->DraggingStarted()   
       
  2705                         )
       
  2706                         {
       
  2707                         iEdwinFepSupport->iFeedback->InstantFeedback( this,
       
  2708                             ETouchFeedbackEdit, ETouchFeedbackVibra,
       
  2709                             aPointerEvent );
       
  2710                         }
       
  2711                     }
       
  2712                 else // Kinetic scrolling not enabled
       
  2713                     {
       
  2714                     if ( aPointerEvent.iType == TPointerEvent::EButton1Up && IsFocused() &&
       
  2715                         ( iEdwinFepSupport->iSelectionIsCancel ||
       
  2716                         !( iEdwinUserFlags & ( CEikEdwin::EAvkonDisableCursor |
       
  2717                             iEdwinUserFlags & CEikEdwin::EDisplayOnly |
       
  2718                             iEdwinUserFlags & CEikEdwin::EReadOnly |
       
  2719                             iEdwinUserFlags & CEikEdwin::EAvkonNotEditable ) ) ) )
       
  2720                         {
       
  2721                         iEdwinFepSupport->iFeedback->InstantFeedback(
       
  2722                             this,
       
  2723                             ETouchFeedbackEdit,
       
  2724                             ETouchFeedbackVibra,
       
  2725                             aPointerEvent );
       
  2726                         iEdwinFepSupport->iSelectionIsCancel = EFalse;
       
  2727                         }
       
  2728                     } 
       
  2729                 
       
  2730                 TBool kineticDragging = kineticScrollingEnabled &&
       
  2731                     ( iEdwinExtension->iPhysicsHandler->DraggingStarted() ||
       
  2732                       iEdwinExtension->iPhysicsHandler->
       
  2733                       DragThresholdExceeded( aPointerEvent.iPosition ) );
       
  2734                 
       
  2735                 if ( edwinState && !IsReadOnly() &&
       
  2736                     !iEdwinExtension->iDragging &&
       
  2737                     !kineticDragging )
       
  2738                     {
       
  2739                     TRAP_IGNORE(
       
  2740                         edwinState->ReportAknEdStateEventL(
       
  2741                             MAknEdStateObserver::EAknActivatePenInputRequest )
       
  2742                         );
       
  2743                     }
       
  2744                 }
       
  2745             }
       
  2746         TInt origWordStartPos, origWordLength;
       
  2747         GetWordInfo(selection.iAnchorPos,origWordStartPos,origWordLength);
       
  2748         TRect pictRect;
       
  2749         if (aPointerEvent.iType==TPointerEvent::EButton1Up &&
       
  2750             iTextView->GetPictureRectangleL(selection.LowerPos(),pictRect))
       
  2751             {
       
  2752         iEdwinFepSupport->iMoveThumbFeedbackNeeded = EFalse;        
       
  2753             break;
       
  2754             }
       
  2755         select=ETrue;
       
  2756         
       
  2757         TRect viewRect( AdjustedViewRect() );
       
  2758         
       
  2759         if ( aPointerEvent.iType != TPointerEvent::EButton1Up &&
       
  2760             ( ( pointerPos.iY >= viewRect.iBr.iY ) ||              
       
  2761               ( pointerPos.iY < viewRect.iTl.iY ) ) )
       
  2762             {            
       
  2763             TRect rect(TPoint(viewRect.iTl.iX-1000,viewRect.iBr.iY),TSize(viewRect.Width()+2000,2000));
       
  2764             if ( pointerPos.iY >= viewRect.iBr.iY )                
       
  2765                 {
       
  2766                 MoveCursorL(TCursorPosition::EFLineDown,select);
       
  2767                 }                
       
  2768             else
       
  2769                 {
       
  2770                 MoveCursorL(TCursorPosition::EFLineUp,select);
       
  2771                 rect.Move(0,-(viewRect.Height()+2000));
       
  2772                 }
       
  2773             Window().RequestPointerRepeatEvent(KPointerRepeatRate,rect);
       
  2774             navigation = ETrue;
       
  2775             iEdwinExtension->iThumbPos = KErrNotFound;
       
  2776             }
       
  2777         else if (iEdwinInternalFlags&EDragDouble)
       
  2778             {
       
  2779             TInt newWordStartPos,newWordLength;
       
  2780             GetWordInfo(newCursorPos,newWordStartPos,newWordLength);
       
  2781             if (selection.iCursorPos>selection.iAnchorPos)
       
  2782                 {
       
  2783                 if (newCursorPos<selection.iAnchorPos)
       
  2784                     SetSelectionL(newWordStartPos,origWordStartPos+origWordLength);
       
  2785                 else
       
  2786                     SetCursorPosL(newWordStartPos+newWordLength,select);
       
  2787                 }
       
  2788             else
       
  2789                 {
       
  2790                 if (newCursorPos>selection.iAnchorPos)
       
  2791                     SetSelectionL(newWordStartPos+newWordLength,origWordStartPos);
       
  2792                 else
       
  2793                     SetCursorPosL(newWordStartPos,select);
       
  2794                 }
       
  2795             }
       
  2796         else if ( aPointerEvent.iType != TPointerEvent::EButton1Up )
       
  2797             {
       
  2798             CAknEdwinState* edwinState = STATIC_CAST( CAknEdwinState*, iEdwinFepSupport->State(KNullUid) );
       
  2799             // Deal with second selection
       
  2800             if ( selection.iCursorPos != selection.iAnchorPos && 
       
  2801                  ( ! ( edwinState->Flags() & EAknEditorFlagTouchInputModeOpened ) )&& 
       
  2802                  !iEdwinExtension->iDragging 
       
  2803                )
       
  2804                 {
       
  2805                 if ( newCursorPos != iEdwinExtension->iRecordCursor )
       
  2806                     {
       
  2807                     SetCursorPosL( iEdwinExtension->iRecordCursor, EFalse );
       
  2808                     iEdwinExtension->iDragging = EFalse;
       
  2809                     iEdwinExtension->iRecordScroll = EFalse;
       
  2810                     }
       
  2811                 }
       
  2812             // If CTextView scroll at the bottom line and there is a little drag, 
       
  2813             // we should ignore the little drag. 
       
  2814             else if ( newCursorPos == iEdwinExtension->iRecordCursor
       
  2815                      && iEdwinExtension->iRecordScroll
       
  2816                      && !iEdwinExtension->iDragging )
       
  2817                 {
       
  2818                 break;
       
  2819                 }
       
  2820             else
       
  2821                 {
       
  2822                 // Deal with little drag in hardware
       
  2823                 if ( newCursorPos != iEdwinExtension->iRecordCursor )
       
  2824                     {
       
  2825                     iEdwinExtension->iDragging = ETrue;
       
  2826                     }
       
  2827                 else
       
  2828                     {
       
  2829                     iEdwinExtension->iDragging = EFalse;   
       
  2830                     }
       
  2831                 SetCursorPosL( newCursorPos, select );
       
  2832                 iEdwinExtension->iRecordScroll = EFalse;
       
  2833                 }
       
  2834             }
       
  2835         iEdwinFepSupport->iMoveThumbFeedbackNeeded = EFalse;        
       
  2836         break;
       
  2837         }
       
  2838     default:
       
  2839         break;
       
  2840         }
       
  2841         if (aPointerEvent.iType == TPointerEvent::EButton1Down 
       
  2842          || aPointerEvent.iType == TPointerEvent::EDrag
       
  2843          || aPointerEvent.iType == TPointerEvent::EButtonRepeat )
       
  2844             {
       
  2845             const TCursorSelection selectionAfter = iTextView->Selection();
       
  2846             TBool selectionVisible = iTextView->SelectionVisible();
       
  2847             TBool paintingPossible = selectionVisible;
       
  2848             TBool selectionChanged = 
       
  2849                 paintingPossible 
       
  2850                 && (  ( selectionAfter.iCursorPos != selectionBefore.iCursorPos )
       
  2851                    || ( selectionAfter.iAnchorPos != selectionBefore.iAnchorPos ) );
       
  2852             const TBool focused=IsFocused();
       
  2853             const TBool readOnly = IsReadOnly();
       
  2854             // editor got event, can be focused -> will be focused? 
       
  2855             TBool editorWillGetFocus = !focused && 
       
  2856                                        !IsNonFocusing() && 
       
  2857                                        aPointerEvent.iType == TPointerEvent::EButton1Down;
       
  2858 
       
  2859             TBool editingEnabled = !readOnly;
       
  2860             if ( iEdwinFepSupport && 
       
  2861                  iEdwinFepSupport->iFeedback && 
       
  2862                  ( paintingPossible || editorWillGetFocus ) )
       
  2863                 {
       
  2864                 if ( aPointerEvent.iType == TPointerEvent::EButton1Down && editingEnabled )
       
  2865                     {
       
  2866                     // on down event feedback is given if cursor/selection changes
       
  2867                     if ( paintingPossible && !readOnly || editorWillGetFocus )
       
  2868                         {
       
  2869                         iEdwinFepSupport->iFeedback->InstantFeedback( this, ETouchFeedbackBasic );
       
  2870                         }
       
  2871                     }
       
  2872                 else  if ( selectionChanged && 
       
  2873                        ( ( aPointerEvent.iType == TPointerEvent::EDrag ) ||
       
  2874                          ( aPointerEvent.iType == TPointerEvent::EButtonRepeat ) ) )
       
  2875                     {
       
  2876                     
       
  2877                     // selectionAfter.iCursorPos-1 below is because we need to select the previous char
       
  2878                     TBool ltr = ( selectionAfter.iCursorPos >= selectionBefore.iCursorPos );
       
  2879                     TInt readPos = selectionAfter.iCursorPos;
       
  2880                     if (ltr && readPos > 0)
       
  2881                         {
       
  2882                         readPos -= 1; // read previous char
       
  2883                         }
       
  2884                     TChar currentSelectedChar = Text()->Read( readPos, 1 )[0]; 
       
  2885                     TBool isSpace = currentSelectedChar.IsSpace();
       
  2886                     TBool isText = currentSelectedChar.IsAlpha() 
       
  2887                                 || currentSelectedChar.IsDigit();
       
  2888                     
       
  2889                     // case line
       
  2890                     TInt prevLineNr = TextLayout()->GetLineNumber(selectionBefore.iCursorPos);
       
  2891                     TInt lineNr = TextLayout()->GetLineNumber(selectionAfter.iCursorPos);
       
  2892                     if ( prevLineNr != lineNr && ( selection.Length() != 0 ) )
       
  2893                         {
       
  2894                         TInt group = ( currentSelectedChar.GetCategory() & 0xF0 );
       
  2895                         TBool isEmptyLine = ( group == TChar::ESeparatorGroup );
       
  2896                         TTouchLogicalFeedback fType = ( isEmptyLine ? 
       
  2897                             ETouchFeedbackEmptyLineSelection : ETouchFeedbackLineSelection );
       
  2898                         iEdwinFepSupport->iFeedback->InstantFeedback( this, fType );
       
  2899                         }
       
  2900                     // case space
       
  2901                     else if (isSpace)
       
  2902                         {
       
  2903                         iEdwinFepSupport->iFeedback->InstantFeedback( this, ETouchFeedbackBlankSelection );
       
  2904                         }
       
  2905                     // case text
       
  2906                     else if (isText)    
       
  2907                         {
       
  2908                         iEdwinFepSupport->iFeedback->InstantFeedback( this, ETouchFeedbackTextSelection );
       
  2909                         }
       
  2910                     }
       
  2911                 }
       
  2912             }
       
  2913     if ( aPointerEvent.iType == TPointerEvent::EButton1Up && iEdwinExtension->iDragging )
       
  2914         {
       
  2915         iEdwinExtension->iDragging = EFalse;
       
  2916         }
       
  2917     if ( aPointerEvent.iType == TPointerEvent::EButton1Up && iEdwinExtension->iRecordScroll )
       
  2918         {
       
  2919         iEdwinExtension->iRecordScroll = EFalse;
       
  2920         }
       
  2921     if ( aPointerEvent.iType == TPointerEvent::EButton1Up )
       
  2922         {
       
  2923         iEdwinExtension->iRecordCursor = -1;
       
  2924         }
       
  2925     if (navigation)
       
  2926         {
       
  2927         ReportEdwinEventL(MEikEdwinObserver::EEventNavigation);
       
  2928         CancelInsertCharFormat();
       
  2929         }
       
  2930     }
       
  2931 
       
  2932 EXPORT_C void CEikEdwin::FocusChanged(TDrawNow /*aDrawNow*/)
       
  2933     {
       
  2934     if (!iTextView)
       
  2935         return;
       
  2936     const TBool focused=IsFocused();
       
  2937     TRAP_IGNORE(SetCursorVisibilityL(focused));
       
  2938     if (!focused && iEdwinUserFlags&EAlwaysShowSelection)
       
  2939         ;
       
  2940     else
       
  2941         {
       
  2942         TRAP_IGNORE( SetSelectionVisibilityL( focused ) );// !! inefficient
       
  2943         }
       
  2944     if (focused)
       
  2945         SetCursorSizeAndType();
       
  2946     else
       
  2947         SetKeyboardRepeatRate(KAknStandardKeyboardRepeatRate);
       
  2948 
       
  2949     TRAP_IGNORE(SetVirtualCursorStateL(focused));
       
  2950     if (iCcpuSupport)
       
  2951         {
       
  2952         TRAP_IGNORE(iCcpuSupport->HandleFocusChangeL());
       
  2953         }
       
  2954     
       
  2955     if ( iEdwinFepSupport )
       
  2956         {
       
  2957         CAknEdwinState* edwinState = STATIC_CAST( CAknEdwinState*, 
       
  2958             iEdwinFepSupport->State(KNullUid) );
       
  2959         if ( edwinState )
       
  2960             {
       
  2961             if ( !focused )
       
  2962                 {
       
  2963                 TRAP_IGNORE( edwinState->ReportAknEdStateEventL( 
       
  2964                     MAknEdStateObserver::EAknSyncEdwinState ) );
       
  2965                 }
       
  2966             else
       
  2967                 {
       
  2968                 if ( edwinState->Flags() & EAknEditorFlagLaunchPenInputAutomatic &&
       
  2969                     !IsReadOnly() && !IsDimmed() && !( iEdwinUserFlags & EDisplayOnly ) )
       
  2970                     {
       
  2971                     edwinState->ReportAknEdStateEventL( 
       
  2972                             MAknEdStateObserver::EAknActivatePenInputRequest );
       
  2973                     }
       
  2974                 }
       
  2975             }
       
  2976         }
       
  2977     }
       
  2978 
       
  2979 void CEikEdwin::SetCursorSizeAndType()
       
  2980     {
       
  2981     TInt first,second;
       
  2982     AknLayoutUtils::CursorExtensionsFromFont(CursorFontSpec(),first,second);
       
  2983     iTextView->SetCursorExtensions(first,second);
       
  2984     iTextView->SetCursorWeight(CursorWidth());
       
  2985     }
       
  2986 
       
  2987 TFontSpec CEikEdwin::CursorFontSpec() const
       
  2988     {
       
  2989     if ( iText && iTextView )
       
  2990         {
       
  2991         TCharFormat charFormat;
       
  2992         TCharFormatMask notUsed;
       
  2993         TInt cursorPos = CursorPos();
       
  2994         if ( cursorPos > iText->DocumentLength() )
       
  2995             {
       
  2996             cursorPos = iText->DocumentLength();
       
  2997             }
       
  2998         STATIC_CAST( CGlobalText*, iText )->GetCharFormat( charFormat, notUsed, 
       
  2999             cursorPos, 0 );
       
  3000         return charFormat.iFontSpec;
       
  3001         }
       
  3002     else
       
  3003         {
       
  3004         return iEikonEnv->NormalFont()->FontSpecInTwips();
       
  3005         }
       
  3006     }
       
  3007 
       
  3008 TInt CEikEdwin::CursorWidth() const
       
  3009     {
       
  3010     return AknLayoutUtils::CursorWidthFromFont( CursorFontSpec() );
       
  3011     }
       
  3012 
       
  3013 void CEikEdwin::SetVirtualCursorStateL(TBool aSetSuspended) const
       
  3014     {
       
  3015     if(!(iEdwinUserFlags&EIgnoreVirtualCursor))
       
  3016         {
       
  3017         TEikVirtualCursor& cursor=iEikonEnv->VirtualCursor();
       
  3018         if(aSetSuspended && cursor.CursorState(*iEikonEnv)==TEikVirtualCursor::EOn)
       
  3019             cursor.SetCursorStateL(TEikVirtualCursor::ESuspended,*iEikonEnv);
       
  3020         else if(!aSetSuspended && cursor.CursorState(*iEikonEnv)==TEikVirtualCursor::ESuspended)
       
  3021             cursor.SetCursorStateL(TEikVirtualCursor::EOn,*iEikonEnv);
       
  3022         }
       
  3023     }
       
  3024 
       
  3025 EXPORT_C void CEikEdwin::ActivateL()
       
  3026     {
       
  3027     User::LeaveIfNull(iEdwinFepSupport);
       
  3028     User::LeaveIfNull(iEdwinFepSupport->State(KNullUid));
       
  3029     __ASSERT_DEBUG(iText,Panic(EEikPanicEdwinNoText));
       
  3030     
       
  3031     CRepository* repository = NULL;
       
  3032     TInt phoneNumberGroupingSupported = 0;
       
  3033     TRAPD(ret, repository = CRepository::NewL(KCRUidNumberGrouping));
       
  3034     if (ret == KErrNone)
       
  3035         {
       
  3036         ret = repository->Get(KNumberGrouping, phoneNumberGroupingSupported);
       
  3037         }
       
  3038     delete repository;
       
  3039     
       
  3040     EnableDragEvents();
       
  3041     Window().SetPointerGrab(ETrue);
       
  3042     
       
  3043     TBool suppressNotifyDraw = iEdwinInternalFlags & ESuppressNotifyDraw;
       
  3044 
       
  3045     SetSuppressNotifyDraw( ETrue );
       
  3046     
       
  3047     if (!iTextView)
       
  3048         {
       
  3049         CreateTextViewL();
       
  3050         }
       
  3051 
       
  3052     if (IsFocused())
       
  3053         {
       
  3054         SetCursorVisibilityL(ETrue);        
       
  3055         }        
       
  3056     else
       
  3057         {
       
  3058         SetSelectionVisibilityL( EFalse );
       
  3059         }
       
  3060             
       
  3061     DoCreateCustomDrawL(); //  Done after TextView is created so that optimized drawer is constructed
       
  3062 
       
  3063     // Create the required formatters according to the editor set-up
       
  3064     if ( IsPurePhoneNumberEditor() )
       
  3065         {
       
  3066         if ( phoneNumberGroupingSupported )
       
  3067             {            
       
  3068             CAknEdwinState* edwinState = STATIC_CAST( CAknEdwinState*, iEdwinFepSupport->State(KNullUid) );            
       
  3069             edwinState->SetFlags( edwinState->Flags() | EAknEditorFlagNumberGrouping );                    
       
  3070             iEdwinExtension->CreatePurePhoneNumberFormatterL( *iLayout, *iText );
       
  3071             }
       
  3072         }
       
  3073     else // Make approximation that all other editors have no matches indicator functionality
       
  3074         {
       
  3075         iEdwinExtension->CreateNoMatchesIndicatorFormatterL( *iLayout );
       
  3076         }
       
  3077 
       
  3078     // Rich text editors that have been configured for phone number grouping
       
  3079     if (iEdwinInternalFlags&ERichText && iEdwinInternalFlags&EPhoneNumberGrouping &&
       
  3080         phoneNumberGroupingSupported )
       
  3081         {        
       
  3082         CAknEdwinState* edwinState = STATIC_CAST( CAknEdwinState*, iEdwinFepSupport->State(KNullUid) );            
       
  3083         edwinState->SetFlags( edwinState->Flags() | EAknEditorFlagNumberGrouping );                
       
  3084         iEdwinExtension->CreateRichTextPhoneNumberFormatterL( *iLayout, *(static_cast<CRichText*>(iText)) );
       
  3085         }
       
  3086 
       
  3087     // Install the custom formatter system if needed
       
  3088     if ( iEdwinExtension->FormExtendedInferfaceProvider() )
       
  3089         TextLayout()->SetInterfaceProvider( iEdwinExtension->FormExtendedInferfaceProvider() );
       
  3090 
       
  3091     UpdateScrollBarsL();
       
  3092     ForceScrollBarUpdateL();
       
  3093 
       
  3094     DoAlignment();
       
  3095     
       
  3096     ApplyAutoSelectionL();
       
  3097 
       
  3098     CCoeControl::ActivateL();
       
  3099     
       
  3100     SetSuppressNotifyDraw( suppressNotifyDraw );
       
  3101     }
       
  3102 
       
  3103 /**
       
  3104  * @internal
       
  3105  */
       
  3106 EXPORT_C void CEikEdwin::CreateTextViewL()
       
  3107     {
       
  3108     if (iTextView)
       
  3109         return;
       
  3110     __ASSERT_DEBUG(iLayout,Panic(EEikPanicEdwinNoLayout));
       
  3111     if (iEdwinInternalFlags&EHasOneLineOnly && !(iEdwinUserFlags&ENoHorizScrolling))
       
  3112         iEdwinUserFlags|=ENoWrap;
       
  3113     if (iEdwinUserFlags&ENoWrap)
       
  3114         iLayout->ForceNoWrapping();
       
  3115     
       
  3116     TRect innerRect = iBorder.InnerRect( Rect() );
       
  3117     
       
  3118     if ( innerRect.Height() < 0 )
       
  3119         {
       
  3120         innerRect.SetHeight( 0 );
       
  3121         }
       
  3122     
       
  3123     iTextView=CTextView::NewL(iLayout,innerRect,iEikonEnv->ScreenDevice(),
       
  3124                                 iZoomFactor,&Window(),&iEikonEnv->RootWin(),&iEikonEnv->WsSession());
       
  3125     // AVKON CHANGE to make less flicker!!!
       
  3126     // (Need to do here instead of LayoutEdwin, because not everyone
       
  3127     // seem to use layoutedwin :( )
       
  3128     iTextView->DisableFlickerFreeRedraw();
       
  3129     // END
       
  3130 
       
  3131     if (LineCursorWidth())
       
  3132         SetLineCursorDetailsL();
       
  3133     if (iText->DocumentLength()>UpperFullFormattingLength())
       
  3134         SetAmountToFormatL(ETrue);
       
  3135     FormatTextL();
       
  3136     iTextView->SetObserver(this);
       
  3137     
       
  3138     CheckEdwinExtensionL(); // checks if iEdwinExtension is non-NULL
       
  3139     iEdwinExtension->FormCursorModifier()->SetTextView(iTextView);
       
  3140     DoCreateCustomDrawL();
       
  3141     }
       
  3142 
       
  3143 EXPORT_C void CEikEdwin::SizeChanged()
       
  3144     {
       
  3145     __ASSERT_DEBUG(iText,Panic(EEikPanicEdwinNoText));
       
  3146     CheckEdwinHeight();
       
  3147     TrappedSizeChanged();
       
  3148     }
       
  3149 
       
  3150 EXPORT_C void CEikEdwin::TrappedSizeChanged()
       
  3151     {
       
  3152     TRAPD(err,HandleSizeChangedL());
       
  3153     if (err)
       
  3154         {
       
  3155         CWindowGc& gc=SystemGc();
       
  3156         gc.Activate(Window());
       
  3157         TRect rect;
       
  3158         if (iTextView)
       
  3159             rect=iTextView->ViewRect();
       
  3160         else
       
  3161             {
       
  3162             rect=Rect();
       
  3163             rect=iBorder.InnerRect(rect);
       
  3164             }
       
  3165         gc.Clear(rect);
       
  3166         gc.Deactivate();
       
  3167         iEikonEnv->NotifyIdleErrorWhileRedrawing(err);
       
  3168         }
       
  3169     }
       
  3170 
       
  3171 EXPORT_C void CEikEdwin::HandleSizeChangedL()
       
  3172     {
       
  3173     if (!iTextView)
       
  3174         CreateTextViewL();
       
  3175 #ifdef _DEBUG
       
  3176     if (iMaximumHeight)
       
  3177         __ASSERT_DEBUG(iSize.iHeight<=iMaximumHeight, Panic(EEikPanicEdwinHeightGreaterThanMaximum));
       
  3178 #endif
       
  3179     TBool condition( IsFocused() );
       
  3180     CAknEdwinState* state( EditorState() );
       
  3181     TBool noInlineEditSpan( !state || 
       
  3182         state->CurrentInlineEditSpan().Length() <= 0 );
       
  3183     condition = ( condition && noInlineEditSpan );
       
  3184     condition = ( condition && ( iEdwinFepSupport->iLengthOfInlineText <= 0 ) );
       
  3185     if ( condition )
       
  3186         {
       
  3187         SetCursorVisibilityL( EFalse );
       
  3188         }
       
  3189     TRect displayRect=iBorder.InnerRect(Rect());
       
  3190     displayRect=iMargins.InnerRect(displayRect);
       
  3191     
       
  3192     // Negative width (and possibly height) seem to break iTextView
       
  3193     // This can happen if editor's width is less than the margins
       
  3194 
       
  3195     // if width equals to zero, will cause the cursor doesn't display in the right-to-left directionality
       
  3196     // so we set the width and height to smallest value 1.
       
  3197     const TInt displayRectWith = 1;
       
  3198     const TInt displayRectHeight = 1;
       
  3199     if ( displayRect.Width() <= 0 )
       
  3200         {
       
  3201         displayRect.iBr.iX = displayRect.iTl.iX + displayRectWith;
       
  3202         }
       
  3203 
       
  3204     if ( displayRect.Height() <= 0 )
       
  3205         {
       
  3206         displayRect.iBr.iY = displayRect.iTl.iY + displayRectHeight;
       
  3207         }
       
  3208 
       
  3209 
       
  3210     iTextView->SetViewRect(displayRect);
       
  3211     iLayout->SetWrapWidth(LayoutWidth());
       
  3212     TViewYPosQualifier yPosQualifier;
       
  3213     yPosQualifier.SetFillScreen();
       
  3214     yPosQualifier.SetMakeLineFullyVisible();
       
  3215     SetAmountToFormatL( EFalse, EFalse ); // Not a new doc; Do not reformat
       
  3216     if (!(iEdwinInternalFlags & ESuppressFormatting))
       
  3217         iTextView->HandleGlobalChangeNoRedrawL(yPosQualifier); // This does the reformat
       
  3218     CalculateLineMetricsForBandFormattingL();
       
  3219     SetScrollBarsL();
       
  3220     UpdateScrollBarsL();
       
  3221     if ( condition )
       
  3222         {
       
  3223         SetCursorVisibilityL( ETrue );
       
  3224         }
       
  3225     // View size changed, Initialize physics here
       
  3226     iEdwinExtension->InitPhysicsL();        
       
  3227     }
       
  3228 
       
  3229 EXPORT_C TInt CEikEdwin::CountComponentControls() const
       
  3230     {
       
  3231     TInt count=CEikBorderedControl::CountComponentControls();
       
  3232     if (iSBFrame)
       
  3233         count+=iSBFrame->CountComponentControls();
       
  3234     return count;
       
  3235     }
       
  3236 
       
  3237 EXPORT_C CCoeControl* CEikEdwin::ComponentControl(TInt aIndex) const
       
  3238     {
       
  3239     TInt baseCount=CEikBorderedControl::CountComponentControls();
       
  3240     if (aIndex<baseCount)
       
  3241         return CEikBorderedControl::ComponentControl(aIndex);
       
  3242     aIndex-=baseCount;
       
  3243     return iSBFrame->ComponentControl(aIndex);
       
  3244     }
       
  3245 
       
  3246 EXPORT_C void CEikEdwin::SetAmountToFormatL(TBool aIsNewDoc)
       
  3247     {
       
  3248     if (!iTextView)
       
  3249         return;
       
  3250     const TInt chars=iText->DocumentLength();
       
  3251     if ( iEdwinExtension->iSmiley && !iEdwinExtension->iDisableConvertInFormat )
       
  3252         {        
       
  3253         if ( chars > KFullFormatLengthForSmiley )
       
  3254             {
       
  3255             ConvertVisibleTextForSmileyL( ETrue );
       
  3256             }
       
  3257         else if ( chars > 0 )
       
  3258             {
       
  3259             ConvertTextForSmileyL( TCursorSelection( 0, chars ), ETrue );
       
  3260             }
       
  3261         }
       
  3262     if (chars>UpperFullFormattingLength())
       
  3263         {
       
  3264         if (aIsNewDoc)
       
  3265             {
       
  3266             iLayout->SetAmountToFormat();
       
  3267             iTextView->FormatTextL();
       
  3268             const TInt formattedLines=iLayout->NumFormattedLines();
       
  3269             const TInt formattedHeight=iLayout->FormattedHeightInPixels();
       
  3270             iAvgCharsPerLine=iLayout->FormattedLength()/formattedLines;
       
  3271             iAvgLinesInViewRect=Max(1,(iTextView->ViewRect().Height()*formattedLines)/formattedHeight);
       
  3272             }
       
  3273         else
       
  3274             {
       
  3275             const TInt numLines=iLayout->NumFormattedLines();
       
  3276             const TInt docHeight=iLayout->FormattedHeightInPixels();
       
  3277             iAvgCharsPerLine=iLayout->FormattedLength()/numLines;
       
  3278             iAvgLinesInViewRect=Max(1,(iTextView->ViewRect().Height()*numLines)/docHeight);
       
  3279             iLayout->SetAmountToFormat();
       
  3280             iTextView->HandleGlobalChangeNoRedrawL();
       
  3281             }
       
  3282         if (IsReadyToDraw() && iSBFrame && iSBFrame->VScrollBarVisibility()!=CEikScrollBarFrame::EOff)
       
  3283             UpdateScrollBarsL();
       
  3284         }
       
  3285     else
       
  3286         {
       
  3287         iAvgCharsPerLine=1;
       
  3288         iAvgLinesInViewRect=0;
       
  3289         iLayout->SetAmountToFormat(CTextLayout::EFFormatAllText);
       
  3290         if (aIsNewDoc)
       
  3291             iTextView->FormatTextL();
       
  3292         else
       
  3293             iTextView->HandleGlobalChangeNoRedrawL();
       
  3294         }
       
  3295     } 
       
  3296     
       
  3297 EXPORT_C void CEikEdwin::SetAmountToFormatL( TBool aIsNewDoc, TBool aReFormat )
       
  3298     {
       
  3299     if (aReFormat)
       
  3300         {
       
  3301         SetAmountToFormatL( aIsNewDoc );
       
  3302         return;
       
  3303         }
       
  3304         
       
  3305     if (!iTextView)
       
  3306         return;
       
  3307     const TInt chars=iText->DocumentLength();
       
  3308     if ( iEdwinExtension->iSmiley && !iEdwinExtension->iDisableConvertInFormat )
       
  3309         {        
       
  3310         if ( chars > KFullFormatLengthForSmiley )
       
  3311             {
       
  3312             ConvertVisibleTextForSmileyL( ETrue );
       
  3313             }
       
  3314         else if ( chars > 0 )
       
  3315             {
       
  3316             ConvertTextForSmileyL( TCursorSelection( 0, chars ), ETrue );
       
  3317             }
       
  3318         }
       
  3319     if (chars>UpperFullFormattingLength())
       
  3320         {
       
  3321         iLayout->SetAmountToFormat(CTextLayout::EFFormatBand);
       
  3322         }
       
  3323     else
       
  3324         {
       
  3325         iLayout->SetAmountToFormat(CTextLayout::EFFormatAllText);
       
  3326         }
       
  3327     }
       
  3328 
       
  3329 void CEikEdwin::CalculateLineMetricsForBandFormattingL()
       
  3330     {
       
  3331     if ( iLayout)
       
  3332         {
       
  3333         if (iLayout->IsFormattingBand())
       
  3334             {
       
  3335             const TInt numLines=iLayout->NumFormattedLines();
       
  3336             const TInt docHeight=iLayout->FormattedHeightInPixels();
       
  3337             
       
  3338             // To make sure that division by 0 does not happen in any situation.
       
  3339             if (numLines > 0)
       
  3340                 {
       
  3341                 iAvgCharsPerLine=iLayout->FormattedLength()/numLines;                
       
  3342                 }
       
  3343             else
       
  3344                 {
       
  3345                 iAvgCharsPerLine = 1;
       
  3346                 }
       
  3347 
       
  3348             // To make sure that division by 0 does not happen in any situation.
       
  3349             if (docHeight > 0)
       
  3350                 {
       
  3351                 iAvgLinesInViewRect=Max(1,(iTextView->ViewRect().Height()*numLines)/docHeight);                           
       
  3352                 }
       
  3353             else
       
  3354                 {
       
  3355                 iAvgLinesInViewRect=0;                
       
  3356                 }
       
  3357             }
       
  3358         else
       
  3359             {
       
  3360             iAvgCharsPerLine=1;
       
  3361             iAvgLinesInViewRect=0;
       
  3362             }
       
  3363         if (IsReadyToDraw() && iSBFrame && iSBFrame->VScrollBarVisibility()!=CEikScrollBarFrame::EOff)
       
  3364             UpdateScrollBarsL();        
       
  3365         }
       
  3366     }
       
  3367     
       
  3368 EXPORT_C void CEikEdwin::ReportEdwinEventL(MEikEdwinObserver::TEdwinEvent aEventType)
       
  3369     {
       
  3370     if(iCustomDrawer && aEventType==MEikEdwinObserver::EEventFormatChanged)
       
  3371         iCustomDrawer->LineSpacingChanged();
       
  3372     if (iEdwinObserver!=NULL)
       
  3373         iEdwinObserver->HandleEdwinEventL(this,aEventType);
       
  3374     if (iCcpuSupport)
       
  3375         iCcpuSupport->HandleSelectionChangeL();
       
  3376     if (iObserverArray)
       
  3377         {
       
  3378         const TInt count=iObserverArray->Count();
       
  3379         for (TInt ii=0;ii<count;ii++)
       
  3380             (*iObserverArray)[ii]->HandleEdwinEventL(this,aEventType);
       
  3381         }
       
  3382     if ( aEventType == MEikEdwinObserver::EEventScroll || 
       
  3383         aEventType == MEikEdwinObserver::EEventNavigation 
       
  3384         )
       
  3385         {
       
  3386         HandleScrollForSmileyL();        
       
  3387         }
       
  3388     if ( aEventType == MEikEdwinObserver::EEventTextUpdate )
       
  3389         {
       
  3390         iEdwinExtension->iExtendedInputCapabilities->ReportEventL( 
       
  3391                 CAknExtendedInputCapabilities::
       
  3392                     MAknEventObserver::EControlContentUpdatedInternally,
       
  3393                 NULL );
       
  3394         }
       
  3395     }
       
  3396     
       
  3397 
       
  3398 
       
  3399 EXPORT_C void CEikEdwin::NotifyNewDocumentL()
       
  3400     {
       
  3401     __ASSERT_DEBUG(iTextView,Panic(EEikPanicEdwinNoView));
       
  3402     __ASSERT_DEBUG(iText,Panic(EEikPanicEdwinNoText));
       
  3403     TViewYPosQualifier yPosQ;
       
  3404     yPosQ.SetMakeLineFullyVisible();
       
  3405     yPosQ.SetFillScreen(); // ???
       
  3406     iTextView->HandleGlobalChangeL(yPosQ);
       
  3407     TInt topLeftYPos=iTextView->ViewRect().iTl.iY;
       
  3408     iTextView->SetViewL(0,topLeftYPos,yPosQ);
       
  3409     iTextView->SetDocPosL(0);
       
  3410     SetAmountToFormatL(ETrue); // performs formatting
       
  3411     UpdateScrollBarsL();
       
  3412     }
       
  3413 
       
  3414 EXPORT_C void CEikEdwin::NotifyNewFormatL()
       
  3415     {
       
  3416     if(iCustomDrawer)
       
  3417         iCustomDrawer->LineSpacingChanged();
       
  3418     __ASSERT_DEBUG(iTextView,Panic(EEikPanicEdwinNoView));
       
  3419     TViewYPosQualifier yPosQualifier;
       
  3420     yPosQualifier.SetMakeLineFullyVisible();
       
  3421     yPosQualifier.SetFillScreen();
       
  3422     if( !(iEdwinInternalFlags & ESuppressFormatting))
       
  3423         {
       
  3424         iTextView->HandleGlobalChangeNoRedrawL(yPosQualifier);
       
  3425         ForceScrollBarUpdateL();
       
  3426         // Drawing here is controlled by an internal mechanism
       
  3427         CAknEdwinDrawingModifier* modifier = AknEdwinDrawingModifier();
       
  3428         if ( ! (iEdwinInternalFlags & ESuppressNotifyDraw) )
       
  3429             {
       
  3430             if ( !(modifier && modifier->InhibitNotifyNewFormatDrawing()) )
       
  3431                 {
       
  3432                 DrawDeferred();                
       
  3433                 } 
       
  3434             }
       
  3435         
       
  3436         }
       
  3437     }
       
  3438 
       
  3439 EXPORT_C void CEikEdwin::SetCursorPosL(TInt aDocPos,TBool aSelect)
       
  3440     {
       
  3441     // CTextView::SetDocPosL will cause textview to be drawn. This could happen 
       
  3442     // before the drawing of editor. So adding following codes to postpone the action to
       
  3443     // first drawing of editor.
       
  3444     if ( iEdwinExtension->iDrawInvoked == CEikEdwinExtension::ENotDraw )
       
  3445         {
       
  3446         iEdwinExtension->iTempCursorPos = aDocPos;
       
  3447         iEdwinExtension->iTempSelect = aSelect;
       
  3448         if ( !aSelect )
       
  3449             {
       
  3450             iEdwinExtension->iTempAnchorPos = KErrNotFound;
       
  3451             }
       
  3452         return;
       
  3453         }
       
  3454         
       
  3455     if ( IsFocused() )
       
  3456         {
       
  3457         CancelFepTransaction(); 
       
  3458         }
       
  3459 
       
  3460     if (!iTextView)
       
  3461         CreateTextViewL();
       
  3462     TInt oldPos( CursorPos() );
       
  3463     TInt docPos( aDocPos );
       
  3464     if ( iEdwinExtension->iSmiley )
       
  3465         {
       
  3466         iEdwinExtension->iSmiley->HandleSetCursor( oldPos, docPos );
       
  3467         }
       
  3468     TCursorSelection select( Selection() );
       
  3469     select.iCursorPos = docPos;
       
  3470     if ( !aSelect )
       
  3471         {        
       
  3472         select.iAnchorPos = docPos;
       
  3473         }
       
  3474     HandleSelectionForSmiley( select );
       
  3475     iTextView->SetDocPosL( docPos, aSelect );
       
  3476     ScrollIfAtTopOrBottomL();
       
  3477     
       
  3478     if ( iEdwinFepSupport && 
       
  3479         ( aDocPos != oldPos || ( select.Length() > 0 && !aSelect ) ) )
       
  3480         {
       
  3481         CAknEdwinState* edwinState = static_cast<CAknEdwinState*>( iEdwinFepSupport->State(KNullUid) );
       
  3482         if ( edwinState )
       
  3483             {
       
  3484             TRAP_IGNORE( edwinState->ReportAknEdStateEventL( MAknEdStateObserver::EAknCursorPositionChanged ) );
       
  3485             }
       
  3486         }
       
  3487         
       
  3488     UpdateVertScrollBarThumbL();
       
  3489     UpdateHorizScrollBarThumb();
       
  3490     }
       
  3491 
       
  3492 EXPORT_C void CEikEdwin::SetDocumentOwnership(TOwnershipType aOwner)
       
  3493     {
       
  3494     if (aOwner==EOwnsText)
       
  3495         iEdwinUserFlags&=~EKeepDocument;
       
  3496     else
       
  3497         iEdwinUserFlags|=EKeepDocument;
       
  3498     }
       
  3499 
       
  3500 EXPORT_C void CEikEdwin::SetSelectionL(TInt aCursorPos,TInt aAnchorPos)
       
  3501     {
       
  3502     if( IsFocused() )
       
  3503         {
       
  3504         CancelFepTransaction();
       
  3505         }
       
  3506     if (!iTextView)
       
  3507         CreateTextViewL();
       
  3508     if ( iEdwinExtension->iDrawInvoked == CEikEdwinExtension::ENotDraw )
       
  3509         {        
       
  3510         iEdwinExtension->iTempCursorPos = aCursorPos;
       
  3511         iEdwinExtension->iTempAnchorPos = aAnchorPos;
       
  3512         return;
       
  3513         }
       
  3514     if ( IsSmileyEnabled() )
       
  3515         {
       
  3516         iEdwinExtension->iSmiley->HandleSetCursor( aAnchorPos, aCursorPos );
       
  3517         iEdwinExtension->iSmiley->HandleSetCursor( aCursorPos, aAnchorPos );
       
  3518         }
       
  3519     TCursorSelection select( aCursorPos, aAnchorPos );    
       
  3520     HandleSelectionForSmiley( select );
       
  3521     iTextView->SetSelectionL( select );
       
  3522     iEdwinExtension->iThumbPos =  KErrNotFound;
       
  3523 
       
  3524     if ( iEdwinFepSupport )
       
  3525         {
       
  3526         CAknEdwinState* edwinState = static_cast<CAknEdwinState*>( iEdwinFepSupport->State(KNullUid) );
       
  3527         if ( edwinState )
       
  3528             {
       
  3529             TRAP_IGNORE( edwinState->ReportAknEdStateEventL( MAknEdStateObserver::EAknCursorPositionChanged ) );
       
  3530             }
       
  3531         }
       
  3532     CancelInsertCharFormat();
       
  3533     UpdateVertScrollBarThumbL();
       
  3534     UpdateHorizScrollBarThumb();
       
  3535     }
       
  3536 
       
  3537 EXPORT_C void CEikEdwin::SelectAllL()
       
  3538     {
       
  3539     CancelFepTransaction();
       
  3540     SetSelectionL( TextLength(), 0 );
       
  3541     }
       
  3542 
       
  3543 TBool CEikEdwin::OwnsScrollBars() const
       
  3544     {
       
  3545     if (!iSBFrame)
       
  3546         return EFalse;
       
  3547     return ((iSBFrame->ScrollBarVisibility(CEikScrollBar::EHorizontal)!=CEikScrollBarFrame::EOff)||(iSBFrame->VScrollBarVisibility()!=CEikScrollBarFrame::EOff));
       
  3548     }
       
  3549 
       
  3550 EXPORT_C void CEikEdwin::SetWordWrapL(TBool aWrapIsOn)
       
  3551     {
       
  3552     __ASSERT_DEBUG(iText,Panic(EEikPanicEdwinNoText));
       
  3553     __ASSERT_DEBUG(iLayout,Panic(EEikPanicEdwinNoLayout));
       
  3554     if (aWrapIsOn)
       
  3555         {
       
  3556         iEdwinUserFlags&=~ENoWrap;
       
  3557         iLayout->ForceNoWrapping(EFalse);
       
  3558         iLayout->SetWrapWidth(LayoutWidth());
       
  3559         }
       
  3560     else
       
  3561         {
       
  3562         iEdwinUserFlags|=ENoWrap;
       
  3563         iLayout->ForceNoWrapping();
       
  3564         }
       
  3565     NotifyNewFormatL();
       
  3566     }
       
  3567 
       
  3568 EXPORT_C TInt CEikEdwin::LineCursorWidth() const
       
  3569     {
       
  3570     return 0;
       
  3571     }
       
  3572 
       
  3573 EXPORT_C void CEikEdwin::SetLineCursorDetailsL()
       
  3574     {
       
  3575     __ASSERT_DEBUG(iTextView,Panic(EEikPanicEdwinNoView));
       
  3576     iTextView->SetMarginWidths(0,LineCursorWidth());
       
  3577     }
       
  3578 
       
  3579 EXPORT_C void CEikEdwin::SetTextLimit(TInt aLimit)
       
  3580     {
       
  3581 #if defined(_DEBUG)
       
  3582     if (aLimit<iText->DocumentLength())
       
  3583         Panic(EEikPanicEdwinInvalidTextLimit);
       
  3584 #endif
       
  3585     iTextLimit=aLimit;
       
  3586     }
       
  3587 
       
  3588 EXPORT_C TMargins8 CEikEdwin::Margins() const
       
  3589     {
       
  3590     return iMargins;
       
  3591     }
       
  3592 
       
  3593 void CEikEdwin::ApplyAutoSelectionL()
       
  3594     {
       
  3595     if ( iEdwinUserFlags & EAvkonNotEditable )
       
  3596         return;
       
  3597     const TInt length=TextLength();
       
  3598     if (iEdwinUserFlags&EJustAutoCurEnd)
       
  3599         {
       
  3600         SetCursorPosL(length,EFalse);
       
  3601         }        
       
  3602     else if (!(iEdwinUserFlags&ENoAutoSelection))
       
  3603         {
       
  3604         SetSelectionL(length,0);        
       
  3605         }        
       
  3606     else
       
  3607         {
       
  3608         SetCursorPosL(0,EFalse);
       
  3609         }    
       
  3610     }
       
  3611 
       
  3612 EXPORT_C TSize CEikEdwin::MinimumSize()
       
  3613     {
       
  3614     TSize edwinSize = iSize;
       
  3615     if ((iEdwinUserFlags&EResizable) && (edwinSize.iHeight == 0))
       
  3616         {
       
  3617         if ((iMinimumHeight > 0) && (edwinSize.iHeight < iMinimumHeight))
       
  3618             edwinSize.iHeight = iMinimumHeight;
       
  3619         }
       
  3620     return edwinSize;
       
  3621     }
       
  3622 
       
  3623 EXPORT_C void CEikEdwin::SetContainerWindowL(const CCoeControl& aParent)
       
  3624     {
       
  3625     if (iEdwinUserFlags&EOwnsWindow && !OwnsWindow())
       
  3626         CreateWindowL(&aParent);
       
  3627     else
       
  3628         CCoeControl::SetContainerWindowL(aParent);
       
  3629 
       
  3630     iEdwinExtension->EnablePhysicsL();
       
  3631     }
       
  3632 
       
  3633 EXPORT_C void CEikEdwin::SetContainerWindowL()
       
  3634     {
       
  3635     __ASSERT_DEBUG(iEdwinUserFlags&EOwnsWindow, Panic(EEikPanicEdwinNoWindow));
       
  3636     if (!OwnsWindow())
       
  3637         CreateWindowL();
       
  3638 
       
  3639     iEdwinExtension->EnablePhysicsL();   
       
  3640     }
       
  3641 
       
  3642 EXPORT_C TCoeInputCapabilities CEikEdwin::InputCapabilities() const
       
  3643     {
       
  3644     if (IsReadOnly())
       
  3645         {
       
  3646         TCoeInputCapabilities readOnlyInputCaps( TCoeInputCapabilities::ENavigation );
       
  3647         readOnlyInputCaps.SetObjectProvider( const_cast<CEikEdwin*>( this ) );
       
  3648         return readOnlyInputCaps;
       
  3649         }
       
  3650 
       
  3651     TCoeInputCapabilities inputCaps( LafEdwin::InputCapabilities(),iEdwinFepSupport,NULL,TUid::Uid(0x100056de),iEdwinFepSupport );
       
  3652     inputCaps.SetObjectProvider( const_cast<CEikEdwin*>( this ) );
       
  3653 
       
  3654     if (iEdwinFepSupport!=NULL)
       
  3655         {
       
  3656         const TCoeInputCapabilities* inputCapabilities=iEdwinFepSupport->InputCapabilities();
       
  3657         
       
  3658         if (inputCapabilities!=NULL)
       
  3659             {
       
  3660             return *inputCapabilities;
       
  3661             }
       
  3662         
       
  3663         // This tries to sense that this is a numeric-only edwin, and
       
  3664         // set the input caps so that FEP would use the _digit mode_ instead
       
  3665         // of input language mode when choosing input type and indicator    
       
  3666         CAknEdwinState* state = static_cast<CAknEdwinState*>( iEdwinFepSupport->State( KNullUid ) );
       
  3667         if ( state )
       
  3668             {
       
  3669             if ( state->PermittedInputModes() == EAknEditorNumericInputMode )
       
  3670                 {
       
  3671                 inputCaps.SetCapabilities( inputCaps.Capabilities() | 
       
  3672                     TCoeInputCapabilities::EWesternNumericIntegerPositive |
       
  3673                     TCoeInputCapabilities::EWesternNumericIntegerNegative );
       
  3674                 }
       
  3675             }
       
  3676         }
       
  3677         
       
  3678     return inputCaps;
       
  3679     }
       
  3680 
       
  3681 EXPORT_C void CEikEdwin::SetInputCapabilitiesL(const TCoeInputCapabilities& aInputCapabilities)
       
  3682     {
       
  3683     User::LeaveIfNull(iEdwinFepSupport);
       
  3684     iEdwinFepSupport->SetInputCapabilitiesL(aInputCapabilities);
       
  3685     }
       
  3686 
       
  3687 EXPORT_C void CEikEdwin::FormatTextL()
       
  3688     {
       
  3689     if (iTextView) // else FormatTextL() will get called later, in ActivateL()
       
  3690         iTextView->FormatTextL();
       
  3691     }
       
  3692 
       
  3693 /**
       
  3694  * @internal
       
  3695  */
       
  3696 EXPORT_C void CEikEdwin::CreateLayoutL(MLayDoc* aLayDoc)
       
  3697     {
       
  3698     __ASSERT_DEBUG(aLayDoc,Panic(EEikPanicEdwinNoText));
       
  3699 
       
  3700     if ((iEdwinUserFlags&EAvkonEditor))
       
  3701         {
       
  3702         iLayout=CTextLayout::NewL(aLayDoc,KMaxTInt); // supply real wrapping width later
       
  3703         iLayout->SetCustomWrap(&(iEdwinExtension->TextWrapper()));
       
  3704         
       
  3705         // This WAS ETrue, then fixed to EFalse, caused regression and now back to
       
  3706         // ETrue. In case it is true the editor scrolls _always_
       
  3707         // so that the topmost line is visible, and the baselines are nicely
       
  3708         // aligned. This had a side effect which sometimes caused editors to
       
  3709         // display only partial lines in the bottom, even if the cursor was in that
       
  3710         // line. Setting this to false makes sure that the line where cursor is
       
  3711         // is always displayed properly, but causes small less-than-linespacing
       
  3712         // scrolls in some occasions where the editor's size doesn't match the
       
  3713         // multiple of font and its highlights and line spacing.
       
  3714         //iLayout->RestrictScrollToTopsOfLines( EFalse );
       
  3715 
       
  3716         if ( KineticScrollingEnabled() )
       
  3717             {
       
  3718             // With kinetic scrolling this is set to EFalse.
       
  3719             // ScrollDisplayPixelsL and ScrollDisplayPixelsNoLimitBorderL
       
  3720             // won't move content pixel by pixel (but line by line)
       
  3721             // if this is not EFalse.
       
  3722             iLayout->RestrictScrollToTopsOfLines( EFalse );
       
  3723             }
       
  3724         else
       
  3725             {
       
  3726             iLayout->RestrictScrollToTopsOfLines( ETrue );
       
  3727             }       
       
  3728 
       
  3729         // the default FontHeightIncreaseFactor in FORM is EDefaultFontHeightIncreaseFactor==7,
       
  3730         // but the Avkon modified FORM change this to 6
       
  3731         // Moved this modification out and using the provided interface instead
       
  3732         iLayout->SetFontHeightIncreaseFactor(6);
       
  3733         // not originally merged in
       
  3734         //iLayout->SetMinimumLineDescent(0);
       
  3735         }
       
  3736     else
       
  3737         {
       
  3738         iLayout=CTextLayout::NewL(aLayDoc,KMaxTInt); // supply real wrapping width later
       
  3739         // Was ETrue, see above.
       
  3740         iLayout->RestrictScrollToTopsOfLines( EFalse );
       
  3741         //iLayout->RestrictScrollToTopsOfLines(ETrue);
       
  3742         // not originally merged in
       
  3743         //iLayout->SetMinimumLineDescent(0);
       
  3744         }
       
  3745 
       
  3746     CheckEdwinExtensionL(); // checks if iEdwinExtension is non-NULL
       
  3747     iEdwinExtension->FormCursorModifier()->SetTextLayout(iLayout);
       
  3748     }
       
  3749 
       
  3750 EXPORT_C void CEikEdwin::SetAvkonWrap(TBool aAvkonWrapIsOn)
       
  3751     {
       
  3752     if (aAvkonWrapIsOn)
       
  3753         iEdwinUserFlags|=EAvkonEditor;
       
  3754     else
       
  3755         iEdwinUserFlags&=~EAvkonEditor;
       
  3756     }
       
  3757 
       
  3758 EXPORT_C void CEikEdwin::Draw(const TRect& /*aRect*/) const
       
  3759     {
       
  3760     CEikEdwin* me = const_cast< CEikEdwin* > ( this );
       
  3761     me->iEdwinInternalFlags |= ESkipBackgroundDrawer;
       
  3762 
       
  3763     if ( iTextView )
       
  3764         {
       
  3765         const TRect rect=Rect();
       
  3766         CWindowGc& gc=SystemGc();
       
  3767 
       
  3768         const TRect viewRect=iTextView->ViewRect();
       
  3769 
       
  3770         TRgb dummyColor;
       
  3771         TRgb backgroundColor = EditorBackgroundColor(dummyColor); 
       
  3772         gc.SetBrushColor( backgroundColor );
       
  3773 
       
  3774         if ( !IsBackgroundDrawingSuppressed() )
       
  3775             {
       
  3776             // Text view may not occupy the whole control area.  So we need to draw in the gaps
       
  3777             DrawBackgroundAroundTextView( gc, rect, viewRect, backgroundColor );
       
  3778             }
       
  3779 
       
  3780         TrappedDraw(viewRect);
       
  3781 
       
  3782     #ifdef RD_UI_TRANSITION_EFFECTS_POPUPS
       
  3783         // Workaround for clipping rect problem in multiline queries with text
       
  3784         // entries.  Because of differences between CRemoteGc and CWindowGc, 
       
  3785         // parts of the query wouldn't be drawn by CRemoteGc.  The Reset() call
       
  3786         // is to cancel the clipping rect.  For some reason, CancelClippingRect()
       
  3787         // and CancelClippingRegion() don't work.
       
  3788         gc.Reset();
       
  3789     #endif
       
  3790         }
       
  3791 
       
  3792     me->iEdwinInternalFlags &= ~ESkipBackgroundDrawer;
       
  3793     }
       
  3794 
       
  3795 void CleanupReleaseFont(TAny* aFont)
       
  3796     {
       
  3797     CFont** fontPtr = (CFont**)aFont;
       
  3798     CEikonEnv::Static()->ScreenDevice()->ReleaseFont(*fontPtr);
       
  3799     }
       
  3800 
       
  3801 void CEikEdwin::DrawFirstLineTextL() const
       
  3802     {
       
  3803    
       
  3804     HBufC* clipbuf = GetTextInHBufL();
       
  3805     CleanupStack::PushL(clipbuf);
       
  3806 
       
  3807     TPtrC clipbufPtr = clipbuf->Des();
       
  3808     TMargins8 margins = Margins();
       
  3809     const TRect rect(Rect());
       
  3810     TInt cursorWidth = CursorWidth(); // need to add cursor width to right hand margin
       
  3811     TRect edwinRect = AknLayoutUtils::RectFromCoords(rect, margins.iLeft, margins.iTop, margins.iRight+cursorWidth, margins.iBottom, ELayoutEmpty, ELayoutEmpty);
       
  3812 
       
  3813     TAknTextLineLayout textLayout = AknLayoutScalable_Avkon::data_form_wide_pane_t1(0).LayoutLine();
       
  3814     const CAknLayoutFont* font = AknLayoutUtils::LayoutFontFromId( textLayout.FontId());
       
  3815 
       
  3816     // reorder the text
       
  3817     AknBidiTextUtils::PrepareRunInfoArray(clipbufPtr);
       
  3818 
       
  3819     HBufC* reorderedText = HBufC::NewLC(clipbufPtr.Length() + TBidiLogicalToVisual::KMinCharAvailable);
       
  3820     TPtr reorderedTextPtr = reorderedText->Des();
       
  3821     TInt width = edwinRect.Size().iWidth;
       
  3822     AknBidiTextUtils::ConvertToVisualAndClip(clipbufPtr, reorderedTextPtr, *font, width, width);
       
  3823     AknTextUtils::ReplaceCharacters( reorderedTextPtr, _L("\x2029"), TChar(' ') );
       
  3824     CleanupStack::Pop(reorderedText);   
       
  3825     CleanupStack::PopAndDestroy(clipbuf);   
       
  3826     CleanupStack::PushL(reorderedText);
       
  3827 
       
  3828     CGraphicsContext::TTextAlign alignment = CGraphicsContext::ELeft;
       
  3829     switch(CurrentAlignment())
       
  3830         {
       
  3831         case EAknEditorAlignLeft:
       
  3832             alignment = CGraphicsContext::ELeft;
       
  3833             break;
       
  3834         case EAknEditorAlignCenter:
       
  3835             alignment = CGraphicsContext::ECenter;
       
  3836             break;
       
  3837         case EAknEditorAlignRight:
       
  3838             alignment = CGraphicsContext::ERight;
       
  3839             break;
       
  3840         case EAknEditorAlignNone: // drop through to default
       
  3841         case EAknEditorAlignBidi: // drop through to default
       
  3842         default:
       
  3843             {
       
  3844             if (TBidiText::TextDirectionality(reorderedTextPtr) == TBidiText::ELeftToRight)
       
  3845                 alignment = CGraphicsContext::ELeft;
       
  3846             else
       
  3847                 alignment = CGraphicsContext::ERight;
       
  3848             }
       
  3849             break;
       
  3850         }
       
  3851         
       
  3852     CWindowGc& gc=SystemGc();               
       
  3853     gc.UseFont(font);
       
  3854 
       
  3855     // Following patching up of the GC are now necessary after calling LafCustomDrawerfor background
       
  3856     gc.SetBrushStyle(CGraphicsContext::ENullBrush);
       
  3857     gc.SetPenStyle(CGraphicsContext::ESolidPen);
       
  3858     TRgb textColor=iEikonEnv->ControlColor(EColorControlText,*this);
       
  3859 
       
  3860     gc.SetPenColor(textColor);  // Text color
       
  3861 
       
  3862     // Edwin is assumed to be laid out already with LayoutEdwin. In that case
       
  3863     // the textpane top is the top of the edwin
       
  3864     TInt ascent = font->TextPaneTopToBaseline();
       
  3865     
       
  3866     gc.DrawText(reorderedTextPtr, edwinRect, ascent, alignment);
       
  3867 
       
  3868     CleanupStack::PopAndDestroy(reorderedText);
       
  3869     
       
  3870     gc.DiscardFont(); // So the GC will not try to use the font.
       
  3871     }
       
  3872 
       
  3873 EXPORT_C void CEikEdwin::TrappedDraw(const TRect& aViewRect) const
       
  3874     {
       
  3875     if ( iEdwinExtension->iDrawInvoked == CEikEdwinExtension::ENotDraw )
       
  3876         {
       
  3877         CEikEdwin* edwin( const_cast<CEikEdwin*>( this ) );
       
  3878         edwin->iEdwinExtension->iDrawInvoked = CEikEdwinExtension::EDrawing;
       
  3879         TRAP_IGNORE( edwin->PerformRecordedOperationL(); );
       
  3880         }
       
  3881     if (!(iEdwinUserFlags & EAvkonNotEditable))
       
  3882         {
       
  3883         TRAPD(err, iTextView->DrawL(aViewRect,SystemGc()) );
       
  3884         if (err)
       
  3885             {
       
  3886             SystemGc().Clear(aViewRect);
       
  3887             iEikonEnv->NotifyIdleErrorWhileRedrawing(err);
       
  3888             }
       
  3889         }
       
  3890     else
       
  3891         {
       
  3892         if(TextLength() == 0) // no text, so nothing to draw.
       
  3893             return;
       
  3894             
       
  3895         // If a non-editable edwin does not vertically fit to the parent window,
       
  3896         // do not draw the text
       
  3897         // TODO: commented code below should be flagged run-time
       
  3898 /*        TRect parentRect = DrawableWindow()->GetDrawRect(); 
       
  3899         if( aViewRect.iTl.iY < parentRect.iTl.iY ||
       
  3900             aViewRect.iBr.iY > parentRect.iBr.iY ) 
       
  3901             return;*/
       
  3902         
       
  3903         TRAP_IGNORE(DrawFirstLineTextL());      
       
  3904         }
       
  3905     }
       
  3906 
       
  3907 EXPORT_C void CEikEdwin::SetDimmed(TBool aDimmed)
       
  3908     {
       
  3909     CCoeControl::SetDimmed(aDimmed);
       
  3910     TRgb dimmedColor=iEikonEnv->ControlColor(EColorControlDimmedText,*this); // KEikEdwinDimmedTextColor
       
  3911     TRgb* pointer=(&dimmedColor);
       
  3912     if (!aDimmed)
       
  3913         pointer=NULL;
       
  3914     if (!iTextView)
       
  3915         {
       
  3916         TRAPD(err,CreateTextViewL());
       
  3917         if (err)
       
  3918             {
       
  3919             SystemGc().Clear(iTextView->ViewRect());
       
  3920             iEikonEnv->NotifyIdleErrorWhileRedrawing(err);
       
  3921             }
       
  3922         }
       
  3923     iTextView->SetTextColorOverride(pointer);
       
  3924     
       
  3925     // make scrollbar also dimmed
       
  3926     if (iSBFrame && iSBFrame->ScrollBarVisibility(CEikScrollBar::EHorizontal)!=CEikScrollBarFrame::EOff)
       
  3927         {
       
  3928         CEikScrollBar* sb = iSBFrame-> CEikScrollBarFrame::HorizontalScrollBar();
       
  3929         sb->SetDimmed(aDimmed);
       
  3930         }
       
  3931     if (iSBFrame && iSBFrame->ScrollBarVisibility(CEikScrollBar::EVertical)!=CEikScrollBarFrame::EOff)
       
  3932         {
       
  3933         CEikScrollBar* sb = iSBFrame-> CEikScrollBarFrame::VerticalScrollBar();
       
  3934         sb->SetDimmed(aDimmed);
       
  3935         }
       
  3936     }
       
  3937 
       
  3938 EXPORT_C void CEikEdwin::DrawContents()
       
  3939     {
       
  3940     if ( CAknEnv::Static()->TransparencyEnabled() )
       
  3941         {
       
  3942         if ( IsReadyToDraw() )
       
  3943             {
       
  3944             // Note that rect may be larger than iTextView->ViewRect(),
       
  3945             // so we have to make sure the whole area is drawn. The
       
  3946             // easiest way to achieve this is to call DrawNow.
       
  3947 
       
  3948             const TRect rect=iBorder.InnerRect(Rect());
       
  3949             DrawNow( rect );
       
  3950             }
       
  3951         }
       
  3952     else
       
  3953         {
       
  3954         if ( IsReadyToDraw() )
       
  3955             {
       
  3956             const TRect rect=iBorder.InnerRect(Rect());
       
  3957             CWindowGc& gc=iEikonEnv->SystemGc();
       
  3958 
       
  3959             gc.Activate(Window());
       
  3960             TrappedDraw(rect); //assumes the SystemGc is active
       
  3961             gc.Deactivate();
       
  3962             }
       
  3963         }
       
  3964     }
       
  3965 
       
  3966 EXPORT_C void CEikEdwin::EditObserver(TInt aStartEdit,TInt aEditLength )
       
  3967     {
       
  3968     if( EdwinExtension() )
       
  3969         {
       
  3970         if ( EdwinExtension()->InlineTextSource() )
       
  3971             EdwinExtension()->InlineTextSource()->EditObserver( aStartEdit, aEditLength );
       
  3972         }
       
  3973     }
       
  3974 
       
  3975 EXPORT_C void CEikEdwin::CancelSelectionL(TEnd aEndOfSelectionToLeaveCursor)
       
  3976     {
       
  3977     CancelFepTransaction();
       
  3978     __ASSERT_DEBUG(iTextView,Panic(EEikPanicEdwinNoView));
       
  3979     TCursorSelection cursorSelection=iTextView->Selection();
       
  3980     SetCursorPosL((aEndOfSelectionToLeaveCursor==EStart)? cursorSelection.LowerPos(): cursorSelection.HigherPos(),EFalse);
       
  3981     }
       
  3982 
       
  3983 EXPORT_C void CEikEdwin::MoveCursorL(TCursorPosition::TMovementType aMovement,TBool aSelect)
       
  3984     {
       
  3985     CancelFepTransaction();    
       
  3986     __ASSERT_DEBUG(iTextView,Panic(EEikPanicEdwinNoView));
       
  3987     if ( aMovement == TCursorPosition::EFLeft || aMovement == TCursorPosition::EFRight )
       
  3988         {
       
  3989         if ( AdjustCursorPosByMovementL( aMovement, aSelect ) )
       
  3990             {
       
  3991             return;
       
  3992             }
       
  3993         }
       
  3994     TInt oldCursor( CursorPos() );
       
  3995     TPoint movePoint=iTextView->MoveCursorL( aMovement, aSelect );
       
  3996     if ( iEdwinExtension->iSmiley )
       
  3997         {
       
  3998         TCursorSelection select( 0, 0 );
       
  3999         if ( AdjustCursorForSmileyL( oldCursor, select ) )
       
  4000             {
       
  4001             SetSelectionL( select.iCursorPos, select.iAnchorPos );
       
  4002             }
       
  4003         else
       
  4004             { 
       
  4005             HandleSelectionForSmiley( select );
       
  4006             }
       
  4007         DrawDeferred();
       
  4008         }
       
  4009     if ( movePoint.iX )
       
  4010         UpdateHorizScrollBarThumb();
       
  4011     if ( movePoint.iY )
       
  4012         UpdateVertScrollBarThumbL();
       
  4013 
       
  4014     if ( iEdwinFepSupport )
       
  4015         {
       
  4016         CAknEdwinState* edwinState = static_cast<CAknEdwinState*>( 
       
  4017             iEdwinFepSupport->State( KNullUid ) );
       
  4018         if ( edwinState )
       
  4019             {
       
  4020             TRAP_IGNORE( edwinState->ReportAknEdStateEventL( 
       
  4021                 MAknEdStateObserver::EAknCursorPositionChanged ) );
       
  4022             }
       
  4023         }
       
  4024     }
       
  4025 
       
  4026 EXPORT_C void CEikEdwin::MoveDisplayL(TCursorPosition::TMovementType aMovement)
       
  4027     {
       
  4028     __ASSERT_DEBUG(iTextView,Panic(EEikPanicEdwinNoView));
       
  4029     
       
  4030     // Before scrolling into blank space was allowed, but this eventually
       
  4031     // causes a panic at CTextView::ScrollDisplayL().
       
  4032     const TInt move=iTextView->ScrollDisplayL(aMovement,CTextLayout::EFDisallowScrollingBlankSpace);
       
  4033     if (move)
       
  4034         {
       
  4035         iEdwinExtension->iThumbPos = KErrNotFound;
       
  4036         switch (aMovement)
       
  4037             {
       
  4038         case TCursorPosition::EFLeft:
       
  4039         case TCursorPosition::EFRight:
       
  4040         case TCursorPosition::EFLineBeg:
       
  4041         case TCursorPosition::EFLineEnd:
       
  4042             UpdateHorizScrollBarThumb();
       
  4043             break;
       
  4044         case TCursorPosition::EFLineUp:
       
  4045         case TCursorPosition::EFLineDown:
       
  4046         case TCursorPosition::EFPageUp:
       
  4047         case TCursorPosition::EFPageDown:
       
  4048             UpdateVertScrollBarThumbL();
       
  4049             break;
       
  4050         default:
       
  4051             break;
       
  4052             }
       
  4053         }
       
  4054     }
       
  4055 
       
  4056 EXPORT_C void CEikEdwin::CancelInsertCharFormat()
       
  4057     {
       
  4058     __ASSERT_DEBUG(iText,Panic(EEikPanicEdwinNoText));
       
  4059     if (iEdwinInternalFlags&ERichText)
       
  4060         STATIC_CAST(CRichText*,iText)->CancelInsertCharFormat();
       
  4061     }
       
  4062 
       
  4063 EXPORT_C void CEikEdwin::MoveCursorToChunkStartL(TBool aSelect,TChunkSize aChunkSize,TEnd aEndScanningTowards)
       
  4064     {
       
  4065     CancelFepTransaction();
       
  4066     __ASSERT_DEBUG(iText,Panic(EEikPanicEdwinNoText));
       
  4067     TInt cursorPos=CursorPos();
       
  4068     TUint flags=CPlainText::EScanToUnitStart|CPlainText::EScanJoinDelimiters;
       
  4069     if (aEndScanningTowards==EStart)
       
  4070         flags|=CPlainText::EScanBackwards;
       
  4071     switch (aChunkSize)
       
  4072         {
       
  4073         case EChunkWord:
       
  4074             iText->ScanWords(cursorPos,flags);
       
  4075             break;
       
  4076         case EChunkPara:
       
  4077             iText->ScanParas(cursorPos,flags);
       
  4078             break;
       
  4079         }
       
  4080     if (cursorPos==CPlainText::EScanEndOfData)
       
  4081         cursorPos=TextLength();
       
  4082     SetCursorPosL(cursorPos,aSelect);
       
  4083     }
       
  4084 
       
  4085 EXPORT_C TInt CEikEdwin::CursorPos() const
       
  4086     {
       
  4087     __ASSERT_DEBUG(iTextView,Panic(EEikPanicEdwinNoView));
       
  4088     if ( iEdwinExtension->iDrawInvoked == CEikEdwinExtension::ENotDraw && 
       
  4089         iEdwinExtension->iTempCursorPos != KErrNotFound )
       
  4090         {
       
  4091         return iEdwinExtension->iTempCursorPos;
       
  4092         }
       
  4093     else
       
  4094         {
       
  4095         TCursorSelection selection=iTextView->Selection();
       
  4096         return(selection.iCursorPos);
       
  4097         }
       
  4098     }
       
  4099 
       
  4100 EXPORT_C TInt CEikEdwin::SelectionLength() const
       
  4101     {
       
  4102     __ASSERT_DEBUG(iTextView,Panic(EEikPanicEdwinNoView));
       
  4103     TCursorSelection selection( 0, 0 );
       
  4104     if ( iEdwinExtension->iDrawInvoked == CEikEdwinExtension::ENotDraw && 
       
  4105         iEdwinExtension->iTempCursorPos != KErrNotFound && 
       
  4106         iEdwinExtension->iTempAnchorPos != KErrNotFound )
       
  4107         {
       
  4108         selection.iCursorPos = iEdwinExtension->iTempCursorPos;
       
  4109         selection.iAnchorPos = iEdwinExtension->iTempAnchorPos;
       
  4110         }
       
  4111     else
       
  4112         {
       
  4113         selection = iTextView->Selection();
       
  4114         }
       
  4115     return(selection.Length());
       
  4116     }
       
  4117 
       
  4118 EXPORT_C TInt CEikEdwin::DeleteHighlightL(TBool& aChanged,TBool aIsBackSpace,TBool aPromptConfirmation)
       
  4119     {
       
  4120     __ASSERT_DEBUG(iTextView,Panic(EEikPanicEdwinNoView));
       
  4121     CancelFepTransaction();
       
  4122     const TCursorSelection selection=iTextView->Selection();
       
  4123     if (aPromptConfirmation)
       
  4124         {
       
  4125         if (!OkToDeleteSelectionL())
       
  4126             CBaActiveScheduler::LeaveNoAlert();
       
  4127         }
       
  4128     iTextView->CancelSelectionL();
       
  4129     SetCursorPosL(selection.LowerPos(),EFalse);
       
  4130     DeleteL(aChanged,selection,aIsBackSpace);
       
  4131     return(selection.LowerPos());
       
  4132     }
       
  4133 
       
  4134 EXPORT_C TBool CEikEdwin::OkToDeleteSelectionL()
       
  4135     {
       
  4136     // Avkon behaviour is always to allow deletion of selection, including
       
  4137     // pictures.
       
  4138     return ETrue;
       
  4139     }
       
  4140 
       
  4141 struct STempCleanup { CEikEdwin* iEdwin; };
       
  4142 
       
  4143 LOCAL_C void DeleteTemp(TAny* aPtr)
       
  4144     { STATIC_CAST(STempCleanup*,aPtr)->iEdwin->ClearUndo(); }
       
  4145 
       
  4146 EXPORT_C void CEikEdwin::DeleteL(TBool& aChanged,const TCursorSelection& aSelection,TBool aIsBackSpace,TBool aAllowUndo)
       
  4147     {
       
  4148     __ASSERT_DEBUG(iText,Panic(EEikPanicEdwinNoText));
       
  4149     CancelFepTransaction();
       
  4150     if (aAllowUndo && !SetUndoBufferL(aSelection))
       
  4151         CBaActiveScheduler::LeaveNoAlert();
       
  4152     STempCleanup tempCleanup;
       
  4153     tempCleanup.iEdwin=this;
       
  4154     CleanupStack::PushL(TCleanupItem(DeleteTemp,&tempCleanup));
       
  4155     const TInt length=Max(1,aSelection.Length());
       
  4156     if ((iEdwinInternalFlags&ERichText) && aIsBackSpace)
       
  4157         aChanged=STATIC_CAST(CRichText*,iText)->DelSetInsertCharFormatL(aSelection.LowerPos(),length);
       
  4158     else
       
  4159         {
       
  4160         if (iEdwinInternalFlags&ERichText)
       
  4161             STATIC_CAST(CRichText*,iText)->CancelInsertCharFormat();
       
  4162         aChanged=iText->DeleteL(aSelection.LowerPos(),length);
       
  4163         }
       
  4164     if ( iEdwinExtension->iSmiley )
       
  4165         { 
       
  4166         iEdwinExtension->iSmiley->HandleDeleteL( aSelection.LowerPos(), length );
       
  4167         }
       
  4168     CleanupStack::Pop();
       
  4169     }
       
  4170 
       
  4171 EXPORT_C TInt CEikEdwin::TextLength() const
       
  4172     {
       
  4173     __ASSERT_DEBUG(iText,Panic(EEikPanicEdwinNoText));
       
  4174     return(iText->DocumentLength());
       
  4175     }
       
  4176 
       
  4177 void CEikEdwin::SetCursorVisibilityL(TBool aEmphasis)
       
  4178     {
       
  4179     TCursor::TVisibility textCursor=(aEmphasis? TCursor::EFCursorFlashing : TCursor::EFCursorInvisible);
       
  4180     TCursor::TVisibility lineCursor=((iEdwinUserFlags&ELineCursor && aEmphasis)? 
       
  4181                                         TCursor::EFCursorVisible : TCursor::EFCursorInvisible);
       
  4182     if (iEdwinUserFlags&EAvkonDisableCursor) 
       
  4183         { 
       
  4184         textCursor = TCursor::EFCursorInvisible;
       
  4185         lineCursor = TCursor::EFCursorInvisible;
       
  4186         }
       
  4187     
       
  4188     iTextView->SetCursorVisibilityL(lineCursor,textCursor);
       
  4189     CAknEdwinState*edwinState = EditorState();
       
  4190     if( !edwinState )
       
  4191     	return;
       
  4192     if( textCursor != TCursor::EFCursorInvisible )
       
  4193     	{
       
  4194         SetAknEditorFlags( edwinState->Flags() | EAknEditorFlagTextCursorVisible );
       
  4195     	}
       
  4196     else
       
  4197     	{
       
  4198     	SetAknEditorFlags( edwinState->Flags() & ~EAknEditorFlagTextCursorVisible );
       
  4199     	
       
  4200         // If cursor is disabled during kinetic scrolling
       
  4201         // by other party (for any reason), reset flag so that we don't show it again
       
  4202         // when kinetic scrolling stops
       
  4203         iEdwinExtension->iCursorWasVisible = EFalse;
       
  4204     	}
       
  4205     }
       
  4206 
       
  4207 EXPORT_C CPlainText* CEikEdwin::Text() const
       
  4208     {
       
  4209     return iText;
       
  4210     }
       
  4211 
       
  4212 /**
       
  4213  * @internal
       
  4214  * @deprecated
       
  4215  */
       
  4216 EXPORT_C CTextView* CEikEdwin::TextView() const
       
  4217     {
       
  4218     return iTextView;
       
  4219     }
       
  4220 
       
  4221 /**
       
  4222  * @internal
       
  4223  * @deprecated
       
  4224  */
       
  4225 EXPORT_C CTextLayout* CEikEdwin::TextLayout() const
       
  4226     {
       
  4227     return iLayout;
       
  4228     }
       
  4229     
       
  4230 EXPORT_C void CEikEdwin::SetZoomFactorL(TZoomFactor* aZoomFactor)
       
  4231     {
       
  4232     iZoomFactor=aZoomFactor;
       
  4233     SetAmountToFormatL(ETrue); // isn't new doc at all !!!
       
  4234     }
       
  4235 
       
  4236 EXPORT_C void CEikEdwin::SetBorderViewMargins(TMargins8 aMargins)
       
  4237     {
       
  4238     iMargins=aMargins;
       
  4239     }
       
  4240 
       
  4241 EXPORT_C void CEikEdwin::SetBackgroundColorL(TRgb aBackground)
       
  4242     {
       
  4243     if (!iTextView)
       
  4244         CreateTextViewL();
       
  4245     
       
  4246     if (iEdwinExtension)
       
  4247         {
       
  4248         iEdwinExtension->iEditorBackgroundColor = aBackground;
       
  4249         }
       
  4250 
       
  4251     // for legacy reasons
       
  4252     AknLayoutUtils::OverrideControlColorL(*this, EColorControlBackground, aBackground);
       
  4253     }
       
  4254 
       
  4255 EXPORT_C void CEikEdwin::SetWysiwygModeOn(TInt aLayoutWidth,MGraphicsDeviceMap* aDevice)
       
  4256     {
       
  4257     __ASSERT_DEBUG(iLayout,Panic(EEikPanicEdwinNoLayout));
       
  4258     iLayoutWidth=aLayoutWidth;
       
  4259     iEdwinInternalFlags|=EWysiwygOn;
       
  4260     iLayout->SetFormatMode(CLayoutData::EFWysiwygMode,aLayoutWidth,aDevice);
       
  4261     }
       
  4262 
       
  4263 EXPORT_C void CEikEdwin::SetWysiwygModeOff()
       
  4264     {
       
  4265     __ASSERT_DEBUG(iLayout,Panic(EEikPanicEdwinNoLayout));
       
  4266     iLayoutWidth=0;
       
  4267     iEdwinInternalFlags&=~EWysiwygOn;
       
  4268     iLayout->SetFormatMode(CLayoutData::EFScreenMode,LayoutWidth(),NULL);
       
  4269     }
       
  4270 
       
  4271 EXPORT_C void CEikEdwin::UpdateLayoutWidth(TInt aLayoutWidth)
       
  4272     {
       
  4273     __ASSERT_DEBUG(iLayout,Panic(EEikPanicEdwinNoLayout));
       
  4274     iLayoutWidth=aLayoutWidth;
       
  4275     iLayout->SetWrapWidth(aLayoutWidth);
       
  4276     }
       
  4277 
       
  4278 EXPORT_C TInt CEikEdwin::UpperFullFormattingLength() const
       
  4279     {
       
  4280     if (iEdwinExtension)
       
  4281         return iEdwinExtension->iUpperFullFormattingLength;
       
  4282     else        
       
  4283         return KFullFormattingUpperThreshold;
       
  4284     }
       
  4285 
       
  4286 EXPORT_C TInt CEikEdwin::LowerPartialFormattingLength() const
       
  4287     {
       
  4288     if (iEdwinExtension)
       
  4289         return iEdwinExtension->iUpperFullFormattingLength - KFormattingThresholdGap;
       
  4290     else
       
  4291         return KPartialFormattingLowerThreshold;
       
  4292     }
       
  4293 
       
  4294 EXPORT_C void CEikEdwin::SetSuppressNotifyDraw( TBool aEnabled )
       
  4295     {
       
  4296     if (aEnabled)
       
  4297         iEdwinInternalFlags |= ESuppressNotifyDraw;
       
  4298     else
       
  4299         iEdwinInternalFlags &= ~ESuppressNotifyDraw;    
       
  4300     }
       
  4301 
       
  4302 EXPORT_C void CEikEdwin::SetSuppressFormatting( TBool aSuppress )
       
  4303     {
       
  4304     if (aSuppress)
       
  4305         iEdwinInternalFlags |= ESuppressFormatting;
       
  4306     else
       
  4307         iEdwinInternalFlags &= ~ESuppressFormatting;    
       
  4308     }
       
  4309     
       
  4310 EXPORT_C void CEikEdwin::SetReadOnly(TBool aReadOnly)
       
  4311     {
       
  4312     if (aReadOnly)
       
  4313         iEdwinUserFlags|=EReadOnly;
       
  4314     else
       
  4315         iEdwinUserFlags&=~EReadOnly;
       
  4316     }
       
  4317 
       
  4318 EXPORT_C TBool CEikEdwin::IsReadOnly() const
       
  4319     {
       
  4320     return iEdwinUserFlags&EReadOnly;
       
  4321     }
       
  4322 
       
  4323 EXPORT_C TInt CEikEdwin::AknEditorFlags() 
       
  4324     { 
       
  4325     if (EditorState()) 
       
  4326         { 
       
  4327         return EditorState()->Flags(); 
       
  4328         } 
       
  4329    return KErrNotFound;     
       
  4330     }
       
  4331 
       
  4332 EXPORT_C void CEikEdwin::SetOnlyASCIIChars(TBool aASCIIOnly)
       
  4333     {
       
  4334     if (aASCIIOnly)
       
  4335         iEdwinUserFlags|=EOnlyASCIIChars;
       
  4336     else
       
  4337         iEdwinUserFlags&=~EOnlyASCIIChars;
       
  4338     }
       
  4339 
       
  4340 EXPORT_C TBool CEikEdwin::OnlyASCIIChars() const
       
  4341     {
       
  4342     return (iEdwinUserFlags&EOnlyASCIIChars) ||
       
  4343     (AknEdwinFlags() & EAknEditorFlagLatinInputModesOnly);
       
  4344     }
       
  4345 
       
  4346 TBool CEikEdwin::IsValidChar(TInt aChar) const
       
  4347     {
       
  4348     TBool ret( ETrue );
       
  4349     
       
  4350     if ( OnlyASCIIChars() && aChar >= 255 )
       
  4351         {
       
  4352         if ( aChar == KPuaCodeSpaceSymbol
       
  4353              || aChar == KEuroSign
       
  4354              )
       
  4355             {
       
  4356             ret = ETrue;
       
  4357             }
       
  4358         else if ( ( aChar == KDownwardsArrowWithTipLeftwards ||
       
  4359                     aChar == KDownwardsArrowWithTipRightwards ||
       
  4360                     aChar == CEditableText::EParagraphDelimiter ||
       
  4361                     aChar == CEditableText::ELineBreak ) &&
       
  4362                   !( iEdwinUserFlags & ENoLineOrParaBreaks ||
       
  4363                      iEdwinInternalFlags & EHasOneLineOnly ) )
       
  4364             {
       
  4365             ret = ETrue;
       
  4366             }
       
  4367         else
       
  4368             {
       
  4369             ret = EFalse;
       
  4370             }
       
  4371         }
       
  4372     
       
  4373     return ret;
       
  4374     }
       
  4375 
       
  4376 EXPORT_C void CEikEdwin::CheckNotReadOnlyL()
       
  4377     {
       
  4378     if (IsReadOnly())
       
  4379         {
       
  4380         NotifyInvalidOperationOnReadOnlyL();
       
  4381         CBaActiveScheduler::LeaveNoAlert();
       
  4382         }
       
  4383     }
       
  4384 
       
  4385 EXPORT_C void CEikEdwin::NotifyInvalidOperationOnReadOnlyL()
       
  4386     {
       
  4387     iEikonEnv->InfoMsg(R_EIK_TBUF_READONLYFILE);
       
  4388     }
       
  4389 
       
  4390 EXPORT_C void CEikEdwin::SetRightWrapGutter(TInt aGap)
       
  4391     {
       
  4392     iRightWrapGutter=aGap;
       
  4393     }
       
  4394 
       
  4395 EXPORT_C void CEikEdwin::GetText(TDes& aDes) const
       
  4396     {
       
  4397     __ASSERT_DEBUG(iText,Panic(EEikPanicEdwinNoText));
       
  4398 
       
  4399     // Uncommitted text in inline editing might temporarily exceed the maximum
       
  4400     // allowed number of characters in editor.
       
  4401     // So, truncate the text to the max allowed number of characters to prevent
       
  4402     // any buffer overflows in caller code.
       
  4403     if ( iTextLimit && TextLength() > iTextLimit )
       
  4404         {
       
  4405         iText->Extract( aDes, 0, iTextLimit );
       
  4406         }
       
  4407     else
       
  4408         {
       
  4409         iText->Extract(aDes); // caller's responsibility to provide long enough buffer
       
  4410         }
       
  4411     TCursorSelection select( TextLength(), 0 );
       
  4412     if ( iTextLimit && TextLength() > iTextLimit )
       
  4413         {
       
  4414         select.iCursorPos = iTextLimit;
       
  4415         }
       
  4416     TBool hasSmiley( EFalse );
       
  4417     if ( iEdwinExtension->iSmiley )
       
  4418         {
       
  4419         hasSmiley = iEdwinExtension->iSmiley->HasSmileyIconsInText();
       
  4420         }
       
  4421     if ( hasSmiley )
       
  4422         {
       
  4423         // ensure conversion happens
       
  4424         iEdwinExtension->iSmiley->ConvertTextForSmileyL( select.LowerPos(), aDes, EFalse );
       
  4425         }
       
  4426     }
       
  4427 
       
  4428 EXPORT_C HBufC* CEikEdwin::GetTextInHBufL() const
       
  4429     {
       
  4430     HBufC* ret=NULL;
       
  4431     TInt textLength=TextLength();
       
  4432     if (textLength)
       
  4433         {
       
  4434         ret=HBufC::NewL(textLength);
       
  4435         TPtr ptr=ret->Des();
       
  4436         GetText(ptr);
       
  4437         }
       
  4438     return(ret);
       
  4439     }
       
  4440 
       
  4441 EXPORT_C void CEikEdwin::ClearSelectionL()
       
  4442     { // !! must ensure with CTextView that this never leaves
       
  4443     if( IsFocused() )
       
  4444         {
       
  4445         CancelFepTransaction();
       
  4446         }
       
  4447     HandleSelectionForSmiley( TCursorSelection( 0, 0 ) );
       
  4448     if (iTextView)
       
  4449     	{
       
  4450         iTextView->CancelSelectionL();
       
  4451         if ( iEdwinFepSupport )
       
  4452             {
       
  4453             CAknEdwinState* edwinState = static_cast<CAknEdwinState*>( iEdwinFepSupport->State(KNullUid) );
       
  4454             if ( edwinState )
       
  4455                 {
       
  4456                 TRAP_IGNORE( edwinState->ReportAknEdStateEventL( MAknEdStateObserver::EAknCursorPositionChanged ) );
       
  4457                 }
       
  4458             }
       
  4459     	}
       
  4460     }
       
  4461 
       
  4462 EXPORT_C void CEikEdwin::SetTextL(const TDesC* aDes)
       
  4463     {
       
  4464     __ASSERT_DEBUG(iText,Panic(EEikPanicEdwinNoText));
       
  4465     if( IsFocused() )
       
  4466         {
       
  4467         CancelFepTransaction();
       
  4468         }
       
  4469     if (iEdwinFepSupport && iEdwinFepSupport->State(KNullUid))
       
  4470         STATIC_CAST(CAknEdwinState*, iEdwinFepSupport->State(KNullUid))->SetInlineEditSpan(TCursorSelection(0,0));
       
  4471     
       
  4472     ClearSelectionL();
       
  4473 
       
  4474     TInt err=0;
       
  4475     if (aDes && aDes->Length())
       
  4476         {
       
  4477         _LIT(KLineBreakCharacter, "\n");
       
  4478         TInt oldLength=iText->DocumentLength();
       
  4479         HBufC* segmBuf = HBufC::NewL(KSegmSize);
       
  4480         CleanupStack::PushL(segmBuf);
       
  4481         TPtr segmBufPtr = segmBuf->Des();
       
  4482         TInt strLength = aDes->Length();
       
  4483         TInt strEnd = strLength - 1;
       
  4484         TInt segmStart = 0;
       
  4485         TInt segmEnd = 0;
       
  4486         TInt insertLength =0;
       
  4487         while ( strLength > 0 && segmStart <= strEnd && segmEnd <= strEnd)
       
  4488         {
       
  4489         if ( strEnd - segmEnd < KSegmSize)
       
  4490             {
       
  4491             segmEnd = strEnd;
       
  4492             insertLength = segmEnd - segmStart + 1;
       
  4493             }
       
  4494         else
       
  4495             {
       
  4496             segmEnd = segmEnd + KSegmSize;
       
  4497             insertLength = KSegmSize;
       
  4498             }
       
  4499         segmBufPtr = aDes->Mid( segmStart, insertLength);
       
  4500         AknTextUtils::ReplaceCharacters(segmBufPtr, KLineBreakCharacter,
       
  4501                       TChar(CEditableText::EParagraphDelimiter));
       
  4502 	    iText->InsertL(oldLength+segmStart,*segmBuf);
       
  4503 	    if ( iEdwinExtension->iSmiley )
       
  4504 	        {
       
  4505 	        iEdwinExtension->iSmiley->HandleInsertL( oldLength+segmStart, 
       
  4506 	            insertLength );	        
       
  4507 	        }
       
  4508 	    segmStart = segmEnd;
       
  4509 	    if ( insertLength < KSegmSize && insertLength > 0)
       
  4510 	        {
       
  4511 	        segmEnd++;	
       
  4512 	        }
       
  4513 	    }
       
  4514 	    
       
  4515 	    CleanupStack::PopAndDestroy(segmBuf);
       
  4516         TRAP(err,iText->DeleteL(0,oldLength));
       
  4517         if ( iEdwinExtension->iSmiley )
       
  4518             {
       
  4519             iEdwinExtension->iSmiley->HandleDeleteL( 0, oldLength );
       
  4520             ConvertTextForSmileyL( TCursorSelection( 0, 
       
  4521                 iText->DocumentLength() ), ETrue );
       
  4522             }
       
  4523         }
       
  4524     else
       
  4525         {
       
  4526         iText->Reset(); // Duplicates previous behaviour where null pointer argument reset text object
       
  4527         if ( iEdwinExtension->iSmiley )
       
  4528             {
       
  4529             iEdwinExtension->iSmiley->HandleDeleteL( 0, 
       
  4530                 iText->DocumentLength() );
       
  4531             }
       
  4532         }
       
  4533 
       
  4534     CheckRemovePictures(0,iText->DocumentLength());
       
  4535     CheckValidityOfChars(0,iText->DocumentLength());
       
  4536     iEdwinExtension->iDisableConvertInFormat = ETrue;
       
  4537     SetAmountToFormatL(ETrue); // performs formatting
       
  4538     iEdwinExtension->iDisableConvertInFormat = EFalse;
       
  4539 	// Update cursor position as CursorWidth() needs that.
       
  4540     if (IsReadyToDraw())
       
  4541         {        
       
  4542         ApplyAutoSelectionL();
       
  4543         }
       
  4544     
       
  4545     TInt left, right=0;
       
  4546     if (iLayout && iLayout->CalculateHorizontalExtremesL(left,right,ETrue) && iTextView)
       
  4547         {
       
  4548         TInt width=iTextView->ViewRect().Width();
       
  4549         TInt labels=0, cursor=0;
       
  4550         iTextView->MarginWidths(labels,cursor);
       
  4551         width-=labels+cursor+labels+cursor+CursorWidth()+iRightWrapGutter;
       
  4552         if (left+right<width)
       
  4553             iTextView->SetLeftTextMargin(0);
       
  4554 
       
  4555         if ( iEdwinExtension )
       
  4556             {
       
  4557             iEdwinExtension->iExtendedInputCapabilities->ReportEventL( 
       
  4558                 CAknExtendedInputCapabilities::
       
  4559                 MAknEventObserver::EControlContentUpdatedInternally,
       
  4560                 NULL );
       
  4561             }
       
  4562         ReportEdwinEventL( MEikEdwinObserver::EEventTextUpdateAPI );
       
  4563         if ( iCcpuSupport )
       
  4564             {
       
  4565             iCcpuSupport->HandleSelectionChangeL();
       
  4566             }
       
  4567         }
       
  4568     if (IsReadyToDraw())
       
  4569         {
       
  4570         UpdateScrollBarsL();
       
  4571         }
       
  4572 
       
  4573     User::LeaveIfError(err);       
       
  4574     }
       
  4575 
       
  4576 EXPORT_C TCursorSelection CEikEdwin::Selection()    const
       
  4577     {
       
  4578     if ( iEdwinExtension->iDrawInvoked == CEikEdwinExtension::ENotDraw && 
       
  4579         iEdwinExtension->iTempCursorPos != KErrNotFound && 
       
  4580         iEdwinExtension->iTempAnchorPos != KErrNotFound )
       
  4581         {        
       
  4582         return TCursorSelection( iEdwinExtension->iTempCursorPos,
       
  4583             iEdwinExtension->iTempAnchorPos );
       
  4584         }
       
  4585     if (iTextView)
       
  4586         return(iTextView->Selection());
       
  4587     return TCursorSelection(0,0);
       
  4588     }
       
  4589 
       
  4590 EXPORT_C TInt CEikEdwin::CountWords()
       
  4591     {
       
  4592     __ASSERT_DEBUG(iText,Panic(EEikPanicEdwinNoText));
       
  4593     return(iText->WordCount());
       
  4594     }
       
  4595 
       
  4596 EXPORT_C void CEikEdwin::SetAllowUndo(TBool aAllow)
       
  4597     {
       
  4598     if (aAllow)
       
  4599         iEdwinUserFlags|=EAllowUndo;
       
  4600     else
       
  4601         iEdwinUserFlags&=~EAllowUndo;
       
  4602     }
       
  4603 
       
  4604 EXPORT_C TBool CEikEdwin::SupportsUndo() const
       
  4605     {
       
  4606     return iEdwinUserFlags&EAllowUndo;
       
  4607     }
       
  4608 
       
  4609 EXPORT_C TBool CEikEdwin::CanUndo() const
       
  4610     {
       
  4611     return (iUndoStore!=NULL);
       
  4612     }
       
  4613     
       
  4614 EXPORT_C void CEikEdwin::UndoL()
       
  4615     {
       
  4616     CancelFepTransaction();
       
  4617     if (!SupportsUndo())
       
  4618         return;
       
  4619     if (!iUndoStore)
       
  4620         iEikonEnv->InfoMsg(R_EIK_TBUF_NOTHING_TO_UNDO);
       
  4621     else
       
  4622         {
       
  4623         TBool changed=EFalse;
       
  4624         TCursorSelection newText=iUndoStore->NewText();
       
  4625         const TInt oldLength=TextLength();
       
  4626         if (newText.Length())
       
  4627             DeleteL(changed,newText,EFalse,EFalse);
       
  4628         const TInt lower=newText.LowerPos();
       
  4629         TInt undoneLength=0;
       
  4630         TRAPD(err,undoneLength=iText->PasteFromStoreL(iUndoStore->Store(),iUndoStore->Dictionary(),lower))
       
  4631         const TInt cursorPos=iUndoStore->OldCursorPos();
       
  4632         iTextView->SetPendingSelection(TCursorSelection(cursorPos,cursorPos));
       
  4633         if ( iEdwinExtension->iSmiley )
       
  4634             {
       
  4635             iEdwinExtension->iSmiley->HandleInsertL( lower, undoneLength );
       
  4636             ConvertTextForSmileyL( TCursorSelection( lower, undoneLength ), ETrue );
       
  4637             }
       
  4638         TRAPD(err2,iTextView->HandleInsertDeleteL(TCursorSelection(lower,lower+undoneLength),newText.Length(),changed));
       
  4639         ClearUndo();
       
  4640         if (NeedToChangeFormattingModeL())
       
  4641             SetAmountToFormatL();
       
  4642         ForceScrollBarUpdateL();
       
  4643         User::LeaveIfError(err);
       
  4644         User::LeaveIfError(err2);
       
  4645         ReportEdwinEventL( MEikEdwinObserver::EEventTextUpdate );
       
  4646         DoReportEventL( MCoeControlObserver::EEventStateChanged );
       
  4647         }
       
  4648     }
       
  4649 
       
  4650 EXPORT_C void CEikEdwin::ClearUndo()
       
  4651     {
       
  4652     delete iUndoStore;
       
  4653     iUndoStore=NULL;
       
  4654     }
       
  4655 
       
  4656 /**
       
  4657  * @internal
       
  4658  */
       
  4659 EXPORT_C TBool CEikEdwin::SetUndoBufferL(const TCursorSelection& aSelection)
       
  4660     {
       
  4661     if (iEdwinUserFlags&EAllowUndo)
       
  4662         {
       
  4663         TRAPD(err,DoSetUndoBufferL(aSelection));
       
  4664         if (err!=KErrNone && iUndoStore!=NULL)
       
  4665             ClearUndo();
       
  4666         if (err==KErrNoMemory)
       
  4667             return iEikonEnv->QueryWinL(R_EIK_TBUF_CANNOT_UNDO_CONFIRM_1,R_EIK_TBUF_CANNOT_UNDO_CONFIRM_2);
       
  4668         User::LeaveIfError(err);
       
  4669         }
       
  4670     return ETrue;
       
  4671     }
       
  4672 
       
  4673 void CEikEdwin::DoSetUndoBufferL(const TCursorSelection& aSelection)
       
  4674     {
       
  4675     if (iUndoStore)
       
  4676         ClearUndo();
       
  4677     iUndoStore=CUndoBuffer::NewL();
       
  4678     iText->CopyToStoreL(iUndoStore->Store(),iUndoStore->Dictionary(),aSelection.LowerPos(),aSelection.Length());
       
  4679     const TInt lowerPos=aSelection.LowerPos();
       
  4680     iUndoStore->SetNewText(TCursorSelection(lowerPos,lowerPos));
       
  4681     iUndoStore->SetOldCursorPos(aSelection.iCursorPos);
       
  4682     }
       
  4683 
       
  4684 /**
       
  4685  * @internal
       
  4686  */
       
  4687 EXPORT_C void CEikEdwin::SetUndoableText(const TCursorSelection& aSelection)
       
  4688     {
       
  4689     iUndoStore->SetNewText(aSelection);
       
  4690     }
       
  4691 
       
  4692 
       
  4693 CAknEdwinState* CEikEdwin::EditorState() const
       
  4694     {
       
  4695     if (iEdwinFepSupport)
       
  4696         return static_cast<CAknEdwinState*>(iEdwinFepSupport->State(KNullUid));
       
  4697     else
       
  4698         return NULL;
       
  4699     }
       
  4700 
       
  4701 EXPORT_C void CEikEdwin::InsertFromTextFileL(const TFileName& aFileName,const CPlainText::TTextOrganisation aTextOrganisation)
       
  4702     {
       
  4703     __ASSERT_DEBUG(iText,Panic(EEikPanicEdwinNoText));
       
  4704     CancelFepTransaction();
       
  4705     const TInt oldLength = iText->DocumentLength();
       
  4706     const TInt cursorPos=CursorPos();
       
  4707     iEikonEnv->BusyMsgL(R_EIK_TBUF_IMPORTING,500000); // after 0.5 seconds
       
  4708     iText->ImportTextFileL(cursorPos,aFileName,aTextOrganisation);
       
  4709     TInt insertLength( iText->DocumentLength() - oldLength );
       
  4710     CheckValidityOfChars( oldLength, insertLength );
       
  4711     if ( iEdwinExtension->iSmiley )
       
  4712         {
       
  4713         iEdwinExtension->iSmiley->HandleInsertL( cursorPos, insertLength );
       
  4714         ConvertTextForSmileyL( TCursorSelection( cursorPos, 
       
  4715             cursorPos + insertLength ), ETrue );
       
  4716         }
       
  4717     const TInt newLength=iText->DocumentLength();
       
  4718     const TInt newCursorPos=cursorPos+newLength-oldLength;
       
  4719     iTextView->SetPendingSelection(TCursorSelection(newCursorPos,newCursorPos));
       
  4720     if (NeedToChangeFormattingModeL())
       
  4721         SetAmountToFormatL();
       
  4722     else
       
  4723         iTextView->HandleInsertDeleteL(TCursorSelection(newCursorPos,cursorPos),0,ETrue);
       
  4724     DrawContents();
       
  4725     UpdateScrollBarsL();
       
  4726     ReportEdwinEventL( MEikEdwinObserver::EEventTextUpdate );
       
  4727     DoReportEventL( MCoeControlObserver::EEventStateChanged );
       
  4728     iEikonEnv->BusyMsgCancel();
       
  4729     }
       
  4730 
       
  4731 EXPORT_C void CEikEdwin::ClipboardL(TClipboardFunc aClipboardFunc)
       
  4732     {
       
  4733     __ASSERT_DEBUG(iTextView,Panic(EEikPanicEdwinNoView));
       
  4734     
       
  4735     TInt prevEndPosition( 0 );
       
  4736     if ( KineticScrollingEnabled() )
       
  4737         {
       
  4738         prevEndPosition =
       
  4739             iLayout->PixelsAboveBand() + AdjustedViewRect().Height();
       
  4740         }
       
  4741     
       
  4742     TBool commitInline( aClipboardFunc == EPaste );
       
  4743     TCursorSelection selection( 0, 0 );
       
  4744     CAknEdwinState* state( EditorState() );    
       
  4745     if ( !commitInline && aClipboardFunc == ECut )
       
  4746         {    
       
  4747         selection = iTextView->Selection();
       
  4748         TInt startOfInline( iEdwinFepSupport->iPositionOfInlineTextInDocument );        
       
  4749         TInt endOfInline( iEdwinFepSupport->iPositionOfInlineTextInDocument + 
       
  4750             iEdwinFepSupport->iLengthOfInlineText );
       
  4751         if ( iEdwinFepSupport->iLengthOfInlineText < 0 )
       
  4752             {          
       
  4753             if ( state && state->CurrentInlineEditSpan().Length() > 0 )
       
  4754                 {
       
  4755                 startOfInline = state->CurrentInlineEditSpan().LowerPos();
       
  4756                 endOfInline = state->CurrentInlineEditSpan().HigherPos();
       
  4757                 }
       
  4758             }
       
  4759         commitInline = ( selection.LowerPos() < endOfInline && 
       
  4760             selection.HigherPos() > startOfInline );
       
  4761         }
       
  4762     if ( commitInline )
       
  4763         {
       
  4764         if ( iEdwinFepSupport->iLengthOfInlineText > 0 )
       
  4765             {
       
  4766             iEdwinFepSupport->DoCommitFepInlineEditL();
       
  4767             SetCursorVisibilityL( ETrue );
       
  4768             }
       
  4769         if ( state && state->CurrentInlineEditSpan().Length() > 0 ) 
       
  4770             {
       
  4771             state->SetInlineEditSpan( TCursorSelection( 0, 0 ) );
       
  4772             }
       
  4773         }
       
  4774     CancelFepTransaction();
       
  4775     TBool reportChange=EFalse;
       
  4776     switch (aClipboardFunc)
       
  4777         {   
       
  4778     case ECut:
       
  4779     case ECopy:
       
  4780         {
       
  4781         TCursorSelection selection=iTextView->Selection();
       
  4782         const TInt selLength=SelectionLength();
       
  4783         if (!selLength)
       
  4784             iEikonEnv->InfoMsg(aClipboardFunc==ECut? R_EIK_TBUF_NOTHING_TO_CUT: R_EIK_TBUF_NOTHING_TO_COPY);
       
  4785         else
       
  4786             {
       
  4787             PlaceDataOnClipboardL();
       
  4788             if (aClipboardFunc==ECopy)
       
  4789                 {
       
  4790                 iEikonEnv->InfoMsg(R_EIK_TBUF_COPIED);
       
  4791                 if (iCcpuSupport)
       
  4792                     iCcpuSupport->HandleSelectionChangeL();
       
  4793                 }
       
  4794             else
       
  4795                 {
       
  4796                 TBool formatHasChanged;
       
  4797                 DeleteHighlightL(formatHasChanged,EFalse,EFalse);
       
  4798                 const TInt lower=selection.LowerPos();
       
  4799                 const TCursorSelection pending(lower,lower);
       
  4800                 iTextView->SetPendingSelection(pending);
       
  4801                 selection.iAnchorPos=lower;
       
  4802                 selection.iCursorPos=lower;
       
  4803                 iTextView->HandleInsertDeleteL(selection,selLength,formatHasChanged);
       
  4804                 reportChange=ETrue;
       
  4805                 }
       
  4806             CAknNoteDialog* dlg = new (ELeave) CAknNoteDialog();
       
  4807             dlg->SetTimeout( CAknNoteDialog::EShortTimeout );
       
  4808             dlg->SetTone( CAknNoteDialog::ENoTone );
       
  4809             dlg->ExecuteLD( R_AVKON_NOTE_CONF_COPIED );            
       
  4810             }
       
  4811         break;
       
  4812         }
       
  4813     case EPaste:
       
  4814         RetrieveDataFromClipboardL();
       
  4815         reportChange=ETrue;
       
  4816         break;
       
  4817     default:
       
  4818 #if defined(_DEBUG)
       
  4819         Panic(EEikPanicEdwinBadClipboardFunc);
       
  4820 #endif
       
  4821         break;
       
  4822         }
       
  4823     
       
  4824     if ( KineticScrollingEnabled() )
       
  4825         {
       
  4826         // If we have deleted some text and previous position (before delete) is
       
  4827         // out of current editor content, we must move back to inside content.
       
  4828         TInt formattedHeight( iLayout->FormattedHeightInPixels() );
       
  4829         if ( prevEndPosition > formattedHeight )
       
  4830            {
       
  4831            TInt movement( prevEndPosition - formattedHeight );   
       
  4832            iEdwinExtension->iPhysicsHandler->MoveScrollIndex( movement );
       
  4833            }
       
  4834         }
       
  4835     
       
  4836     if (reportChange)
       
  4837         {
       
  4838         ReportEdwinEventL( MEikEdwinObserver::EEventTextUpdate );
       
  4839         DoReportEventL( MCoeControlObserver::EEventStateChanged );
       
  4840         NotifyEditorStateObserverOfStateChangeL();
       
  4841         UpdateScrollBarsL();
       
  4842         }
       
  4843     }
       
  4844 
       
  4845 EXPORT_C void CEikEdwin::PlaceDataOnClipboardL()
       
  4846     {
       
  4847     __ASSERT_DEBUG(iText,Panic(EEikPanicEdwinNoText));
       
  4848     CancelFepTransaction();
       
  4849     CClipboard* cb=CClipboard::NewForWritingLC(iCoeEnv->FsSession());
       
  4850     CopyToStoreL(cb->Store(),cb->StreamDictionary());
       
  4851     cb->CommitL();
       
  4852     CleanupStack::PopAndDestroy();
       
  4853     }
       
  4854 
       
  4855 void CEikEdwin::RetrieveDataFromClipboardL()
       
  4856     {
       
  4857     CancelFepTransaction();
       
  4858     CClipboard* cb=NULL;
       
  4859     TRAPD(err,cb=CClipboard::NewForReadingL(iCoeEnv->FsSession()));
       
  4860     CleanupStack::PushL(cb);
       
  4861     if (err==KErrPathNotFound || err==KErrNotFound)
       
  4862         iEikonEnv->LeaveWithInfoMsg(R_EIK_TBUF_NOTHING_TO_PASTE);
       
  4863     User::LeaveIfError(err);
       
  4864     PasteFromStoreL(cb->Store(), cb->StreamDictionary());
       
  4865     CleanupStack::PopAndDestroy();  // cb
       
  4866     }
       
  4867 
       
  4868 EXPORT_C void CEikEdwin::SendDataOverIrL()
       
  4869     {
       
  4870     __ASSERT_DEBUG(iText,Panic(EEikPanicEdwinNoText));
       
  4871     iEikonEnv->IrFactory()->SendDataOverIrL(this);
       
  4872     }
       
  4873 
       
  4874 EXPORT_C void CEikEdwin::ReceiveDataOverIrL()
       
  4875     { 
       
  4876     iEikonEnv->IrFactory()->ReceiveDataOverIrL(this);
       
  4877     }
       
  4878 
       
  4879 EXPORT_C void CEikEdwin::CopyToStoreL(CStreamStore& aStore,CStreamDictionary& aDict)
       
  4880     {
       
  4881     CancelFepTransaction();
       
  4882     TCursorSelection selection=Selection();
       
  4883     CPlainText* text( iText );
       
  4884     TInt start( selection.LowerPos() );
       
  4885     HBufC* buf( NULL );
       
  4886     if ( iEdwinExtension->iSmiley )
       
  4887         {
       
  4888         buf = ExtractTextLC( selection );
       
  4889         text = CPlainText::NewL();
       
  4890         CleanupStack::PushL( text );
       
  4891         TPtr ptr( buf->Des() );
       
  4892         iEdwinExtension->iSmiley->ConvertTextForSmileyL( selection.LowerPos(),
       
  4893             ptr, EFalse );
       
  4894         start = 0;
       
  4895         text->InsertL( start, *buf );                
       
  4896         }
       
  4897     text->CopyToStoreL(aStore, aDict, start, selection.Length() );
       
  4898     if ( iEdwinExtension->iSmiley )
       
  4899         {
       
  4900         CleanupStack::PopAndDestroy( text );    
       
  4901         CleanupStack::PopAndDestroy( buf );
       
  4902         }
       
  4903     }
       
  4904 
       
  4905 EXPORT_C void CEikEdwin::PasteFromStoreL(CStreamStore& aStore,CStreamDictionary& aDict)
       
  4906     {
       
  4907     CancelFepTransaction();
       
  4908     TStreamId streamId=aDict.At(KClipboardUidTypeRichText);
       
  4909     if (streamId==KNullStreamId)
       
  4910         streamId=aDict.At(KClipboardUidTypePlainText);
       
  4911     TInt nothingResId=(iEdwinInternalFlags&EPasteFromIrStore)? R_EIK_TBUF_UNSUITABLE_IR_TYPE : R_EIK_TBUF_NOTHING_TO_PASTE;
       
  4912     SetPasteFromIrStore(EFalse); // nothing to leave before this line
       
  4913     if (streamId==KNullStreamId)
       
  4914         iEikonEnv->LeaveWithInfoMsg(nothingResId);
       
  4915     iEikonEnv->BusyMsgL(R_EIK_TBUF_PASTING,500000);
       
  4916     TCursorSelection selection=iTextView->Selection();
       
  4917     const TInt oldTextLength=TextLength();
       
  4918     const TInt selLength=selection.Length();
       
  4919     TBool formatHasChanged=EFalse;
       
  4920     if (selLength)
       
  4921         DeleteHighlightL(formatHasChanged);
       
  4922     else
       
  4923         ClearUndo();
       
  4924     const TInt lengthBeforePaste=TextLength();
       
  4925     TRAPD(err,DoPasteFromStoreL(aStore,aDict));
       
  4926     TInt newLength=iText->DocumentLength();
       
  4927     TInt pastedLength=newLength-lengthBeforePaste;
       
  4928     if (err!=KErrNone && pastedLength==0)
       
  4929         {
       
  4930         ClearUndo();
       
  4931         User::Leave(err);
       
  4932         }
       
  4933     const TInt higher=selection.HigherPos()+newLength-oldTextLength;
       
  4934     iTextView->SetPendingSelection(TCursorSelection(higher,higher));
       
  4935     selection.iAnchorPos=selection.LowerPos();
       
  4936     selection.iCursorPos=selection.iAnchorPos+pastedLength;
       
  4937     if ( iEdwinExtension->iSmiley )
       
  4938         {
       
  4939         iEdwinExtension->iSmiley->HandleInsertL( selection.LowerPos(), 
       
  4940             selection.Length() );
       
  4941         ConvertTextForSmileyL( selection, ETrue );
       
  4942         } 
       
  4943     if (iUndoStore)
       
  4944         iUndoStore->SetNewText(selection);
       
  4945     if ( NeedToChangeFormattingModeL())
       
  4946         {
       
  4947         SetAmountToFormatL();
       
  4948         DrawContents();
       
  4949         }
       
  4950     else
       
  4951         iTextView->HandleInsertDeleteL(selection,selLength,formatHasChanged);
       
  4952     iEikonEnv->BusyMsgCancel();
       
  4953     User::LeaveIfError(err);
       
  4954     }
       
  4955 
       
  4956 void CEikEdwin::DoPasteFromStoreL(const CStreamStore& aStore,const CStreamDictionary& aDict)
       
  4957     {
       
  4958     const TInt lengthBeforePaste=iText->DocumentLength();
       
  4959     const TInt cursorPos=CursorPos();
       
  4960     
       
  4961     TBool pasteAsPlainText = iEdwinUserFlags & CEikRichTextEditor::EPasteAsPlainText;
       
  4962     
       
  4963     CAknEdwinState* state = static_cast<CAknEdwinState*>( iEdwinFepSupport->State( KNullUid ) );    
       
  4964     if (state && state->PermittedInputModes() == EAknEditorNumericInputMode )
       
  4965         {
       
  4966         TBool isDigit(ETrue);
       
  4967         CPlainText* txtStore = CPlainText::NewL();
       
  4968         CleanupStack::PushL(txtStore);
       
  4969         TInt bufferLength = txtStore->PasteFromStoreL(aStore, aDict, 0);
       
  4970                 
       
  4971         HBufC* txtStoreBuf = txtStore->Read(0).AllocL();
       
  4972         CleanupStack::PushL( txtStoreBuf ); 
       
  4973         TPtr text = txtStoreBuf->Des();
       
  4974         TInt textLength = text.Length();
       
  4975         
       
  4976         HBufC* allowedChars = GetAllowedCharsLC();
       
  4977         for ( TInt ii = 0; ii < textLength; ii++ )
       
  4978             {
       
  4979             TChar chr(text[ii]);
       
  4980             if ((*allowedChars).Locate(chr) == KErrNotFound && text[ii] != 0x2029)
       
  4981                 {
       
  4982                 isDigit = EFalse;
       
  4983                 break;
       
  4984                 }
       
  4985             }
       
  4986         CleanupStack::PopAndDestroy(3);//texStore, txtStoreBuf, allowedChars
       
  4987 
       
  4988         if (!isDigit)
       
  4989             return;        
       
  4990         }
       
  4991     if ( (iEdwinInternalFlags & ERichText) && pasteAsPlainText )
       
  4992         { 
       
  4993         static_cast<CRichText*>(iText)->PasteFromStoreL( aStore, aDict, cursorPos, CParagraphStyle::EIgnoreNewStyles ); 
       
  4994         } 
       
  4995     else 
       
  4996         { 
       
  4997         iText->PasteFromStoreL(aStore,aDict,cursorPos); 
       
  4998         } 
       
  4999   
       
  5000     // Remove tabulators from text if found
       
  5001     TInt length = iText->DocumentLength();
       
  5002     
       
  5003     TPtrC ptr= iText->Read(0);
       
  5004     TInt position = ptr.Mid(0).LocateReverse('\t');
       
  5005     while (position != KErrNotFound )
       
  5006         {
       
  5007         iText->DeleteL( position, 1 );
       
  5008         position = ptr.Left(position).LocateReverse('\t');
       
  5009         }
       
  5010     
       
  5011     TInt newLength=iText->DocumentLength();
       
  5012     TInt pastedLength=newLength-lengthBeforePaste;
       
  5013     CheckRemovePictures(cursorPos,pastedLength);
       
  5014     const TInt tmp=iText->DocumentLength();
       
  5015     if (tmp<newLength)
       
  5016         iEikonEnv->InfoMsg(R_EIK_TBUF_CANNOT_PASTE_OBJECTS);
       
  5017     CheckValidityOfChars(cursorPos,pastedLength);
       
  5018     newLength = iText->DocumentLength();
       
  5019     pastedLength=newLength-lengthBeforePaste;
       
  5020     if ( iEdwinInternalFlags&EHasOneLineOnly || iEdwinUserFlags&ENoLineOrParaBreaks )
       
  5021         {
       
  5022         ReplaceParaDelimitersL( cursorPos, pastedLength );        
       
  5023         newLength=iText->DocumentLength();
       
  5024         pastedLength=newLength-lengthBeforePaste;
       
  5025         }
       
  5026     const TInt extraChars=newLength-iTextLimit;
       
  5027     if (iTextLimit && extraChars>0)
       
  5028         {
       
  5029         const TInt pos=cursorPos+pastedLength-extraChars;
       
  5030         DeleteExtraParasL(pos,extraChars);
       
  5031         const TInt length=iText->DocumentLength()-iTextLimit;
       
  5032         if (iEdwinInternalFlags&ERichText && length>0)
       
  5033             STATIC_CAST(CRichText*,iText)->DeleteFromParagraph(pos,length);
       
  5034         else
       
  5035             iText->DeleteL(pos,iText->DocumentLength()-iTextLimit); // won't leave
       
  5036         CEikonEnv::Beep();
       
  5037         iEikonEnv->InfoMsg(R_EIK_TBUF_MAX_CHARACTERS_REACHED);
       
  5038         }
       
  5039     pastedLength=iText->DocumentLength()-lengthBeforePaste;
       
  5040     
       
  5041     // The CParagraphStyle::EIgnoreNewStyles doesn't remove italics,
       
  5042     // bold or underline. We'll try to hack it here.
       
  5043     if ( (iEdwinInternalFlags & ERichText) && pasteAsPlainText ) 
       
  5044         { 
       
  5045         TCharFormat charFormat;
       
  5046         TCharFormatMask charFormatMask;
       
  5047 
       
  5048         CRichText* text = static_cast<CRichText*>(iText); 
       
  5049         text->CGlobalText::GetCharFormat( charFormat, charFormatMask, 0, 0 ); 
       
  5050         charFormatMask.SetAll();
       
  5051         text->ApplyCharFormatL( charFormat, charFormatMask, cursorPos, pastedLength );
       
  5052         
       
  5053         // To make sure that no parts of the text are left formatted with
       
  5054         // something else than the globalcharformat.
       
  5055         text->RemoveSpecificCharFormatL( cursorPos, pastedLength );
       
  5056         }
       
  5057     
       
  5058     HandleTextPastedL(cursorPos,pastedLength);
       
  5059     }
       
  5060     
       
  5061 void CEikEdwin::ReplaceParaDelimitersL( TInt aStartPos, TInt aLength )
       
  5062     {
       
  5063     TPtrC ptr = iText->Read( aStartPos, aLength );
       
  5064     TInt delimiter[2] = { 0 };    
       
  5065     _LIT( KSpace, " " );
       
  5066     while( delimiter[0] >= 0 || delimiter[1] >= 0 )
       
  5067         {
       
  5068         delimiter[0] = ptr.Locate( TChar(CEditableText::EParagraphDelimiter) );
       
  5069         delimiter[1] = ptr.Locate( TChar(CEditableText::ELineBreak) );
       
  5070         for( TInt i = 0; i < 2; i++ )
       
  5071             {            
       
  5072             if ( delimiter[i] >= 0 )
       
  5073                 {
       
  5074                 iText->DeleteL( aStartPos + delimiter[i], 1 );
       
  5075                 iText->InsertL( aStartPos + delimiter[i], KSpace );
       
  5076                 }
       
  5077             }
       
  5078         }
       
  5079     }
       
  5080 
       
  5081 void CEikEdwin::DeleteExtraParasL(TInt aStartPos,TInt aLength)
       
  5082     {
       
  5083     TInt pos=aStartPos;
       
  5084     TInt charsRead=0;
       
  5085     const TBool pastedAtEnd=(aStartPos+aLength==iText->DocumentLength());
       
  5086     while (charsRead<aLength)
       
  5087         {
       
  5088         TPtrC ptr=iText->Read(pos,Min(aLength-charsRead,10));       
       
  5089         const TInt paraDelimiter=ptr.Locate(TChar(CEditableText::EParagraphDelimiter));
       
  5090         const TInt lineDelimiter=ptr.Locate(TChar(CEditableText::ELineBreak));
       
  5091         if (!(iEdwinInternalFlags&ERichText))
       
  5092             {
       
  5093             const TInt delimiter=(paraDelimiter==-1? lineDelimiter : (lineDelimiter==-1? 
       
  5094                                                 paraDelimiter : Min(lineDelimiter,paraDelimiter)));
       
  5095             if (delimiter!=-1)
       
  5096                 {
       
  5097                 iText->DeleteL(pos+delimiter,aLength-(charsRead+delimiter)); // won't leave
       
  5098                 break;
       
  5099                 }
       
  5100             }
       
  5101         else
       
  5102             {
       
  5103             if (paraDelimiter!=-1)
       
  5104                 {
       
  5105                 if (pastedAtEnd)
       
  5106                     STATIC_CAST(CRichText*,iText)->DeleteParagraph(pos+paraDelimiter+1,aLength-(charsRead+paraDelimiter));
       
  5107                 else
       
  5108                     {
       
  5109                     TChar delimiter(CEditableText::EParagraphDelimiter);
       
  5110                     TInt startPos=pos+paraDelimiter+1;
       
  5111                     TInt length=aLength-(charsRead+paraDelimiter)-1;
       
  5112                     TInt lastParaDelimiter=KErrNotFound;
       
  5113                     TInt charPos=LocateChar(delimiter,startPos,length);
       
  5114                     while (charPos!=KErrNotFound)
       
  5115                         {
       
  5116                         lastParaDelimiter=startPos+charPos;
       
  5117                         startPos+=(charPos+1);
       
  5118                         length-=(charPos+1);
       
  5119                         charPos=LocateChar(delimiter,startPos,length);
       
  5120                         }
       
  5121                     TInt len=aLength-(startPos-aStartPos);
       
  5122                     if (len>0)
       
  5123                         STATIC_CAST(CRichText*,iText)->DeleteFromParagraph(startPos,len);
       
  5124                     if (lastParaDelimiter!=KErrNotFound)
       
  5125                         {
       
  5126                         const TInt start=pos+paraDelimiter+1;
       
  5127                         length=lastParaDelimiter-start+1;
       
  5128                         STATIC_CAST(CRichText*,iText)->DeleteParagraph(start,length);
       
  5129                         }
       
  5130                     }
       
  5131                 }
       
  5132             if (lineDelimiter!=-1 && (paraDelimiter==-1 || lineDelimiter<paraDelimiter))
       
  5133                 {
       
  5134                 TInt length=aLength-(charsRead+lineDelimiter);
       
  5135                 if (paraDelimiter!=-1)
       
  5136                     length=paraDelimiter-lineDelimiter;
       
  5137                 STATIC_CAST(CRichText*,iText)->DeleteFromParagraph(pos+lineDelimiter,length);
       
  5138                 break;
       
  5139                 }
       
  5140             if (paraDelimiter!=-1)
       
  5141                 {
       
  5142                 if (!pastedAtEnd)
       
  5143                     iText->DeleteL(pos+paraDelimiter,1);
       
  5144                 break;
       
  5145                 }
       
  5146             }
       
  5147         const TInt ptrLen=ptr.Length();
       
  5148         pos+=ptrLen;
       
  5149         charsRead+=ptrLen;
       
  5150         }
       
  5151     }
       
  5152 
       
  5153 TInt CEikEdwin::LocateChar(TChar aChar,TInt aStartPos,TInt aLength)
       
  5154     {
       
  5155     TInt pos=aStartPos;
       
  5156     TInt charsRead=0;
       
  5157     while (charsRead<aLength)
       
  5158         {
       
  5159         TPtrC ptr=iText->Read(pos,Min(aLength-charsRead,10));       
       
  5160         const TInt charPos=ptr.Locate(aChar);
       
  5161         if (charPos!=KErrNotFound)
       
  5162             return (charsRead+charPos);
       
  5163         const TInt ptrLen=ptr.Length();
       
  5164         pos+=ptrLen;
       
  5165         charsRead+=ptrLen;
       
  5166         }
       
  5167     return KErrNotFound;
       
  5168     }
       
  5169 
       
  5170 EXPORT_C void CEikEdwin::SetPasteFromIrStore(TBool aPasteFromIrStore)
       
  5171     {
       
  5172     if (aPasteFromIrStore)
       
  5173         iEdwinInternalFlags|=EPasteFromIrStore;
       
  5174     else
       
  5175         iEdwinInternalFlags&=(~EPasteFromIrStore);
       
  5176     }
       
  5177 
       
  5178 EXPORT_C void CEikEdwin::HandleTextPastedL(TInt /*aStartPos*/,TInt& /*aLength*/)
       
  5179     {
       
  5180     }
       
  5181 
       
  5182 EXPORT_C void CEikEdwin::CancelFepTransaction()
       
  5183     {    
       
  5184     CCoeFep* fep=iCoeEnv->Fep();
       
  5185     if ( fep!=NULL )
       
  5186         {
       
  5187         fep->CancelTransaction();
       
  5188         }
       
  5189     }
       
  5190 
       
  5191 EXPORT_C void CEikEdwin::HandleTextChangedL()
       
  5192     {
       
  5193     ClearSelectionL(); // ?? maybe too late here!!
       
  5194 
       
  5195     // clear inline edit state info
       
  5196     if (iEdwinFepSupport)
       
  5197         STATIC_CAST(CAknEdwinState*, iEdwinFepSupport->State(KNullUid))->SetInlineEditSpan(TCursorSelection(0,0));
       
  5198 
       
  5199     SetAmountToFormatL( ETrue );
       
  5200     
       
  5201     if (IsReadyToDraw())
       
  5202         {
       
  5203         DrawContents();
       
  5204         UpdateScrollBarsL();
       
  5205         }
       
  5206     }
       
  5207 
       
  5208 EXPORT_C void CEikEdwin::RunCharMapDialogL()
       
  5209     {
       
  5210     CancelFepTransaction();
       
  5211     ASSERT(iEikonEnv->CDlgDialogFactory());
       
  5212     iEikonEnv->CDlgDialogFactory()->RunCharMapDlgLD(this);
       
  5213     }
       
  5214 
       
  5215 EXPORT_C void CEikEdwin::ForceScrollBarUpdateL()
       
  5216     {
       
  5217     SetScrollBarsL();   
       
  5218     }
       
  5219 
       
  5220 EXPORT_C void CEikEdwin::UpdateScrollBarsL()
       
  5221     {
       
  5222     CheckEdwinExtensionL(); // checks if iEdwinExtension is non-NULL
       
  5223     
       
  5224     // Updating via CIdle is needed only if kinetic scrolling is not in use
       
  5225     if ( !KineticScrollingEnabled() )
       
  5226         {
       
  5227         if ( !iEdwinExtension->ScrollBarSetter() && OwnsScrollBars() )
       
  5228             {
       
  5229             iEdwinExtension->SetScrollBarSetter( CIdle::NewL(
       
  5230                     CTextView::EFBackgroundFormattingPriority - 1 ) );
       
  5231             }
       
  5232         if ( iEdwinExtension->ScrollBarSetter()
       
  5233                 && !iEdwinExtension->ScrollBarSetter()->IsActive() )
       
  5234             {
       
  5235             iEdwinExtension->ScrollBarSetter()->Start( TCallBack(
       
  5236                     CEikEdwin::IdleL, this ) );
       
  5237             }
       
  5238         }
       
  5239     else
       
  5240         {
       
  5241         SetScrollBarsL();
       
  5242         }
       
  5243     }
       
  5244 
       
  5245 void CEikEdwin::UpdateHorizScrollBarThumb()
       
  5246     {
       
  5247     __ASSERT_DEBUG(iTextView,Panic(EEikPanicEdwinNoView));
       
  5248     if (iSBFrame)
       
  5249         {
       
  5250         iSBFrame->MoveHorizThumbTo(iTextView->LeftTextMargin());
       
  5251         }
       
  5252     }   
       
  5253 
       
  5254 void CEikEdwin::UpdateVertScrollBarThumbL()
       
  5255     {
       
  5256     __ASSERT_DEBUG(iTextView,Panic(EEikPanicEdwinNoView));
       
  5257     __ASSERT_DEBUG(iText,Panic(EEikPanicEdwinNoLayout));
       
  5258     if (iSBFrame)
       
  5259         {
       
  5260         if ( KineticScrollingEnabled() )
       
  5261             {
       
  5262             if ( iEdwinExtension && iEdwinExtension->iScrolledByScrollBar )
       
  5263                 {
       
  5264                 CEikScrollBar* sb =
       
  5265                     iSBFrame-> CEikScrollBarFrame::VerticalScrollBar();
       
  5266                 iEdwinExtension->iScrollbarPosition = sb->ThumbPosition();
       
  5267                 return;
       
  5268                 }
       
  5269             }
       
  5270         
       
  5271         CEikScrollBar* sb = iSBFrame-> CEikScrollBarFrame::VerticalScrollBar();
       
  5272         TInt prevSBPos = sb->ThumbPosition();
       
  5273 
       
  5274         TEikScrollBarModel vertModel;
       
  5275         SetVertScrollBarModelByCharactersL(vertModel);
       
  5276         if ( iSBFrame->TypeOfVScrollBar() == CEikScrollBarFrame::EDoubleSpan )
       
  5277             {
       
  5278             TAknDoubleSpanScrollBarModel doubleModel( vertModel );
       
  5279             sb->SetModel( &doubleModel );
       
  5280             }
       
  5281         else
       
  5282             {
       
  5283             sb->SetModel( &vertModel );
       
  5284             }            
       
  5285 
       
  5286         TInt newSBPos = sb->ThumbPosition();
       
  5287         TBool paintingEnabled = !(iEdwinUserFlags&EDisplayOnly) 
       
  5288         && !(iEdwinUserFlags&EAvkonDisableCursor) 
       
  5289         && iTextView->SelectionVisible();
       
  5290         if (iEdwinFepSupport->iFeedback 
       
  5291             && iEdwinFepSupport->iMoveThumbFeedbackNeeded 
       
  5292             && (prevSBPos != newSBPos)
       
  5293             && !paintingEnabled)
       
  5294             {
       
  5295             iEdwinFepSupport->iFeedback->InstantFeedback( this, ETouchFeedbackSensitive );
       
  5296             }
       
  5297         }        
       
  5298     }
       
  5299 
       
  5300 EXPORT_C CEikScrollBarFrame* CEikEdwin::CreateScrollBarFrameL()
       
  5301     {
       
  5302     return CreateScrollBarFrameL(EFalse);
       
  5303     }
       
  5304 
       
  5305 EXPORT_C CEikScrollBarFrame* CEikEdwin::CreateScrollBarFrameL(TBool aPreAlloc)
       
  5306     {
       
  5307     if(!iSBFrame)
       
  5308         {
       
  5309         iSBFrame=new(ELeave) CEikScrollBarFrame(this, this, aPreAlloc, ETrue);
       
  5310 
       
  5311         // Check which type of scrollbar is to be shown
       
  5312 
       
  5313         if (AknLayoutUtils::DefaultScrollBarType(iAvkonAppUi) == CEikScrollBarFrame::EDoubleSpan)
       
  5314             {
       
  5315             iSBFrame->CreateDoubleSpanScrollBarsL(ETrue, EFalse);
       
  5316             }
       
  5317         }
       
  5318     return iSBFrame;
       
  5319     }
       
  5320 void CEikEdwin::CreateScrollBarFrameLayout(TEikScrollBarFrameLayout& aLayout) const
       
  5321     {
       
  5322     aLayout.iInclusiveMargin=iBorder.Margins();
       
  5323     const TRect inner=iBorder.InnerRect(Rect());
       
  5324     const TRect& viewRect=iTextView->ViewRect();
       
  5325     aLayout.iClientMargin.iLeft=viewRect.iTl.iX-inner.iTl.iX;
       
  5326     aLayout.iClientMargin.iRight=inner.iBr.iX-viewRect.iBr.iX;
       
  5327     aLayout.iClientMargin.iTop=viewRect.iTl.iY-inner.iTl.iY;
       
  5328     aLayout.iClientMargin.iBottom=inner.iBr.iY-viewRect.iBr.iY;
       
  5329     aLayout.iTilingMode=TEikScrollBarFrameLayout::EInclusiveRectConstant;
       
  5330     }
       
  5331 
       
  5332 EXPORT_C TInt CEikEdwin::IdleL(TAny *anObj)
       
  5333     {
       
  5334     CEikEdwin* edwin = static_cast<CEikEdwin*>( anObj );
       
  5335     if ( edwin && !edwin->KineticScrollingEnabled() )
       
  5336         {
       
  5337         edwin->SetScrollBarsL();
       
  5338         }
       
  5339     return EFalse;
       
  5340     }
       
  5341 
       
  5342 void CEikEdwin::SetScrollBarsL()
       
  5343     {
       
  5344     __ASSERT_DEBUG(iText,Panic(EEikPanicEdwinNoText));
       
  5345     if (!iSBFrame)
       
  5346         return;
       
  5347     CheckEdwinExtensionL(); // checks if iEdwinExtension is non-NULL
       
  5348     
       
  5349     if ( KineticScrollingEnabled() )
       
  5350         {
       
  5351         SetKineticScrollingScrollBarsL();
       
  5352         return;
       
  5353         }
       
  5354     
       
  5355     if (iEdwinExtension->ScrollBarSetter() && iEdwinExtension->ScrollBarSetter()->IsActive())
       
  5356         iEdwinExtension->ScrollBarSetter()->Cancel();
       
  5357     TEikScrollBarModel hSbarModel(0,0,0);
       
  5358     TEikScrollBarModel vSbarModel(0,0,0);
       
  5359     TRect rect = AdjustedViewRect();
       
  5360 
       
  5361     rect=iMargins.OuterRect(rect);
       
  5362     // Ignore scrollbars presence to set the model, Scrollbar Frame will change it as required
       
  5363     if (iSBFrame->VScrollBarVisibility()!=CEikScrollBarFrame::EOff)
       
  5364         {
       
  5365         SetVertScrollBarModelByCharactersL(vSbarModel);
       
  5366         // Examine the model to see how the "under one screen" flag is to be set:
       
  5367         if ( vSbarModel.iThumbSpan >= vSbarModel.iScrollSpan )
       
  5368             {
       
  5369             iEdwinInternalFlags|=EUnderOneScreenFormattedText;
       
  5370             }
       
  5371         else
       
  5372             {
       
  5373             iEdwinInternalFlags&=~EUnderOneScreenFormattedText;
       
  5374             }
       
  5375         }
       
  5376     if (iSBFrame->ScrollBarVisibility(CEikScrollBar::EHorizontal)!=CEikScrollBarFrame::EOff)
       
  5377         {
       
  5378         if (iEdwinInternalFlags&EWysiwygOn)
       
  5379             {
       
  5380             hSbarModel.iScrollSpan=iZoomFactor->HorizontalTwipsToPixels(LayoutWidth());
       
  5381             TInt labels=0, cursor=0;
       
  5382             iTextView->MarginWidths(labels,cursor);
       
  5383             hSbarModel.iScrollSpan+=labels+cursor+LineCursorWidth();
       
  5384             }
       
  5385         else
       
  5386             hSbarModel.iScrollSpan=LayoutWidth();   
       
  5387         hSbarModel.iThumbSpan=rect.Width();
       
  5388         hSbarModel.iThumbPosition=iTextView->LeftTextMargin();
       
  5389         }
       
  5390     TRect inclusiveRect=Rect();
       
  5391     TRect clientRect=rect; // claim client is as large as possible
       
  5392     TEikScrollBarFrameLayout layout;
       
  5393     CreateScrollBarFrameLayout(layout);
       
  5394     if (vSbarModel.iThumbSpan)
       
  5395         {
       
  5396         const TInt granularityHeight = AdjustedViewRect().Height()/vSbarModel.iThumbSpan;
       
  5397         if (granularityHeight)
       
  5398             layout.iClientAreaGranularity.iHeight=granularityHeight;
       
  5399         }
       
  5400 
       
  5401     TBool sizeChanged = EFalse;
       
  5402     if (iSBFrame && iSBFrame->TypeOfVScrollBar() == CEikScrollBarFrame::EDoubleSpan)
       
  5403         {
       
  5404         // For EDoubleSpan type scrollbar
       
  5405         TAknDoubleSpanScrollBarModel hDsSbarModel(hSbarModel);
       
  5406         TAknDoubleSpanScrollBarModel vDsSbarModel(vSbarModel);
       
  5407         
       
  5408         TRect inclusiveRectForDoubleSpan = Rect();
       
  5409         TRect clientRectForDoubleSpan = Rect(); 
       
  5410         TEikScrollBarFrameLayout layout;
       
  5411         layout.iTilingMode = TEikScrollBarFrameLayout::EClientRectConstant;
       
  5412         TInt focusPostion = 0;
       
  5413         if (!(iLayout->IsFormattingBand()))
       
  5414         {
       
  5415         TInt numLines = iLayout->NumFormattedLines();
       
  5416         if (numLines > 1)
       
  5417             numLines--;
       
  5418         else 
       
  5419             numLines = 1;
       
  5420             
       
  5421         TInt height = iLayout->FormattedHeightInPixels();
       
  5422         TInt lineNo = 0;
       
  5423         lineNo = iLayout->FirstLineInBand();
       
  5424         focusPostion = (height*lineNo)/numLines;
       
  5425         }
       
  5426         else
       
  5427         {
       
  5428         TEikScrollBarModel vertModel;
       
  5429         SetVertScrollBarModelByCharactersL(vertModel);
       
  5430             
       
  5431         focusPostion = vertModel.iThumbPosition;
       
  5432         }
       
  5433         
       
  5434         vDsSbarModel.SetFocusPosition(focusPostion);
       
  5435         iSBFrame->TileL(&hDsSbarModel, &vDsSbarModel, clientRectForDoubleSpan, inclusiveRectForDoubleSpan, layout);
       
  5436         }
       
  5437     else
       
  5438         {
       
  5439         // For EArrowHead type scrollbar
       
  5440         sizeChanged=iSBFrame->TileL(&hSbarModel, &vSbarModel, clientRect, inclusiveRect, layout);
       
  5441         }
       
  5442     
       
  5443     if (!OwnsScrollBars())
       
  5444         {
       
  5445         delete iSBFrame;
       
  5446         iSBFrame=NULL;
       
  5447         }
       
  5448     UpdateVertScrollBarThumbL();
       
  5449     if (!sizeChanged)
       
  5450         return;
       
  5451     // else size of client/inclusive rect has changed
       
  5452     if (layout.iTilingMode==TEikScrollBarFrameLayout::EClientRectConstant)
       
  5453         {
       
  5454         iSize=inclusiveRect.Size();
       
  5455         DrawNow();
       
  5456         }
       
  5457     else
       
  5458         {
       
  5459         clientRect=iMargins.InnerRect(clientRect);
       
  5460         iTextView->SetViewRect(clientRect);
       
  5461         if (!(iEdwinUserFlags&ENoWrap))
       
  5462             iLayout->SetWrapWidth(LayoutWidth());
       
  5463         TViewYPosQualifier yPosQualifier;
       
  5464         yPosQualifier.SetMakeLineFullyVisible();
       
  5465         iTextView->HandleGlobalChangeNoRedrawL(yPosQualifier);
       
  5466         CWindowGc& gc=SystemGc();
       
  5467         ActivateGc();
       
  5468         gc.SetBrushColor(iEikonEnv->ControlColor(EColorControlBackground,*this));
       
  5469         DrawUtils::ClearBetweenRects(gc,iBorder.InnerRect(Rect()),clientRect);
       
  5470         DeactivateGc();
       
  5471         if (iEdwinInternalFlags&ELockScrollBarState)
       
  5472             {
       
  5473             iTextView->HandleGlobalChangeNoRedrawL(yPosQualifier);
       
  5474             CEikScrollBarFrame::TScrollBarVisibility vis=iSBFrame->VScrollBarVisibility();
       
  5475             CEikScrollBarFrame::TScrollBarVisibility vVis=(vis==CEikScrollBarFrame::EAuto? CEikScrollBarFrame::EOn : vis);
       
  5476             vis=iSBFrame->ScrollBarVisibility(CEikScrollBar::EHorizontal);
       
  5477             CEikScrollBarFrame::TScrollBarVisibility hVis=(vis==CEikScrollBarFrame::EAuto? CEikScrollBarFrame::EOn : vis);
       
  5478             iSBFrame->SetScrollBarVisibilityL(hVis,vVis);
       
  5479             }
       
  5480         else
       
  5481             iEdwinInternalFlags|=ELockScrollBarState;
       
  5482         SetAmountToFormatL(); // will call SetScrollBarsL() again if need be
       
  5483         if (!iLayout->IsFormattingBand())
       
  5484             SetScrollBarsL();
       
  5485         iEdwinInternalFlags&=~ELockScrollBarState;
       
  5486         if (iEdwinInternalFlags&EWysiwygOn && iSBFrame->ScrollBarVisibility(CEikScrollBar::EHorizontal)==CEikScrollBarFrame::EAuto)
       
  5487             {
       
  5488             CEikScrollBar* hSBar=iSBFrame->GetScrollBarHandle(CEikScrollBar::EHorizontal);
       
  5489             if (!hSBar || !hSBar->IsVisible())
       
  5490                 iTextView->SetLeftTextMargin(0);
       
  5491             }
       
  5492         iTextView->DrawL(clientRect);
       
  5493         }
       
  5494     }
       
  5495 
       
  5496 void CEikEdwin::SetKineticScrollingScrollBarsL()
       
  5497     {
       
  5498     TEikScrollBarModel hSbarModel( 0, 0, 0 );
       
  5499     TEikScrollBarModel vSbarModel( 0, 0, 0 );
       
  5500     TRect rect( AdjustedViewRect() );
       
  5501 
       
  5502     rect = iMargins.OuterRect( rect );
       
  5503     // Ignore scrollbars presence to set the model,
       
  5504     // Scrollbar Frame will change it as required
       
  5505     if ( iSBFrame->VScrollBarVisibility() != CEikScrollBarFrame::EOff )
       
  5506         {
       
  5507         if ( iLayout->IsFormattingBand() )
       
  5508             {
       
  5509             SetVertScrollBarModelByCharactersL( vSbarModel );
       
  5510             // Examine the model to see how the "under one screen"
       
  5511             // flag is to be set:
       
  5512             if ( vSbarModel.iThumbSpan >= vSbarModel.iScrollSpan )
       
  5513                 {
       
  5514                 iEdwinInternalFlags |= EUnderOneScreenFormattedText;
       
  5515                 }
       
  5516             else
       
  5517                 {
       
  5518                 iEdwinInternalFlags &= ~EUnderOneScreenFormattedText;
       
  5519                 }
       
  5520             }
       
  5521         else
       
  5522             {
       
  5523             vSbarModel.iScrollSpan = iLayout->FormattedHeightInPixels();
       
  5524             vSbarModel.iThumbSpan = AdjustedViewRect().Height();
       
  5525             if ( vSbarModel.iScrollSpan < vSbarModel.iThumbSpan
       
  5526                 && vSbarModel.iThumbPosition )
       
  5527                 {
       
  5528                 vSbarModel.iScrollSpan = vSbarModel.iThumbSpan
       
  5529                         + vSbarModel.iThumbPosition;
       
  5530                 iEdwinInternalFlags |= EUnderOneScreenFormattedText;
       
  5531                 }
       
  5532             else
       
  5533                 {
       
  5534                 iEdwinInternalFlags &= ~EUnderOneScreenFormattedText;
       
  5535                 }
       
  5536             }
       
  5537         }
       
  5538     
       
  5539     if ( iSBFrame->ScrollBarVisibility( CEikScrollBar::EHorizontal )
       
  5540             != CEikScrollBarFrame::EOff )
       
  5541         {
       
  5542         if ( iEdwinInternalFlags & EWysiwygOn )
       
  5543             {
       
  5544             hSbarModel.iScrollSpan = iZoomFactor->HorizontalTwipsToPixels(
       
  5545                     LayoutWidth() );
       
  5546             TInt labels = 0, cursor = 0;
       
  5547             iTextView->MarginWidths( labels, cursor );
       
  5548             hSbarModel.iScrollSpan += labels + cursor + LineCursorWidth();
       
  5549             }
       
  5550         else
       
  5551             {
       
  5552             hSbarModel.iScrollSpan = LayoutWidth();
       
  5553             }
       
  5554         hSbarModel.iThumbSpan = rect.Width();
       
  5555         hSbarModel.iThumbPosition = iTextView->LeftTextMargin();
       
  5556         }
       
  5557     
       
  5558     TRect inclusiveRect( Rect() );
       
  5559     TEikScrollBarFrameLayout layout;
       
  5560     CreateScrollBarFrameLayout( layout );
       
  5561     
       
  5562     if ( vSbarModel.iThumbSpan )
       
  5563         {
       
  5564         TInt granularityHeight = AdjustedViewRect().Height()
       
  5565             / vSbarModel.iThumbSpan;
       
  5566         if ( granularityHeight )
       
  5567             layout.iClientAreaGranularity.iHeight = granularityHeight;
       
  5568         }
       
  5569 
       
  5570     // For EDoubleSpan type scrollbar
       
  5571     TAknDoubleSpanScrollBarModel hDsSbarModel( hSbarModel );
       
  5572     TAknDoubleSpanScrollBarModel vDsSbarModel( vSbarModel );
       
  5573 
       
  5574     TRect inclusiveRectForDoubleSpan( Rect() );
       
  5575     TRect clientRectForDoubleSpan ( Rect() );
       
  5576 
       
  5577     TEikScrollBarFrameLayout layout2;
       
  5578     layout2.iTilingMode = TEikScrollBarFrameLayout::EClientRectConstant;
       
  5579         
       
  5580     TInt focusPosition = 0;
       
  5581     if ( !( iLayout->IsFormattingBand() ) )
       
  5582         {
       
  5583         TInt numLines = iLayout->NumFormattedLines();
       
  5584         if ( numLines > 1 )
       
  5585             {
       
  5586             numLines--;
       
  5587             }
       
  5588         else
       
  5589             {
       
  5590             numLines = 1;
       
  5591             }
       
  5592 
       
  5593         TInt height = iLayout->FormattedHeightInPixels();
       
  5594         TInt lineNo = 0;
       
  5595         lineNo = iLayout->FirstLineInBand();
       
  5596         focusPosition = ( height * lineNo ) / numLines;
       
  5597         }
       
  5598     else
       
  5599         {
       
  5600         TEikScrollBarModel vertModel;
       
  5601         SetVertScrollBarModelByCharactersL( vertModel );
       
  5602 
       
  5603         focusPosition = vertModel.iThumbPosition;
       
  5604         }
       
  5605 
       
  5606     vDsSbarModel.SetFocusPosition( focusPosition );
       
  5607     iSBFrame->TileL( &hDsSbarModel, &vDsSbarModel, clientRectForDoubleSpan,
       
  5608             inclusiveRectForDoubleSpan, layout2 );
       
  5609 
       
  5610     if ( !OwnsScrollBars() )
       
  5611         {
       
  5612         delete iSBFrame;
       
  5613         iSBFrame = NULL;
       
  5614         }
       
  5615     UpdateVertScrollBarThumbL();     
       
  5616     }
       
  5617 
       
  5618 void CEikEdwin::SetVertScrollBarModelByCharactersL(TEikScrollBarModel& aVertModel) const
       
  5619     {
       
  5620     __ASSERT_DEBUG(iText,Panic(EEikPanicEdwinNoText));
       
  5621     __ASSERT_DEBUG(iLayout,Panic(EEikPanicEdwinNoLayout));
       
  5622 
       
  5623     if ( KineticScrollingEnabled() )
       
  5624         {
       
  5625         SetKineticScrollingScrollBarModel( aVertModel );
       
  5626         return;
       
  5627         }
       
  5628     
       
  5629     TRect viewRect( AdjustedViewRect() );
       
  5630     const TInt formattedLines = Max(1, iLayout->NumFormattedLines());
       
  5631     const TInt formattedHeight = iLayout->FormattedHeightInPixels();    
       
  5632     const TInt viewRectHeight = viewRect.Height();
       
  5633     const TInt totalChars = iText->DocumentLength();    
       
  5634     const TInt formattedLength = Min( totalChars, iLayout->FormattedLength() );
       
  5635     const TInt topLeftDocPos=iLayout->FirstDocPosFullyInBand();
       
  5636     const TInt avgCharsPerLine = iAvgCharsPerLine ? iAvgCharsPerLine : 
       
  5637         Max( 1, formattedLength / formattedLines );    
       
  5638     const TInt avgLineHeight = formattedHeight/formattedLines;
       
  5639     TInt posRange( 0 );
       
  5640     TInt topPos( iTextView->XyPosToDocPosL( viewRect.iTl ) );
       
  5641     TInt bottomPos( iTextView->XyPosToDocPosL( viewRect.iBr ) );    
       
  5642     if( AknLayoutUtils::PenEnabled() )
       
  5643         {
       
  5644         if ( !iLayout->IsFormattingBand() )
       
  5645             {                        
       
  5646             aVertModel.iThumbSpan = viewRectHeight;
       
  5647             aVertModel.iScrollSpan = formattedHeight;            
       
  5648             aVertModel.iThumbPosition = iEdwinExtension->iThumbPos;   
       
  5649             if ( aVertModel.iThumbPosition == KErrNotFound )
       
  5650                 {
       
  5651                 if ( bottomPos == totalChars )
       
  5652                     {
       
  5653                     aVertModel.iThumbPosition = aVertModel.iScrollSpan - 
       
  5654                         aVertModel.iThumbSpan;
       
  5655                     TPoint bottomPoint(0,0);
       
  5656                     iTextView->DocPosToXyPosL(bottomPos,bottomPoint);
       
  5657                     if ( topPos == 0 && bottomPoint.iY == viewRect.iBr.iY )
       
  5658                         {
       
  5659                         aVertModel.iThumbPosition = 0;
       
  5660                         TInt gapFhAndVh = formattedHeight-viewRectHeight;
       
  5661                         if (gapFhAndVh < avgLineHeight/2)
       
  5662                             {      
       
  5663                             aVertModel.iThumbSpan = viewRectHeight;
       
  5664                             aVertModel.iScrollSpan = viewRectHeight;
       
  5665                             }
       
  5666                         }
       
  5667                     }
       
  5668                 else
       
  5669                     {
       
  5670                     TInt topLine( iLayout->GetLineNumber( topPos ) );
       
  5671                     aVertModel.iThumbPosition = topLine * formattedHeight / 
       
  5672                         formattedLines;
       
  5673                     }                
       
  5674                 }
       
  5675             }
       
  5676         else
       
  5677             {
       
  5678             aVertModel.iThumbSpan = bottomPos - topPos;
       
  5679             aVertModel.iScrollSpan = totalChars;        
       
  5680             aVertModel.iThumbPosition = topPos;
       
  5681             }
       
  5682         return;
       
  5683         }
       
  5684     else
       
  5685         {
       
  5686         // - units for all elements of the model are numbers of characters, not pixels.
       
  5687         // - character positions refer to the VISIBLE band (not the total formatted text),
       
  5688         // - scrollspan is the total no. of characters, not pixels, to avoid "bounce" on the 
       
  5689         //   fractional position (this is because thumb info is sent separately from the whole model at times)
       
  5690         // - take advantage of form APIs as well as we can 
       
  5691         aVertModel.iScrollSpan = Max(1,totalChars);
       
  5692         TInt docPos;
       
  5693         posRange = iLayout->PosRangeInBand( docPos ); // gives number of characters in visible range 
       
  5694         }
       
  5695     
       
  5696     if (iSBFrame && iSBFrame->TypeOfVScrollBar() == CEikScrollBarFrame::EDoubleSpan)
       
  5697         {
       
  5698         // For EDoubleSpan type scrollbar
       
  5699         // Normally, the thumbspan is just the size of the range of visible characters, and the top of the thumb is
       
  5700         // index of first character in the view.
       
  5701         aVertModel.iThumbSpan = Max(1,posRange);
       
  5702         aVertModel.iThumbPosition = topLeftDocPos; // Simply the top left character   
       
  5703 
       
  5704         // A situation can arise when cursor is near the end of text, and the user is deleting.  This can leave empty lines.
       
  5705         // Thumbspan must try to measure the whole view - even if there are no characters in some of it.
       
  5706         // (Note that this problem does not arise when there is very little text in the document and the screen is only half
       
  5707         // full. In that case thumb and scroll span are equal.)
       
  5708         // The approach is to invent ficticious characters. Estimate how many characters there would be if the text were as dense
       
  5709         // as the average formatted line.
       
  5710         // It is biased against by a factor, so that it does not trigger unless we are in the above situation.
       
  5711 #define KSparseCharactersNumerator 8
       
  5712 #define KSparseCharactersDenominator 10
       
  5713         // Note deliberate ordering of multiplies and divides to avoid chance of overflow
       
  5714         TInt estimatedCharsToFillVisibleArea = 
       
  5715         ( KSparseCharactersNumerator * viewRectHeight / KSparseCharactersDenominator * formattedLength ) 
       
  5716         / Max(1,formattedHeight);
       
  5717         TInt excessChars = estimatedCharsToFillVisibleArea - posRange;
       
  5718         if ( excessChars > 0 && (posRange < totalChars/2 ) ) // Additional cond. that most of text is not showing
       
  5719             {
       
  5720             aVertModel.iThumbSpan += excessChars;
       
  5721             // Also have to increase the span, as these ficticious characters are (sort of) included in the whole document.
       
  5722             aVertModel.iScrollSpan += excessChars;           
       
  5723             }            
       
  5724         }
       
  5725     else
       
  5726         {        
       
  5727         // For scroll-indicator functionality (EArrowHead)
       
  5728         // - quantize thumb position according to a "line model" to avoid changing values each time the cursor 
       
  5729         // moves 1 character.         
       
  5730         // Divide the visible band into a number of lines to get a "line" quantized value.  
       
  5731         // (This leads to less drawing of the arrowheads, or at least stops that notification earlier)
       
  5732         // Number of lines is calculated with approximation that the last line is half filled.
       
  5733         // This is chosen because the correct behaviour is most important when at the (top line is usually filled) 
       
  5734         // and at the bottom (Sometimes full, sometimes just one character).
       
  5735         const TInt nLines = ( posRange - avgCharsPerLine/2 ) / avgCharsPerLine + 1;        
       
  5736         const TInt currentPos = CursorPos();
       
  5737         const TInt line = Max(0,currentPos - topLeftDocPos) / avgCharsPerLine; // zero-based line number; bigger because of rounding down above. 
       
  5738         if ( line >= (nLines - 1) ) // last line or too high because of rounding?
       
  5739             {
       
  5740             aVertModel.iThumbPosition = topLeftDocPos + posRange - 1; //Clamp to max value
       
  5741             }
       
  5742         else
       
  5743             {
       
  5744             aVertModel.iThumbPosition = topLeftDocPos + line * avgCharsPerLine;
       
  5745             }    
       
  5746         // Although arrowhead implementations probably ignore the thumb span, just ensure its bottom end does not go below
       
  5747         // the scrollspan.    
       
  5748         aVertModel.iThumbSpan = Min( aVertModel.iThumbSpan, aVertModel.iScrollSpan - aVertModel.iThumbPosition );
       
  5749         }
       
  5750     }
       
  5751 
       
  5752 void CEikEdwin::SetKineticScrollingScrollBarModel(
       
  5753     TEikScrollBarModel& aVertModel ) const
       
  5754     {
       
  5755     // This function is related to Rate scrolling implementation.
       
  5756     //
       
  5757     // When kinetic scrolling is not enabled, original way
       
  5758     // (named here as Position Scrolling) is used. When kinetic
       
  5759     // scrolling is enabled, new way (named here as Rate Scrolling) is used.
       
  5760     //
       
  5761     // In Position Scrolling there is always a one-to-one mapping relationship
       
  5762     // of position between text view and scrollbar. When you scroll one of
       
  5763     // them, the other one will always be moved to follow the new position of
       
  5764     // its friend.
       
  5765     //
       
  5766     // But there is one issue, the height of the whole document is not accurate
       
  5767     // but a approximate value according to current band
       
  5768     // (Band: current formatted text area, including current shown view and
       
  5769     // some text leading and following it). So the mapping is somehow
       
  5770     // irregular, that when you scroll the view regularly, the scrollbar will
       
  5771     // change its position not regularly.
       
  5772     //
       
  5773     // When you move text view from Pos1 to Pos2, the scrollbar will be moved
       
  5774     // from Pos3 to Pos4, and here the Pos4 is only related to Pos2.
       
  5775     //
       
  5776     // 
       
  5777     // Rate Scrolling is designed to make regular scrolling for both text view
       
  5778     // and scrollbar. The “regular?here is not absolutely regular but more
       
  5779     // regular than before, or regular to end users. It is also impacted by
       
  5780     // the Band area changing, but the impact is much smaller than before.
       
  5781     //
       
  5782     // When you move text view from Pos1 to Pos2, the scrollbar will be moved
       
  5783     // from Pos3 to Pos4. Here the Pos4 is related to all Pos1, Pos2 and Pos3.
       
  5784     // The relationship between them is the Rate.
       
  5785     //
       
  5786     // The Rate means how many percentage it has moved to the end boundary. 
       
  5787     // If you move downwards, expected whole text view height is H, remaining
       
  5788     // way to the end boundary is (H - Pos1), the Percentage you have moved is
       
  5789     // offset/(H - Pos1) = (Pos2 - Pos1)/(H - Pos1)
       
  5790     //
       
  5791     // So the scrollbar should also move for the same percentage of the
       
  5792     // remaining way. 
       
  5793     //
       
  5794     // This moving behavior is more regular than before, and the visible result
       
  5795     // proves it.
       
  5796     //
       
  5797     // With this way, It can be proved that when text view is scrolled to the
       
  5798     // end, the scrollbar will also be in the end, and vice versa. 
       
  5799     //
       
  5800     // In Rate scrolling way, scrollbar will have different position values
       
  5801     // if you scroll text view same to X but from different starting position.
       
  5802     
       
  5803     TInt formattedLines = Max( 1, iLayout->NumFormattedLines() );
       
  5804     TInt formattedHeight = iLayout->FormattedHeightInPixels();
       
  5805     TInt viewRectHeight = AdjustedViewRect().Height();
       
  5806     TInt totalChars = iText->DocumentLength();
       
  5807     TInt formattedLength = iLayout->FormattedLength();
       
  5808     TInt topLeftDocPos = iLayout->FirstDocPosFullyInBand();
       
  5809     TInt avgCharsPerLine = Max( 1, formattedLength / formattedLines );
       
  5810 
       
  5811     TInt formattedHeightAboveView = iLayout->PixelsAboveBand();
       
  5812     TInt formattedHeightBelowView = formattedHeight - viewRectHeight
       
  5813         - formattedHeightAboveView;
       
  5814 
       
  5815     TInt anchorThumbPos = 0;
       
  5816     TInt avgLineHeight = 0;
       
  5817 
       
  5818     // Approximate top visible line from bottom if we are over half of text,
       
  5819     // otherwise from top of text. 
       
  5820     TInt approxTopVisibleLine = 0;
       
  5821 
       
  5822     // Variables only used in this block
       
  5823     TInt firstFormattedPos = iLayout->FirstFormattedPos();
       
  5824     TInt lastFormattedPos = firstFormattedPos + formattedLength;
       
  5825         
       
  5826     avgLineHeight = formattedHeight / formattedLines;
       
  5827         
       
  5828     TInt lineNo = iLayout->GetLineNumber( CursorPos() );
       
  5829     TInt heightBeforeFormat = ( avgLineHeight * firstFormattedPos )
       
  5830         / avgCharsPerLine;
       
  5831     TInt heightAfterFormat = ( avgLineHeight * ( totalChars
       
  5832         - lastFormattedPos ) ) / avgCharsPerLine;
       
  5833 
       
  5834     const TAknDoubleSpanScrollBarModel* doubleModel =
       
  5835         static_cast< const TAknDoubleSpanScrollBarModel* >
       
  5836             ( iSBFrame->CEikScrollBarFrame::VerticalScrollBar()->Model() );
       
  5837 
       
  5838     if ( !iEdwinExtension->iUseRateScroll )
       
  5839         {
       
  5840         aVertModel.iScrollSpan = heightBeforeFormat + formattedHeight
       
  5841             + heightAfterFormat;
       
  5842         aVertModel.iThumbSpan = viewRectHeight;
       
  5843         }
       
  5844 
       
  5845     // Rate scrolling
       
  5846 
       
  5847     if ( iEdwinExtension->iUseRateScroll )
       
  5848         {
       
  5849         TInt heightAboveView = formattedHeightAboveView + heightBeforeFormat;
       
  5850         TInt heightBelowView = formattedHeightBelowView + heightAfterFormat;
       
  5851 
       
  5852         TInt curScrollSpan = aVertModel.iScrollSpan
       
  5853             = doubleModel->ScrollSpan();
       
  5854         TInt curThumbSpan = aVertModel.iThumbSpan
       
  5855             = doubleModel->WindowSize();
       
  5856             
       
  5857         TInt thumbSpaceAbove = aVertModel.iThumbPosition
       
  5858             = iSBFrame-> CEikScrollBarFrame::VerticalScrollBar()->ThumbPosition();
       
  5859                 
       
  5860         TInt thumbSpaceBelow = curScrollSpan - curThumbSpan - thumbSpaceAbove;
       
  5861             
       
  5862         // We have moved above
       
  5863         if ( iEdwinExtension->iScrolledDelta > 0 )//Move above
       
  5864             {
       
  5865             TInt prePosition = heightAboveView + iEdwinExtension->iScrolledDelta;
       
  5866             if ( prePosition == 0 )
       
  5867                 {
       
  5868                 return;
       
  5869                 }
       
  5870             anchorThumbPos = thumbSpaceAbove
       
  5871                 - iEdwinExtension->iScrolledDelta * thumbSpaceAbove
       
  5872                 / prePosition;
       
  5873             }
       
  5874         // We have moved below
       
  5875         else if ( iEdwinExtension->iScrolledDelta < 0 )//Move below
       
  5876             {
       
  5877             TInt postPosition = heightBelowView - iEdwinExtension->iScrolledDelta;
       
  5878             if ( postPosition == 0 )
       
  5879                 {
       
  5880                 return;
       
  5881                 }
       
  5882             anchorThumbPos = thumbSpaceAbove
       
  5883                 - iEdwinExtension->iScrolledDelta * thumbSpaceBelow
       
  5884                 / postPosition;
       
  5885             }
       
  5886         else
       
  5887             {
       
  5888             return;
       
  5889             }
       
  5890         } 
       
  5891     else // Original way, no rate scrolling
       
  5892         {
       
  5893          approxTopVisibleLine = topLeftDocPos / avgCharsPerLine;
       
  5894         if ( approxTopVisibleLine == 0 && topLeftDocPos > 0 )
       
  5895             {
       
  5896             approxTopVisibleLine = 1;
       
  5897             }
       
  5898         }
       
  5899     
       
  5900     if ( iEdwinExtension->iUseRateScroll )
       
  5901         {
       
  5902         aVertModel.iThumbPosition = anchorThumbPos;
       
  5903         }
       
  5904     else
       
  5905         {
       
  5906         aVertModel.iThumbPosition = approxTopVisibleLine * avgLineHeight;
       
  5907         }
       
  5908     iEdwinExtension->iScrollbarPosition = aVertModel.iThumbPosition; 
       
  5909     }
       
  5910 
       
  5911 // ---------------------------------------------------------------------------
       
  5912 // CEikEdwin::HandleScrollEventWithPhysicsL
       
  5913 // ---------------------------------------------------------------------------
       
  5914 // 
       
  5915 void CEikEdwin::HandleScrollEventWithPhysics( CEikScrollBar* aScrollBar )
       
  5916     {
       
  5917     // Scroll view based on scrollbar thumb position  
       
  5918     
       
  5919     const TAknDoubleSpanScrollBarModel * doubleModel =
       
  5920         static_cast< const TAknDoubleSpanScrollBarModel* >
       
  5921             ( aScrollBar->Model() );
       
  5922 
       
  5923     TInt curScrollSpan = doubleModel->ScrollSpan();
       
  5924     TInt curThumbSpan = doubleModel->WindowSize();
       
  5925     TInt thumbSpaceAbove = aScrollBar->ThumbPosition();
       
  5926     TInt thumbSpaceBelow = curScrollSpan - curThumbSpan - thumbSpaceAbove;
       
  5927 
       
  5928     TInt moveOffset = thumbSpaceAbove - iEdwinExtension->iScrollbarPosition;
       
  5929 
       
  5930     const TInt formattedLines = Max( 1, iLayout->NumFormattedLines() );
       
  5931     const TInt formattedHeight = iLayout->FormattedHeightInPixels();
       
  5932     const TInt viewRectHeight = AdjustedViewRect().Height();
       
  5933     const TInt totalChars = iText->DocumentLength();
       
  5934     const TInt formattedLength = iLayout->FormattedLength();
       
  5935     const TInt avgCharsPerLine = Max( 1, formattedLength / formattedLines );
       
  5936 
       
  5937     const TInt formattedHeightAboveView = iLayout->PixelsAboveBand();
       
  5938     const TInt formattedHeightBelowView = formattedHeight - viewRectHeight
       
  5939             - formattedHeightAboveView;
       
  5940 
       
  5941     const TInt firstFormattedPos = iLayout->FirstFormattedPos();
       
  5942     const TInt lastFormattedPos = firstFormattedPos + formattedLength;
       
  5943     const TInt heightBeforeFormat = ( formattedHeight * firstFormattedPos )
       
  5944             / avgCharsPerLine / formattedLines;
       
  5945     const TInt heightAfterFormat = ( formattedHeight * ( totalChars
       
  5946             - lastFormattedPos ) ) / avgCharsPerLine / formattedLines;
       
  5947 
       
  5948     const TInt heightAboveView = formattedHeightAboveView + heightBeforeFormat;
       
  5949     const TInt heightBelowView = formattedHeightBelowView + heightAfterFormat;
       
  5950 
       
  5951     TInt textMovePixels = 0;
       
  5952     if ( moveOffset > 0 )
       
  5953         {
       
  5954         textMovePixels = heightBelowView * moveOffset / ( 0 - thumbSpaceBelow
       
  5955                 - moveOffset );   
       
  5956         }
       
  5957     else if ( moveOffset < 0 )
       
  5958         {
       
  5959         textMovePixels = heightAboveView * moveOffset / ( moveOffset
       
  5960                 - thumbSpaceAbove );
       
  5961         }
       
  5962     else
       
  5963         {
       
  5964         return;
       
  5965         }
       
  5966     iEdwinExtension->iScrollbarPosition = thumbSpaceAbove;
       
  5967 
       
  5968     // If scrollbar thumb is moved to the beginning or end of scrollbar,
       
  5969     // ensure that also editor content is moved also exactly to the beginning
       
  5970     // or end. This is needed because otherwise in some situations editor
       
  5971     // content is not moved enough. We can't move too much because moving is
       
  5972     // limited to begin and end of actual editor content.
       
  5973     if ( thumbSpaceAbove <= 0 )
       
  5974         {
       
  5975         textMovePixels += KAdditionalPixels;
       
  5976         }
       
  5977     else if ( thumbSpaceAbove >= curScrollSpan - curThumbSpan )
       
  5978         {
       
  5979         textMovePixels -= KAdditionalPixels;
       
  5980         }
       
  5981     
       
  5982     iEdwinExtension->iScrolledByScrollBar = ETrue;
       
  5983     
       
  5984     // Actual scrolling is done by calling MoveScrollIndex
       
  5985     iEdwinExtension->iPhysicsHandler->MoveScrollIndex( -textMovePixels );
       
  5986     
       
  5987     iEdwinExtension->iScrolledByScrollBar = EFalse;
       
  5988     }
       
  5989 
       
  5990 EXPORT_C void CEikEdwin::HandleScrollEventL(CEikScrollBar* aScrollBar,TEikScrollEvent aEventType)
       
  5991     {
       
  5992     __ASSERT_DEBUG(iText,Panic(EEikPanicEdwinNoText));
       
  5993     __ASSERT_DEBUG(iLayout,Panic(EEikPanicEdwinNoLayout));
       
  5994     
       
  5995     TInt thumbPosition=aScrollBar->ThumbPosition();
       
  5996     TInt thumbSpan = 0;
       
  5997     if ( aScrollBar->Model()->ScrollBarModelType() == 
       
  5998         TEikScrollBarModel::EAknDoubleSpanScrollBarModel)
       
  5999         {
       
  6000         const TAknDoubleSpanScrollBarModel* doubleModel = 
       
  6001             static_cast<const TAknDoubleSpanScrollBarModel*>( aScrollBar->Model() );
       
  6002         thumbSpan = doubleModel->ScrollSpan();
       
  6003         thumbSpan -= doubleModel->WindowSize();
       
  6004         }
       
  6005     else
       
  6006         {
       
  6007         thumbSpan = aScrollBar->Model()->MaxThumbPos();
       
  6008         }
       
  6009     switch (aEventType&KEikScrollEventBarMask)
       
  6010         { 
       
  6011     case KEikScrollEventFromHBar:
       
  6012         switch (aEventType)
       
  6013             {
       
  6014         case EEikScrollLeft:
       
  6015         case EEikScrollRight:
       
  6016             MoveDisplayL((aEventType==EEikScrollLeft)? TCursorPosition::EFLeft: TCursorPosition::EFRight);
       
  6017             break;
       
  6018         case EEikScrollPageLeft:
       
  6019         case EEikScrollPageRight:
       
  6020             {
       
  6021             TInt singleScrollJump=iTextView->HorizontalScrollJump();
       
  6022             if (aEventType==EEikScrollPageLeft)
       
  6023                 singleScrollJump=-singleScrollJump;
       
  6024             const TInt leftTextViewMargin=iTextView->LeftTextMargin();
       
  6025             const TInt layoutWidth = LayoutWidth();
       
  6026             const TInt textViewWidth = iTextView->ViewRect().Width();
       
  6027 
       
  6028             TInt leftMargin = (5*singleScrollJump) + leftTextViewMargin; // ?? scroll how far!!
       
  6029             if (leftMargin < 0)
       
  6030                 leftMargin=0;
       
  6031             else if (leftMargin>layoutWidth)
       
  6032                 leftMargin=leftTextViewMargin + layoutWidth - textViewWidth;
       
  6033             iTextView->SetLeftTextMargin(leftMargin); // !! this doesn't actually scroll anything so...
       
  6034             TRect rect=iBorder.InnerRect(Rect());
       
  6035             iMargins.InnerRect(rect);
       
  6036             iTextView->DrawL(rect);
       
  6037             UpdateScrollBarsL();
       
  6038             UpdateHorizScrollBarThumb();
       
  6039             }
       
  6040             break;
       
  6041         case EEikScrollThumbDragHoriz:
       
  6042 //      case EEikScrollThumbReleaseHoriz:
       
  6043             {
       
  6044             iTextView->SetLeftTextMargin(thumbPosition);
       
  6045             TRect rect=iBorder.InnerRect(Rect());
       
  6046             iMargins.InnerRect(rect);
       
  6047             iTextView->DrawL(rect);
       
  6048             }
       
  6049             break;
       
  6050         default:
       
  6051             break;
       
  6052             }
       
  6053         break;
       
  6054     case KEikScrollEventFromVBar:
       
  6055         switch (aEventType)
       
  6056             {
       
  6057         default:
       
  6058             break;
       
  6059         case EEikScrollTop:
       
  6060         case EEikScrollBottom:
       
  6061             {
       
  6062             TInt docPos=(aEventType==EEikScrollTop)? 0 : iText->DocumentLength();
       
  6063             TInt yPos=iPosition.iY+iBorder.Margins().iLeft;
       
  6064             TViewYPosQualifier yPosQ;
       
  6065             yPosQ.SetMakeLineFullyVisible();
       
  6066             yPosQ.SetFillScreen();
       
  6067             iTextView->SetViewL(docPos, yPos, yPosQ);
       
  6068             UpdateVertScrollBarThumbL();
       
  6069             UpdateHorizScrollBarThumb();// can also change horizontally
       
  6070             }
       
  6071             break;
       
  6072         case EEikScrollThumbReleaseVert:
       
  6073             {
       
  6074             if ( KineticScrollingEnabled() )
       
  6075                 {
       
  6076                 RestoreCursorState();
       
  6077                 }
       
  6078             }
       
  6079             break;
       
  6080         case EEikScrollUp:
       
  6081         case EEikScrollDown:            
       
  6082         case EEikScrollPageUp:
       
  6083         case EEikScrollPageDown:            
       
  6084         case EEikScrollThumbDragVert:
       
  6085             {
       
  6086             if ( KineticScrollingEnabled() )
       
  6087                 {
       
  6088                 StoreCursorState();
       
  6089                 HandleScrollEventWithPhysics( aScrollBar );
       
  6090                 break;
       
  6091                 }
       
  6092             
       
  6093             TRect viewRect( AdjustedViewRect() );            
       
  6094             TInt docPos( 0 );
       
  6095             TInt yPos = viewRect.iTl.iY;
       
  6096             TInt totalChars( iText->DocumentLength() );
       
  6097             if ( !iLayout->IsFormattingBand() )
       
  6098                 {                
       
  6099                 TInt topLine( thumbPosition * iLayout->NumFormattedLines() /
       
  6100                     iLayout->FormattedHeightInPixels() + 1 );                
       
  6101                 docPos = iLayout->FirstCharOnLine( topLine );                
       
  6102                 }
       
  6103             else
       
  6104                 {
       
  6105                 TInt topPos( iTextView->XyPosToDocPosL( viewRect.iTl ) );
       
  6106                 TInt bottomPos( iTextView->XyPosToDocPosL( viewRect.iBr ) );
       
  6107                 TInt visibleRange( bottomPos - topPos );
       
  6108                 
       
  6109                 if ( thumbPosition != thumbSpan )                
       
  6110                     {   
       
  6111                     TInt scrollRange( totalChars - visibleRange );
       
  6112                     docPos = ( TInt )( ( TInt64 )( thumbPosition ) * scrollRange
       
  6113                         / thumbSpan );
       
  6114                     if ( iEdwinExtension->iThumbPos > thumbPosition && 
       
  6115                         docPos >= topPos && topPos != 0)
       
  6116                         {
       
  6117                         docPos = (TInt)( topPos - ( TInt64 )( thumbPosition - 
       
  6118                             iEdwinExtension->iThumbPos ) * scrollRange / thumbSpan );
       
  6119                         docPos = docPos < 0 ? 0 : docPos;
       
  6120                         }
       
  6121                     else if ( iEdwinExtension->iThumbPos < thumbPosition &&
       
  6122                         docPos <= topPos && bottomPos != totalChars )
       
  6123                         {
       
  6124                         docPos = (TInt)( topPos + ( TInt64 )( thumbPosition - 
       
  6125                             iEdwinExtension->iThumbPos ) * scrollRange / thumbSpan );
       
  6126                         docPos = docPos > totalChars ? totalChars : docPos; 
       
  6127                         }
       
  6128                     }                
       
  6129                 }
       
  6130             if ( thumbPosition == thumbSpan )
       
  6131                 {
       
  6132                 docPos = totalChars;
       
  6133                 yPos = viewRect.iBr.iY;
       
  6134                 }
       
  6135             iEdwinExtension->iThumbPos = thumbPosition;
       
  6136             TViewYPosQualifier yPosQ;
       
  6137             yPosQ.SetMakeLineFullyVisible();            
       
  6138             iTextView->SetViewL( docPos, yPos, yPosQ,
       
  6139                 CTextView::EFViewDontDiscardFormat,
       
  6140                 CTextView::EFNoHorizontalScroll);
       
  6141             UpdateVertScrollBarThumbL();
       
  6142             }
       
  6143             break;        
       
  6144             }
       
  6145         if (aEventType!=EEikScrollThumbDragVert && iEdwinInternalFlags&EUnderOneScreenFormattedText)
       
  6146             UpdateScrollBarsL();
       
  6147         break;
       
  6148         }
       
  6149     ReportEdwinEventL( MEikEdwinObserver::EEventScroll );
       
  6150     }
       
  6151 
       
  6152 EXPORT_C TInt CEikEdwin::LayoutWidth() const
       
  6153     {
       
  6154     if (iLayoutWidth)
       
  6155         return iLayoutWidth;
       
  6156     TMargins margins=iBorder.Margins();
       
  6157     TInt labels=0, cursor=0;
       
  6158     if (iTextView)
       
  6159         iTextView->MarginWidths(labels,cursor);
       
  6160 
       
  6161     TInt width;
       
  6162    
       
  6163     if ( iTextView )
       
  6164         {
       
  6165         width = iTextView->ViewRect().Width();
       
  6166         }
       
  6167     else
       
  6168         {
       
  6169         width = iSize.iWidth - ( margins.iLeft + margins.iRight );
       
  6170         }
       
  6171     
       
  6172     return width - ( labels + cursor + CursorWidth() + iRightWrapGutter );
       
  6173     }
       
  6174 
       
  6175 void CEikEdwin::DoReplaceAllL(SEdwinFindModel* aModel,TBool& aTextFound,TBool& aReplaced)
       
  6176     {
       
  6177     aReplaced=EFalse;
       
  6178     aTextFound=EFalse;
       
  6179     TInt flags=aModel->iFlags;
       
  6180     //text is found when called from replace dialog.
       
  6181     if (SelectionLength())
       
  6182         ClearSelectionL();
       
  6183     TInt startPos=CursorPos();
       
  6184     if (flags&EFindDirectionUp)
       
  6185         startPos+=aModel->iText.Length();
       
  6186     else
       
  6187         startPos-=aModel->iText.Length();
       
  6188     TInt count=-1;
       
  6189 FindAgain:
       
  6190     count=FindTextL(&aModel->iText,startPos,aModel->iFlags);        
       
  6191     if (count!=KErrNotFound)
       
  6192         {
       
  6193         aReplaced=ETrue;
       
  6194         aTextFound=ETrue;
       
  6195         iText->InsertL(count,aModel->iReplaceText);
       
  6196         iText->DeleteL(count+aModel->iReplaceText.Length(),aModel->iText.Length());
       
  6197         if (!(flags&EFindDirectionUp))
       
  6198             startPos=count+aModel->iReplaceText.Length();
       
  6199         else
       
  6200             startPos=count;
       
  6201         goto FindAgain;
       
  6202         }
       
  6203     }
       
  6204 
       
  6205 EXPORT_C void CEikEdwin::ReplaceAllL(SEdwinFindModel* aModel)
       
  6206     {
       
  6207     __ASSERT_DEBUG(iText,Panic(EEikPanicEdwinNoText));
       
  6208     __ASSERT_DEBUG(iTextView,Panic(EEikPanicEdwinNoView));
       
  6209     CancelFepTransaction();
       
  6210     TBool textFound=EFalse;
       
  6211     TBool replaced=EFalse;
       
  6212     const TBool undoEnabled=SupportsUndo();
       
  6213     if (undoEnabled)
       
  6214         SetAllowUndo(EFalse);
       
  6215     TRAPD(ret,DoReplaceAllL(aModel,textFound,replaced));
       
  6216     if (undoEnabled)
       
  6217         SetAllowUndo(ETrue);
       
  6218     if (ret==KErrNone)
       
  6219         {
       
  6220         if (!textFound)
       
  6221             DisplayFindTextNotFound(aModel->iText);
       
  6222         if (replaced)
       
  6223             {
       
  6224             ReportEdwinEventL( MEikEdwinObserver::EEventTextUpdate );
       
  6225             DoReportEventL( MCoeControlObserver::EEventStateChanged );
       
  6226             NotifyNewFormatL(); //do global format
       
  6227             }
       
  6228         if (SelectionLength())
       
  6229             ClearSelectionL();  
       
  6230         }
       
  6231     else
       
  6232         {
       
  6233         iEikonEnv->BusyMsgCancel();
       
  6234         ReportEdwinEventL( MEikEdwinObserver::EEventTextUpdate );
       
  6235         DoReportEventL( MCoeControlObserver::EEventStateChanged );
       
  6236         NotifyNewFormatL();//this will fail too if oom.
       
  6237         User::Leave(ret);
       
  6238         }
       
  6239     }    
       
  6240       
       
  6241 EXPORT_C void CEikEdwin::ReplaceL(SEdwinFindModel* aModel)
       
  6242     {
       
  6243     __ASSERT_DEBUG(iText,Panic(EEikPanicEdwinNoText));
       
  6244     __ASSERT_DEBUG(iTextView,Panic(EEikPanicEdwinNoView));
       
  6245     
       
  6246     CancelFepTransaction();
       
  6247     const TInt oldLength=iText->DocumentLength();
       
  6248     TBool formatHasChanged;
       
  6249     TCursorSelection selection=iTextView->Selection();
       
  6250     const TBool undoEnabled=SupportsUndo();
       
  6251     if (undoEnabled)
       
  6252         SetAllowUndo(EFalse);
       
  6253     TInt startPos=DeleteHighlightL(formatHasChanged,EFalse,EFalse);
       
  6254     if (undoEnabled)
       
  6255         SetAllowUndo(ETrue);
       
  6256     TRAPD(err,iText->InsertL(startPos,aModel->iReplaceText));
       
  6257     if (aModel->iFlags&EFindDirectionUp)
       
  6258         {
       
  6259         selection.iCursorPos=selection.LowerPos();
       
  6260         selection.iAnchorPos=selection.iCursorPos+aModel->iReplaceText.Length();
       
  6261         }
       
  6262     else
       
  6263         {
       
  6264         selection.iAnchorPos=selection.LowerPos();
       
  6265         selection.iCursorPos=selection.iAnchorPos+aModel->iReplaceText.Length();
       
  6266         }
       
  6267     const TCursorSelection pending(selection.iCursorPos,selection.iCursorPos);
       
  6268     iTextView->SetPendingSelection(pending);
       
  6269     iTextView->HandleInsertDeleteL(selection,aModel->iText.Length(),formatHasChanged);
       
  6270     if ( NeedToChangeFormattingModeL())
       
  6271         SetAmountToFormatL();
       
  6272     ReportEdwinEventL( MEikEdwinObserver::EEventTextUpdate );
       
  6273     DoReportEventL( MCoeControlObserver::EEventStateChanged );
       
  6274     User::LeaveIfError(err);
       
  6275     }    
       
  6276 
       
  6277 EXPORT_C TBool CEikEdwin::FindL(const TDesC* aFindText,TInt aFindFlags)
       
  6278     { 
       
  6279     TBuf<EEikEdwinFindStringMaxLen>* findText=new(ELeave) TBuf<EEikEdwinFindStringMaxLen>;
       
  6280     CleanupStack::PushL(findText);
       
  6281     if (!aFindText)
       
  6282         {
       
  6283         GetFindText(findText);
       
  6284         if (!findText->Length())
       
  6285             {
       
  6286             CleanupStack::PopAndDestroy();
       
  6287             if (SelectionLength())
       
  6288                 ClearSelectionL();
       
  6289             return EFalse;
       
  6290             }
       
  6291         }
       
  6292     else
       
  6293         *findText=*aFindText;
       
  6294     TBool noBusyMessage=(aFindFlags&ENoBusyMessage);
       
  6295     if(!noBusyMessage)
       
  6296         iEikonEnv->BusyMsgL(R_EIK_TBUF_SEARCHING,500000); // 0.5s delay 
       
  6297     TInt startPos=CursorPos();
       
  6298     TBool isUp=(aFindFlags&EFindDirectionUp);
       
  6299     TBool findAgain=(aFindFlags&EFindAgain);
       
  6300     if ((isUp==EFalse) != (findAgain==EFalse))
       
  6301         startPos=Selection().HigherPos();
       
  6302     else
       
  6303         startPos=Selection().LowerPos();
       
  6304     TInt pos=FindTextL(findText,startPos,aFindFlags);
       
  6305     if (pos==KErrNotFound) //ie not found
       
  6306         {
       
  6307         CleanupStack::PopAndDestroy(); // findText
       
  6308         if (SelectionLength())
       
  6309             ClearSelectionL();
       
  6310         if(!noBusyMessage)
       
  6311             iEikonEnv->BusyMsgCancel();
       
  6312         return EFalse;
       
  6313         }
       
  6314     if (aFindFlags&EFindDirectionUp)
       
  6315         SetSelectionL(pos,pos+findText->Length());
       
  6316     else
       
  6317         SetSelectionL(pos+findText->Length(),pos);
       
  6318     CleanupStack::PopAndDestroy(); // findText
       
  6319     if(!noBusyMessage)
       
  6320         iEikonEnv->BusyMsgCancel();
       
  6321     return ETrue;
       
  6322     }
       
  6323 
       
  6324 EXPORT_C TInt CEikEdwin::FindTextL(const TDesC* aFindText,TInt aPos,TInt aFindFlags)
       
  6325     {
       
  6326     __ASSERT_DEBUG(iText,Panic(EEikPanicEdwinNoText));
       
  6327     const TInt docLength=TextLength();
       
  6328     if (docLength<aPos)
       
  6329         return KErrNotFound;
       
  6330     TInt findParams=aFindFlags;
       
  6331     TBuf<EEikEdwinFindStringMaxLen>* findText=new(ELeave) TBuf<EEikEdwinFindStringMaxLen>;
       
  6332     CleanupStack::PushL(findText);
       
  6333     if (aFindText)
       
  6334         *findText=*aFindText;
       
  6335     else
       
  6336         {
       
  6337         GetFindText(findText);
       
  6338         findParams&=(~EFindCaseSensitive);
       
  6339         }
       
  6340     const TInt findLen=findText->Length();
       
  6341     if (!findLen || docLength<findLen)
       
  6342         {
       
  6343         CleanupStack::PopAndDestroy(); // findText
       
  6344         return KErrNotFound;
       
  6345         }
       
  6346     if (!(findParams&EFindCaseSensitive))
       
  6347         findText->LowerCase();
       
  6348     TBuf<EEikEdwinFindStringMaxLen>* docText=new(ELeave) TBuf<EEikEdwinFindStringMaxLen>;
       
  6349     CleanupStack::PushL(docText);
       
  6350     TInt count=aPos;
       
  6351     if (findParams&EFindDirectionUp)
       
  6352         {
       
  6353         if (aPos<findText->Length())
       
  6354             {
       
  6355             CleanupStack::PopAndDestroy(2); // findText, docText
       
  6356             return KErrNotFound; 
       
  6357             }
       
  6358         count=aPos-findLen;
       
  6359         }
       
  6360     FOREVER
       
  6361         {
       
  6362         if (count<0 || (count>(docLength-findLen) && !(findParams&EFindDirectionUp)))
       
  6363             {
       
  6364             CleanupStack::PopAndDestroy(2); // findText, docText
       
  6365             return KErrNotFound; 
       
  6366             }
       
  6367         *docText=iText->Read(count,findLen);
       
  6368         TInt docLen=docText->Length();
       
  6369         while (docLen<findLen) // tried to read across a segment boundary
       
  6370             {
       
  6371             docText->Append(iText->Read(count+docLen,findLen-docLen));
       
  6372             docLen=docText->Length();
       
  6373             }
       
  6374         if (!(findParams&EFindCaseSensitive))
       
  6375             docText->LowerCase();
       
  6376         if (*findText==*docText)
       
  6377             {
       
  6378             if (findParams&EFindWholeWord)
       
  6379                 {
       
  6380                 if ((count==0 || !TCharF(*((iText->Read(count-1,1)).Ptr())).IsAlphaDigit()) &&
       
  6381                 (count+findLen==docLength || !TCharF(*((iText->Read(count+findLen,1)).Ptr())).IsAlphaDigit()))
       
  6382                     {
       
  6383                     break;
       
  6384                     }
       
  6385                 }
       
  6386             else
       
  6387                 {
       
  6388                 break;
       
  6389                 }
       
  6390             }
       
  6391         if (findParams&EFindDirectionUp)
       
  6392             count--;
       
  6393         else
       
  6394             count++;
       
  6395         }
       
  6396     CleanupStack::PopAndDestroy(2); // findText, docText
       
  6397     return count;
       
  6398     }
       
  6399 
       
  6400 EXPORT_C void CEikEdwin::DisplayFindTextNotFound(TDes& aFindText)
       
  6401     {
       
  6402     TBuf<80> tmp;
       
  6403     TRAPD( err, iCoeEnv->ReadResourceL( tmp,R_EIK_TBUF_CANNOT_FIND_TEXT ) );
       
  6404     if ( err == KErrNone )
       
  6405         {
       
  6406         TInt rem = tmp.MaxLength() - tmp.Length() - 1;
       
  6407         if ( aFindText.Length() > rem )
       
  6408             {
       
  6409             TextUtils::TruncateToNumChars( aFindText, rem );
       
  6410             }
       
  6411         TBuf<80> buf;
       
  6412         buf.Format( tmp, &aFindText );
       
  6413         TextUtils::ClipToFit( buf, *iCoeEnv->NormalFont(), 
       
  6414             iAvkonAppUi->ApplicationRect().Width() - 20 ); // -20 allows for borders on infomsg
       
  6415         iEikonEnv->InfoMsg( buf );
       
  6416         }
       
  6417     }
       
  6418 
       
  6419 EXPORT_C void CEikEdwin::GetFindText(TDes* aSearchText)
       
  6420     {
       
  6421     CancelFepTransaction();
       
  6422     TInt startPos=0;
       
  6423     TInt length=0;
       
  6424     if (SelectionLength())
       
  6425         {
       
  6426         TCursorSelection selection=Selection();
       
  6427         startPos=selection.LowerPos();
       
  6428         length=SelectionLength();
       
  6429         if (length>EEikEdwinFindStringMaxLen)
       
  6430             goto GetWord;
       
  6431         }
       
  6432     else
       
  6433         {
       
  6434 GetWord:
       
  6435         GetWordInfo(CursorPos(),startPos,length);
       
  6436         }
       
  6437     if (!length)
       
  6438         return;
       
  6439     length=Min(length,EEikEdwinFindStringMaxLen);
       
  6440     *aSearchText=iText->Read(startPos,length);
       
  6441     TInt searchLen=aSearchText->Length();
       
  6442     while (searchLen<length) // tried to read across a segment boundary
       
  6443         {
       
  6444         aSearchText->Append(iText->Read(startPos+searchLen,length-searchLen));
       
  6445         searchLen=aSearchText->Length();
       
  6446         }
       
  6447     }
       
  6448 
       
  6449 EXPORT_C void CEikEdwin::SetAllowPictures(TBool aAllow)
       
  6450     {
       
  6451     if (aAllow)
       
  6452         iEdwinUserFlags|=EAllowPictures;
       
  6453     else
       
  6454         iEdwinUserFlags&=~EAllowPictures;
       
  6455     }
       
  6456 
       
  6457 EXPORT_C void CEikEdwin::CheckRemovePictures(TInt aStartPos,TInt aLength)
       
  6458     {
       
  6459     if (iEdwinUserFlags&EAllowPictures)
       
  6460         return;
       
  6461     TInt charsRead=0;
       
  6462     while (charsRead<aLength)
       
  6463         {
       
  6464         TPtrC ptr=iText->Read(aStartPos,Min(aLength-charsRead,10));
       
  6465         const TInt ptrLength=ptr.Length();
       
  6466         TInt located=0;
       
  6467         TInt pos=ptr.Locate(TChar(CEditableText::EPictureCharacter));
       
  6468         while(pos!=-1)
       
  6469             {
       
  6470             if (iEdwinInternalFlags&ERichText)
       
  6471                 STATIC_CAST(CRichText*,iText)->DeleteFromParagraph(aStartPos+pos,1);
       
  6472             else
       
  6473                 {
       
  6474                 TRAP_IGNORE( iText->DeleteL(aStartPos+pos,1));
       
  6475                 }
       
  6476             ++located;
       
  6477             ptr.Set(ptr.Ptr(),ptr.Length()-1);
       
  6478             pos=ptr.Locate(TChar(CEditableText::EPictureCharacter));
       
  6479             }
       
  6480         aStartPos+=(ptrLength-located);
       
  6481         charsRead+=ptrLength;
       
  6482         }
       
  6483     }
       
  6484 
       
  6485 /*
       
  6486  * This function will remove the non Ascii character when the UNICODE
       
  6487  * charaters are not allowed
       
  6488  */
       
  6489 EXPORT_C void CEikEdwin::CheckValidityOfChars(TInt aStartPos,TInt aLength)
       
  6490     {
       
  6491     if (!OnlyASCIIChars())
       
  6492         return;
       
  6493     TInt charsRead=0;
       
  6494     while (charsRead<aLength)
       
  6495         {
       
  6496         TBuf<1> buf;
       
  6497         iText->Extract(buf, aStartPos, 1);
       
  6498         if (!IsValidChar(buf[0]))
       
  6499             {
       
  6500             if (iEdwinInternalFlags&ERichText)
       
  6501                 STATIC_CAST(CRichText*,iText)->DeleteFromParagraph(aStartPos,1);
       
  6502             else
       
  6503                 {
       
  6504                 TRAP_IGNORE( iText->DeleteL(aStartPos,1));
       
  6505                 }
       
  6506             if ( iEdwinExtension->iSmiley )
       
  6507                 {
       
  6508                 iEdwinExtension->iSmiley->HandleDeleteL( aStartPos, 1 );
       
  6509                 }
       
  6510             }
       
  6511         else
       
  6512             aStartPos++;//=(ptrLength-located);
       
  6513         charsRead++;//=ptrLength;
       
  6514         }
       
  6515 
       
  6516     }
       
  6517 
       
  6518 EXPORT_C void CEikEdwin::SetWordDelimiters(TBool aPicture,TBool aPunctuation)
       
  6519     {
       
  6520     if (aPicture)
       
  6521         iEdwinInternalFlags|=EPictureDelimits;
       
  6522     else
       
  6523         iEdwinInternalFlags&=~EPictureDelimits;
       
  6524     if (aPunctuation)
       
  6525         iEdwinInternalFlags|=EPunctuationDelimits;
       
  6526     else
       
  6527         iEdwinInternalFlags&=~EPunctuationDelimits;
       
  6528     }
       
  6529 
       
  6530 EXPORT_C void CEikEdwin::GetWordInfo(TInt aCurrentPos,TInt& aStartPos,TInt& aLength) const
       
  6531     {
       
  6532     __ASSERT_DEBUG(iText,Panic(EEikPanicEdwinNoText));
       
  6533     iText->GetWordInfo(aCurrentPos,aStartPos,aLength,iEdwinInternalFlags&EPictureDelimits,iEdwinInternalFlags&EPunctuationDelimits);
       
  6534     }
       
  6535 
       
  6536 EXPORT_C void CEikEdwin::InsertFieldL(CTextField* aField,TUid aFieldType)
       
  6537 // Takes ownership of aField
       
  6538 // Inserts if there is space for the insert
       
  6539 //
       
  6540     {
       
  6541     __ASSERT_DEBUG(aField,Panic(EEikPanicFieldDoesNotExist));
       
  6542     __ASSERT_DEBUG(iTextView,Panic(EEikPanicEdwinNoView));
       
  6543     __ASSERT_DEBUG(iText,Panic(EEikPanicEdwinNoText));
       
  6544     
       
  6545     CancelFepTransaction();
       
  6546     TPtr ptr(NULL,0); // a null TPtr
       
  6547     TInt fieldLength=aField->Value(ptr);
       
  6548     CleanupStack::PushL(aField);
       
  6549     if (!((iTextLimit>(TextLength()+fieldLength)) || !iTextLimit))
       
  6550         {
       
  6551         iEikonEnv->InfoMsg(R_EIK_TBUF_MAX_CHARACTERS_REACHED);
       
  6552         CleanupStack::PopAndDestroy(); // aField
       
  6553         }
       
  6554     else
       
  6555         {
       
  6556         TCursorSelection selection=iTextView->Selection();
       
  6557         const TInt selectionLength=selection.Length();
       
  6558         TBool formatHasChanged=EFalse;
       
  6559         if (selectionLength)
       
  6560             DeleteHighlightL(formatHasChanged);
       
  6561         const TInt oldLength=TextLength();
       
  6562         const TInt cursorPos=CursorPos();
       
  6563         CleanupStack::Pop(); // InsertFieldL takes ownership of aField
       
  6564         TRAPD(err,iText->InsertFieldL(cursorPos,aField,aFieldType));
       
  6565         TRAP(err,iText->UpdateFieldL(cursorPos));
       
  6566         if (NeedToChangeFormattingModeL())
       
  6567             TRAP(err,SetAmountToFormatL());
       
  6568         const TInt fieldLength=TextLength()-oldLength;
       
  6569         const TInt newCursorPos=selection.LowerPos()+fieldLength;
       
  6570         iTextView->SetPendingSelection(TCursorSelection(newCursorPos,newCursorPos));
       
  6571         const TInt anchor=selection.LowerPos();
       
  6572         selection.iAnchorPos=anchor;
       
  6573         selection.iCursorPos=anchor+fieldLength;
       
  6574         if (iUndoStore)
       
  6575             iUndoStore->SetNewText(selection);
       
  6576         iTextView->HandleInsertDeleteL(selection,selectionLength,formatHasChanged);
       
  6577         ReportEdwinEventL( MEikEdwinObserver::EEventTextUpdate );
       
  6578         DoReportEventL( MCoeControlObserver::EEventStateChanged );
       
  6579         User::LeaveIfError(err);
       
  6580         }
       
  6581     }
       
  6582 
       
  6583 EXPORT_C void CEikEdwin::UpdateAllFieldsL()
       
  6584 // move to the start of the document then update all fields
       
  6585 // (must move to the start first because doc may get much shorter)
       
  6586 //
       
  6587     {
       
  6588     __ASSERT_DEBUG(iTextView,Panic(EEikPanicEdwinNoView));
       
  6589     __ASSERT_DEBUG(iText,Panic(EEikPanicEdwinNoText));
       
  6590 
       
  6591     CancelFepTransaction();
       
  6592     SetCursorPosL(0,EFalse);
       
  6593     const TInt oldLength=iText->DocumentLength();
       
  6594     iText->UpdateAllFieldsL();
       
  6595     if (NeedToChangeFormattingModeL())
       
  6596         SetAmountToFormatL();
       
  6597     TViewYPosQualifier yPosQualifier;
       
  6598     yPosQualifier.SetMakeLineFullyVisible();
       
  6599     iTextView->HandleGlobalChangeL(yPosQualifier);
       
  6600     ReportEdwinEventL( MEikEdwinObserver::EEventTextUpdate );
       
  6601     DoReportEventL( MCoeControlObserver::EEventStateChanged );
       
  6602     }
       
  6603 
       
  6604 EXPORT_C void CEikEdwin::UpdateCurrentFieldL()
       
  6605 // if we're in a field move to the start of it and update it, else do nothing
       
  6606 //
       
  6607     {
       
  6608     __ASSERT_DEBUG(iTextView,Panic(EEikPanicEdwinNoView));
       
  6609     __ASSERT_DEBUG(iText,Panic(EEikPanicEdwinNoText));
       
  6610 
       
  6611     CancelFepTransaction();
       
  6612     TInt pos = CursorPos();
       
  6613     TFindFieldInfo info;
       
  6614     if (iText->FindFields(info,pos))
       
  6615         {// we are in a field
       
  6616         // move cursor to start of field
       
  6617         SetCursorPosL(info.iFirstFieldPos,EFalse);
       
  6618         const TInt oldLength=iText->DocumentLength();
       
  6619         // update the field
       
  6620         iText->UpdateFieldL(pos);
       
  6621         if (NeedToChangeFormattingModeL())
       
  6622             SetAmountToFormatL();
       
  6623         iTextView->HandleRangeFormatChangeL(TCursorSelection(info.iFirstFieldPos,info.iFirstFieldLen),EFalse);
       
  6624         ReportEdwinEventL( MEikEdwinObserver::EEventTextUpdate );
       
  6625         DoReportEventL( MCoeControlObserver::EEventStateChanged );
       
  6626         }
       
  6627     }
       
  6628 
       
  6629 /**
       
  6630  * Gets the list of logical colors employed in the drawing of the control,
       
  6631  * paired with an explanation of how they are used. Appends the list to aColorUseList.
       
  6632  *
       
  6633  * @since ER5U 
       
  6634  */
       
  6635 EXPORT_C void CEikEdwin::GetColorUseListL(CArrayFix<TCoeColorUse>& aColorUseList) const
       
  6636     {
       
  6637     CEikBorderedControl::GetColorUseListL(aColorUseList);
       
  6638     LafEdwin::GetColorUseListL(aColorUseList);
       
  6639     }
       
  6640 
       
  6641 /**
       
  6642  * Handles a change to the control's resources of type aType
       
  6643  * which are shared across the environment, e.g. colors or fonts.
       
  6644  * For this particular control aType can be a request of handling either the caps lock
       
  6645  * modifier or the virtual cursor state.
       
  6646  *
       
  6647  * @since ER5U 
       
  6648  */
       
  6649 EXPORT_C void CEikEdwin::HandleResourceChange(TInt aType)
       
  6650     {
       
  6651     CEikBorderedControl::HandleResourceChange(aType);
       
  6652 
       
  6653     switch (aType)
       
  6654         {
       
  6655     case KEikDynamicLayoutVariantSwitch:
       
  6656         {
       
  6657         iEdwinExtension->iThumbPos = KErrNotFound;
       
  6658         SizeChanged();
       
  6659         if ( !IsReadOnly() && !IsNonFocusing() 
       
  6660                 && !( iEdwinUserFlags & EDisplayOnly ) )
       
  6661             {
       
  6662             TInt docPos = CursorPos();
       
  6663             TRect viewRect( AdjustedViewRect() );
       
  6664             TViewYPosQualifier yPosQ;
       
  6665             TInt yPos = ( viewRect.iBr.iY + viewRect.iTl.iY )/2;
       
  6666             yPosQ.SetMakeLineFullyVisible();
       
  6667             yPosQ.SetFillScreen();
       
  6668             TRAP_IGNORE( iTextView->SetViewL( docPos, yPos, yPosQ ) ); 
       
  6669             }                
       
  6670         }
       
  6671         break;
       
  6672     case KEikMessageVirtualCursorStateChange:
       
  6673         {
       
  6674         TEikVirtualCursor& cursor=iEikonEnv->VirtualCursor();
       
  6675     
       
  6676         if(!(iEdwinUserFlags&EIgnoreVirtualCursor) && IsFocused()
       
  6677             && cursor.CursorState(*iEikonEnv)==TEikVirtualCursor::EOn)
       
  6678             {
       
  6679             TRAP_IGNORE( cursor.SetCursorStateL(TEikVirtualCursor::ESuspended,*iEikonEnv));
       
  6680             }
       
  6681         }
       
  6682         break;
       
  6683     case KEikMessageCaptionedControlEditableStateChange:
       
  6684         {
       
  6685         iEdwinUserFlags &= ~EAvkonNotEditable;
       
  6686         }
       
  6687         break;
       
  6688     case KEikMessageCaptionedControlNotEditableStateChange:
       
  6689         {
       
  6690         iEdwinUserFlags |= EAvkonNotEditable;
       
  6691         }
       
  6692         break;
       
  6693     case KEikInputLanguageChange:
       
  6694         {
       
  6695         UpdateCache(KEikInputLanguageChange);
       
  6696         DoAlignment();
       
  6697         }
       
  6698         break;
       
  6699     default:
       
  6700         break;
       
  6701         }
       
  6702     }
       
  6703 
       
  6704 
       
  6705 /**
       
  6706  * Sets the edwin size observer to aObserver. Does not imply transfer of ownership.
       
  6707  */
       
  6708 EXPORT_C void CEikEdwin::SetEdwinSizeObserver(MEikEdwinSizeObserver* aEdwinSizeObserver)
       
  6709     {
       
  6710     iEdwinSizeObserver = aEdwinSizeObserver;
       
  6711     CheckIfEdwinIsResizable();
       
  6712     }
       
  6713 
       
  6714 void CEikEdwin::CheckIfEdwinIsResizable()
       
  6715     {
       
  6716     if (iEdwinSizeObserver!=NULL && iEdwinUserFlags&EResizable)
       
  6717         {
       
  6718         iEdwinInternalFlags &= ~EHasOneLineOnly;
       
  6719         }
       
  6720 
       
  6721     if ((iEdwinSizeObserver==NULL || !(iEdwinUserFlags&EResizable)) && 
       
  6722         (iNumberOfLines==1))
       
  6723         {
       
  6724         iEdwinInternalFlags |= EHasOneLineOnly;
       
  6725         }
       
  6726     }
       
  6727 
       
  6728 TBool CEikEdwin::IsNewHeightWithinMinimumAndMaximum(TInt aNewHeight) const
       
  6729 // Checks if the new height is within the minimum and maximum edwin height.
       
  6730     {
       
  6731     const TInt edwinHeight = iSize.iHeight;
       
  6732     TBool validHeight = ETrue;
       
  6733     if (aNewHeight < edwinHeight)
       
  6734         {
       
  6735         if ( ((iMinimumHeight > 0) && (iMinimumHeight > aNewHeight) ) ||
       
  6736             (iMinimumHeight == 0) )
       
  6737             validHeight =  EFalse;
       
  6738         }
       
  6739     else if (aNewHeight > edwinHeight)
       
  6740         {
       
  6741         if ((iMaximumHeight > 0) && (iMaximumHeight < aNewHeight))
       
  6742             validHeight =  EFalse;
       
  6743         }
       
  6744     return validHeight;
       
  6745     }
       
  6746 
       
  6747 /**
       
  6748  * Reports the event EEventSizeChanging to the observer every time the text view height changes.
       
  6749  *
       
  6750  *  This routine has been significantly changed for AVKON:  (TimW Aug 2000)
       
  6751  *  - It deals in numbers of lines rather than pixels for height.
       
  6752  *  - It is triggers the oberver when the height reduces as well as when it increases.
       
  6753  *  - It updates iNumberOfLInes
       
  6754  *
       
  6755  */
       
  6756 EXPORT_C void CEikEdwin::OnReformatL(const CTextView* /*aTextView*/)
       
  6757     {
       
  6758     if (iEdwinInternalFlags&EOnReformatting) 
       
  6759         return;
       
  6760 
       
  6761     CheckIfEdwinIsResizable();
       
  6762     if ( (iEdwinSizeObserver) && (iEdwinUserFlags&EResizable) )
       
  6763         {
       
  6764         const TInt extraHeight = iBorder.SizeDelta().iHeight+iMargins.iTop+iMargins.iBottom;
       
  6765 #ifdef _DEBUG
       
  6766         TInt edwinHeightWithBorgersAndMargins = iSize.iHeight;
       
  6767 #endif
       
  6768 
       
  6769         TInt newHeight = TextLayout()->FormattedHeightInPixels() + extraHeight;
       
  6770 
       
  6771         TInt lines = TextLayout()->NumFormattedLines() ;
       
  6772  
       
  6773 
       
  6774         iEdwinInternalFlags |= EOnReformatting;
       
  6775 //      if (newHeight!=edwinHeightWithBorgersAndMargins) 
       
  6776         if ( lines != iNumberOfLines ) 
       
  6777             {
       
  6778 #ifdef _DEBUG
       
  6779             RDebug::Print(_L("Resizing edwin: newlines = %d, oldlines = %d, newHeight = %d. ehwbm = %d"), lines, iNumberOfLines, newHeight, edwinHeightWithBorgersAndMargins ) ; 
       
  6780 #endif
       
  6781             iNumberOfLines = lines ;
       
  6782 
       
  6783             TInt minimumHeight = CalcMinimumHeightFromNumOfLinesL();
       
  6784 //          if ( IsEdwinHeightWithinMinimumAndMaximum(newHeight) ||
       
  6785 //              ((edwinHeightWithBorgersAndMargins > newHeight) && (newHeight == minimumHeight)) ||
       
  6786 //              (minimumHeight > newHeight) && (minimumHeight != edwinHeightWithBorgersAndMargins) )
       
  6787 //            if (ETrue)  
       
  6788 //                {
       
  6789 //              if ((minimumHeight > newHeight) && (minimumHeight != edwinHeightWithBorgersAndMargins))
       
  6790                     newHeight = minimumHeight;
       
  6791                 TSize desirableEdwinSize(iSize.iWidth, newHeight);
       
  6792                 if (iEdwinSizeObserver->HandleEdwinSizeEventL(this, MEikEdwinSizeObserver::EEventSizeChanging, desirableEdwinSize))
       
  6793                     {
       
  6794                     DrawDeferred();
       
  6795                 }
       
  6796 //              }
       
  6797             }
       
  6798         iEdwinInternalFlags &= ~EOnReformatting;
       
  6799         }
       
  6800     }
       
  6801 
       
  6802 TInt CEikEdwin::CalcMinimumHeightFromNumOfLinesL() const
       
  6803     {
       
  6804     TInt minimumHeight = iSize.iHeight;
       
  6805     if (iNumberOfLines == 0)
       
  6806         {
       
  6807         if (iMinimumHeight > 0 )
       
  6808             minimumHeight = iMinimumHeight;
       
  6809         }
       
  6810     else
       
  6811         {
       
  6812         __ASSERT_DEBUG(iLayout,Panic(EEikPanicEdwinNoLayout));
       
  6813         TInt lineHeight = iLayout->FormattedHeightInPixels();
       
  6814         const TInt docLength = iLayout->DocumentLength();
       
  6815         if (docLength > 0)
       
  6816             {
       
  6817             const TInt numFormattedLines = iLayout->NumFormattedLines();
       
  6818             lineHeight = lineHeight / numFormattedLines;
       
  6819             }
       
  6820         minimumHeight = (lineHeight * iNumberOfLines) + iBorder.SizeDelta().iHeight+iMargins.iTop+iMargins.iBottom;
       
  6821         }
       
  6822     return minimumHeight;
       
  6823     }
       
  6824 
       
  6825 void CEikEdwin::CheckEdwinHeight()
       
  6826     {
       
  6827     const TInt height = iSize.iHeight;
       
  6828     if ( (height >= iMaximumHeight) && (iMaximumHeight > 0) )
       
  6829         iSize.iHeight = iMaximumHeight;
       
  6830     else if ( (height < iMinimumHeight) && (iMinimumHeight > 0) )
       
  6831         iSize.iHeight = iMinimumHeight;
       
  6832     }
       
  6833 
       
  6834 void CEikEdwin::SetEdwinHeight(TInt aHeight)
       
  6835     {
       
  6836     if ( (aHeight > iMaximumHeight) && (iMaximumHeight > 0) )
       
  6837         iSize.iHeight = iMaximumHeight;
       
  6838     else if ( (aHeight < iMinimumHeight) && (iMinimumHeight > 0) )
       
  6839         iSize.iHeight = iMinimumHeight;
       
  6840     else
       
  6841         iSize.iHeight = aHeight;
       
  6842     }
       
  6843 
       
  6844 /**
       
  6845  * Returns the minimum edwin height.
       
  6846  * 
       
  6847  */
       
  6848 EXPORT_C TInt CEikEdwin::MinimumHeight() const
       
  6849     {
       
  6850     return iMinimumHeight;
       
  6851     } 
       
  6852 
       
  6853 /**
       
  6854  * Returns the maximum edwin height.
       
  6855  */
       
  6856 EXPORT_C TInt CEikEdwin::MaximumHeight() const
       
  6857     {
       
  6858     return iMaximumHeight;
       
  6859     } 
       
  6860 
       
  6861 
       
  6862 /**
       
  6863  * Sets the minimum edwin height to be aHeight. It also adjustes the maximum edwin height when
       
  6864  * its values is smaller than aHeight.
       
  6865  */
       
  6866 EXPORT_C void CEikEdwin::SetMinimumHeight(TInt aHeight)
       
  6867     {
       
  6868     if (aHeight > iMaximumHeight)
       
  6869         iMaximumHeight  = aHeight;
       
  6870     iMinimumHeight = aHeight;
       
  6871     } 
       
  6872 
       
  6873 /**
       
  6874  * Sets the maximum edwin height to be aHeight. It also adjustes the minimum edwin height when
       
  6875  * its values is bigger than aHeight.
       
  6876  */
       
  6877 EXPORT_C void CEikEdwin::SetMaximumHeight(TInt aHeight)
       
  6878     {
       
  6879     if (iMinimumHeight > aHeight)
       
  6880         iMinimumHeight = aHeight;
       
  6881     iMaximumHeight = aHeight;
       
  6882     } 
       
  6883 
       
  6884 EXPORT_C void CEikEdwin::InsertDeleteCharsL(TInt aInsertPos,const TDesC& aText,const TCursorSelection& aSelection)
       
  6885     {
       
  6886     __ASSERT_DEBUG(iText,Panic(EEikPanicEdwinNoText));
       
  6887     __ASSERT_DEBUG(iTextView,Panic(EEikPanicEdwinNoView));
       
  6888     const TInt lowerPos=aSelection.LowerPos();
       
  6889     TBool formatChanged=EFalse;
       
  6890     const TInt length=aSelection.Length();
       
  6891     if (iEdwinInternalFlags&ERichText)
       
  6892         {
       
  6893         STATIC_CAST(CRichText*,iText)->CancelInsertCharFormat();
       
  6894         formatChanged=STATIC_CAST(CRichText*,iText)->DelSetInsertCharFormatL(lowerPos,length);
       
  6895         }
       
  6896     else
       
  6897         {
       
  6898         formatChanged=iText->DeleteL(lowerPos,length);
       
  6899         if ( iEdwinExtension->iSmiley )
       
  6900             {
       
  6901             iEdwinExtension->iSmiley->HandleDeleteL( lowerPos, length );
       
  6902             }
       
  6903         }
       
  6904     iText->InsertL(aInsertPos,aText);
       
  6905     if ( iEdwinExtension->iSmiley )
       
  6906         {
       
  6907         iEdwinExtension->iSmiley->HandleInsertL( aInsertPos, aText.Length() );
       
  6908         ConvertTextForSmileyL( TCursorSelection( aInsertPos, 
       
  6909             aInsertPos + aText.Length() ), ETrue );
       
  6910         }
       
  6911     iTextView->HandleInsertDeleteL(TCursorSelection(aInsertPos,aInsertPos+aText.Length()),length,formatChanged);
       
  6912     }
       
  6913 
       
  6914 EXPORT_C void CEikEdwin::SetNonPrintingCharsVisibility(TNonPrintingCharVisibility aVisibility)
       
  6915     {
       
  6916     __ASSERT_DEBUG(iLayout,Panic(EEikPanicEdwinNoLayout));
       
  6917     iLayout->SetNonPrintingCharsVisibility(aVisibility);
       
  6918     }
       
  6919 
       
  6920 EXPORT_C TNonPrintingCharVisibility CEikEdwin::NonPrintingCharsVisibility() const
       
  6921     {
       
  6922     __ASSERT_DEBUG(iLayout,Panic(EEikPanicEdwinNoLayout));
       
  6923     return iLayout->NonPrintingCharsVisibility();
       
  6924     }
       
  6925 
       
  6926 /**
       
  6927  * Writes the internal state of the control and its components to aStream.
       
  6928  * Does nothing in release mode.
       
  6929  * Designed to be overidden and base called by subclasses.
       
  6930  *
       
  6931  * @internal
       
  6932  * @since App-Framework_6.1
       
  6933  */
       
  6934 #ifndef _DEBUG
       
  6935 EXPORT_C void CEikEdwin::WriteInternalStateL(RWriteStream&) const
       
  6936     {}
       
  6937 #else
       
  6938 EXPORT_C void CEikEdwin::WriteInternalStateL(RWriteStream& aWriteStream) const
       
  6939     {
       
  6940     _LIT(KEikLitEdWnCtlStart,"<CEikEdwin>");
       
  6941     _LIT(KEikLitEdWnCtlEnd,"<\\CEikEdwin>");
       
  6942     _LIT(KEikLitEdWnUsFlgs,"<iEdwinUserFlags>");
       
  6943     _LIT(KEikLitEdWnUsFlgsEnd,"<\\iEdwinUserFlags>");
       
  6944     _LIT(KEikLitEdWnIntFlgs,"<iEdwinInternalFlags>");
       
  6945     _LIT(KEikLitEdWnIntFlgsEnd,"<\\iEdwinInternalFlags>");
       
  6946     _LIT(KEikLitEdWnPlnTxt,"<iText>");
       
  6947     _LIT(KEikLitEdWnPlnTxtEnd,"<\\iText>");
       
  6948     _LIT(KEikLitEdWnTxtLmt,"<iTextLimit>");
       
  6949     _LIT(KEikLitEdWnTxtLmtEnd,"<\\iTextLimit>");
       
  6950     _LIT(KEikLitEdWnNoLns,"<iNumberOfLines>");
       
  6951     _LIT(KEikLitEdWnNoLnsEnd,"<\\iNumberOfLines>");
       
  6952     _LIT(KEikLitEdWnLstPtrDPs,"<iLastPointerDocPos>");
       
  6953     _LIT(KEikLitEdWnLstPtrDPsEnd,"<\\iLastPointerDocPos>");
       
  6954     _LIT(KEikLitEdWnMrgns, "<iMargins>");
       
  6955     _LIT(KEikLitEdWnMrgnsEnd, "<\\iMargins>");
       
  6956     _LIT(KEikLitEdWnAvLnsVwRct,"<iAvgLinesInViewRect>");
       
  6957     _LIT(KEikLitEdWnAvLnsVwRctEnd,"<\\iAvgLinesInViewRect>");
       
  6958     _LIT(KEikLitEdWnAvChPrLn,"<iAvgCharsPerLine>");
       
  6959     _LIT(KEikLitEdWnAvChPrLnEnd,"<\\iAvgCharsPerLine>");
       
  6960     _LIT(KEikLitEdWnRgWrpGtr,"<iRightWrapGutter>");
       
  6961     _LIT(KEikLitEdWnRgWrpGtrEnd,"<\\iRightWrapGutter>");
       
  6962     _LIT(KEikLitEdWnLyWdth,"<iLayoutWidth>");
       
  6963     _LIT(KEikLitEdWnLyWdthEnd,"<\\iLayoutWidth>");
       
  6964     _LIT(KEikLitEdWnMinH,"<iMinimumHeight>");
       
  6965     _LIT(KEikLitEdWnMinHEnd,"<\\iMinimumHeight>");
       
  6966     _LIT(KEikLitEdWnMaxH,"<iMaximumHeight>");
       
  6967     _LIT(KEikLitEdWnMaxHEnd,"<\\iMaximumHeight>");
       
  6968     _LIT(KEikLitEdWnLstPrtAPs,"<iLastPointerAnchorPosition>");
       
  6969     _LIT(KEikLitEdWnLstPrtAPsEnd,"<\\iLastPointerAnchorPosition>");
       
  6970     
       
  6971     aWriteStream << KEikLitEdWnCtlStart;
       
  6972     aWriteStream << KEikLitEdWnUsFlgs;
       
  6973     aWriteStream.WriteInt32L(iEdwinUserFlags);
       
  6974     aWriteStream << KEikLitEdWnUsFlgsEnd;
       
  6975     aWriteStream << KEikLitEdWnIntFlgs;
       
  6976     aWriteStream.WriteInt32L(iEdwinInternalFlags);
       
  6977     aWriteStream << KEikLitEdWnIntFlgsEnd;
       
  6978     aWriteStream << KEikLitEdWnPlnTxt;
       
  6979     if(iText->DocumentLength())
       
  6980         aWriteStream << *iText;
       
  6981     aWriteStream << KEikLitEdWnPlnTxtEnd;
       
  6982     aWriteStream << KEikLitEdWnTxtLmt;
       
  6983     aWriteStream.WriteInt32L(iTextLimit);
       
  6984     aWriteStream << KEikLitEdWnTxtLmtEnd;
       
  6985     aWriteStream << KEikLitEdWnNoLns;
       
  6986     aWriteStream.WriteInt32L(iNumberOfLines);
       
  6987     aWriteStream << KEikLitEdWnNoLnsEnd;
       
  6988     aWriteStream << KEikLitEdWnLstPtrDPs;
       
  6989     aWriteStream.WriteInt32L(iLastPointerDocPos);
       
  6990     aWriteStream << KEikLitEdWnLstPtrDPsEnd;
       
  6991     aWriteStream << KEikLitEdWnMrgns;
       
  6992     aWriteStream.WriteInt8L(iMargins.iLeft);
       
  6993     aWriteStream.WriteInt8L(iMargins.iRight);
       
  6994     aWriteStream.WriteInt8L(iMargins.iTop);
       
  6995     aWriteStream.WriteInt8L(iMargins.iBottom);
       
  6996     aWriteStream << KEikLitEdWnMrgnsEnd;
       
  6997     aWriteStream << KEikLitEdWnAvLnsVwRct;
       
  6998     aWriteStream.WriteInt32L(iAvgLinesInViewRect);
       
  6999     aWriteStream << KEikLitEdWnAvLnsVwRctEnd;
       
  7000     aWriteStream << KEikLitEdWnAvChPrLn;
       
  7001     aWriteStream.WriteInt32L(iAvgCharsPerLine);
       
  7002     aWriteStream << KEikLitEdWnAvChPrLnEnd;
       
  7003     aWriteStream << KEikLitEdWnRgWrpGtr;
       
  7004     aWriteStream.WriteInt32L(iRightWrapGutter);
       
  7005     aWriteStream << KEikLitEdWnRgWrpGtrEnd;
       
  7006     aWriteStream << KEikLitEdWnLyWdth;
       
  7007     aWriteStream.WriteInt32L(iLayoutWidth);
       
  7008     aWriteStream << KEikLitEdWnLyWdthEnd;
       
  7009     aWriteStream << KEikLitEdWnMinH;
       
  7010     aWriteStream.WriteInt32L(iMinimumHeight);
       
  7011     aWriteStream << KEikLitEdWnMinHEnd;
       
  7012     aWriteStream << KEikLitEdWnMaxH;
       
  7013     aWriteStream.WriteInt32L(iMaximumHeight);
       
  7014     aWriteStream << KEikLitEdWnMaxHEnd;
       
  7015     aWriteStream << KEikLitEdWnLstPrtAPs;
       
  7016     aWriteStream.WriteInt32L(iLastPointerAnchorPos);
       
  7017     aWriteStream << KEikLitEdWnLstPrtAPsEnd;
       
  7018     CEikBorderedControl::WriteInternalStateL(aWriteStream);
       
  7019     aWriteStream << KEikLitEdWnCtlEnd;
       
  7020     }
       
  7021 #endif
       
  7022 
       
  7023 EXPORT_C void CEikEdwin::Reserved_2()
       
  7024     {}
       
  7025 
       
  7026 EXPORT_C void CEikEdwin::Reserved_3()
       
  7027     {}
       
  7028 
       
  7029 // Avkon editor extensions
       
  7030 EXPORT_C void CEikEdwin::SetAknEditorCase(TInt aCase)
       
  7031     {
       
  7032     if (iEdwinFepSupport && iEdwinFepSupport->State(KNullUid))
       
  7033         STATIC_CAST(CAknEdwinState*, iEdwinFepSupport->State(KNullUid))->SetDefaultCase(aCase);
       
  7034     }
       
  7035 
       
  7036 EXPORT_C void CEikEdwin::SetAknEditorPermittedCaseModes(TInt aPermittedCaseModes)
       
  7037     {
       
  7038     if (iEdwinFepSupport && iEdwinFepSupport->State(KNullUid))
       
  7039         STATIC_CAST(CAknEdwinState*, iEdwinFepSupport->State(KNullUid))->SetPermittedCases(aPermittedCaseModes);
       
  7040     }
       
  7041 
       
  7042 EXPORT_C void CEikEdwin::SetAknEditorNumericKeymap(TAknEditorNumericKeymap aNumericKeymap)
       
  7043     {
       
  7044     if (iEdwinFepSupport && iEdwinFepSupport->State(KNullUid))
       
  7045         STATIC_CAST(CAknEdwinState*, iEdwinFepSupport->State(KNullUid))->SetNumericKeymap(aNumericKeymap);
       
  7046     }
       
  7047 
       
  7048 EXPORT_C void CEikEdwin::SetAknEditorInputMode(TInt aInputMode)
       
  7049     {
       
  7050     if (iEdwinFepSupport && iEdwinFepSupport->State(KNullUid))
       
  7051         STATIC_CAST(CAknEdwinState*, iEdwinFepSupport->State(KNullUid))->SetDefaultInputMode(aInputMode);
       
  7052     }
       
  7053 
       
  7054 EXPORT_C void CEikEdwin::SetAknEditorAllowedInputModes(TInt aInputModes)
       
  7055     {
       
  7056     if (iEdwinFepSupport && iEdwinFepSupport->State(KNullUid))
       
  7057         STATIC_CAST(CAknEdwinState*, iEdwinFepSupport->State(KNullUid))->SetPermittedInputModes(aInputModes);
       
  7058     }
       
  7059 
       
  7060 EXPORT_C void CEikEdwin::SetAknEditorSpecialCharacterTable(TInt aSCTResId)
       
  7061     {
       
  7062     if (iEdwinFepSupport && iEdwinFepSupport->State(KNullUid))
       
  7063         STATIC_CAST(CAknEdwinState*, iEdwinFepSupport->State(KNullUid))->SetSpecialCharacterTableResourceId(aSCTResId);
       
  7064     }
       
  7065 
       
  7066 EXPORT_C void CEikEdwin::SetAknEditorFlags(TInt aFlags)
       
  7067     {
       
  7068     if (iEdwinFepSupport)
       
  7069         {
       
  7070         CAknEdwinState* edwinState = STATIC_CAST(CAknEdwinState*, iEdwinFepSupport->State(KNullUid));
       
  7071         if (edwinState)
       
  7072             {
       
  7073             edwinState->SetFlags(aFlags);
       
  7074             TRAP_IGNORE( edwinState->ReportAknEdStateEventL(MAknEdStateObserver::EAknEdwinStateFlagsUpdate));
       
  7075             }
       
  7076         }
       
  7077     }
       
  7078 
       
  7079 EXPORT_C void CEikEdwin::SetAknEditorCurrentInputMode(TInt aInputMode)
       
  7080     {
       
  7081     if (iEdwinFepSupport)
       
  7082         {
       
  7083         CAknEdwinState* edwinState = STATIC_CAST(CAknEdwinState*, iEdwinFepSupport->State(KNullUid));
       
  7084         if (edwinState)
       
  7085             {
       
  7086             edwinState->SetCurrentInputMode(aInputMode);
       
  7087             TRAP_IGNORE(edwinState->ReportAknEdStateEventL(MAknEdStateObserver::EAknEdwinStateInputModeUpdate));
       
  7088             }
       
  7089         }    
       
  7090     }
       
  7091 
       
  7092 EXPORT_C TInt CEikEdwin::AknEditorCurrentInputMode()
       
  7093     {
       
  7094     TInt inputMode = EAknEditorNullInputMode;
       
  7095     if (iEdwinFepSupport)
       
  7096         {
       
  7097         CAknEdwinState* edwinState = STATIC_CAST(CAknEdwinState*, iEdwinFepSupport->State(KNullUid));
       
  7098         if (edwinState)
       
  7099             {
       
  7100             inputMode = edwinState->CurrentInputMode();
       
  7101             }
       
  7102         }
       
  7103     return inputMode;
       
  7104     }
       
  7105 
       
  7106 EXPORT_C void CEikEdwin::SetAknEditorCurrentCase(TInt aCase)
       
  7107     {
       
  7108     if (iEdwinFepSupport)
       
  7109         {
       
  7110         CAknEdwinState* edwinState = STATIC_CAST(CAknEdwinState*, iEdwinFepSupport->State(KNullUid));
       
  7111         if (edwinState)
       
  7112             {
       
  7113             edwinState->SetCurrentCase(aCase);
       
  7114             TRAP_IGNORE( edwinState->ReportAknEdStateEventL(MAknEdStateObserver::EAknEdwinStateCaseModeUpdate));
       
  7115             }
       
  7116         }
       
  7117     }
       
  7118 
       
  7119 EXPORT_C void CEikEdwin::SetAknEditorLocalLanguage(TLanguage aLanguage)
       
  7120     {
       
  7121     if (iEdwinFepSupport)
       
  7122         {
       
  7123         CAknEdwinState* edwinState = STATIC_CAST(CAknEdwinState*, iEdwinFepSupport->State(KNullUid));
       
  7124         if (edwinState)
       
  7125             {
       
  7126             edwinState->SetLocalLanguage(aLanguage);
       
  7127             TRAP_IGNORE( edwinState->ReportAknEdStateEventL(MAknEdStateObserver::EAknEdwinStateLocalLanguageUpdate));
       
  7128             }
       
  7129         }
       
  7130     }
       
  7131 
       
  7132 EXPORT_C void CEikEdwin::NotifyEditorStateObserverOfStateChangeL()
       
  7133     {
       
  7134     if (iEdwinFepSupport && iEdwinFepSupport->State(KNullUid))
       
  7135         {
       
  7136         STATIC_CAST(CAknEdwinState*, iEdwinFepSupport->State(KNullUid))->ReportAknEdStateEventL(MAknEdStateObserver::EAknEdwinStateEventStateUpdate);
       
  7137         }
       
  7138     }
       
  7139 
       
  7140 EXPORT_C void CEikEdwin::ReadAknResourceL(TResourceReader& aReader)
       
  7141     {
       
  7142     SetAknEditorCase(aReader.ReadInt16());
       
  7143     SetAknEditorPermittedCaseModes(aReader.ReadInt16());
       
  7144     SetAknEditorNumericKeymap(static_cast<TAknEditorNumericKeymap>(aReader.ReadInt16()));
       
  7145     SetAknEditorAllowedInputModes(aReader.ReadInt16());
       
  7146     SetAknEditorInputMode(aReader.ReadInt16());
       
  7147     SetAknEditorSpecialCharacterTable(aReader.ReadInt32());
       
  7148 
       
  7149     SetAknEditorFlags(aReader.ReadInt16() | AknEdwinFlags());
       
  7150     
       
  7151     // added to have a max height
       
  7152     SetMaximumHeightInLines(aReader.ReadInt16());
       
  7153 
       
  7154     aReader.ReadInt16(); // ignore baseline
       
  7155     aReader.ReadInt16(); // spare
       
  7156     
       
  7157     // The following tries to ensure that those unfortunate number editors that
       
  7158     // trust the default resource keymapping value don't break.
       
  7159     if ( iEdwinFepSupport && iEdwinFepSupport->State( KNullUid ) )
       
  7160         {
       
  7161         CAknEdwinState* state = static_cast<CAknEdwinState*>( iEdwinFepSupport->State( KNullUid ) );
       
  7162         
       
  7163         if ( !( state->PermittedInputModes() & EAknEditorTextInputMode ) && 
       
  7164              state->NumericKeymap() == EAknEditorAlphanumericNumberModeKeymap )
       
  7165             {
       
  7166             // The OLD default value of the resource. This is safe, since alphanumeric is
       
  7167             // invalid anyway if the editor doesn't allow text input.
       
  7168             SetAknEditorNumericKeymap( EAknEditorStandardNumberModeKeymap );
       
  7169             }
       
  7170         }
       
  7171     }
       
  7172 
       
  7173 
       
  7174 EXPORT_C void CEikEdwin::SetSuppressBackgroundDrawing( TBool aSuppress )
       
  7175     {
       
  7176     if ( iEdwinExtension )
       
  7177         {
       
  7178         iEdwinExtension->SetSuppressBackgroundDrawing( aSuppress );
       
  7179         }
       
  7180     }
       
  7181     
       
  7182 EXPORT_C TBool CEikEdwin::IsBackgroundDrawingSuppressed() const
       
  7183     {
       
  7184     TBool ret( EFalse );
       
  7185     
       
  7186     if ( iEdwinExtension )
       
  7187         {
       
  7188         ret = iEdwinExtension->IsBackgroundDrawingSuppressed();
       
  7189         }
       
  7190         
       
  7191     return ret;
       
  7192     }
       
  7193     
       
  7194 EXPORT_C void CEikEdwin::SetTextLinesRect( const TRect& aRect )
       
  7195     {
       
  7196     if ( iEdwinExtension )
       
  7197         {
       
  7198         iEdwinExtension->iTextLinesRect = aRect;
       
  7199         }
       
  7200     }
       
  7201 
       
  7202 EXPORT_C void CEikEdwin::SetScrollRect( const TRect & aRect )
       
  7203     {
       
  7204     if ( iEdwinExtension )
       
  7205         {
       
  7206         iEdwinExtension->iScrollRect = aRect;
       
  7207         }
       
  7208     }
       
  7209     
       
  7210 EXPORT_C TRect CEikEdwin::GetTextLinesRect() const
       
  7211     {
       
  7212     if ( iEdwinExtension )
       
  7213         {
       
  7214         return iEdwinExtension->iTextLinesRect;
       
  7215         }
       
  7216     else
       
  7217         {
       
  7218         return TRect(); // Should initialize to empty
       
  7219         }
       
  7220     }
       
  7221 
       
  7222 EXPORT_C TBool CEikEdwin::CcpuIsFocused() const
       
  7223     {
       
  7224     return IsFocused();
       
  7225     }
       
  7226 
       
  7227 EXPORT_C TBool CEikEdwin::CcpuCanCut() const
       
  7228     {
       
  7229     CAknEdwinState* state( EditorState() );
       
  7230     if( state && state->Flags() & EAknEditorFlagFindPane )
       
  7231     	{
       
  7232     	return EFalse;
       
  7233     	}
       
  7234     return iCcpuSupport && !IsReadOnly() && SelectionLength() != 0;
       
  7235     }
       
  7236 
       
  7237 EXPORT_C void CEikEdwin::CcpuCutL()
       
  7238     {
       
  7239     ClipboardL(ECut);
       
  7240     }
       
  7241 
       
  7242 EXPORT_C TBool CEikEdwin::CcpuCanCopy() const
       
  7243     {
       
  7244     CAknEdwinState* state( EditorState() );
       
  7245     if( state && state->Flags() & EAknEditorFlagFindPane )
       
  7246     	{
       
  7247     	return EFalse;
       
  7248     	}
       
  7249     return iCcpuSupport && SelectionLength() != 0;
       
  7250     }
       
  7251 
       
  7252 EXPORT_C void CEikEdwin::CcpuCopyL()
       
  7253     {
       
  7254     ClipboardL(ECopy);
       
  7255     }
       
  7256 
       
  7257 EXPORT_C TBool CEikEdwin::CcpuCanPaste() const
       
  7258     {
       
  7259     CAknEdwinState* state( EditorState() );
       
  7260     if( state && state->Flags() & EAknEditorFlagFindPane )
       
  7261     	{
       
  7262     	return EFalse;
       
  7263     	}
       
  7264     if (!iCcpuSupport || IsReadOnly())
       
  7265         return EFalse;
       
  7266 
       
  7267     TRAPD(err, DoCcpuCanPasteL());
       
  7268     return err == KErrNone;
       
  7269     }
       
  7270 
       
  7271 EXPORT_C void CEikEdwin::CcpuPasteL()
       
  7272     {
       
  7273     ClipboardL(EPaste);
       
  7274     }
       
  7275 
       
  7276 EXPORT_C TBool CEikEdwin::CcpuCanUndo() const
       
  7277     {
       
  7278     return CanUndo();
       
  7279     }
       
  7280 
       
  7281 EXPORT_C void CEikEdwin::CcpuUndoL()
       
  7282     {
       
  7283     UndoL();
       
  7284     }
       
  7285 
       
  7286 void CEikEdwin::DoCcpuCanPasteL() const
       
  7287     {
       
  7288     if (!SelectionLength() && (iTextLimit && (TextLength() >= iTextLimit)))
       
  7289         User::Leave(KErrNotFound);
       
  7290 
       
  7291     CClipboard* cb=CClipboard::NewForReadingL(iCoeEnv->FsSession());
       
  7292     CleanupStack::PushL(cb);
       
  7293 
       
  7294     TBool richText = ETrue;
       
  7295     TStreamId streamId=cb->StreamDictionary().At(KClipboardUidTypeRichText);
       
  7296     if (streamId==KNullStreamId)
       
  7297         {
       
  7298         streamId=cb->StreamDictionary().At(KClipboardUidTypePlainText);
       
  7299         richText = EFalse;
       
  7300         }
       
  7301     if (streamId==KNullStreamId)
       
  7302         User::Leave(KErrNotFound);
       
  7303 
       
  7304     HBufC* allowedChars = GetAllowedCharsLC();
       
  7305     User::LeaveIfError(CheckAllowedCharsL(*allowedChars, *cb, richText));
       
  7306 
       
  7307     CleanupStack::PopAndDestroy(2); // allowedChars, cb
       
  7308     }
       
  7309 
       
  7310 HBufC* CEikEdwin::GetAllowedCharsLC() const
       
  7311     {
       
  7312     if (iEdwinFepSupport && iEdwinFepSupport->State(KNullUid))
       
  7313         {
       
  7314         CAknEdwinState* state = STATIC_CAST(CAknEdwinState*, iEdwinFepSupport->State(KNullUid));
       
  7315         TInt permittedModes = state->PermittedInputModes();
       
  7316 
       
  7317         if ( permittedModes & 
       
  7318             ~(EAknEditorNumericInputMode | EAknEditorFullWidthNumericInputMode))
       
  7319             {
       
  7320             if ( OnlyASCIIChars() )
       
  7321                 {
       
  7322                 // While the specification for what characters actually are
       
  7323                 // allowed in "latin only" editor is underway, we'll do this. Once
       
  7324                 // the spec is set, a more efficient solution with constant
       
  7325                 // unicode ranges is in order..
       
  7326                 const TInt asciiLimit( 256 );
       
  7327                 HBufC* buf = HBufC::NewLC( asciiLimit );
       
  7328                 TPtr ptr( buf->Des() );
       
  7329                 
       
  7330                 for ( TInt i = 1; i < asciiLimit; ++i )
       
  7331                     {
       
  7332                     ptr.Append( TChar( i ) );
       
  7333                     }
       
  7334                     
       
  7335                 return buf;
       
  7336                 }
       
  7337             else
       
  7338                 {
       
  7339                 return KNullDesC().AllocLC();
       
  7340                 }
       
  7341             }
       
  7342 
       
  7343         // EAknEditorNumericInputMode and EAknEditorFullWidthNumericInputMode are only left.
       
  7344         TInt resId = 0;
       
  7345         switch (state->NumericKeymap())
       
  7346             {
       
  7347             case EAknEditorStandardNumberModeKeymap:
       
  7348                 resId = R_EIK_ALLOWED_STANDARDNUMBERMODEKEYMAP;
       
  7349                 break;
       
  7350             case EAknEditorPlainNumberModeKeymap:
       
  7351                 resId = R_EIK_ALLOWED_PLAINNUMBERMODEKEYMAP;
       
  7352                 break;
       
  7353             case EAknEditorCalculatorNumberModeKeymap:
       
  7354                 resId = R_EIK_ALLOWED_CALCULATORNUMBERMODEKEYMAP;
       
  7355                 break;
       
  7356             case EAknEditorConverterNumberModeKeymap:
       
  7357                 resId = R_EIK_ALLOWED_CONVERTERNUMBERMODEKEYMAP;
       
  7358                 break;
       
  7359             case EAknEditorToFieldNumberModeKeymap:
       
  7360                 resId = R_EIK_ALLOWED_TOFIELDNUMBERMODEKEYMAP;
       
  7361                 break;
       
  7362             case EAknEditorFixedDiallingNumberModeKeymap:
       
  7363             default:
       
  7364                 resId = R_EIK_ALLOWED_FIXEDDIALLINGNUMBERMODEKEYMAP;
       
  7365                 break;
       
  7366             }
       
  7367 
       
  7368         return iEikonEnv->AllocReadResourceLC(resId);
       
  7369         }
       
  7370     else
       
  7371         {
       
  7372         User::Leave(KErrNoMemory);
       
  7373         return NULL;
       
  7374         }
       
  7375     }
       
  7376 
       
  7377 TInt CEikEdwin::CheckAllowedCharsL(const TDesC& aChars, CClipboard& aClipboard, TBool aRichText) const
       
  7378     {
       
  7379     TBool pictographsEnabled = EFalse;
       
  7380     TBool fullWidthCharactersAllowed = ETrue;
       
  7381 
       
  7382     CAknEdwinState* edwinState = NULL;
       
  7383     if (iEdwinFepSupport)
       
  7384         {
       
  7385         edwinState = STATIC_CAST(CAknEdwinState*, iEdwinFepSupport->State(KNullUid));
       
  7386         }
       
  7387 
       
  7388     CAknPictographInterface* pictographInterface = iEdwinExtension->PictographInterface();
       
  7389     if (edwinState)
       
  7390         {
       
  7391         if (FeatureManager::FeatureSupported(KFeatureIdJapanese))
       
  7392             {
       
  7393             fullWidthCharactersAllowed = edwinState->PermittedInputModes() & (
       
  7394                 EAknEditorFullWidthTextInputMode |
       
  7395                 EAknEditorFullWidthNumericInputMode |
       
  7396                 EAknEditorFullWidthKatakanaInputMode |
       
  7397                 EAknEditorHiraganaKanjiInputMode |
       
  7398                 EAknEditorHiraganaInputMode | 
       
  7399                 EAknEditorTextInputMode
       
  7400                 );
       
  7401             }
       
  7402         if (pictographInterface)
       
  7403             {
       
  7404             pictographsEnabled = edwinState->Flags() & EAknEditorFlagEnablePictographInput;
       
  7405             }
       
  7406         }
       
  7407     
       
  7408     if (aChars.Length() == 0 && (pictographsEnabled || !pictographInterface) && fullWidthCharactersAllowed)
       
  7409         {
       
  7410         // All characters are allowed to paste.
       
  7411         return KErrNone;
       
  7412         }
       
  7413 
       
  7414     CPlainText* txtStore;
       
  7415     CRichText* richText = STATIC_CAST(CRichText*, Text());
       
  7416     if (aRichText && richText)
       
  7417         {
       
  7418         const CParaFormatLayer* paraFormatLayer=richText->GlobalParaFormatLayer();
       
  7419         const CCharFormatLayer* charFormatLayer=richText->GlobalCharFormatLayer();
       
  7420         txtStore = CRichText::NewL(paraFormatLayer, charFormatLayer);
       
  7421         }
       
  7422     else
       
  7423         {
       
  7424         txtStore = CPlainText::NewL();
       
  7425         }
       
  7426     CleanupStack::PushL(txtStore);
       
  7427     TInt bufferLength = txtStore->PasteFromStoreL(aClipboard.Store(), aClipboard.StreamDictionary(), 0);
       
  7428     TInt textLength = 0;
       
  7429     TInt textIndex = 0;
       
  7430     TBool finished = EFalse;
       
  7431     TInt err = KErrNone;
       
  7432     do 
       
  7433         {
       
  7434         // EAknEditorNumericInputMode and EAknEditorFullWidthNumericInputMode are the only ones
       
  7435         // that get this far, so we convert the input to latin if non-ascii chars
       
  7436         // are allowed in the editor. This can leave if the text in the clipboard is huge.
       
  7437         HBufC* txtStoreBuf = txtStore->Read( textIndex ).AllocL();
       
  7438         CleanupStack::PushL( txtStoreBuf ); // in case something leavable is added later
       
  7439         TPtr text = txtStoreBuf->Des();
       
  7440         textLength = text.Length();
       
  7441         
       
  7442         if (aChars.Length() == 0)
       
  7443             {
       
  7444             if (pictographInterface && !pictographsEnabled &&
       
  7445                 pictographInterface->Interface()->ContainsPictographs(text))
       
  7446                 {
       
  7447                 // The clipboard contains pictographs but those are not allowed by the editor.
       
  7448                 finished = ETrue;
       
  7449                 err = KErrNotFound;
       
  7450                 }
       
  7451             if ( err == KErrNone && !fullWidthCharactersAllowed )
       
  7452                 {
       
  7453                 // Go through clipboard context and check if full-width characters exist.
       
  7454                 for ( TInt ii = 0; ii < textLength; ii++ )
       
  7455                     {
       
  7456                     if (JPLangUtil::IsFullWidth(text[ii]) && text[ii] != 0x2029)
       
  7457                         {
       
  7458                         // The clipboard contains full-width character(s) but those are not allowed by the editor.
       
  7459                         err = KErrNotFound;
       
  7460                         finished = ETrue;
       
  7461                         break;
       
  7462                         }
       
  7463                     }
       
  7464                 }
       
  7465             }
       
  7466         else
       
  7467             {
       
  7468             if ( !OnlyASCIIChars() )
       
  7469                 {
       
  7470                 AknTextUtils::ConvertDigitsTo( text, EDigitTypeWestern );
       
  7471                 }
       
  7472                 
       
  7473             // Go through all allowed characters and check if the clipboard contains unallowed characters.
       
  7474             for (TInt ii=0; ii < textLength; ii++)
       
  7475                 {
       
  7476                 TChar ch = text[ii];
       
  7477                 if (ch.IsPrint() && aChars.Locate(ch) == KErrNotFound)
       
  7478                     {
       
  7479                     err = KErrNotFound;
       
  7480                     finished = ETrue;
       
  7481                     break;
       
  7482                     }
       
  7483                 }
       
  7484             }
       
  7485         CleanupStack::PopAndDestroy(); // txtStoreBuf
       
  7486         textIndex += textLength;
       
  7487         }
       
  7488     while (!finished && textIndex < bufferLength);
       
  7489 
       
  7490     CleanupStack::PopAndDestroy(txtStore);    
       
  7491     return err;
       
  7492     }
       
  7493 
       
  7494 EXPORT_C void CEikEdwin::EnableCcpuSupportL(TBool aSupport)
       
  7495     {
       
  7496     CAknCcpuSupport* ccpu = NULL;
       
  7497     CAknEdwinState* edwinState = EditorState(); 
       
  7498     
       
  7499     if (aSupport)
       
  7500         {
       
  7501         ccpu = new(ELeave) CAknCcpuSupport(this);
       
  7502         ccpu->SetMopParent(this);
       
  7503         CleanupStack::PushL(ccpu);
       
  7504         ccpu->ConstructL();
       
  7505         CleanupStack::Pop(ccpu);
       
  7506         if (edwinState)
       
  7507             {
       
  7508             edwinState->SetCcpuState(this);                 
       
  7509             }       
       
  7510         }
       
  7511     else
       
  7512         {       
       
  7513         if (edwinState)
       
  7514             {
       
  7515             edwinState->SetCcpuState(NULL);                 
       
  7516             }
       
  7517         }           
       
  7518             
       
  7519     delete iCcpuSupport;
       
  7520     iCcpuSupport = ccpu;
       
  7521     } 
       
  7522 
       
  7523 void CEikEdwin::DoReportEventL(MCoeControlObserver::TCoeEvent aEvent)
       
  7524     {
       
  7525     if (iCcpuSupport && aEvent == MCoeControlObserver::EEventStateChanged)
       
  7526         iCcpuSupport->HandleSelectionChangeL();
       
  7527     ReportEventL(aEvent);
       
  7528     }
       
  7529 
       
  7530 void CEikEdwin::SetKeyboardRepeatRate(TTimeIntervalMicroSeconds32 aKeyRepeatRate) const
       
  7531     {
       
  7532     // test for fixed timeouts (do not require capabilities)
       
  7533     if (aKeyRepeatRate == TTimeIntervalMicroSeconds32(KAknStandardKeyboardRepeatRate))
       
  7534         {
       
  7535         CAknSgcClient::SetKeyboardRepeatRate(EAknApplicationDefaulRepeatRate);
       
  7536         return;
       
  7537         }
       
  7538     else if (aKeyRepeatRate == TTimeIntervalMicroSeconds32(KAknEditorKeyboardRepeatRate))
       
  7539         {
       
  7540         CAknSgcClient::SetKeyboardRepeatRate(EAknEditorDefaulRepeatRate);
       
  7541         return;
       
  7542         }
       
  7543 
       
  7544     // fall through, this requires capability WriteDeviceData
       
  7545     TTimeIntervalMicroSeconds32 currentRepeatDelay;
       
  7546     TTimeIntervalMicroSeconds32 currentRepeatRate;
       
  7547     iCoeEnv->WsSession().GetKeyboardRepeatRate(currentRepeatDelay, currentRepeatRate);
       
  7548     if (aKeyRepeatRate!=currentRepeatRate)
       
  7549         iCoeEnv->WsSession().SetKeyboardRepeatRate(currentRepeatDelay, aKeyRepeatRate);
       
  7550     }
       
  7551 
       
  7552 
       
  7553 EXPORT_C void CEikEdwin::SetMaximumHeightInLines(TInt aLines)
       
  7554     {
       
  7555     iMaximumHeightInLines=aLines; 
       
  7556     };
       
  7557 
       
  7558 EXPORT_C TInt CEikEdwin::MaximumHeightInLines() const
       
  7559     {
       
  7560     return iMaximumHeightInLines;
       
  7561     };
       
  7562 
       
  7563 EXPORT_C void CEikEdwin::AddFlagToUserFlags(TUint32 aFlag)
       
  7564     {
       
  7565     iEdwinUserFlags|=aFlag;
       
  7566     SetVKBStatus(); 
       
  7567     if ( aFlag & EAvkonEnableSmileySupport )
       
  7568         {
       
  7569         EnableSmileySupportL( ETrue );
       
  7570         }
       
  7571     }
       
  7572 
       
  7573 EXPORT_C void CEikEdwin::RemoveFlagFromUserFlags(TUint32 aFlag)
       
  7574     {
       
  7575     iEdwinUserFlags&=~aFlag;
       
  7576     SetVKBStatus(); 
       
  7577     if ( aFlag & EAvkonEnableSmileySupport )
       
  7578         {    
       
  7579         EnableSmileySupportL( EFalse );
       
  7580         }
       
  7581     }
       
  7582 
       
  7583 EXPORT_C TUint32 CEikEdwin::UserFlags() const
       
  7584     {
       
  7585     return iEdwinUserFlags;
       
  7586     }
       
  7587 
       
  7588 EXPORT_C TTypeUid::Ptr CEikEdwin::MopSupplyObject(TTypeUid aId)
       
  7589     {
       
  7590     TRAPD(err, CheckEdwinExtensionL());
       
  7591     if (err==KErrNone)
       
  7592         {
       
  7593         if (iEdwinExtension->FormAccessor() && aId.iUid == MAknFormAccessor::ETypeId)
       
  7594             {
       
  7595             return aId.MakePtr(iEdwinExtension->FormAccessor());
       
  7596             }
       
  7597         else if ( aId.iUid == CAknExtendedInputCapabilities::ETypeId )
       
  7598             {
       
  7599             return aId.MakePtr( iEdwinExtension->iExtendedInputCapabilities );
       
  7600             }
       
  7601         }
       
  7602     return TTypeUid::Null();
       
  7603     }
       
  7604 
       
  7605 EXPORT_C void CEikEdwin::SetAlignment(TInt aAlignment)
       
  7606     {
       
  7607     if (iEdwinExtension)
       
  7608         iEdwinExtension->SetAlignment(aAlignment);
       
  7609     DoAlignment();
       
  7610     }
       
  7611 
       
  7612 void CEikEdwin::NewParagraphL()
       
  7613     {
       
  7614     CheckEdwinExtensionL(); // checks if iEdwinExtension is NULL and constucts it if necessary
       
  7615     DoAlignment();
       
  7616     }
       
  7617 
       
  7618 TInt CEikEdwin::CurrentAlignment() const
       
  7619     {
       
  7620     if (iEdwinExtension)
       
  7621         return iEdwinExtension->CurrentAlignment();
       
  7622     return EAknEditorAlignBidi;
       
  7623     }
       
  7624 
       
  7625 void CEikEdwin::DoAlignment()
       
  7626     {
       
  7627     CParaFormat paraFormat;
       
  7628     TParaFormatMask paraFormatMask;
       
  7629 
       
  7630     // Get para format information from existing para format - else it gets overwritten.
       
  7631     if (iParaFormatLayer)
       
  7632         {
       
  7633         TRAPD( err,  iParaFormatLayer->SenseL( &paraFormat, paraFormatMask ) ) ;
       
  7634         if (err)
       
  7635             {
       
  7636 #ifdef _DEBUG
       
  7637             RDebug::Print(_L("CEikEdwin: Error in sensing format\n"));
       
  7638 #endif
       
  7639             return;
       
  7640             }
       
  7641         }
       
  7642 
       
  7643     CAknSettingCache& cache = CAknEnv::Static()->SettingCache();
       
  7644     paraFormat.iLanguage = ELangEnglish;
       
  7645     TLanguage currentLanguage = cache.InputLanguage();
       
  7646 
       
  7647     switch (CurrentAlignment())
       
  7648         {
       
  7649         case EAknEditorAlignLeft: paraFormat.iHorizontalAlignment = CParaFormat::EAbsoluteLeftAlign; break;
       
  7650         case EAknEditorAlignRight: paraFormat.iHorizontalAlignment = CParaFormat::EAbsoluteRightAlign; break;
       
  7651         case EAknEditorAlignCenter: paraFormat.iHorizontalAlignment = CParaFormat::ECenterAlign; break;
       
  7652         case EAknEditorAlignBidi:
       
  7653             {
       
  7654             paraFormat.iHorizontalAlignment = CParaFormat::ELeftAlign;
       
  7655             paraFormat.iLanguage = currentLanguage;
       
  7656             break;
       
  7657             }
       
  7658         default: paraFormat.iHorizontalAlignment = CParaFormat::ELeftAlign; break;
       
  7659         }
       
  7660     paraFormatMask.SetAttrib(EAttParaLanguage);
       
  7661     paraFormatMask.SetAttrib(EAttAlignment);
       
  7662 
       
  7663     CParaFormatLayer* paraFormatLayer = NULL;
       
  7664     TBool alignNull = EFalse;
       
  7665     TRAPD(error, 
       
  7666         {
       
  7667         paraFormatLayer = CParaFormatLayer::NewL(&paraFormat,paraFormatMask);
       
  7668         SetParaFormatLayer(paraFormatLayer);
       
  7669         if (iTextView)
       
  7670             {
       
  7671             NotifyNewFormatL();
       
  7672             }
       
  7673         else
       
  7674             {
       
  7675             alignNull = ETrue;
       
  7676             }
       
  7677         });
       
  7678     
       
  7679         if ( alignNull )
       
  7680             {
       
  7681 #ifdef _DEBUG
       
  7682             RDebug::Print(_L("CEikEdwin: Alignment found null CEikEdwin::iTextView\n"));
       
  7683 #endif
       
  7684             }
       
  7685 
       
  7686     if (error)
       
  7687         {
       
  7688 #ifdef _DEBUG
       
  7689         RDebug::Print(_L("Error in applying formatting\n"));
       
  7690 #endif
       
  7691         }
       
  7692     }
       
  7693 
       
  7694 CAknEdwinDrawingModifier* CEikEdwin::AknEdwinDrawingModifier()
       
  7695     {
       
  7696     CAknEdwinDrawingModifier* modifier = NULL;  
       
  7697     MopGetObject( modifier );
       
  7698     return modifier;
       
  7699     }
       
  7700 
       
  7701 TBool CEikEdwin::EditorSupportsNeutralProtection() const
       
  7702     {
       
  7703     TBool ret = ETrue;
       
  7704     if (!InputCapabilities().FepAwareTextEditor())
       
  7705         ret = EFalse;
       
  7706 
       
  7707     else if (InputCapabilities().SupportsSecretText())
       
  7708         ret = EFalse;
       
  7709 
       
  7710     else if ( AknEdwinFlags() & EAknEditorFlagLatinInputModesOnly )
       
  7711         ret = EFalse;
       
  7712 
       
  7713     else if (iEdwinFepSupport && iEdwinFepSupport->State(KNullUid))
       
  7714         {
       
  7715         if ( static_cast<CAknEdwinState*>(iEdwinFepSupport->State(KNullUid))->PermittedInputModes() == EAknEditorNumericInputMode)
       
  7716             ret = EFalse;
       
  7717         }
       
  7718     else if ( !IsValidChar( EEikEdwinLeftToRightMark ) )
       
  7719         ret = EFalse;
       
  7720 
       
  7721     return ret;
       
  7722     }
       
  7723 
       
  7724 
       
  7725 TBool CEikEdwin::NeedsNeutralProtection( TInt aPosOfLowEndOfDelete, TInt aLengthToDelete, TDes& aNewText, TBool& aForwardProtection )
       
  7726     {
       
  7727     TBool protect(ETrue);
       
  7728     if (!EditorSupportsNeutralProtection() || ( aLengthToDelete == 0) )
       
  7729         protect = EFalse;
       
  7730 
       
  7731     // Perform no neutral protection if the beginning of the text is deleted.
       
  7732     // Note that there MAY be protection occuring if the delete is from the end so there is 
       
  7733     // no corresponding text on DocLength
       
  7734     if ( aPosOfLowEndOfDelete <= 0 )
       
  7735         protect = EFalse;
       
  7736 
       
  7737     TInt posOfNextCharHigherThanDelete = aPosOfLowEndOfDelete + aLengthToDelete;
       
  7738 
       
  7739     TInt docLen = Text()->DocumentLength();
       
  7740 
       
  7741     // Length to delete should not exceed the document length
       
  7742     if ( posOfNextCharHigherThanDelete > docLen)
       
  7743         protect = EFalse;
       
  7744         
       
  7745     TBool adjacentPrecedingIsNeutral(EFalse);
       
  7746     TBool adjacentTrailingIsNeutral(EFalse);
       
  7747 
       
  7748     if ( protect )
       
  7749         {
       
  7750         adjacentPrecedingIsNeutral = CharIsNeutral( aPosOfLowEndOfDelete - 1);
       
  7751         if ( posOfNextCharHigherThanDelete < Text()->DocumentLength() )
       
  7752             adjacentTrailingIsNeutral = CharIsNeutral( posOfNextCharHigherThanDelete);
       
  7753 
       
  7754         if ( !adjacentPrecedingIsNeutral && !adjacentTrailingIsNeutral )
       
  7755             protect = EFalse;
       
  7756         }
       
  7757 
       
  7758     // Inits actually correspond to LTR, but they are only used if the bools indicating 
       
  7759     // strong directionality found get set
       
  7760     TBool directionPrecedingDeleteIsRTL(EFalse);
       
  7761     TBool directionTrailingDeleteIsRTL(EFalse); 
       
  7762     if ( protect )
       
  7763         {
       
  7764         TBool strongPreceding = GetExposedDirectionOfText( aPosOfLowEndOfDelete - 1, EFalse, directionPrecedingDeleteIsRTL );
       
  7765         TBool strongTrailing = GetExposedDirectionOfText( posOfNextCharHigherThanDelete, ETrue, directionTrailingDeleteIsRTL );
       
  7766         if (!strongTrailing)
       
  7767             {
       
  7768             TFormCursorModifierUtils cursorModifierUtils( *TextView(), *TextLayout() );
       
  7769             TTmDocPosSpec pos = cursorModifierUtils.DocPos();
       
  7770             TBool isRTLPara = cursorModifierUtils.IsRightToLeftParagraph(pos);
       
  7771             directionTrailingDeleteIsRTL = isRTLPara;
       
  7772             strongTrailing = ETrue;
       
  7773             }
       
  7774         if ( !strongPreceding || !strongTrailing)
       
  7775             protect = EFalse;
       
  7776         else if ( COMPARE_BOOLS( directionPrecedingDeleteIsRTL, directionTrailingDeleteIsRTL ) )
       
  7777             protect = EFalse;
       
  7778         }
       
  7779 
       
  7780     // Obtain ptr to text being deleted
       
  7781     TPtrC deletedText = Text()->Read( aPosOfLowEndOfDelete, aLengthToDelete) ;
       
  7782 
       
  7783     if ( protect )
       
  7784         {
       
  7785         protect = EFalse;
       
  7786         TBool deletedWasRTL;
       
  7787 
       
  7788         // Check for and do reverse protection
       
  7789         if ( adjacentPrecedingIsNeutral ) 
       
  7790             {
       
  7791             TBool deletedTextIsStrong = GetExposedDirectionOfTextInDescriptor( deletedText, ETrue, deletedWasRTL ); // search forward into deleted stuff
       
  7792             if ( deletedTextIsStrong && (directionPrecedingDeleteIsRTL == deletedWasRTL))
       
  7793                 {
       
  7794                 protect = ETrue;
       
  7795                 aForwardProtection = EFalse;
       
  7796                 if ( deletedWasRTL )
       
  7797                     aNewText.Append( KEikEdwinRightToLeftMark );
       
  7798                 else
       
  7799                     aNewText.Append( KEikEdwinLeftToRightMark );
       
  7800                 }
       
  7801             }
       
  7802 
       
  7803         // Check for and do forward protection
       
  7804         // Note it is possible to have both forward and reverse redecoration.
       
  7805         if ( adjacentTrailingIsNeutral )
       
  7806             {
       
  7807             TBool deletedTextIsStrong = GetExposedDirectionOfTextInDescriptor( deletedText, EFalse, deletedWasRTL ); // search backward in deleted stuff
       
  7808             if (deletedTextIsStrong && (directionTrailingDeleteIsRTL == deletedWasRTL) )
       
  7809                 {
       
  7810                 protect = ETrue;
       
  7811                 aForwardProtection = ETrue;
       
  7812                 if ( deletedWasRTL )
       
  7813                     aNewText.Append( KEikEdwinRightToLeftMark );
       
  7814                 else
       
  7815                     aNewText.Append( KEikEdwinLeftToRightMark );
       
  7816                 }
       
  7817             }
       
  7818         }
       
  7819 
       
  7820     return protect;
       
  7821     }
       
  7822 
       
  7823 TBool CEikEdwin::GetStrongDirectionality(TChar aChar, TBool& aRightToLeft ) const
       
  7824     {
       
  7825     TBool hasStrongDirectionality(EFalse);
       
  7826     TChar::TBdCategory bdcat = aChar.GetBdCategory();
       
  7827     
       
  7828     if (    (bdcat == TChar::ERightToLeft) || 
       
  7829             (bdcat == TChar::ERightToLeftArabic)
       
  7830        )
       
  7831         {
       
  7832         hasStrongDirectionality = ETrue;
       
  7833         aRightToLeft = ETrue;
       
  7834         }
       
  7835     else if (bdcat == TChar::ELeftToRight) 
       
  7836         {
       
  7837         hasStrongDirectionality = ETrue;
       
  7838         aRightToLeft = EFalse;
       
  7839         }
       
  7840 
       
  7841     return hasStrongDirectionality;
       
  7842     }
       
  7843 
       
  7844 TBool CEikEdwin::CharIsNeutral( TInt aPos ) const
       
  7845     {
       
  7846     TChar ch = Text()->Read( aPos, 1 )[0];
       
  7847     TChar::TBdCategory bdcat = ch.GetBdCategory();
       
  7848     return (    bdcat == TChar::EWhitespace || 
       
  7849                 bdcat == TChar::EOtherNeutral );
       
  7850     }
       
  7851 
       
  7852 TBool CEikEdwin::GetExposedDirectionOfTextInDescriptor( const TDesC& aText, TBool aForward, TBool& aIsRightToLeft ) const
       
  7853     {
       
  7854     TBool hasStrongCharacter(EFalse);
       
  7855 
       
  7856     TInt length = aText.Length();
       
  7857 
       
  7858     // bail out if there is zero length, 'cos it would add a lot of tests in the rest of the source
       
  7859     if ( length <= 0 )
       
  7860         return EFalse;
       
  7861 
       
  7862     TInt start = 0;
       
  7863     TInt increment = 1;
       
  7864     TInt limit = length;
       
  7865 
       
  7866     if ( !aForward )
       
  7867         {
       
  7868         start = length - 1;
       
  7869         increment = -1;
       
  7870         limit = -1; // Limit is one beyond that last executed in the loop
       
  7871         }
       
  7872     
       
  7873     for ( TInt index = start; index != limit; index += increment )
       
  7874         {
       
  7875         TBool isRTL;
       
  7876         if ( GetStrongDirectionality( aText[ index ], isRTL ) )
       
  7877             {
       
  7878             hasStrongCharacter = ETrue;
       
  7879             aIsRightToLeft = isRTL;
       
  7880             break;
       
  7881             }
       
  7882         }
       
  7883 
       
  7884     return hasStrongCharacter;    
       
  7885     }
       
  7886 
       
  7887 /** 
       
  7888 * Start at pos and scan for strong characters.
       
  7889 * Stop at paragraph boundaries. 
       
  7890 * Maximum of KMaxSearch of about 1 line...
       
  7891 */
       
  7892 TBool CEikEdwin::GetExposedDirectionOfText( TInt aPos, TBool aForward, TBool& aIsRightToLeft ) const
       
  7893     {
       
  7894     TBool hasStrongCharacter(EFalse);
       
  7895 
       
  7896     // Access the plain text from the editor, getting a little bit at a time.
       
  7897     TBool done(EFalse);
       
  7898     TBool dataLeft(ETrue);
       
  7899 
       
  7900     TInt docLen = Text()->DocumentLength();
       
  7901     if ( aPos < 0 || aPos >= docLen)
       
  7902         dataLeft = EFalse;
       
  7903 
       
  7904     // These are the inclusive start and end positions of the chunk of text to look at in the 
       
  7905     // loop.
       
  7906     TInt start = aPos;
       
  7907     TInt end = aPos;
       
  7908     TInt len;
       
  7909 
       
  7910     while ( !done && dataLeft )
       
  7911         {
       
  7912         // Get new end/start position - constrained
       
  7913         if ( aForward )
       
  7914             {          
       
  7915             end = start + KLengthAtATime - 1;
       
  7916             if ( end >= docLen ) 
       
  7917                 end = docLen - 1;
       
  7918             }
       
  7919         else 
       
  7920             {
       
  7921             start = end - KLengthAtATime + 1;
       
  7922             if ( start < 0 )
       
  7923                 start = 0;
       
  7924             }
       
  7925 
       
  7926         len = end - start + 1;
       
  7927 
       
  7928         if ( len > 0 )
       
  7929             {
       
  7930             TPtrC ptr = Text()->Read( start, len );
       
  7931             TBool isRightToLeft;
       
  7932             if ( GetExposedDirectionOfTextInDescriptor( ptr, aForward, isRightToLeft ) )
       
  7933                 {
       
  7934                 done = ETrue;
       
  7935                 hasStrongCharacter = ETrue;
       
  7936                 aIsRightToLeft = isRightToLeft;
       
  7937                 }
       
  7938             else
       
  7939                 {
       
  7940                 // Get new start/end position - constrained
       
  7941                 if (aForward)
       
  7942                     {
       
  7943                     start = end + 1;
       
  7944                     if ( start >= docLen )
       
  7945                         dataLeft = EFalse;
       
  7946                     }
       
  7947                 else
       
  7948                     {
       
  7949                     end = start - 1;
       
  7950                     if ( end <= -1 ) 
       
  7951                         dataLeft = EFalse;
       
  7952                     }
       
  7953                 }
       
  7954             }
       
  7955         else
       
  7956             dataLeft = EFalse;          
       
  7957 
       
  7958         }
       
  7959     return hasStrongCharacter;    
       
  7960     }
       
  7961 
       
  7962 EXPORT_C void CEikEdwin::SetPictographAnimationCallBack( TCallBack& aCallBack )
       
  7963     {
       
  7964     iEdwinExtension->SetPictoCallBack( aCallBack );
       
  7965     }
       
  7966 
       
  7967 const TCallBack& CEikEdwin::PictographAnimationCallBack() const
       
  7968     {
       
  7969     return iEdwinExtension->PictoCallBack();
       
  7970     }
       
  7971 
       
  7972 TBool CEikEdwin::IsPurePhoneNumberEditor() const
       
  7973     {
       
  7974     TBool retVal(EFalse);
       
  7975 
       
  7976     if (iEdwinFepSupport && iEdwinFepSupport->State(KNullUid))
       
  7977         {
       
  7978         CAknEdwinState* state = STATIC_CAST(CAknEdwinState*, iEdwinFepSupport->State(KNullUid) );
       
  7979         if ( state->PermittedInputModes() == EAknEditorNumericInputMode && 
       
  7980             ( state->NumericKeymap() == EAknEditorStandardNumberModeKeymap
       
  7981             || state->NumericKeymap() == EAknEditorFixedDiallingNumberModeKeymap
       
  7982             || state->NumericKeymap() == EAknEditorSATHiddenNumberModeKeymap
       
  7983             || state->NumericKeymap() == EAknEditorSATNumberModeKeymap )
       
  7984             )
       
  7985                 retVal = ETrue;
       
  7986         }
       
  7987     return retVal;
       
  7988     }
       
  7989     
       
  7990 EXPORT_C void CEikEdwin::SetTextSkinColorIdL(TInt aAknSkinIdForTextColor)
       
  7991     {
       
  7992     CheckEdwinExtensionL();
       
  7993     iEdwinExtension->iSkinIdForText = aAknSkinIdForTextColor;
       
  7994     }
       
  7995 
       
  7996 EXPORT_C void CEikEdwin::SetHighlightStyleL(TAknsHighlightStyle aStyle)
       
  7997     {
       
  7998     CheckEdwinExtensionL();
       
  7999     iEdwinExtension->iSkinHighlightStyle = aStyle;    
       
  8000     }
       
  8001 
       
  8002     // for custom drawer, not exported
       
  8003 TInt CEikEdwin::SkinColorId() const
       
  8004     {
       
  8005     if (iEdwinExtension)
       
  8006         {
       
  8007         return iEdwinExtension->iSkinIdForText;
       
  8008         }
       
  8009     return KErrNotFound;
       
  8010     }
       
  8011 
       
  8012 TAknsHighlightStyle CEikEdwin::HighlightStyle() const
       
  8013     {
       
  8014     if (iEdwinExtension)
       
  8015         {
       
  8016         return iEdwinExtension->iSkinHighlightStyle;
       
  8017         }
       
  8018     return EEikEdwinHighlightNormal;    
       
  8019     }
       
  8020 
       
  8021 TRgb CEikEdwin::EditorBackgroundColor(TRgb& aConditionalColor) const
       
  8022     {
       
  8023     TRgb color;
       
  8024     if (iEdwinExtension && iEdwinExtension->iEditorBackgroundColor.IsSet() )
       
  8025         {
       
  8026         aConditionalColor = iEdwinExtension->iEditorBackgroundColor.Value();        
       
  8027         color = aConditionalColor;
       
  8028         }
       
  8029     else
       
  8030         {
       
  8031         color = CEikonEnv::Static()->ControlColor(EColorControlBackground, *this);
       
  8032         }
       
  8033     return color;
       
  8034     }    
       
  8035 
       
  8036 EXPORT_C void CEikEdwin::SetUpperFullFormattingLength( TInt aUpperFullFormattingLimit )
       
  8037     {
       
  8038     if ( iEdwinExtension )
       
  8039         {
       
  8040         iEdwinExtension->iUpperFullFormattingLength = Max( KMinimumFullFormattingLength, aUpperFullFormattingLimit );
       
  8041         }
       
  8042     }
       
  8043 
       
  8044 EXPORT_C void CEikEdwin::EnableKineticScrollingL( TBool aEnable )
       
  8045     {
       
  8046     if ( iEdwinExtension && aEnable )
       
  8047         {
       
  8048         iEdwinExtension->EnableKineticScrollingL();
       
  8049         }
       
  8050     }
       
  8051 
       
  8052 TBool CEikEdwin::NeedToChangeFormattingModeL() const
       
  8053     {
       
  8054     if ( TextLayout() && iText )
       
  8055         {
       
  8056         const TInt docLength = iText->DocumentLength();
       
  8057         TBool bandFormatting = TextLayout()->IsFormattingBand();
       
  8058         if ( ( !bandFormatting && docLength > UpperFullFormattingLength() )
       
  8059             || ( bandFormatting && docLength <= LowerPartialFormattingLength() ) )
       
  8060             {
       
  8061             return ETrue;
       
  8062             }
       
  8063         }
       
  8064     return EFalse;
       
  8065     }
       
  8066     
       
  8067 TRect CEikEdwin::AdjustedViewRect() const
       
  8068     {        
       
  8069     TRect mainPaneRect( 0, 0, 0, 0 );    
       
  8070     AknLayoutUtils::LayoutMetricsRect (AknLayoutUtils::EMainPane, 
       
  8071             mainPaneRect );
       
  8072     TInt mainPaneHeight = mainPaneRect.Height();
       
  8073     
       
  8074     TRect rect( iTextView->ViewRect() );
       
  8075     if ( rect.iTl.iY < 0 )
       
  8076         {
       
  8077         rect.iTl.iY = 0;
       
  8078         }    
       
  8079     if ( rect.iBr.iY > mainPaneHeight )
       
  8080         {
       
  8081         rect.iBr.iY = mainPaneHeight;
       
  8082         }
       
  8083     return rect;
       
  8084     }
       
  8085     
       
  8086 void CEikEdwin::SetVKBStatus()
       
  8087     {
       
  8088     TUint cap = iEdwinExtension->iExtendedInputCapabilities->Capabilities();
       
  8089     if ( iEdwinUserFlags & EAvkonDisableVKB )
       
  8090         {
       
  8091         cap |= CAknExtendedInputCapabilities::EInputEditorDisableVKB;    
       
  8092         }
       
  8093     else
       
  8094         {
       
  8095         cap &= ~CAknExtendedInputCapabilities::EInputEditorDisableVKB;
       
  8096         }   
       
  8097     iEdwinExtension->iExtendedInputCapabilities->SetCapabilities( cap );
       
  8098     }
       
  8099     
       
  8100 void CEikEdwin::ScrollViewToCursorLineL()
       
  8101     {
       
  8102     TInt cursorPos = CursorPos();
       
  8103     TRect viewRect( AdjustedViewRect() );    
       
  8104     TInt pixels = -1;
       
  8105     TBool scroll = EFalse;
       
  8106     TInt endPos = iTextView->XyPosToDocPosL( viewRect.iBr );  
       
  8107     while ( cursorPos > endPos && pixels != 0 )
       
  8108         {        
       
  8109         pixels = iTextView->ScrollDisplayL( TCursorPosition::EFLineDown );
       
  8110         if ( pixels != 0 )
       
  8111             {
       
  8112             scroll = ETrue;
       
  8113             }
       
  8114         endPos = iTextView->XyPosToDocPosL( viewRect.iBr );        
       
  8115         }
       
  8116     if ( scroll )
       
  8117         {
       
  8118         UpdateScrollBarsL();
       
  8119         }
       
  8120     }
       
  8121     
       
  8122 EXPORT_C void CEikEdwin::SetCursorVisible(TBool aVisible)
       
  8123     {
       
  8124     TRAP_IGNORE( SetCursorVisibilityL( aVisible ) );
       
  8125     }
       
  8126 
       
  8127 void CEikEdwin::PerformRecordedOperationL()
       
  8128     {
       
  8129     if ( iEdwinExtension->iDrawInvoked == CEikEdwinExtension::ENotDraw ||
       
  8130         iEdwinExtension->iDrawInvoked == CEikEdwinExtension::EDrawing )
       
  8131         {        
       
  8132         if ( iEdwinExtension->iDrawInvoked == CEikEdwinExtension::ENotDraw )
       
  8133             {
       
  8134             iEdwinExtension->iDrawInvoked = CEikEdwinExtension::EDrawn;
       
  8135             }
       
  8136         if ( iEdwinExtension->iTempCursorPos != KErrNotFound )
       
  8137             {
       
  8138             if ( iEdwinExtension->iTempAnchorPos == KErrNotFound )
       
  8139                 {
       
  8140                 SetCursorPosL( iEdwinExtension->iTempCursorPos, 
       
  8141                     iEdwinExtension->iTempSelect );      
       
  8142                 }
       
  8143             else
       
  8144                 {
       
  8145                 SetSelectionL( iEdwinExtension->iTempCursorPos, 
       
  8146                     iEdwinExtension->iTempAnchorPos );
       
  8147                 }            
       
  8148             }
       
  8149         iEdwinExtension->iTempCursorPos = KErrNotFound;
       
  8150         iEdwinExtension->iTempAnchorPos = KErrNotFound;
       
  8151         if ( iEdwinExtension->iDrawInvoked == CEikEdwinExtension::EDrawing )
       
  8152             {
       
  8153             iEdwinExtension->iDrawInvoked = CEikEdwinExtension::EDrawn;
       
  8154             }
       
  8155         }
       
  8156     }
       
  8157 
       
  8158 void CEikEdwin::ScrollIfAtTopOrBottomL()
       
  8159     {
       
  8160     TInt cursorPos = CursorPos();
       
  8161     TRect viewRect( AdjustedViewRect() );    
       
  8162     TPoint cursorPoint;
       
  8163     if ( ! iTextView->DocPosToXyPosL(cursorPos, cursorPoint) )
       
  8164         {
       
  8165         return;
       
  8166         }
       
  8167         
       
  8168     TInt topPos = iTextView->XyPosToDocPosL( viewRect.iTl );
       
  8169     TInt bottomPos = iTextView->XyPosToDocPosL( viewRect.iBr );
       
  8170     TPoint cursorLineLeftPiont(viewRect.iTl.iX,cursorPoint.iY );
       
  8171     TPoint cursorLineRightPiont(viewRect.iBr.iX,cursorPoint.iY ); 
       
  8172     TInt cursorLineLeftPos = iTextView->XyPosToDocPosL( cursorLineLeftPiont );
       
  8173     TInt cursorLineRightPos = iTextView->XyPosToDocPosL( cursorLineRightPiont );
       
  8174     const TInt totalChars = iText->DocumentLength();
       
  8175     TBool scroll( EFalse );
       
  8176     if (topPos >= 0 && topPos == cursorLineLeftPos)
       
  8177         {
       
  8178         iTextView->ScrollDisplayL( TCursorPosition::EFLineUp );
       
  8179         UpdateScrollBarsL();
       
  8180         scroll = ETrue ;
       
  8181         }        
       
  8182     if (bottomPos < totalChars && bottomPos == cursorLineRightPos)
       
  8183         {
       
  8184         iTextView->ScrollDisplayL( TCursorPosition::EFLineDown );
       
  8185         UpdateScrollBarsL();
       
  8186         scroll = ETrue ;
       
  8187         }
       
  8188     if ( scroll && iEdwinExtension->iDrawInvoked != 
       
  8189         CEikEdwinExtension::EDrawing )
       
  8190         {
       
  8191         ReportEdwinEventL( MEikEdwinObserver::EEventNavigation );
       
  8192         }
       
  8193     }
       
  8194 
       
  8195 void CEikEdwin::OnEditorStateFlagChange( TInt aOldFlags, TInt aNewFlags )
       
  8196     {
       
  8197     // for chinese popup flag
       
  8198     TInt chinesePopup( aOldFlags & EAknEditorFlagChinesePopup );
       
  8199     if ( chinesePopup != ( aNewFlags & EAknEditorFlagChinesePopup ) )
       
  8200         {
       
  8201         TRAP_IGNORE( ReportChinesePopupEventL( chinesePopup == 0 ) );
       
  8202         }    
       
  8203     }
       
  8204 
       
  8205 void CEikEdwin::ReportChinesePopupEventL( TBool aChinesePopupOpen )
       
  8206     {
       
  8207     if ( aChinesePopupOpen )
       
  8208         {
       
  8209         ReportEdwinEventL( MEikEdwinObserver::EEventChinesePopupOpen );
       
  8210         }
       
  8211     else
       
  8212         {
       
  8213         ReportEdwinEventL( MEikEdwinObserver::EEventChinesePopupClose );
       
  8214         }
       
  8215     }
       
  8216 
       
  8217 // for smiley support
       
  8218 void CEikEdwin::EnableSmileySupportL( TBool aEnableSmiley )
       
  8219     {
       
  8220     if ( aEnableSmiley && !AknLayoutUtils::LayoutMirrored() )
       
  8221         {
       
  8222         if ( !iEdwinExtension->iSmiley )
       
  8223             {
       
  8224             iEdwinExtension->iSmiley = CSmileyManager::NewL( *this );
       
  8225             iEdwinExtension->iSmiley->SetAnimationPlayTimes( KNormalAnimPlayTimes );
       
  8226             if ( IsReadOnly() || iEdwinUserFlags & EDisplayOnly )
       
  8227                 {
       
  8228                 iEdwinExtension->iSmiley->SetAnimationPlayTimes( 
       
  8229                     KInfiniteAnimPlayTimes );
       
  8230                 }
       
  8231             }        
       
  8232         if ( TextLayout() )
       
  8233             {
       
  8234             TextLayout()->SetCustomWrap( iEdwinExtension->iSmileyWrap );
       
  8235             }
       
  8236         }    
       
  8237     else
       
  8238         {
       
  8239         delete iEdwinExtension->iSmiley;
       
  8240         iEdwinExtension->iSmiley = NULL;
       
  8241         if ( TextLayout() )
       
  8242             {
       
  8243             TextLayout()->SetCustomWrap( NULL );
       
  8244             }
       
  8245         }
       
  8246     }
       
  8247 
       
  8248 TBool CEikEdwin::IsSmileyEnabled() const
       
  8249     {
       
  8250     return ( iEdwinExtension->iSmiley != NULL );
       
  8251     }
       
  8252 
       
  8253 void CEikEdwin::DrawSmileyInTextL( CBitmapContext& aGc, CFont& aFont, 
       
  8254         const TDesC& aText, const TPoint& aPt )
       
  8255     {    
       
  8256     TRect viewRect( AdjustedViewRect() );
       
  8257     TInt topY( aPt.iY - aFont.AscentInPixels() );
       
  8258     TInt bottomY( aPt.iY + aFont.DescentInPixels() );
       
  8259     const TInt KThreshold = 10;
       
  8260     if ( topY < viewRect.iTl.iY - KThreshold || 
       
  8261         bottomY > viewRect.iBr.iY + KThreshold )
       
  8262         {
       
  8263         return;
       
  8264         }
       
  8265     TInt pos( 0 );
       
  8266     TPoint pt( aPt );
       
  8267     HBufC* buf( NULL );
       
  8268     TRAPD( err, 
       
  8269         {
       
  8270         pos = iTextView->XyPosToDocPosL( pt );
       
  8271         buf = HBufC::NewL( aText.Length() );
       
  8272         });
       
  8273     if ( err == KErrNone )
       
  8274         {
       
  8275         TPtr text( buf->Des() );
       
  8276         text.Copy( aText );
       
  8277         TrimText( text );
       
  8278         TInt smileyWidth( aFont.TextWidthInPixels( KSmileyString ) );
       
  8279         for ( TInt i( 0 ); i < text.Length(); i++ )
       
  8280             {
       
  8281             if ( CSmileyManager::IsSmileyCode( text[i] ) )
       
  8282                 {
       
  8283                 TInt x( pt.iX + aFont.TextWidthInPixels( text.Left( i ) ) );
       
  8284                 TRect rect( x, topY, x + smileyWidth, bottomY );
       
  8285                 iEdwinExtension->iSmiley->DrawIconL( aGc, rect, i + pos );
       
  8286                 }
       
  8287             }
       
  8288         }
       
  8289     delete buf;
       
  8290     }
       
  8291 
       
  8292 void CEikEdwin::ConvertVisibleTextForSmileyL( TBool aTextToCode )
       
  8293     {
       
  8294     if ( !iEdwinExtension->iSmiley && !iTextView )
       
  8295         {
       
  8296         return;
       
  8297         }
       
  8298     TCursorSelection visibleRange( GetVisibleTextRangeL() );
       
  8299     ConvertTextForSmileyL( visibleRange, aTextToCode );    
       
  8300     }
       
  8301 
       
  8302 void CEikEdwin::ConvertTextForSmileyL( TCursorSelection aSelect, 
       
  8303     TBool aTextToCode, TBool aRedraw )
       
  8304     {    
       
  8305     if ( iEdwinExtension->iSmiley && !iEdwinExtension->iInlineEditing )
       
  8306         {
       
  8307         if ( aTextToCode )
       
  8308             {
       
  8309             ExtendedRangeForSmiley( aSelect );
       
  8310             }
       
  8311         TInt start( aSelect.LowerPos() );   
       
  8312         TInt length( aSelect.Length() );
       
  8313         HBufC* buf( ExtractTextLC( aSelect ) );
       
  8314         TPtr ptr( buf->Des() );
       
  8315         if ( ptr.Length() > 0 &&
       
  8316             iEdwinExtension->iSmiley->ConvertTextForSmileyL( aSelect.LowerPos(), 
       
  8317                 ptr, aTextToCode ) )
       
  8318             {                
       
  8319             iText->DeleteL( start, length );            
       
  8320             iText->InsertL( start, ptr );            
       
  8321             }
       
  8322         CleanupStack::PopAndDestroy( buf );
       
  8323         if ( aRedraw )
       
  8324             {
       
  8325             DrawDeferred();
       
  8326             }
       
  8327         }
       
  8328     }
       
  8329     
       
  8330 void CEikEdwin::TrimText( TDes& aText )
       
  8331     {
       
  8332     TInt index( -1 );
       
  8333     const TText KTrimChar = 0xffff;
       
  8334     for ( TInt i( 0 ); i < aText.Length() && aText[i] == KTrimChar; i++ )
       
  8335         {        
       
  8336         index = i;
       
  8337         }
       
  8338     if ( index != -1 )
       
  8339         {
       
  8340         aText.Delete( 0, index + 1 );
       
  8341         }
       
  8342     index = -1;
       
  8343     for ( TInt i( aText.Length() - 1 ); i >= 0 && aText[i] == KTrimChar; i-- )
       
  8344         {
       
  8345         index = i;
       
  8346         }
       
  8347     if ( index != -1 )
       
  8348         {
       
  8349         aText.Delete( index, aText.Length() - index );
       
  8350         }        
       
  8351     }
       
  8352 
       
  8353 TCursorSelection CEikEdwin::GetVisibleTextRangeL()
       
  8354     {
       
  8355     if ( iTextView )
       
  8356         {
       
  8357         TRect viewRect( AdjustedViewRect() );
       
  8358         TInt start( iTextView->XyPosToDocPosL( viewRect.iTl ) );
       
  8359         TInt end( iTextView->XyPosToDocPosL( viewRect.iBr ) );
       
  8360         return TCursorSelection( start, end );
       
  8361         }
       
  8362     return TCursorSelection( 0, 0 );
       
  8363     }
       
  8364 
       
  8365 HBufC* CEikEdwin::ExtractTextLC( TCursorSelection aSelect )
       
  8366     {
       
  8367     TInt length( aSelect.Length() );
       
  8368     HBufC* buf( HBufC::NewL( length ) );
       
  8369     CleanupStack::PushL( buf );
       
  8370     TPtr ptr( buf->Des() );
       
  8371     iText->Extract( ptr, aSelect.LowerPos(), length );
       
  8372     return buf;
       
  8373     }
       
  8374 
       
  8375 void CEikEdwin::ConvertSmileyIconToTextL( TInt aStartPos, TDes& aText )
       
  8376     {
       
  8377     if ( iEdwinExtension->iSmiley )
       
  8378         {
       
  8379         iEdwinExtension->iSmiley->ConvertTextForSmileyL( aStartPos,
       
  8380             aText, EFalse );
       
  8381         }
       
  8382     }
       
  8383 
       
  8384 void CEikEdwin::ExtendedRangeForSmiley( TCursorSelection& aSelect )
       
  8385     { 
       
  8386     if ( iEdwinExtension->iSmiley )
       
  8387         {
       
  8388         TInt textLength( TextLength() );
       
  8389         TInt start = aSelect.LowerPos() - CSmileyManager::KMaxLength;
       
  8390         if ( start < 0 )
       
  8391             {
       
  8392             start = 0;
       
  8393             }
       
  8394         TInt end = aSelect.HigherPos() + CSmileyManager::KMaxLength;
       
  8395         if ( end > textLength )
       
  8396             {
       
  8397             end = textLength;
       
  8398             }
       
  8399         aSelect.iAnchorPos = start;
       
  8400         aSelect.iCursorPos = end;
       
  8401         }
       
  8402     }
       
  8403 
       
  8404 TBool CEikEdwin::ConvertSmileyForDeleteL( TInt aDocPos, TBool aBackSpace )
       
  8405     {
       
  8406     if ( !iEdwinExtension->iSmiley || ( aDocPos == 0 && aBackSpace ) || 
       
  8407         ( aDocPos == TextLength() && !aBackSpace ) )
       
  8408         {
       
  8409         return EFalse;
       
  8410         }
       
  8411     TInt checkPos( aDocPos );
       
  8412     if ( aBackSpace )
       
  8413         {
       
  8414         checkPos--;
       
  8415         checkPos = checkPos >= 0 ? checkPos : 0;
       
  8416         }
       
  8417     if ( CSmileyManager::IsSmileyCode( iEdwinExtension->iSmiley->
       
  8418         SmileyCodeByPos( checkPos ) ) && 
       
  8419         !iEdwinExtension->iSmiley->IsDisabledSmileyIcon( checkPos ) )
       
  8420         {
       
  8421         TInt codeLength( iEdwinExtension->iSmiley->SmileyLength( checkPos ) );
       
  8422         iEdwinExtension->iSmiley->DisableSmileyIcon( checkPos );
       
  8423         TCursorSelection select( aDocPos, aDocPos );
       
  8424         if ( aBackSpace )
       
  8425             {
       
  8426             select.iAnchorPos -= codeLength;
       
  8427             }
       
  8428         else
       
  8429             {
       
  8430             select.iCursorPos += codeLength;
       
  8431             }
       
  8432         ConvertTextForSmileyL( select, EFalse );
       
  8433         iEdwinExtension->iExtendedInputCapabilities->ReportEventL( 
       
  8434             CAknExtendedInputCapabilities::
       
  8435             MAknEventObserver::EControlContentUpdatedInternally,
       
  8436             NULL );
       
  8437         return ETrue;
       
  8438         }
       
  8439     return EFalse;
       
  8440     }
       
  8441 
       
  8442 void CEikEdwin::ConvertSmileyForDeleteL( const TCursorSelection &aSelect )
       
  8443     {
       
  8444     if ( !iEdwinExtension->iSmiley )
       
  8445         {
       
  8446         return;
       
  8447         }
       
  8448 
       
  8449     TInt lowerPos( aSelect.LowerPos() );
       
  8450     TInt higherPos( aSelect.HigherPos() );
       
  8451 
       
  8452     // Extend the lowerPos to the edge of a smiley
       
  8453     iEdwinExtension->iSmiley->HandleSetCursor( lowerPos + 1, lowerPos );
       
  8454     // Extend the higherPos to the edge of a smiley
       
  8455     iEdwinExtension->iSmiley->HandleSetCursor( higherPos - 1, higherPos );
       
  8456   
       
  8457     TCursorSelection select( lowerPos, higherPos );   
       
  8458     HBufC* buf( ExtractTextLC( select ) );
       
  8459     TPtr ptr( buf->Des() );
       
  8460     if ( ptr.Length() > 0 &&
       
  8461         iEdwinExtension->iSmiley->ConvertTextForSmileyL( lowerPos, 
       
  8462             ptr, EFalse ) )
       
  8463         {                
       
  8464         iText->DeleteL( lowerPos, higherPos - lowerPos );            
       
  8465         iText->InsertL( lowerPos, ptr );            
       
  8466         }
       
  8467     CleanupStack::PopAndDestroy( buf );
       
  8468     }
       
  8469 
       
  8470 void CEikEdwin::HandleScrollForSmileyL()
       
  8471     {
       
  8472     if ( !iEdwinExtension->iSmiley )
       
  8473         {
       
  8474         return;
       
  8475         }
       
  8476     TCursorSelection select( GetVisibleTextRangeL() );
       
  8477     if ( select.LowerPos() != iEdwinExtension->iVisibleRange.LowerPos() ||
       
  8478         select.HigherPos() != iEdwinExtension->iVisibleRange.HigherPos() )
       
  8479         {
       
  8480         iEdwinExtension->iVisibleRange.iCursorPos = select.iCursorPos;
       
  8481         iEdwinExtension->iVisibleRange.iAnchorPos = select.iAnchorPos;
       
  8482         }
       
  8483     iEdwinExtension->iSmiley->SetVisibleRange( select.LowerPos(), 
       
  8484         select.Length() );
       
  8485     }
       
  8486 
       
  8487 TBool CEikEdwin::AdjustCursorForSmileyL( TInt aOldCursor, TCursorSelection& aSelect )
       
  8488     {
       
  8489     TBool ret( EFalse );
       
  8490     TCursorSelection select( Selection() );
       
  8491     TInt cursor( select.iCursorPos );
       
  8492     iEdwinExtension->iSmiley->HandleSetCursor( aOldCursor, cursor );
       
  8493     if ( cursor != select.iCursorPos )
       
  8494         {
       
  8495         if ( select.iAnchorPos == select.iCursorPos )
       
  8496             {
       
  8497             select.iAnchorPos = cursor;
       
  8498             }
       
  8499         select.iCursorPos = cursor;        
       
  8500         ret = ETrue;
       
  8501         }
       
  8502     aSelect = select;
       
  8503     return ret;
       
  8504     }
       
  8505 
       
  8506 TRect CEikEdwin::AdjustDrawRectForSmiley( const TRect& aRect ) const 
       
  8507     {
       
  8508     TRect viewRect( AdjustedViewRect() );
       
  8509     return TRect( viewRect.iTl.iX, aRect.iTl.iY, viewRect.iBr.iX, aRect.iBr.iY );
       
  8510     }
       
  8511 
       
  8512 void CEikEdwin::GetClipRegionForSmiley( RRegion& rgn, CFont& aFont, 
       
  8513     const TDesC& aText, const TPoint& aPt, const TRect& aDrawRect ) const
       
  8514     {
       
  8515     TInt smileyWidth( aFont.TextWidthInPixels( KSmileyString ) );
       
  8516     TInt topY( aDrawRect.iTl.iY );
       
  8517     TInt bottomY( aDrawRect.iBr.iY );
       
  8518     for ( TInt i( 0 ); i < aText.Length(); i++ )
       
  8519         {
       
  8520         if ( CSmileyManager::IsSmileyCode( aText[i] ) )
       
  8521             {
       
  8522             TInt x( aPt.iX + aFont.TextWidthInPixels( aText.Left( i ) ) );
       
  8523             TRect rect( x, topY, x + smileyWidth, bottomY );
       
  8524             rgn.SubRect( rect, NULL );
       
  8525             }
       
  8526         }
       
  8527     }
       
  8528 
       
  8529 TBool CEikEdwin::AdjustCursorPosByMovementL( TCursorPosition::TMovementType aMovement, 
       
  8530     TBool aSelect )
       
  8531     {
       
  8532     TBool ret( EFalse );
       
  8533     if ( iEdwinExtension->iSmiley )
       
  8534         {
       
  8535         TInt oldPos( CursorPos() );
       
  8536         TInt curPos( oldPos );
       
  8537         if ( aMovement == TCursorPosition::EFLeft )
       
  8538             {
       
  8539             curPos--;
       
  8540             }
       
  8541         else if ( aMovement == TCursorPosition::EFRight )
       
  8542             {
       
  8543             curPos++;
       
  8544             }
       
  8545         iEdwinExtension->iSmiley->HandleSetCursor( oldPos, curPos );
       
  8546         if ( oldPos != curPos )
       
  8547             {
       
  8548             SetCursorPosL( curPos, aSelect );
       
  8549             ret = ETrue;
       
  8550             }
       
  8551         }
       
  8552     return ret;
       
  8553     }
       
  8554 
       
  8555 void CEikEdwin::SetSelectionVisibilityL( TBool isVisable )
       
  8556     {
       
  8557     iTextView->SetSelectionVisibilityL(isVisable);
       
  8558     CAknEdwinState*edwinState = EditorState();
       
  8559     if( !edwinState )
       
  8560     	return;
       
  8561     if(isVisable)
       
  8562     	{
       
  8563         SetAknEditorFlags( edwinState->Flags() | EAknEditorFlagSelectionVisible );
       
  8564     	}
       
  8565     else
       
  8566     	{
       
  8567     	SetAknEditorFlags( edwinState->Flags() & ~EAknEditorFlagSelectionVisible );
       
  8568     	}
       
  8569     return;
       
  8570     }
       
  8571 TBool CEikEdwin::IsSelectionVisible()
       
  8572 	{
       
  8573 	TBool ret = EFalse;
       
  8574 	const TCursorSelection selection=iTextView->Selection();
       
  8575 	if (selection.Length() == 0)
       
  8576 		return ret;
       
  8577 	TPtrC text = iText->Read( selection.LowerPos(), selection.Length() );
       
  8578 	for (TInt i = 0; i < text.Length(); i++)
       
  8579 		{
       
  8580 		TChar character(text[i]);
       
  8581 		if (text[i] == ' ')
       
  8582 			return ETrue;
       
  8583 		
       
  8584 		TChar::TCategory category = character.GetCategory();
       
  8585 		
       
  8586 		if ( !((category&TChar::ESeparatorGroup == TChar::ESeparatorGroup) ||
       
  8587 			   (text[i]>=0x200B && text[i]<=0xFFFC)) )
       
  8588 			{
       
  8589 			ret = ETrue;
       
  8590 			break;
       
  8591 			}
       
  8592 		}
       
  8593     return ret;
       
  8594 	}
       
  8595 
       
  8596 // ---------------------------------------------------------------------------
       
  8597 // CEikEdwin::ScrollView
       
  8598 // ---------------------------------------------------------------------------
       
  8599 // 
       
  8600 TInt CEikEdwin::ScrollView( TInt aPixelsToScroll, TBool& aBorderExceeded, TInt& aRestOfPixels )
       
  8601     {
       
  8602     EnableRateScrolling( ETrue );
       
  8603     TInt scrolledPixels( aPixelsToScroll );
       
  8604     
       
  8605     // Normal scrolling, we need to use old function because
       
  8606     // we know from return value if border has been exceeded
       
  8607     // This function call updates scrolledPixels to number
       
  8608     // of actually scrolled pixels.
       
  8609     
       
  8610     TRAP_IGNORE( iTextView->ScrollDisplayPixelsL( scrolledPixels ) );
       
  8611              
       
  8612     if ( scrolledPixels != aPixelsToScroll )
       
  8613         {
       
  8614         // We can't move enough, we have exceeded the border
       
  8615         // (at the beginning or end of the document)
       
  8616         if ( aPixelsToScroll != 0 )
       
  8617             {
       
  8618             if ( aPixelsToScroll < 0 )
       
  8619                 {
       
  8620                 // End of document. Set flag to tell about that
       
  8621                 iEdwinExtension->iEndBorderExceeded = ETrue;
       
  8622                 aBorderExceeded = ETrue;
       
  8623                 }
       
  8624             else
       
  8625                 {
       
  8626                 // Beginning of document. Set flag to tell about that
       
  8627                 iEdwinExtension->iStartBorderExceeded = ETrue;
       
  8628                 aBorderExceeded = ETrue;
       
  8629                 }
       
  8630             
       
  8631             // Calculate how many pixels more we should scroll and
       
  8632             // return it in variable
       
  8633             aRestOfPixels = aPixelsToScroll - scrolledPixels;
       
  8634                         
       
  8635             // Set variable how many pixels we are out of border 
       
  8636             iEdwinExtension->iPixelsOutOfBorder = 0;
       
  8637             }
       
  8638         }
       
  8639        
       
  8640     if ( scrolledPixels != 0 )
       
  8641         {
       
  8642         iEdwinExtension->iScrolledDelta = scrolledPixels;
       
  8643         TRAP_IGNORE( UpdateVertScrollBarThumbL() );
       
  8644         iEdwinExtension->iScrolledDelta = 0;
       
  8645         }
       
  8646     
       
  8647     EnableRateScrolling( EFalse );
       
  8648     return scrolledPixels;    
       
  8649     }
       
  8650 
       
  8651 // ---------------------------------------------------------------------------
       
  8652 // CEikEdwin::ScrollViewWithBounce
       
  8653 // ---------------------------------------------------------------------------
       
  8654 // 
       
  8655 TInt CEikEdwin::ScrollViewWithBounce( TInt aPixelsToScroll,
       
  8656     TBool& aEndOfBounce, TInt& aRestOfPixels )
       
  8657     {
       
  8658     aEndOfBounce = EFalse;
       
  8659     aRestOfPixels = 0;
       
  8660     EnableRateScrolling( ETrue );
       
  8661      
       
  8662     // We have to check here if we are moving enough so that bounce
       
  8663     // ends (scrolling over the border toward content). In this case we
       
  8664     // can use ScrollDisplayPixelsNoLimitBorderL to scroll only to border.
       
  8665     // After that we have to move to mode where we use ScrollDisplayPixelsL
       
  8666     // to detect if we exceed border again.
       
  8667     TBool adjustScrolling( EFalse );
       
  8668     if ( aPixelsToScroll > 0  && iEdwinExtension->iEndBorderExceeded )
       
  8669         {
       
  8670         if ( aPixelsToScroll > - iEdwinExtension->iPixelsOutOfBorder )
       
  8671             {
       
  8672             adjustScrolling = ETrue;
       
  8673             }
       
  8674         }
       
  8675     else if ( aPixelsToScroll < 0 &&  iEdwinExtension->iStartBorderExceeded )
       
  8676         {
       
  8677         if ( aPixelsToScroll < - iEdwinExtension->iPixelsOutOfBorder )
       
  8678             {            
       
  8679             adjustScrolling = ETrue;
       
  8680             }
       
  8681         }
       
  8682     
       
  8683     if ( adjustScrolling )
       
  8684         {
       
  8685         // we are scrolling over the border, calculate how many
       
  8686         // pixels we can scroll and how many pixels there is rest
       
  8687         // after movement
       
  8688         aRestOfPixels = aPixelsToScroll + iEdwinExtension->iPixelsOutOfBorder;
       
  8689         aPixelsToScroll = -iEdwinExtension->iPixelsOutOfBorder;
       
  8690         }
       
  8691     
       
  8692     // We are out of borders. Call scrolling function that supports bounce-effect
       
  8693     TRAP_IGNORE( iTextView->ScrollDisplayPixelsNoLimitBorderL( aPixelsToScroll ) );
       
  8694 
       
  8695     // Update variable that tells how near the border we are.
       
  8696     iEdwinExtension->iPixelsOutOfBorder += aPixelsToScroll;
       
  8697                
       
  8698     if ( iEdwinExtension->iStartBorderExceeded
       
  8699         && iEdwinExtension->iPixelsOutOfBorder <= 0 )
       
  8700         {
       
  8701         // We are inside borders, reset flag and tell to caller
       
  8702         iEdwinExtension->iStartBorderExceeded = EFalse;
       
  8703         aEndOfBounce = ETrue;
       
  8704         }
       
  8705     else if ( iEdwinExtension->iEndBorderExceeded
       
  8706         && iEdwinExtension->iPixelsOutOfBorder >= 0 )
       
  8707         {
       
  8708         // we are inside borders, reset flag and tell to caller
       
  8709         iEdwinExtension->iEndBorderExceeded = EFalse;
       
  8710         aEndOfBounce = ETrue;
       
  8711         }
       
  8712           
       
  8713     if ( aPixelsToScroll != 0 )
       
  8714         {
       
  8715         TRAP_IGNORE( UpdateVertScrollBarThumbL() );
       
  8716         }
       
  8717     EnableRateScrolling( EFalse );
       
  8718     // Return how many pixels we actually moved. It can be different to
       
  8719     // value what user requested
       
  8720     return aPixelsToScroll;  
       
  8721     }
       
  8722 
       
  8723 // ---------------------------------------------------------------------------
       
  8724 // CEikEdwin::PixelsOutOfBorder
       
  8725 // ---------------------------------------------------------------------------
       
  8726 //
       
  8727 TInt CEikEdwin::PixelsOutOfBorder() const
       
  8728     {
       
  8729     return iEdwinExtension->iPixelsOutOfBorder;
       
  8730     }
       
  8731 
       
  8732 // ---------------------------------------------------------------------------
       
  8733 // CEikEdwin::EnableRateScrolling
       
  8734 // ---------------------------------------------------------------------------
       
  8735 //
       
  8736 void CEikEdwin::EnableRateScrolling( TBool aEnable )
       
  8737     {
       
  8738     // This function is related to Rate scrolling implementation.
       
  8739     // See comments in function SetKineticScrollingScrollbarModelL
       
  8740     // for more information about Rate scrolling.
       
  8741     
       
  8742     // Use this function to change scrolling mode.
       
  8743     // If aEnable is EFalse, Position scrolling mode is in use.
       
  8744     // If aEnable is ETrue, Rate scrolling mode is in use.
       
  8745     
       
  8746     iEdwinExtension->iUseRateScroll = aEnable;
       
  8747     }
       
  8748 
       
  8749 // ---------------------------------------------------------------------------
       
  8750 // CEikEdwin::StoreCursorState
       
  8751 // ---------------------------------------------------------------------------
       
  8752 //
       
  8753 void CEikEdwin::StoreCursorState()
       
  8754     {
       
  8755     CAknEdwinState* state( EditorState() );
       
  8756     if ( state && state->Flags() & EAknEditorFlagTextCursorVisible )
       
  8757         {
       
  8758         TRAP_IGNORE( SetCursorVisibilityL( EFalse ) );
       
  8759         iEdwinExtension->iCursorWasVisible = ETrue;
       
  8760         }
       
  8761     }
       
  8762 
       
  8763 // ---------------------------------------------------------------------------
       
  8764 // CEikEdwin::RestoreCursorState
       
  8765 // ---------------------------------------------------------------------------
       
  8766 //
       
  8767 void CEikEdwin::RestoreCursorState()
       
  8768     {
       
  8769     if ( iEdwinExtension->iCursorWasVisible )
       
  8770         {
       
  8771         TRAP_IGNORE( SetCursorVisibilityL( ETrue ) );
       
  8772         iEdwinExtension->iCursorWasVisible = EFalse;
       
  8773         }
       
  8774     }
       
  8775 
       
  8776 // ---------------------------------------------------------------------------
       
  8777 // CEikEdwin::KineticScrollingEnabled
       
  8778 // ---------------------------------------------------------------------------
       
  8779 //
       
  8780 TBool CEikEdwin::KineticScrollingEnabled() const
       
  8781     {
       
  8782     return iEdwinExtension && iEdwinExtension->iPhysicsHandler;
       
  8783     }
       
  8784 
       
  8785 
       
  8786 void CEikEdwin::HandleSelectionForSmiley( TCursorSelection aSelect )
       
  8787     {
       
  8788     if ( !iEdwinExtension->iSmiley )
       
  8789         {
       
  8790         return;
       
  8791         }
       
  8792     if ( iCustomDrawer )
       
  8793         {
       
  8794         iEdwinExtension->iSmiley->SetHighlightColor( 
       
  8795             iCustomDrawer->SystemColor( TLogicalRgb::ESystemSelectionBackgroundIndex, 
       
  8796                 KRgbWhite ) );
       
  8797         }
       
  8798     iEdwinExtension->iSmiley->HandleSelection( aSelect.LowerPos(), 
       
  8799         aSelect.Length() );
       
  8800     }
       
  8801 
       
  8802 // ---------------------------------------------------------------------------
       
  8803 // CEikEdwin::SkipBackgroundDrawer
       
  8804 // ---------------------------------------------------------------------------
       
  8805 //
       
  8806 TBool CEikEdwin::SkipBackgroundDrawer() const
       
  8807     {
       
  8808     return iEdwinInternalFlags & ESkipBackgroundDrawer;
       
  8809     }
       
  8810 
       
  8811 TBool CEikEdwin::IsValidNumericCharL( TChar aChar )
       
  8812     { 
       
  8813     TBool ret(ETrue);
       
  8814     CAknEdwinState* state = static_cast<CAknEdwinState*>( iEdwinFepSupport->State( KNullUid ) );    
       
  8815     if (state && state->CurrentInputMode() == EAknEditorNumericInputMode )
       
  8816     	{
       
  8817         HBufC* allowedChars = GetAllowedCharsLC();
       
  8818         if ( (*allowedChars).Length() > 0 && (*allowedChars).Locate( aChar ) == KErrNotFound )
       
  8819             {
       
  8820             ret = EFalse;
       
  8821             }
       
  8822         CleanupStack::PopAndDestroy(1);//allowedChars
       
  8823         }
       
  8824     return ret;
       
  8825     }
       
  8826 
       
  8827 // End of File
       
  8828