messagingappbase/msgeditor/viewsrc/MsgBodyControlEditor.cpp
branchRCL_3
changeset 60 7fdbb852d323
equal deleted inserted replaced
57:ebe688cedc25 60:7fdbb852d323
       
     1 /*
       
     2 * Copyright (c) 2002 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:  MsgBodyControlEditor implementation
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 
       
    20 // ========== INCLUDE FILES ================================
       
    21 
       
    22 #include <eikenv.h>                        // for CEikonEnv
       
    23 #include <txtrich.h>                       // for CRichText
       
    24 #include <baclipb.h>                       // for CClipboard
       
    25 #include <AknUtils.h>                      // for AknUtils
       
    26 #include <ItemFinder.h>                    // for automatic highlight
       
    27 
       
    28 #include <applayout.cdl.h> // LAF
       
    29 #include <aknlayoutscalable_apps.cdl.h>
       
    30 
       
    31 #ifdef RD_TACTILE_FEEDBACK
       
    32 #include <touchfeedback.h>
       
    33 #endif 
       
    34 
       
    35 #include "MsgEditorCommon.h"               //
       
    36 #include "MsgBodyControlEditor.h"          // for CMsgBodyControlEditor
       
    37 #include "MsgBaseControl.h"                // for TMsgEditPermissionFlags
       
    38 #include "MsgBaseControlObserver.h"        // for MMsgBaseControlObserver
       
    39 #include "MsgEditorCustomDraw.h"           // for CMsgEditorCustomDraw
       
    40 #include "MsgEditor.hrh"
       
    41 #include <MmsViewer.rsg>            // resouce identifiers
       
    42 
       
    43 // ========== EXTERNAL DATA STRUCTURES =====================
       
    44 
       
    45 // ========== EXTERNAL FUNCTION PROTOTYPES =================
       
    46 
       
    47 // ========== CONSTANTS ====================================
       
    48 
       
    49 // ========== MACROS =======================================
       
    50 
       
    51 // ========== LOCAL CONSTANTS AND MACROS ===================
       
    52 
       
    53 const TInt KBodyFullFormattingLength = 500;
       
    54 
       
    55 // ========== MODULE DATA STRUCTURES =======================
       
    56 
       
    57 // ========== LOCAL FUNCTION PROTOTYPES ====================
       
    58 
       
    59 // ========== LOCAL FUNCTIONS ==============================
       
    60 
       
    61 // ========== MEMBER FUNCTIONS =============================
       
    62 
       
    63 // ---------------------------------------------------------
       
    64 // CMsgBodyControlEditor::CMsgBodyControlEditor
       
    65 //
       
    66 // Constructor.
       
    67 // ---------------------------------------------------------
       
    68 //
       
    69 CMsgBodyControlEditor::CMsgBodyControlEditor( const CCoeControl* aParent,
       
    70                                               TUint32& aFlags,
       
    71                                               MMsgBaseControlObserver* aBaseControlObserver ) :
       
    72     CMsgExpandableControlEditor( aParent, aFlags, aBaseControlObserver ),
       
    73     iPreviousItemStart( -1 ),
       
    74     iPreviousItemLength( -1 )
       
    75     {
       
    76     }
       
    77 
       
    78 // ---------------------------------------------------------
       
    79 // CMsgBodyControlEditor::~CMsgBodyControlEditor
       
    80 //
       
    81 // Destructor.
       
    82 // ---------------------------------------------------------
       
    83 //
       
    84 CMsgBodyControlEditor::~CMsgBodyControlEditor()
       
    85     {
       
    86     if (iItemFinder)
       
    87         {
       
    88         TRAP_IGNORE(iItemFinder->SetItemFinderObserverL( NULL ));
       
    89         }
       
    90     }
       
    91 
       
    92 // ---------------------------------------------------------
       
    93 // CMsgBodyControlEditor::ConstructL
       
    94 //
       
    95 //
       
    96 // ---------------------------------------------------------
       
    97 //
       
    98 void CMsgBodyControlEditor::ConstructL()
       
    99     {
       
   100     TInt edwinFlags = ENoHorizScrolling | 
       
   101                       ENoAutoSelection | 
       
   102                       EWidthInPixels | 
       
   103                       EAllowUndo | 
       
   104                       EResizable |
       
   105                       EPasteAsPlainText;
       
   106 
       
   107     iFlags |= EMsgControlModeDoNotDrawFrameBgContext;
       
   108     ResolveLayouts();
       
   109     
       
   110     /*if ( iBaseControlObserver &&
       
   111          !iBaseControlObserver->ViewInitialized() )
       
   112         {
       
   113         SetSuppressFormatting( ETrue );
       
   114         }*/
       
   115     
       
   116     iItemFinder = CItemFinder::NewL(  CItemFinder::EUrlAddress | 
       
   117                                       CItemFinder::EEmailAddress | 
       
   118                                       CItemFinder::EPhoneNumber | 
       
   119                                       CItemFinder::EUriScheme );
       
   120 
       
   121     iItemFinder->AddObserver( *this );
       
   122     
       
   123     iFocusChangedBeforeParseFinish = EFalse;
       
   124 
       
   125     CEikRichTextEditor::ConstructL( iParentControl, 0, iMaxNumberOfChars, edwinFlags );
       
   126     // 107-24185 : Emoticon support for SMS and MMS
       
   127     AddFlagToUserFlags(EAvkonEnableSmileySupport);
       
   128     
       
   129     // Both global text editor and edwin have it's own formatting layers.
       
   130     // CEikRichTextEditor::ConstructL call will set global formatting layers
       
   131     // into use for text. This is not correct as edwin formatting layers
       
   132     // will hold correct formatting values. Below calls will set edwin
       
   133     // formatting layers into use and prevent client based formatting from
       
   134     // being based on incorrect formatting layer.
       
   135     SetParaFormatLayer( iEikonEnv->SystemParaFormatLayerL()->CloneL() );
       
   136     SetCharFormatLayer( iEikonEnv->SystemCharFormatLayerL()->CloneL() );
       
   137     
       
   138     SetUpperFullFormattingLength( KBodyFullFormattingLength );
       
   139     
       
   140     SetMaximumHeight( MsgEditorCommons::MaxBodyHeight() );
       
   141     
       
   142     // Set the wrap width to be that of the current body text pane. 
       
   143     // This will make the formatting of text safer if it is performed 
       
   144     // before the editor has ever had SetSize() called. WrapWidth is 
       
   145     // usually set in HandleSizeChanged()
       
   146     if ( iLayout )
       
   147         {
       
   148         iLayout->SetWrapWidth( iTextLayout.TextRect().Width() );
       
   149         }
       
   150     
       
   151     TRect dataPane = MsgEditorCommons::MsgDataPane();
       
   152     
       
   153     TMargins8 edwinMargins;
       
   154     edwinMargins.iTop = 0;
       
   155     edwinMargins.iBottom = 0;
       
   156     edwinMargins.iLeft = (TInt8)( iTextLayout.TextRect().iTl.iX - dataPane.iTl.iX );
       
   157     edwinMargins.iRight = (TInt8)( dataPane.iBr.iX - iTextLayout.TextRect().iBr.iX );
       
   158     SetBorderViewMargins( edwinMargins );
       
   159     }
       
   160 
       
   161 // ---------------------------------------------------------
       
   162 // CMsgBodyControlEditor::SetAndGetSizeL
       
   163 //
       
   164 // Calculates and sets the size of the control and returns new size as
       
   165 // reference aSize.
       
   166 // ---------------------------------------------------------
       
   167 //
       
   168 void CMsgBodyControlEditor::SetAndGetSizeL( TSize& aSize )
       
   169     {
       
   170     // This may change the heigh if the content has changed
       
   171     SetSize( aSize );
       
   172     aSize = iSize;
       
   173     }
       
   174 
       
   175 // ---------------------------------------------------------
       
   176 // CMsgBodyControlEditor::InsertCharacterL
       
   177 //
       
   178 // Inserts a character to the editor.
       
   179 // ---------------------------------------------------------
       
   180 //
       
   181 void CMsgBodyControlEditor::InsertCharacterL( const TChar& aCharacter )
       
   182     {
       
   183     	
       
   184     // 107-24185 : Emoticon support for SMS and MMS
       
   185     
       
   186     TBuf<1> text;
       
   187     text.Append( aCharacter );
       
   188     InsertTextL( text );
       
   189 
       
   190     //UpdateScrollBarsL();
       
   191     }
       
   192 
       
   193 // ---------------------------------------------------------
       
   194 // CMsgBodyControlEditor::InsertTextL
       
   195 //
       
   196 // Inserts text to the editor.
       
   197 // ---------------------------------------------------------
       
   198 //
       
   199 void CMsgBodyControlEditor::InsertTextL( const TDesC& aText )
       
   200     {
       
   201     if ( iTextView )
       
   202         {
       
   203         TCursorSelection selection = iTextView->Selection();
       
   204         const TInt selLength = selection.Length();
       
   205         const TInt lower = selection.LowerPos();
       
   206 
       
   207         if ( selLength )
       
   208             {
       
   209             // 107-24185 : Emoticon support for SMS and MMS, symbian call
       
   210             InsertDeleteCharsL( lower, aText, selection );
       
   211             }
       
   212         else
       
   213             {
       
   214             InsertDeleteCharsL( selection.iCursorPos, aText, selection );
       
   215             }
       
   216 
       
   217         SetCursorPosL( lower + aText.Length(), EFalse );
       
   218 
       
   219         NotifyNewFormatL();
       
   220         }
       
   221     else
       
   222         {
       
   223         iText->InsertL( 0, aText );
       
   224         }
       
   225     }
       
   226 
       
   227 // ---------------------------------------------------------
       
   228 // CMsgBodyControlEditor::ActivateL
       
   229 //
       
   230 // This function is needed for overriding
       
   231 // CMsgExpandableControlEditor::ActivateL().
       
   232 // ---------------------------------------------------------
       
   233 //
       
   234 void CMsgBodyControlEditor::ActivateL()
       
   235     {
       
   236     if ( IsActivated() )
       
   237         {
       
   238         return;
       
   239         }
       
   240         
       
   241     CMsgExpandableControlEditor::ActivateL();      
       
   242     
       
   243     }
       
   244 
       
   245 
       
   246 // ---------------------------------------------------------
       
   247 // CMsgBodyControlEditor::OfferKeyEventL
       
   248 //
       
   249 //
       
   250 // ---------------------------------------------------------
       
   251 //
       
   252 TKeyResponse CMsgBodyControlEditor::OfferKeyEventL(
       
   253     const TKeyEvent& aKeyEvent, TEventCode aType )
       
   254     {
       
   255     if ( IsReadOnly() )
       
   256         {
       
   257         switch ( aKeyEvent.iCode )
       
   258             {
       
   259             case EKeyDevice3:  
       
   260                 {
       
   261                 if ( iFindItemEventReceived )
       
   262                     {
       
   263                     // Find item was activated by touch, 
       
   264                     // no need to restore highlight
       
   265                     iFindItemEventReceived = EFalse;
       
   266                     return EKeyWasNotConsumed;
       
   267                     }
       
   268                 // fall through
       
   269                 } 
       
   270             case EKeyEnter:
       
   271                 {
       
   272                 // Restore highlight
       
   273                 const CItemFinder::CFindItemExt& item =
       
   274                     iItemFinder->CurrentItemExt();
       
   275                                                             
       
   276                 if ( item.iItemType != CItemFinder::ENoneSelected )
       
   277                     {
       
   278                     SetSelectionL( item.iStart, item.iEnd + 1 );
       
   279                     }
       
   280                 else if ( iInitTop )
       
   281                     {
       
   282                     SetHighlightL( 0, EMsgFocusDown, ETrue ); 
       
   283                     }
       
   284                 else
       
   285                     {
       
   286                     SetHighlightL( TextLength(), EMsgFocusUp, ETrue ); 
       
   287                     }
       
   288                 return EKeyWasConsumed;
       
   289                 }
       
   290             case EKeyUpArrow:
       
   291             case EKeyDownArrow:
       
   292                 break;
       
   293 
       
   294             default:
       
   295                 return CEikRichTextEditor::OfferKeyEventL( aKeyEvent, aType );
       
   296             }
       
   297 
       
   298         SetHighlightL( CursorPos(), 
       
   299             ( aKeyEvent.iCode == EKeyUpArrow )
       
   300             ? EMsgFocusUp
       
   301             : EMsgFocusDown );
       
   302         return EKeyWasConsumed;
       
   303         }
       
   304     else
       
   305         {
       
   306         return CEikRichTextEditor::OfferKeyEventL( aKeyEvent, aType );
       
   307         }
       
   308     }
       
   309 
       
   310 // ---------------------------------------------------------
       
   311 // CMsgBodyControlEditor::HandleFindItemEventL
       
   312 //
       
   313 // Handles finditem events. 
       
   314 // ---------------------------------------------------------
       
   315 //
       
   316 void CMsgBodyControlEditor::HandleFindItemEventL(
       
   317                         const CItemFinder::CFindItemExt& aItem,
       
   318                         MAknItemFinderObserver::TEventFlag aEvent,
       
   319                         TUint aFlags)
       
   320     {     
       
   321     // Body text find item was clicked, we will send simulated key event for
       
   322     // opening context sensitive menu in AppUI::HandleKeyEvent    
       
   323     if ( MAknItemFinderObserver::EPointerEvent == aEvent )
       
   324         {
       
   325         TKeyEvent event;
       
   326         event.iCode = EKeyDevice3;
       
   327         event.iScanCode = EKeyDevice3;
       
   328         event.iModifiers = 0;
       
   329         event.iRepeats = 0;
       
   330 
       
   331         iFindItemEventReceived = ETrue;
       
   332         iCoeEnv->WsSession().SimulateKeyEvent( event );
       
   333         }
       
   334     }
       
   335 
       
   336 // ---------------------------------------------------------
       
   337 // CMsgBodyControlEditor::HandlePointerEventL
       
   338 //
       
   339 // Handles pointer events. 
       
   340 // ---------------------------------------------------------
       
   341 //
       
   342 #ifdef RD_SCALABLE_UI_V2
       
   343 void CMsgBodyControlEditor::HandlePointerEventL( const TPointerEvent& aPointerEvent )
       
   344     {
       
   345     TBool forwardRequest( ETrue );
       
   346     
       
   347     if ( IsActivated() &&
       
   348          IsReadOnly() && 
       
   349          ( aPointerEvent.iType == TPointerEvent::EButton1Down ||
       
   350            aPointerEvent.iType == TPointerEvent::EButton1Up ) )
       
   351         {
       
   352         TPoint tapPoint( aPointerEvent.iPosition );
       
   353         TInt docPos( TextView()->XyPosToDocPosL( tapPoint ) );
       
   354         
       
   355         TInt start( 0 );
       
   356         TInt length( 0 );
       
   357         MParser* parser = iItemFinder;
       
   358         
       
   359         TBool tappedOverTag( RichText()->CursorOverTag( docPos, parser, start, length ) );
       
   360             
       
   361         if ( aPointerEvent.iType == TPointerEvent::EButton1Down )
       
   362             {
       
   363             if ( !tappedOverTag )
       
   364                 {
       
   365                 // Reset current finditem
       
   366                 iItemFinder->ResetCurrentItem();
       
   367                 }
       
   368             else
       
   369                 {
       
   370                 // Find item tapped, do not forward event
       
   371                 forwardRequest = EFalse;
       
   372                 }
       
   373             }
       
   374         }
       
   375 
       
   376     if ( forwardRequest )
       
   377         {
       
   378         CMsgExpandableControlEditor::HandlePointerEventL( aPointerEvent );
       
   379         }                
       
   380 #ifdef RD_TACTILE_FEEDBACK         
       
   381     else if(aPointerEvent.iType == TPointerEvent::EButton1Down)
       
   382         {                                
       
   383         MTouchFeedback* feedback = MTouchFeedback::Instance();
       
   384         if ( feedback )
       
   385             {
       
   386             feedback->InstantFeedback( this, ETouchFeedbackBasic );
       
   387             }
       
   388         }
       
   389 #endif //  RD_TACTILE_FEEDBACK      
       
   390     }
       
   391 #else
       
   392 void CMsgBodyControlEditor::HandlePointerEventL( const TPointerEvent& /*aPointerEvent*/ )
       
   393     {
       
   394     }
       
   395 #endif // RD_SCALABLE_UI_V2
       
   396 
       
   397 
       
   398 // ---------------------------------------------------------
       
   399 // CMsgBodyControlEditor::IsFocusChangePossibleL
       
   400 //
       
   401 //
       
   402 // ---------------------------------------------------------
       
   403 //
       
   404 TBool CMsgBodyControlEditor::IsFocusChangePossibleL(
       
   405     TMsgFocusDirection aDirection )
       
   406     {
       
   407     CItemFinder::TFindDirection direction = aDirection == EMsgFocusUp
       
   408         ? CItemFinder::ENextUp
       
   409         : CItemFinder::ENextDown;
       
   410 
       
   411     TInt cursorPos = CursorPos();
       
   412     iItemFinder->ResolveAndSetItemTypeL( cursorPos );
       
   413     TInt nextItem = iItemFinder->PositionOfNextItem( direction );
       
   414     TPoint dummy;
       
   415 
       
   416     if ( nextItem < KErrNone )
       
   417         {
       
   418         // Next item not found.
       
   419         if ( aDirection == EMsgFocusUp )
       
   420             {
       
   421             return TextLayout()->FirstDocPosFullyInBand() == 0;
       
   422             }
       
   423         else
       
   424             {
       
   425             return TextLayout()->PosInBand( TextLength(),dummy );
       
   426             }
       
   427         }
       
   428     else
       
   429         {
       
   430         // Next item found. -> Focus change not allowed.
       
   431         return 0;
       
   432         }
       
   433     }
       
   434 
       
   435 // ---------------------------------------------------------
       
   436 // CMsgBodyControlEditor::SetupAutomaticFindAfterFocusChangeL
       
   437 //
       
   438 //
       
   439 // ---------------------------------------------------------
       
   440 //
       
   441 void CMsgBodyControlEditor::SetupAutomaticFindAfterFocusChangeL( TBool aBeginning )
       
   442     {
       
   443     iInitTop = aBeginning;
       
   444     if ( !iTextParsed )
       
   445         {
       
   446         iFocusChangedBeforeParseFinish = ETrue;
       
   447         }
       
   448     else
       
   449         {
       
   450         if ( aBeginning )
       
   451             {
       
   452             SetHighlightL( 0, EMsgFocusDown, ETrue ); 
       
   453             }
       
   454         else
       
   455             {
       
   456             SetHighlightL( TextLength(), EMsgFocusUp, ETrue ); 
       
   457             }
       
   458         }
       
   459     }
       
   460 
       
   461 // ---------------------------------------------------------
       
   462 // CMsgBodyControlEditor::SetHighlightL
       
   463 //
       
   464 //
       
   465 // ---------------------------------------------------------
       
   466 //
       
   467 void CMsgBodyControlEditor::SetHighlightL(
       
   468     TInt aCursorPos, TMsgFocusDirection aDirection,
       
   469     TBool aInit /*= EFalse*/ )
       
   470     {
       
   471     // Use "link highlight"
       
   472     SetHighlightStyleL( EEikEdwinHighlightLink );
       
   473     TInt textLength = TextLength();
       
   474 
       
   475     TCursorPosition::TMovementType movetype = aDirection == EMsgFocusUp
       
   476         ? TCursorPosition::EFPageUp
       
   477         : TCursorPosition::EFPageDown;
       
   478 
       
   479     CItemFinder::TFindDirection direction = aDirection == EMsgFocusUp
       
   480         ? CItemFinder::ENextUp
       
   481         : CItemFinder::ENextDown;
       
   482 
       
   483     TInt nextItem = KErrNotFound;
       
   484     TPoint dummy;
       
   485     if ( iTextParsed )
       
   486         {
       
   487         if ( aInit )
       
   488             {
       
   489             iItemFinder->NextItemOrScrollL( aCursorPos == 0
       
   490                 ? CItemFinder::EInitDown
       
   491                 : CItemFinder::EInitUp );
       
   492             }
       
   493         else
       
   494             {
       
   495             nextItem = iItemFinder->PositionOfNextItem( direction );
       
   496             }
       
   497         }
       
   498 
       
   499     if ( nextItem > KErrNotFound )
       
   500         {
       
   501         if ( !aInit &&
       
   502             !TextLayout()->PosInBand( nextItem ,dummy ) )
       
   503             {
       
   504             // first move one page and then set selection
       
   505             SetCursorPosL( CursorPos(), EFalse );
       
   506             iTextView->MoveCursorL( movetype, EFalse );
       
   507             }
       
   508 
       
   509         if ( TextLayout()->PosInBand( nextItem ,dummy ) )
       
   510             {
       
   511             // next item is visible, just change selection
       
   512             iItemFinder->ResolveAndSetItemTypeL( nextItem );
       
   513 
       
   514             TInt selectionLength = iItemFinder->CurrentItemExt().iEnd - iItemFinder->CurrentItemExt().iStart + 1;
       
   515             TCursorSelection cursorSelection;
       
   516             cursorSelection.iCursorPos = nextItem;
       
   517             cursorSelection.iAnchorPos = nextItem + selectionLength;
       
   518             if ( !TextLayout()->PosInBand( nextItem + selectionLength, dummy ) )
       
   519                 {
       
   520                 // Next item does not fit fully on the screen.
       
   521                 // Have to move page first.
       
   522                 SetCursorPosL( CursorPos(), EFalse );
       
   523                 iTextView->MoveCursorL( movetype, EFalse );
       
   524                 }
       
   525 
       
   526             iTextView->SetSelectionL( cursorSelection );
       
   527             }
       
   528 
       
   529         }
       
   530     else
       
   531         {
       
   532         if ( !aInit )
       
   533             {
       
   534             switch ( aDirection )
       
   535                 {
       
   536                 case EMsgFocusDown:
       
   537                     if ( !TextLayout()->PosInBand( textLength, dummy) )
       
   538                         {
       
   539                         iTextView->MoveCursorL( movetype, EFalse );
       
   540 
       
   541                         // Following is a bit tricky since MoveCursor looses
       
   542                         // selection so we have to set it again if previous
       
   543                         // selection still on the screen.
       
   544                         nextItem = iItemFinder->PositionOfNextItem(
       
   545                             CItemFinder::ENextUp );
       
   546                         if ( nextItem > KErrNotFound )
       
   547                             {
       
   548                             if ( TextLayout()->PosInBand( nextItem ,dummy ) )
       
   549                                 {
       
   550                                 // next item is visible, change selection
       
   551                                 iItemFinder->ResolveAndSetItemTypeL( nextItem );
       
   552 
       
   553                                 TInt selectionLength = iItemFinder->CurrentItemExt().iEnd - iItemFinder->CurrentItemExt().iStart + 1;
       
   554                                 TCursorSelection cursorSelection;
       
   555                                 cursorSelection.iCursorPos = nextItem;
       
   556                                 cursorSelection.iAnchorPos = nextItem + selectionLength;
       
   557                                 iTextView->SetSelectionL( cursorSelection );
       
   558                                 }
       
   559                             else
       
   560                                 {
       
   561                                 nextItem = iItemFinder->PositionOfNextItem(
       
   562                                     CItemFinder::ENextDown );
       
   563                                 }
       
   564                             }
       
   565                         }
       
   566                     break;
       
   567                 default:
       
   568                 case EMsgFocusUp:
       
   569                     if ( !TextLayout()->PosInBand( 0,dummy ) )
       
   570                         {
       
   571                         iTextView->MoveCursorL( movetype, EFalse );
       
   572                         }
       
   573                     break;
       
   574                 };
       
   575 
       
   576             }
       
   577         }
       
   578 
       
   579     }
       
   580 
       
   581 
       
   582 // ---------------------------------------------------------
       
   583 // CMsgBodyControlEditor::CursorInLastLine
       
   584 //
       
   585 //
       
   586 // ---------------------------------------------------------
       
   587 //
       
   588 TBool CMsgBodyControlEditor::CursorInLastLine()
       
   589     {
       
   590     if (IsReadOnly())
       
   591         {
       
   592         TPoint dummy;
       
   593         return ( iItemFinder->PositionOfNextItem( CItemFinder::ENextDown ) == KErrNotFound  
       
   594             && TextLayout()->PosInBand( TextLength(), dummy ) );
       
   595 
       
   596         }
       
   597     else
       
   598         {
       
   599         return CMsgExpandableControlEditor::CursorInLastLine();
       
   600         }
       
   601 
       
   602     }
       
   603 
       
   604 // ---------------------------------------------------------
       
   605 // CMsgBodyControlEditor::HandleParsingComplete
       
   606 // ---------------------------------------------------------
       
   607 //
       
   608 void CMsgBodyControlEditor::HandleParsingComplete()
       
   609     {
       
   610     TRAP_IGNORE( DoHandleParsingCompleteL() );
       
   611     }
       
   612 
       
   613 // ---------------------------------------------------------
       
   614 // CMsgBodyControlEditor::DoHandleParsingCompleteL
       
   615 // ---------------------------------------------------------
       
   616 //
       
   617 void CMsgBodyControlEditor::DoHandleParsingCompleteL()
       
   618     {
       
   619     iTextParsed = ETrue;
       
   620     // this needs to be changed so that bottom init can also be set
       
   621     if ( iFocusChangedBeforeParseFinish )
       
   622         {
       
   623         iFocusChangedBeforeParseFinish = EFalse; // just to make sure this is done only once
       
   624         if ( iInitTop )
       
   625             {
       
   626             SetHighlightL( 0, EMsgFocusDown, ETrue ); 
       
   627             }
       
   628         else
       
   629             {
       
   630             SetHighlightL( TextLength(), EMsgFocusUp, ETrue ); 
       
   631             }
       
   632         
       
   633         if ( iBaseControlObserver )
       
   634             {
       
   635             iBaseControlObserver->HandleBaseControlEventRequestL( NULL, 
       
   636                                                                   EMsgUpdateScrollbar );
       
   637             }
       
   638         }
       
   639     else
       
   640         {
       
   641         // In some cases the text view is left to some
       
   642         // strange state. Make sure the view is in sync
       
   643         // with cursor position.
       
   644         SetCursorPosL( CursorPos(), EFalse );
       
   645         }
       
   646     }
       
   647 
       
   648 // ---------------------------------------------------------
       
   649 // CMsgBodyControlEditor::ResolveLayouts
       
   650 //
       
   651 //
       
   652 // ---------------------------------------------------------
       
   653 //
       
   654 void CMsgBodyControlEditor::ResolveLayouts()
       
   655     {
       
   656     TRect dataPane = MsgEditorCommons::MsgDataPane();
       
   657     
       
   658     TAknLayoutRect msgTextPane;
       
   659     msgTextPane.LayoutRect(
       
   660         dataPane,
       
   661         AknLayoutScalable_Apps::msg_text_pane( 0 ).LayoutLine() );
       
   662     TAknLayoutRect msgBodyPane;
       
   663     msgBodyPane.LayoutRect(
       
   664             msgTextPane.Rect(),
       
   665             AknLayoutScalable_Apps::msg_body_pane().LayoutLine() );
       
   666 
       
   667     if ( IsReadOnly() )
       
   668         {
       
   669         iTextLayout.LayoutText(
       
   670             msgBodyPane.Rect(),
       
   671             AknLayoutScalable_Apps::msg_body_pane_t1( 0 ).LayoutLine() );
       
   672         }
       
   673     else
       
   674         {
       
   675         iTextLayout.LayoutText(
       
   676             msgBodyPane.Rect(),
       
   677             AknLayoutScalable_Apps::msg_body_pane_t1( 1 ).LayoutLine() );            
       
   678         }
       
   679 
       
   680     
       
   681     if ( MsgEditorCustomDraw() )
       
   682         {
       
   683         MsgEditorCustomDraw()->ResolveLayouts();
       
   684         }
       
   685     }
       
   686 
       
   687 // ---------------------------------------------------------
       
   688 // CMsgBodyControlEditor::LayoutEdwin
       
   689 // ---------------------------------------------------------
       
   690 //
       
   691 void CMsgBodyControlEditor::LayoutEdwin()
       
   692     {
       
   693     TAknLayoutRect msgTextPane;
       
   694     msgTextPane.LayoutRect( MsgEditorCommons::MsgDataPane(),
       
   695                             AknLayoutScalable_Apps::msg_text_pane( 0 ).LayoutLine() );
       
   696                             
       
   697     TAknLayoutRect msgBodyPane;
       
   698     msgBodyPane.LayoutRect( msgTextPane.Rect(),
       
   699                             AknLayoutScalable_Apps::msg_body_pane().LayoutLine() );
       
   700     
       
   701     TRect parentRect( msgBodyPane.Rect() );
       
   702     parentRect.Move( 0, iParentControl->Position().iY );
       
   703     
       
   704     DoLayoutEdwin( parentRect, 
       
   705                    AknLayoutScalable_Apps::msg_body_pane_t1( 0 ).LayoutLine() );
       
   706     }
       
   707 
       
   708 // ---------------------------------------------------------
       
   709 // CMsgBodyControlEditor::PrepareFocusTransition
       
   710 //
       
   711 // Do not change focus when automatic find parsing has been finished
       
   712 // if focus transition out of this control has been performed.
       
   713 // ---------------------------------------------------------
       
   714 //
       
   715 void CMsgBodyControlEditor::PrepareFocusTransition()
       
   716     {
       
   717     if ( IsFocused() )
       
   718         {
       
   719         iFocusChangedBeforeParseFinish = EFalse;
       
   720         }
       
   721     }
       
   722 
       
   723 // ---------------------------------------------------------
       
   724 // CMsgBodyControlEditor::SetTextSkinColorIdL
       
   725 // ---------------------------------------------------------
       
   726 //
       
   727 void CMsgBodyControlEditor::SetTextSkinColorIdL()
       
   728     {
       
   729     CEikEdwin::SetTextSkinColorIdL( EAknsCIQsnTextColorsCG6 );
       
   730     }
       
   731 
       
   732 // ---------------------------------------------------------
       
   733 // CMsgBodyControlEditor::HandleResourceChange
       
   734 //
       
   735 // Sets correct highlight extension.
       
   736 // ---------------------------------------------------------
       
   737 //
       
   738 void CMsgBodyControlEditor::HandleResourceChange( TInt aType )
       
   739     {
       
   740     CMsgExpandableControlEditor::HandleResourceChange( aType );
       
   741     
       
   742     if ( aType == KAknsMessageSkinChange &&  MsgEditorCustomDraw() )
       
   743         {
       
   744          MsgEditorCustomDraw()->SkinChanged();;    
       
   745     	}
       
   746     }
       
   747 // ---------------------------------------------------------
       
   748 // CMsgBodyControlEditor::PrepareForReadOnlyL
       
   749 //
       
   750 // Sets SetItemFinderObserverL for viewers
       
   751 // ---------------------------------------------------------
       
   752 //
       
   753 
       
   754 void CMsgBodyControlEditor::PrepareForReadOnlyL( TBool aReadOnly )
       
   755    {
       
   756    if ( iItemFinder )
       
   757        {
       
   758        if ( aReadOnly )
       
   759            {
       
   760            iItemFinder->SetItemFinderObserverL( this ); 
       
   761            }
       
   762        else
       
   763            {
       
   764            iItemFinder->SetItemFinderObserverL( NULL );
       
   765            }
       
   766        } 
       
   767 
       
   768    CMsgExpandableControlEditor::PrepareForReadOnlyL( aReadOnly );
       
   769    }
       
   770 
       
   771 
       
   772 //  End of File