meetingrequest/mrgui/mrfieldbuildercommon/src/cesmrrichtextviewer.cpp
branchRCL_3
changeset 12 4ce476e64c59
parent 4 e7aa27f58ae1
child 13 8592a65ad3fb
equal deleted inserted replaced
11:0396474f30f5 12:4ce476e64c59
     1 /*
     1 /*
     2 * Copyright (c) 2003-2009 Nokia Corporation and/or its subsidiary(-ies).
     2 * Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
     3 * All rights reserved.
     3 * All rights reserved.
     4 * This component and the accompanying materials are made available
     4 * This component and the accompanying materials are made available
     5 * under the terms of "Eclipse Public License v1.0"
     5 * under the terms of "Eclipse Public License v1.0"
     6 * which accompanies this distribution, and is available
     6 * which accompanies this distribution, and is available
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
    10 * Nokia Corporation - initial contribution.
    10 * Nokia Corporation - initial contribution.
    11 *
    11 *
    12 * Contributors:
    12 * Contributors:
    13 *
    13 *
    14 *  Description : CEikRichTextEditor based Rich Text viewer
    14 *  Description : CEikRichTextEditor based Rich Text viewer
       
    15 *  Version     : %version: e002sa32#36 %
    15 *
    16 *
    16 */
    17 */
    17 
    18 
    18 #include "cesmrrichtextviewer.h"
    19 #include "cesmrrichtextviewer.h"
    19 
    20 
    20 #include "mesmrlistobserver.h"// SCROLLING_MOD: List observer header
    21 #include "mesmrlistobserver.h"// SCROLLING_MOD: List observer header
    21 #include "esmrconfig.hrh"
    22 #include "esmrconfig.hrh"
    22 #include "esmrhelper.h"
    23 #include "esmrhelper.h"
    23 #include "cesmriconfield.h"
       
    24 #include "cesmrfieldcommandevent.h"
    24 #include "cesmrfieldcommandevent.h"
    25 #include "mesmrfieldeventqueue.h"
    25 #include "mesmrfieldeventqueue.h"
    26 #include "cesmrlayoutmgr.h"
       
    27 #include "cesmrrichtextlink.h"
    26 #include "cesmrrichtextlink.h"
    28 #include "cesmrcontactmenuhandler.h"
    27 #include "cesmrcontactmenuhandler.h"
    29 #include "nmrbitmapmanager.h"
    28 #include "nmrbitmapmanager.h"
       
    29 #include "nmrcolormanager.h"
       
    30 #include "esmrfieldbuilderdef.h"
       
    31 #include "cesmrfield.h"
    30 
    32 
    31 #include <esmrgui.rsg>
    33 #include <esmrgui.rsg>
    32 #include <commonphoneparser.h>
    34 #include <commonphoneparser.h>
    33 #include <finditemengine.h>
    35 #include <finditemengine.h>
    34 #include <txtrich.h>
    36 #include <txtrich.h>
    35 #include <AknsUtils.h>
    37 #include <aknsutils.h>
       
    38 #include <aknbiditextutils.h>
       
    39 #include <aknutils.h>
    36 #include <eikenv.h>
    40 #include <eikenv.h>
    37 #include <data_caging_path_literals.hrh>
    41 #include <data_caging_path_literals.hrh>
    38 #include <baclipb.h> // for clipboard copy
    42 #include <baclipb.h> // for clipboard copy
    39 #include <aknlongtapdetector.h>
       
    40 #include <touchfeedback.h>
       
    41 
       
    42 #ifndef FF_CMAIL_INTEGRATION
       
    43 #include <txtclipboard.h>
    43 #include <txtclipboard.h>
    44 #endif // FF_CMAIL_INTEGRATION
       
    45 
    44 
    46 // DEBUG
    45 // DEBUG
    47 #include "emailtrace.h"
    46 #include "emailtrace.h"
    48 
    47 
    49 // <cmail> Removed profiling. </cmail>
       
    50 
       
    51 // Unnamed namespace for local definitions
    48 // Unnamed namespace for local definitions
    52 namespace{ // codescanner::namespace
    49 namespace{ // codescanner::namespace
    53 
    50 
    54 const TInt KArrowUpperMargin (2);
    51 #ifdef _DEBUG
    55 const TInt KArrowRightMargin (5);
    52     enum TPanic
       
    53         {
       
    54         EParaFormatNotInitialised = 1
       
    55         };
       
    56     void Panic( TPanic aPanic )
       
    57         {
       
    58         _LIT( KCategory, "CESMRRichTextViewer" );
       
    59         User::Panic( KCategory(), aPanic );
       
    60         }
       
    61 #endif // DEBUG
       
    62 
       
    63 // Side margin in twips, needed because not possible to set it in pixels
       
    64 const TInt KDefaultTextSideMargin( 1 );
    56 
    65 
    57 }//namespace
    66 }//namespace
    58 
    67 
    59 // ======== MEMBER FUNCTIONS ========
    68 // ======== MEMBER FUNCTIONS ========
    60 
    69 
    79 //
    88 //
    80 EXPORT_C CESMRRichTextViewer::~CESMRRichTextViewer( )
    89 EXPORT_C CESMRRichTextViewer::~CESMRRichTextViewer( )
    81     {
    90     {
    82     FUNC_LOG;
    91     FUNC_LOG;
    83     iLinkList.ResetAndDestroy ( );
    92     iLinkList.ResetAndDestroy ( );
    84     delete iActionMenuIcon;
       
    85     delete iActionMenuIconMask;
       
    86     iESMRStatic.Close ( );
    93     iESMRStatic.Close ( );
    87     delete iLongTapDetector;
    94     delete iParaFormat;
    88     }
    95     }
    89 
    96 
    90 // -----------------------------------------------------------------------------
    97 // -----------------------------------------------------------------------------
    91 // CESMRRichTextViewer::PositionChanged
    98 // CESMRRichTextViewer::PositionChanged
    92 // -----------------------------------------------------------------------------
    99 // -----------------------------------------------------------------------------
   114         {
   121         {
   115         // not constructed totally:
   122         // not constructed totally:
   116         return;
   123         return;
   117         }
   124         }
   118 
   125 
   119     if ( IsFocused() )
   126     // Check the current selection.
   120         {
   127     // If a link has been highlighted, don't change it.
   121         if( iLayout )
   128     TCursorSelection selection = Selection();
   122             {
   129 
   123             TRAP_IGNORE( SetFontColorL( ETrue ) );
   130     // Gaining focus
   124             }
   131     if ( IsFocused()
   125 
   132          && iLinkList.Count() > 0
   126         if ( iCurrentLinkIndex == KErrNotFound )
   133          && selection.Length() == 0 )
   127             {
   134         {
   128             TInt linkRow = KErrNotFound;
   135         // We need the field indexes, cast required
   129             if ( CursorPos() == 0 )
   136         CESMRField* parent = static_cast< CESMRField* >( Parent() );
   130                 {
   137 
   131                 // focus is coming from field above:
   138         iCntMenuHdlr->SetContactMenuObserver( this );
   132                 linkRow = FindTextLinkBetweenNextScrollArea(
   139         // Focus coming from above ...
   133                 		0, 1, TCursorPosition::EFLineDown );
   140         if( parent->CurrentItemIndex() > parent->PreItemIndex() )
   134                 }
   141             {
   135             else
   142             // ... Highlight first link
   136                 {
   143             TRAP_IGNORE( HighlightLinkL( *( iLinkList[0] ) ) );
   137                 linkRow = FindTextLinkBetweenNextScrollArea(
   144             }
   138                 		LineCount()-2,
   145         // Focus coming from below ...
   139                         LineCount()-1,
       
   140                         TCursorPosition::EFLineUp);
       
   141                 }
       
   142             if ( linkRow != KErrNotFound )
       
   143                 {
       
   144                 const CESMRRichTextLink* link = GetSelectedLink ( );
       
   145                 if (link )
       
   146                     {
       
   147                     HighlightLink (*link );
       
   148                     DrawDeferred ( );
       
   149                     }
       
   150                 }
       
   151             }
       
   152         else
   146         else
   153             {
   147             {
   154             const CESMRRichTextLink* link = GetSelectedLink ( );
   148             // ... Highlight last link
   155             if ( link )
   149             TRAP_IGNORE( HighlightLinkL( *( iLinkList[iLinkList.Count() - 1 ] ) ) );
   156             	{
   150             }
   157             	HighlightLink( *link );
   151         DrawDeferred();
   158             	DrawDeferred();
   152         }
   159             	}
   153 
   160             }
   154     // Losing focus
   161         }
   155     if ( !IsFocused() )
   162 
   156         {
   163     if (!IsFocused())
   157         TRAP_IGNORE(
   164         {
   158                 SetSelectionL( CursorPos(), CursorPos() );
   165         // losing focus
   159                 ResetActionMenuL();
   166         // <cmail> codescanner
   160                 );
   167 		TRAP_IGNORE(SetSelectionL(CursorPos(), CursorPos()));
       
   168         if( iLayout )
       
   169             {
       
   170             TRAP_IGNORE(SetFontColorL( EFalse ));
       
   171             }
       
   172         // </cmail>
       
   173         TRAP_IGNORE( TextView()->SetDocPosL( 0 ));
       
   174         }
   161         }
   175     }
   162     }
   176 
   163 
   177 // -----------------------------------------------------------------------------
   164 // -----------------------------------------------------------------------------
   178 // CESMRRichTextViewer::FindTextLinkBetweenNextScrollArea
   165 // CESMRRichTextViewer::FindTextLinkBetweenNextScrollArea
   206                 {
   193                 {
   207                 return linkRow;
   194                 return linkRow;
   208                 }
   195                 }
   209             }
   196             }
   210 
   197 
   211     iCurrentLinkIndex = KErrNotFound;
       
   212     return linkRow;
   198     return linkRow;
   213     }
   199     }
   214 
   200 
   215 // -----------------------------------------------------------------------------
   201 // -----------------------------------------------------------------------------
   216 // CESMRRichTextViewer::ValidLinkForFocusing
   202 // CESMRRichTextViewer::ValidLinkForFocusing
   222         TInt aStartRow,
   208         TInt aStartRow,
   223         TInt aEndRow )
   209         TInt aEndRow )
   224     {
   210     {
   225     FUNC_LOG;
   211     FUNC_LOG;
   226 
   212 
   227 
   213     if ( iLinkList.Count() > aIndex)
   228     if(iLinkList.Count() > aIndex)
       
   229 	    {
   214 	    {
   230         TInt pos = iLinkList[aIndex]->StartPos();
   215 	    TInt currPos( KErrNotFound );
       
   216         const CESMRRichTextLink* currentLink = GetSelectedLink();
       
   217         if ( currentLink )
       
   218             {
       
   219             currPos = currentLink->StartPos();
       
   220             }
       
   221 
       
   222         TInt pos = iLinkList[ aIndex ]->StartPos();
   231 
   223 
   232 	    TInt checkRow = TextLayout()->GetLineNumber( pos );
   224 	    TInt checkRow = TextLayout()->GetLineNumber( pos );
   233 
   225 
   234 	    if ( checkRow >= aStartRow && checkRow <= ( aEndRow ) )
   226 	    if ( checkRow >= aStartRow && checkRow <= aEndRow )
   235 	        {
   227 	        {
   236 	        if ( aDirection == TCursorPosition::EFLineDown &&
   228 	        if ( aDirection == TCursorPosition::EFLineDown &&
   237 	             aIndex > iCurrentLinkIndex  ||
   229 	             pos > currPos ||
   238 	             aDirection == TCursorPosition::EFLineUp &&
   230 	             aDirection == TCursorPosition::EFLineUp &&
   239 	             ( aIndex < iCurrentLinkIndex ||
   231 	             ( pos < currPos || currPos == KErrNotFound ) )
   240 	               iCurrentLinkIndex == KErrNotFound ))
       
   241 	            {
   232 	            {
   242 	            iCurrentLinkIndex = aIndex;
       
   243 
       
   244 	            // link found between next scroll area.
   233 	            // link found between next scroll area.
   245 	            return checkRow;
   234 	            return checkRow;
   246 	            }
   235 	            }
   247 	        }
   236 	        }
   248 	    }
   237 	    }
   249     return KErrNotFound;
   238     return KErrNotFound;
   250     }
   239     }
   251 
   240 
   252 // -----------------------------------------------------------------------------
   241 // -----------------------------------------------------------------------------
   253 // CESMRRichTextViewer::SetHighLightToNextLinkL
       
   254 // -----------------------------------------------------------------------------
       
   255 //
       
   256 TBool CESMRRichTextViewer::SetHighLightToNextLinkL(
       
   257         TCursorPosition::TMovementType aDirection,
       
   258         TInt aStartRow,
       
   259         TInt aEndRow )
       
   260     {
       
   261     FUNC_LOG;
       
   262     TBool ret( EFalse );
       
   263 
       
   264     TInt currentLineNumber = TextLayout()->GetLineNumber( CursorPos() );
       
   265 
       
   266     // check is there a link before next scroll point:
       
   267     TInt linkRow = FindTextLinkBetweenNextScrollArea(
       
   268 						aStartRow , aEndRow, aDirection);
       
   269 
       
   270     if ( linkRow != KErrNotFound && iCurrentLinkIndex != KErrNotFound )
       
   271         {
       
   272         const CESMRRichTextLink* link = GetSelectedLink ( );
       
   273         if (link )
       
   274             {
       
   275             HighlightLink (*link );
       
   276 
       
   277             if ( iObserver && linkRow != currentLineNumber )
       
   278                 {
       
   279                 TInt endOfLink = link->StartPos()+link->Length();
       
   280                 TInt line = TextLayout()->GetLineNumber( endOfLink );
       
   281                 if ( aDirection == TCursorPosition::EFLineUp ) // moving up:
       
   282                     {
       
   283                     iObserver->MoveListAreaDownL(
       
   284                             RowHeight() * ( currentLineNumber - line ));
       
   285                     }
       
   286                 else
       
   287                     {
       
   288                     iObserver->MoveListAreaUpL(
       
   289                             RowHeight() * ( line - currentLineNumber ));
       
   290                     }
       
   291                 }
       
   292 
       
   293             DrawDeferred ( );
       
   294             ret = ETrue;
       
   295             }
       
   296         }
       
   297     else
       
   298     	{
       
   299     	// no link are focused, do reset work to refresh the option menu.
       
   300     	ResetActionMenuL();
       
   301     	}
       
   302 
       
   303     return ret;
       
   304     }
       
   305 
       
   306 // -----------------------------------------------------------------------------
       
   307 // CESMRRichTextViewer::OfferKeyEventL
   242 // CESMRRichTextViewer::OfferKeyEventL
   308 // -----------------------------------------------------------------------------
   243 // -----------------------------------------------------------------------------
   309 //
   244 //
   310 EXPORT_C TKeyResponse CESMRRichTextViewer::OfferKeyEventL(
   245 EXPORT_C TKeyResponse CESMRRichTextViewer::OfferKeyEventL(
   311         const TKeyEvent &aKeyEvent,
   246         const TKeyEvent &aKeyEvent,
   312         TEventCode aType )
   247         TEventCode aType )
   313     {
   248     {
   314     FUNC_LOG;
   249     FUNC_LOG;
   315     // Handle only event keys
   250     TKeyResponse response( EKeyWasNotConsumed );
   316     if ( aType == EEventKey )
   251 
   317         {
   252     // Handle only event keys.
   318         if ( iObserver ) // only description field has observer set.
   253     if( aType != EEventKey )
   319             {
   254         {
   320             // fetch the current line number:
   255         return response;
   321             TInt currentLineNumber = TextLayout()->GetLineNumber( CursorPos() );
   256         }
   322 
   257 
   323             if ( aKeyEvent.iCode == EKeyDownArrow && aType == EEventKey )
   258     /*
   324                 {
   259      * Handles scrolling between rich text links.
   325                 if ( !iObserver->IsFieldBottomVisible() &&
   260      */
   326                      SetHighLightToNextLinkL(
   261     const CESMRRichTextLink* selectedLink = GetSelectedLink();
   327                     		 TCursorPosition::EFLineDown,
   262     TInt linkCount = iLinkList.Count();
   328                              currentLineNumber,
   263 
   329                              currentLineNumber + KMaxAddressFieldLines) )
   264     // If a link is selected, it means that we are operating within
       
   265     // the field and can move focus between the links.
       
   266     if( linkCount && selectedLink )
       
   267         {
       
   268         TInt selectedLinkIndex = iLinkList.Find( selectedLink );
       
   269 
       
   270         switch ( aKeyEvent.iCode )
       
   271             {
       
   272             case EKeyLeftArrow:
       
   273             case EKeyUpArrow:
       
   274                 {
       
   275                 // If possible and exists ...
       
   276                 if( selectedLinkIndex > 0 &&
       
   277                         selectedLinkIndex < linkCount )
   330                     {
   278                     {
   331                     return EKeyWasConsumed;
   279                     // ...Highlight previous link.
       
   280                     HighlightLinkL( *( iLinkList[ selectedLinkIndex - 1 ] ) );
       
   281                     response = EKeyWasConsumed;
       
   282 
       
   283                     // View update required, for example if link is out of
       
   284                     // viewable area.
       
   285                     UpdateViewL( aKeyEvent );
   332                     }
   286                     }
   333                 else if ( iObserver->IsFieldBottomVisible() )
   287 
       
   288                 break;
       
   289                 }
       
   290             case EKeyRightArrow:
       
   291             case EKeyDownArrow:
       
   292                 {
       
   293                 // If possible and exists ...
       
   294                 if( selectedLinkIndex + 1 < linkCount &&
       
   295                         selectedLinkIndex >= 0 )
   334                     {
   296                     {
   335                     if ( SetHighLightToNextLinkL(TCursorPosition::EFLineDown,
   297                     // ...Highlight next link.
   336                                             currentLineNumber,
   298                     HighlightLinkL( *( iLinkList[ selectedLinkIndex + 1 ] ) );
   337                                             iNumberOfLines) )
   299                     response = EKeyWasConsumed;
       
   300 
       
   301                     // View update required, for example if link is out of
       
   302                     // viewable area.
       
   303                     UpdateViewL( aKeyEvent );
       
   304                     }
       
   305 
       
   306                 break;
       
   307                 }
       
   308             case EKeyDevice3: // Selection key
       
   309                 {
       
   310                 // No implementation. Non-MSK devices might require this.
       
   311                 break;
       
   312                 }
       
   313             default:
       
   314                 break;
       
   315             }
       
   316         }
       
   317 
       
   318     return response;
       
   319     }
       
   320 
       
   321 // -----------------------------------------------------------------------------
       
   322 // CESMRRichTextViewer::HandlePointerEventL
       
   323 // -----------------------------------------------------------------------------
       
   324 //
       
   325 void CESMRRichTextViewer::HandlePointerEventL( const TPointerEvent& aPointerEvent )
       
   326     {
       
   327     if ( Rect().Contains( aPointerEvent.iPosition) )
       
   328         {
       
   329         TBool linkFound( EFalse );
       
   330 
       
   331         switch ( aPointerEvent.iType )
       
   332             {
       
   333             case TPointerEvent::EButton1Down:
       
   334             case TPointerEvent::EDrag:
       
   335                 {
       
   336                 RRegion linkArea;
       
   337                 CleanupClosePushL( linkArea );
       
   338 
       
   339                 // Find matching link
       
   340                 TInt count = iLinkList.Count();
       
   341 
       
   342                 for ( TInt i = 0; i < count; ++i )
       
   343                     {
       
   344                     CESMRRichTextLink* link = iLinkList[ i ];
       
   345                     GetLinkAreaL( linkArea, *link );
       
   346 
       
   347                     if ( linkArea.Contains( aPointerEvent.iPosition ) )
   338                         {
   348                         {
   339                         return EKeyWasConsumed;
   349                         if ( link != GetSelectedLink() )
       
   350                             {
       
   351                             iCntMenuHdlr->SetContactMenuObserver( this );
       
   352                             HighlightLinkL( *link );
       
   353                             DrawDeferred();
       
   354                             }
       
   355 
       
   356                         linkFound = ETrue;
       
   357                         break;
   340                         }
   358                         }
   341                     // means that the whole control is visible:
       
   342                     // and we can skip to next field
       
   343                     return EKeyWasNotConsumed;
       
   344                     }
   359                     }
   345 
   360 
   346                 if ( currentLineNumber == iNumberOfLines )
   361                 CleanupStack::PopAndDestroy( &linkArea );
       
   362 
       
   363                 break;
       
   364                 }
       
   365 
       
   366             case TPointerEvent::EButton1Up:
       
   367                 {
       
   368                 const CESMRRichTextLink* link = GetSelectedLink();
       
   369 
       
   370                 TBool menuAvailable = iCntMenuHdlr->OptionsMenuAvailable();
       
   371 
       
   372                 if ( link
       
   373                      && ( menuAvailable
       
   374                      || link->Type() == CESMRRichTextLink::ETypeLocationUrl
       
   375                      || link->Type() == CESMRRichTextLink::ETypeAttachment ) )
   347                     {
   376                     {
   348                     // the end of text has been reached
   377                     linkFound = ETrue;
   349                     return EKeyWasConsumed;
   378 
       
   379                     LinkSelectedL();
   350                     }
   380                     }
   351 
   381                 else if ( link && !menuAvailable )
   352                 // move three lines...
       
   353                 ScrollViewL( KMaxAddressFieldLines,
       
   354 							 TCursorPosition::EFLineDown);
       
   355 
       
   356 
       
   357                 SetSelectionL( CursorPos(), CursorPos() );
       
   358                 iCurrentLinkIndex = KErrNotFound;
       
   359                 if ( iObserver )
       
   360                     {
   382                     {
   361                     iObserver->MoveListAreaUpL(
   383                     linkFound = ETrue;
   362                     		RowHeight() * KMaxAddressFieldLines );
   384                     iOpenActionMenu = ETrue;
   363                     }
   385                     }
   364 
   386                 break;
   365                 return EKeyWasConsumed;
   387                 }
   366                 }
   388             default:
   367             else if ( aKeyEvent.iCode == EKeyUpArrow && aType == EEventKey )
   389                 {
   368                 {
   390                 break;
   369                 if (iPosition.iY < 0 &&
   391                 }
   370                     SetHighLightToNextLinkL(
   392             }
   371                     		TCursorPosition::EFLineUp,
   393 
   372                             currentLineNumber - KMaxAddressFieldLines,
   394         if ( !linkFound )
   373                             currentLineNumber))
   395             {
   374                     {
   396             // Tap on plain text
   375                     return EKeyWasConsumed;
   397             TextView()->ClearSelectionL();
   376                     }
   398             ResetActionMenuL();
   377                 if ( iPosition.iY > 0 )
   399             DrawDeferred();
   378                     {
   400             }
   379                     // before changing the focus the field above,
   401 
   380                     // check is there any links in rest of text
   402         }
   381                     if (SetHighLightToNextLinkL(TCursorPosition::EFLineUp,
   403 
   382                                         0,
       
   383                                         currentLineNumber))
       
   384                         {
       
   385                         return EKeyWasConsumed;
       
   386                         }
       
   387 
       
   388                     // means that the whole control is visible:
       
   389                     // and we can skip to next field
       
   390                     return EKeyWasNotConsumed;
       
   391                     }
       
   392                 else
       
   393                     {
       
   394                     TInt currentLineNumber =
       
   395                     TextLayout()->GetLineNumber( CursorPos() );
       
   396                     // move three lines...
       
   397                     ScrollViewL( KMaxAddressFieldLines,
       
   398                     		     TCursorPosition::EFLineUp);
       
   399 
       
   400                     SetSelectionL( CursorPos(), CursorPos());
       
   401                     iCurrentLinkIndex = KErrNotFound;
       
   402 
       
   403                      if ( iObserver )
       
   404                         {
       
   405                         iObserver->MoveListAreaDownL(
       
   406                         		RowHeight() * KMaxAddressFieldLines );
       
   407                         }
       
   408 
       
   409                     currentLineNumber =
       
   410 						TextLayout()->GetLineNumber( CursorPos() );
       
   411                     return EKeyWasConsumed;
       
   412                     }
       
   413                 }
       
   414             }
       
   415         if ( aKeyEvent.iCode == EKeyRightArrow ||
       
   416         	 aKeyEvent.iCode == EKeyDevice3 ||
       
   417              aKeyEvent.iCode == EKeyDevice4 ||
       
   418              aKeyEvent.iCode == EKeyEnter )
       
   419             {
       
   420             // Show right click menu (action menu)
       
   421             const CESMRRichTextLink* link = GetSelectedLink();
       
   422             if (link &&
       
   423             	link->TriggerKey ( )== CESMRRichTextLink::ETriggerKeyRight )
       
   424                 {
       
   425                 if ( !iLinkObserver ||
       
   426                 	 !iLinkObserver->HandleRichTextLinkSelection(link) )
       
   427                     {
       
   428                     iCntMenuHdlr->ShowActionMenuL();
       
   429                     }
       
   430                 return EKeyWasConsumed;
       
   431                 }
       
   432             }
       
   433         if ( aKeyEvent.iCode == EKeyLeftArrow )
       
   434             {
       
   435             const CESMRRichTextLink* link = GetSelectedLink();
       
   436             if ( link )
       
   437                 {
       
   438                 return EKeyWasConsumed;
       
   439                 }
       
   440             }
       
   441         if ( aKeyEvent.iCode == EKeyDevice3 ||
       
   442         		aKeyEvent.iCode == EKeyDevice4 ||
       
   443         		aKeyEvent.iCode == EKeyEnter )
       
   444             {
       
   445             // Select link
       
   446             const CESMRRichTextLink* link = GetSelectedLink ( );
       
   447             if (link &&
       
   448             	link->TriggerKey ( )== CESMRRichTextLink::ETriggerKeyOk )
       
   449                 {
       
   450                 if (iLinkObserver &&
       
   451                 	iLinkObserver->HandleRichTextLinkSelection (link ) )
       
   452                     {
       
   453                     return EKeyWasConsumed;
       
   454                     }
       
   455                 }
       
   456             }
       
   457         }
       
   458 
       
   459     return EKeyWasNotConsumed;
       
   460     }
       
   461 
       
   462 
       
   463 // -----------------------------------------------------------------------------
       
   464 // CESMRRichTextViewer::ScrollViewL
       
   465 // -----------------------------------------------------------------------------
       
   466 //
       
   467 void CESMRRichTextViewer::ScrollViewL(
       
   468         TInt aNumberOfRows,
       
   469         TCursorPosition::TMovementType aDirection)
       
   470     {
       
   471     FUNC_LOG;
       
   472     for( TInt i=0; i < aNumberOfRows; i++ )
       
   473         {
       
   474         MoveCursorL( aDirection, EFalse);
       
   475         }
       
   476     }
   404     }
   477 
   405 
   478 // -----------------------------------------------------------------------------
   406 // -----------------------------------------------------------------------------
   479 // CESMRRichTextViewer::SetMargins
   407 // CESMRRichTextViewer::SetMargins
   480 // -----------------------------------------------------------------------------
   408 // -----------------------------------------------------------------------------
   481 //
   409 //
   482 EXPORT_C void CESMRRichTextViewer::SetMargins( TInt sMargin )
   410 EXPORT_C void CESMRRichTextViewer::SetMargins( TInt sMargin )
   483 	{
   411 	{
   484 	// Set new value for left and right margins
   412 	// Set new value for left and right margins
   485 	if ( TextView() )
   413     TextView()->SetMarginWidths( sMargin ,0);
   486 	    {
       
   487         TextView()->SetMarginWidths( sMargin ,0);
       
   488 	    }
       
   489 	}
   414 	}
   490 
   415 
   491 // -----------------------------------------------------------------------------
   416 // -----------------------------------------------------------------------------
       
   417 // CESMRRichTextViewer::SetTextL
       
   418 // -----------------------------------------------------------------------------
       
   419 //
       
   420 EXPORT_C void CESMRRichTextViewer::SetTextL(
       
   421         const TDesC* aText,
       
   422         TBool aSearchLinks )
       
   423     {
       
   424     FUNC_LOG;
       
   425 
       
   426     iLinkList.ResetAndDestroy();
       
   427 
       
   428     TextView()->SetMarginWidths( KDefaultTextSideMargin ,0);
       
   429 
       
   430     // Clear edwin text
       
   431     CEikEdwin::SetCursorPosL( 0, EFalse );
       
   432     CEikRichTextEditor::SetTextL( &KNullDesC );
       
   433     RichText()->Reset();
       
   434 
       
   435     // text lenght plus one to ensure the formatting
       
   436     // used is full, not band formatting.
       
   437     SetUpperFullFormattingLength( aText->Length() + 1 );
       
   438 
       
   439     // Set new edwin text
       
   440     CEikEdwin::SetTextLimit( aText->Length ( ) );
       
   441     CEikRichTextEditor::SetTextL( aText );
       
   442 
       
   443     //Make sure cursor is invisible and selection visible
       
   444     TextView()->SetCursorVisibilityL(
       
   445             TCursor::EFCursorInvisible,
       
   446             TCursor::EFCursorInvisible );
       
   447     TextView()->SetSelectionVisibilityL( ETrue );
       
   448 
       
   449     // Search text for links (highlights)
       
   450     if ( aSearchLinks )
       
   451         {
       
   452         SearchLinksL( *aText );
       
   453         // find first link.
       
   454         FindTextLinkBetweenNextScrollArea(0, KMaxAddressFieldLines, TCursorPosition::EFLineDown);
       
   455         }
       
   456     }
       
   457 
       
   458 // -----------------------------------------------------------------------------
       
   459 // CESMRRichTextViewer::SetLinkObserver
       
   460 // -----------------------------------------------------------------------------
       
   461 //
       
   462 EXPORT_C void CESMRRichTextViewer::SetLinkObserver(
       
   463         MESMRRichTextObserver* aLinkObserver )
       
   464     {
       
   465     FUNC_LOG;
       
   466     iLinkObserver = aLinkObserver;
       
   467     }
       
   468 
       
   469 // -----------------------------------------------------------------------------
       
   470 // CESMRRichTextViewer::AddLinkL
       
   471 // -----------------------------------------------------------------------------
       
   472 //
       
   473 EXPORT_C void CESMRRichTextViewer::AddLinkL( CESMRRichTextLink* aLink )
       
   474     {
       
   475     FUNC_LOG;
       
   476     // If this is first link, set it highlighted
       
   477     TBool highlight = IsFocused()&& ( iLinkList.Count() == 0 );
       
   478 
       
   479     // Reserve space for new link
       
   480     iLinkList.ReserveL( iLinkList.Count() + 1 );
       
   481 
       
   482     RichText()->ApplyCharFormatL( iRichTextLinkFormat,
       
   483                                   iRichTextLinkFormatMask,
       
   484                                   aLink->StartPos(),
       
   485                                   aLink->Length() );
       
   486 
       
   487     // Append aLink to link list. Space has been reserved, so this cannot fail.
       
   488     iLinkList.AppendL( aLink );
       
   489 
       
   490     if ( highlight )
       
   491         {
       
   492         HighlightLinkL( *aLink );
       
   493         }
       
   494     }
       
   495 
       
   496 // -----------------------------------------------------------------------------
       
   497 // CESMRRichTextViewer::InsertLinkL
       
   498 // -----------------------------------------------------------------------------
       
   499 //
       
   500 EXPORT_C void CESMRRichTextViewer::InsertLinkL( CESMRRichTextLink* aLink,
       
   501                                                 TInt aPosition )
       
   502     {
       
   503     FUNC_LOG;
       
   504     // If this is first link, set it highlighted
       
   505     TBool highlight = IsFocused()&& ( iLinkList.Count() == 0 );
       
   506 
       
   507     // Reserve space for new link
       
   508     iLinkList.ReserveL( iLinkList.Count() + 1 );
       
   509 
       
   510     RichText()->ApplyCharFormatL( iRichTextLinkFormat,
       
   511                                   iRichTextLinkFormatMask,
       
   512                                   aLink->StartPos(),
       
   513                                   aLink->Length() );
       
   514 
       
   515     // Insert aLink to link list. Space has been reserved, so this cannot fail.
       
   516     // InsertL panics if aPosition is illegal.
       
   517     iLinkList.InsertL( aLink, aPosition );
       
   518 
       
   519     if ( highlight )
       
   520         {
       
   521         HighlightLinkL( *aLink );
       
   522         }
       
   523     }
       
   524 
       
   525 // -----------------------------------------------------------------------------
       
   526 // CESMRRichTextViewer::GetSelectedLink
       
   527 // -----------------------------------------------------------------------------
       
   528 //
       
   529 EXPORT_C const CESMRRichTextLink* CESMRRichTextViewer::GetSelectedLink( ) const
       
   530     {
       
   531     FUNC_LOG;
       
   532     CESMRRichTextLink* link( NULL );
       
   533 
       
   534     TCursorSelection currentSelection = Selection();
       
   535 
       
   536     for ( TInt i = 0; i < iLinkList.Count(); ++i )
       
   537         {
       
   538         CESMRRichTextLink* tempLink = iLinkList[i];
       
   539         TInt startPos = tempLink->StartPos();
       
   540         TInt length = tempLink->Length();
       
   541 
       
   542         TCursorSelection linkSelection( startPos, startPos + length );
       
   543 
       
   544         if( currentSelection.iCursorPos == linkSelection.iCursorPos &&
       
   545                 currentSelection.iAnchorPos == linkSelection.iAnchorPos )
       
   546             {
       
   547             link = tempLink;
       
   548             break;
       
   549             }
       
   550         }
       
   551 
       
   552     return link;
       
   553     }
       
   554 
       
   555 // -----------------------------------------------------------------------------
       
   556 // CESMRRichTextViewer::GetLinkTextL
       
   557 // -----------------------------------------------------------------------------
       
   558 //
       
   559 EXPORT_C HBufC* CESMRRichTextViewer::GetLinkTextLC(
       
   560         const CESMRRichTextLink& aLink ) const
       
   561     {
       
   562     FUNC_LOG;
       
   563     return RichText()->Read( aLink.StartPos(), aLink.Length() ).AllocLC();
       
   564     }
       
   565 
       
   566 // -----------------------------------------------------------------------------
       
   567 // CESMRRichTextViewer::CESMRRichTextViewer
       
   568 // -----------------------------------------------------------------------------
       
   569 //
       
   570 EXPORT_C void CESMRRichTextViewer::SetListObserver(
       
   571         MESMRListObserver* aObserver )
       
   572     {
       
   573     FUNC_LOG;
       
   574     iObserver = aObserver;
       
   575     }
       
   576 
       
   577 // -----------------------------------------------------------------------------
       
   578 // CESMRRichTextViewer::RowHeight
       
   579 // -----------------------------------------------------------------------------
       
   580 //
       
   581 EXPORT_C TInt CESMRRichTextViewer::RowHeight()
       
   582     {
       
   583     FUNC_LOG;
       
   584     TInt bandHeight = TextLayout()->BandHeight();
       
   585     // Starts from zero, so let's increase the count by one.
       
   586     TInt lineNumberCount = TextLayout()->GetLineNumber( TextLength() ) + 1;
       
   587 
       
   588     return ( bandHeight / lineNumberCount );
       
   589     }
       
   590 
       
   591 // -----------------------------------------------------------------------------
       
   592 // CESMRRichTextViewer::LineCount
       
   593 // -----------------------------------------------------------------------------
       
   594 //
       
   595 EXPORT_C TInt CESMRRichTextViewer::LineCount()
       
   596     {
       
   597     FUNC_LOG;
       
   598 
       
   599     // First row is 0, so let's add one...
       
   600     return ( TextLayout()->GetLineNumber( TextLength() ) + 1 );
       
   601     }
       
   602 // -----------------------------------------------------------------------------
       
   603 // CESMRRichTextViewer::CurrentLineNumber
       
   604 // -----------------------------------------------------------------------------
       
   605 //
       
   606 EXPORT_C TInt CESMRRichTextViewer::CurrentLineNumber()
       
   607     {
       
   608     FUNC_LOG;
       
   609     // first line is zero, let's increase it by one
       
   610     return TextLayout()->GetLineNumber( CursorPos() ) + 1;
       
   611     }
       
   612 
       
   613 // -----------------------------------------------------------------------------
   492 // CESMRRichTextViewer::SetFontL
   614 // CESMRRichTextViewer::SetFontL
   493 // -----------------------------------------------------------------------------
   615 // -----------------------------------------------------------------------------
   494 //
   616 //
   495 EXPORT_C void CESMRRichTextViewer::SetFontL( const CFont* aFont,
   617 EXPORT_C void CESMRRichTextViewer::SetFontL( const CFont* aFont )
   496                                              CESMRLayoutManager* aLayout )
   618     {
   497     {
   619     FUNC_LOG;
   498     FUNC_LOG;
   620     // iFont is stored for changing font color when losing or
   499     // These pointers are stored to able font color changing when losing or
       
   500     // gaining focus
   621     // gaining focus
   501     iLayout = aLayout;
       
   502     iFont = aFont;
   622     iFont = aFont;
   503 
   623     if ( !iParaFormat )
   504     SetFontColorL( IsFocused() );
   624         {
   505 
   625         iParaFormat = new ( ELeave ) CParaFormat();
       
   626         }
       
   627 
       
   628     // All this required, otherwise the font loses its
       
   629     // antialiasing drawing.
       
   630     iParaFormat->iLineSpacingControl = CParaFormat::ELineSpacingExactlyInPixels;
       
   631 
       
   632     iParaFormatMask.SetAttrib( EAttLineSpacing );
       
   633     iParaFormat->iHorizontalAlignment = CParaFormat::ELeftAlign;
       
   634     iParaFormat->iVerticalAlignment = CParaFormat::ECenterAlign;
       
   635     iParaFormatMask.SetAttrib( EAttAlignment );
       
   636     iParaFormatMask.SetAttrib( EAttVerticalAlignment );
       
   637 
       
   638     iCharFormat.iFontSpec = iFont->FontSpecInTwips();
       
   639 
       
   640     iCharFormatMask.SetAttrib( EAttFontTypeface );
       
   641     iCharFormatMask.SetAttrib( EAttFontHeight );
       
   642     iCharFormatMask.SetAttrib( EAttFontPosture );
       
   643     iCharFormatMask.SetAttrib( EAttFontStrokeWeight );
       
   644 
       
   645     iCharFormat.iFontPresentation.iTextColor =
       
   646         NMRColorManager::Color( NMRColorManager::EMRMainAreaTextColor );
       
   647 
       
   648     iCharFormatMask.SetAttrib( EAttColor );
       
   649     }
       
   650 
       
   651 // -----------------------------------------------------------------------------
       
   652 // CESMRRichTextViewer::SetLineSpacingL
       
   653 // -----------------------------------------------------------------------------
       
   654 //
       
   655 EXPORT_C void CESMRRichTextViewer::SetLineSpacingL( TInt aLineSpacingInTwips )
       
   656     {
       
   657     __ASSERT_DEBUG( iParaFormat, Panic( EParaFormatNotInitialised ) );
       
   658     iParaFormatMask.SetAttrib( EAttLineSpacing );
       
   659     iParaFormatMask.SetAttrib( EAttLineSpacingControl );
       
   660     iParaFormat->iLineSpacingControl =
       
   661         CParaFormat::ELineSpacingExactlyInPixels;
       
   662 
       
   663     iParaFormat->iLineSpacingInTwips = aLineSpacingInTwips;
       
   664     }
       
   665 
       
   666 // -----------------------------------------------------------------------------
       
   667 // CESMRRichTextViewer::ApplyLayoutChanges
       
   668 // -----------------------------------------------------------------------------
       
   669 //
       
   670 EXPORT_C void CESMRRichTextViewer::ApplyLayoutChangesL()
       
   671     {
       
   672     __ASSERT_DEBUG( iParaFormat, Panic( EParaFormatNotInitialised ) );
       
   673     CRichText* richtext = RichText();
       
   674     TInt paraCount( richtext->ParagraphCount() );
       
   675     // Go through each paragraph and apply the same format
       
   676     for( TInt i = 0; i < paraCount; ++i  )
       
   677         {
       
   678         TInt paraLen( 0 );   // Length of paragraph
       
   679         TInt fiChPos( 0 );   // First character position of paragraph
       
   680         // Get the length of the paragraph
       
   681         fiChPos = richtext->CharPosOfParagraph( paraLen, i );
       
   682         richtext->ApplyParaFormatL(
       
   683                 iParaFormat, iParaFormatMask, fiChPos, paraLen );
       
   684         richtext->ApplyCharFormatL(
       
   685                 iCharFormat, iCharFormatMask, fiChPos, paraLen );
       
   686         }
   506     // This forces CEikEdwin::OnReformatL to notify observer
   687     // This forces CEikEdwin::OnReformatL to notify observer
   507     // through HandleEdwinSizeEventL about changed size.
   688     // through HandleEdwinSizeEventL about changed size.
   508     // It is notified only if linecount changes.
   689     // It is notified only if linecount changes.
   509     CEikEdwin::iNumberOfLines = 0;
   690     CEikEdwin::iNumberOfLines = 0;
   510     CEikEdwin::FormatTextL();
   691     CEikEdwin::FormatTextL();
   511     }
   692     }
   512 
   693 
   513 // -----------------------------------------------------------------------------
   694 
   514 // CESMRRichTextViewer::SetFontColor
   695 // -----------------------------------------------------------------------------
   515 // -----------------------------------------------------------------------------
   696 // CESMRRichTextViewer::SetSelectedLink
   516 //
   697 // -----------------------------------------------------------------------------
   517 void CESMRRichTextViewer::SetFontColorL( TBool aFocused )
   698 //
   518     {
   699 EXPORT_C void CESMRRichTextViewer::SetFocusLink( TInt aLinkIndex )
   519     FUNC_LOG;
   700     {
   520     // all this stuff is needed to be set, otherwise the
   701     if ( ( aLinkIndex >= 0 ) && ( aLinkIndex < iLinkList.Count() ) )
   521     // font loses its antialiasing drawing
   702         {
   522 
   703         TRAP_IGNORE( HighlightLinkL( *( iLinkList[aLinkIndex] ) ) );
   523     TFontSpec fontSpec = iFont->FontSpecInTwips();
   704         DrawDeferred();
   524 
       
   525     CParaFormat paraFormat;
       
   526     TParaFormatMask paraFormatMask;
       
   527     paraFormat.iLineSpacingControl = CParaFormat::ELineSpacingExactlyInPixels;
       
   528 
       
   529     paraFormatMask.SetAttrib( EAttLineSpacing );
       
   530     paraFormat.iHorizontalAlignment = CParaFormat::ELeftAlign;
       
   531     paraFormatMask.SetAttrib( EAttAlignment );
       
   532 
       
   533     TCharFormat charFormat;
       
   534     TCharFormatMask formatMask;
       
   535     charFormat.iFontSpec = fontSpec;
       
   536 
       
   537     formatMask.SetAttrib( EAttFontTypeface );
       
   538     formatMask.SetAttrib( EAttFontHeight );
       
   539     formatMask.SetAttrib( EAttFontPosture );
       
   540     formatMask.SetAttrib( EAttFontStrokeWeight );
       
   541 
       
   542     if( aFocused )
       
   543         {
       
   544         charFormat.iFontPresentation.iTextColor =
       
   545         iLayout->ViewerListAreaHighlightedTextColor();
       
   546         }
       
   547     else
       
   548         {
       
   549         charFormat.iFontPresentation.iTextColor = KRgbBlack;
       
   550         }
       
   551     formatMask.SetAttrib( EAttColor );
       
   552 
       
   553     CParaFormatLayer* paraFormatLayer =
       
   554         CParaFormatLayer::NewL( &paraFormat, paraFormatMask );
       
   555     CleanupStack::PushL( paraFormatLayer );
       
   556 
       
   557     CCharFormatLayer* charFormatLayer =
       
   558         CCharFormatLayer::NewL( charFormat, formatMask );
       
   559 
       
   560     SetParaFormatLayer( paraFormatLayer );
       
   561     SetCharFormatLayer( charFormatLayer );
       
   562 
       
   563     CleanupStack::Pop( paraFormatLayer );
       
   564     }
       
   565 
       
   566 // -----------------------------------------------------------------------------
       
   567 // CESMRRichTextViewer::SetTextL
       
   568 // -----------------------------------------------------------------------------
       
   569 //
       
   570 EXPORT_C void CESMRRichTextViewer::SetTextL(
       
   571         const TDesC* aText,
       
   572         TBool aSearchLinks )
       
   573     {
       
   574     FUNC_LOG;
       
   575     iCurrentLinkIndex = KErrNotFound;
       
   576     iLinkList.ResetAndDestroy ( );
       
   577 
       
   578     // Clear edwin text
       
   579     CEikEdwin::SetCursorPosL( 0, EFalse );
       
   580 
       
   581     // text lenght plus one to ensure the formatting
       
   582     // used is full, not band formatting.
       
   583     SetUpperFullFormattingLength( aText->Length() + 1 );
       
   584 
       
   585     // Set new edwin text
       
   586     CEikRichTextEditor::SetTextL( aText );
       
   587 
       
   588     //Make sure cursor is invisible and selection visible
       
   589     TextView()->SetCursorVisibilityL (TCursor::EFCursorInvisible,
       
   590             TCursor::EFCursorInvisible );
       
   591     TextView()->SetSelectionVisibilityL (ETrue );
       
   592 
       
   593     // Search text for links (highlights)
       
   594     if (aSearchLinks )
       
   595         {
       
   596         SearchLinksL( *aText );
       
   597         // find first link.
       
   598         FindTextLinkBetweenNextScrollArea(0, KMaxAddressFieldLines, TCursorPosition::EFLineDown);
       
   599         }
       
   600 
       
   601     // first row is 0, so let's add one...
       
   602     iNumberOfLines = TextLayout()->GetLineNumber( TextLength() ) + 1;
       
   603     }
       
   604 
       
   605 // -----------------------------------------------------------------------------
       
   606 // CESMRRichTextViewer::SetLinkObserver
       
   607 // -----------------------------------------------------------------------------
       
   608 //
       
   609 EXPORT_C void CESMRRichTextViewer::SetLinkObserver(
       
   610         MESMRRichTextObserver* aLinkObserver )
       
   611     {
       
   612     FUNC_LOG;
       
   613     iLinkObserver = aLinkObserver;
       
   614     }
       
   615 
       
   616 // -----------------------------------------------------------------------------
       
   617 // CESMRRichTextViewer::AddLinkL
       
   618 // -----------------------------------------------------------------------------
       
   619 //
       
   620 EXPORT_C void CESMRRichTextViewer::AddLinkL( CESMRRichTextLink* aLink )
       
   621     {
       
   622     FUNC_LOG;
       
   623     // If this is first link, set it highlighted
       
   624     TBool highlight = IsFocused()&& ( iLinkList.Count() == 0 );
       
   625 
       
   626     // Reserve space for new link
       
   627     iLinkList.ReserveL( iLinkList.Count() + 1 );
       
   628 
       
   629     RichText()->ApplyCharFormatL( iFormat,
       
   630                                   iFormatMask,
       
   631                                   aLink->StartPos(),
       
   632                                   aLink->Length() );
       
   633 
       
   634     // Append aLink to link list. Space has been reserved, so this cannot fail.
       
   635     iLinkList.AppendL( aLink );
       
   636 
       
   637     if ( highlight )
       
   638         {
       
   639         HighlightLink( *aLink );
       
   640         }
       
   641     }
       
   642 
       
   643 // -----------------------------------------------------------------------------
       
   644 // CESMRRichTextViewer::InsertLinkL
       
   645 // -----------------------------------------------------------------------------
       
   646 //
       
   647 EXPORT_C void CESMRRichTextViewer::InsertLinkL( CESMRRichTextLink* aLink,
       
   648                                                 TInt aPosition )
       
   649     {
       
   650     FUNC_LOG;
       
   651     // If this is first link, set it highlighted
       
   652     TBool highlight = IsFocused()&& ( iLinkList.Count() == 0 );
       
   653 
       
   654     // Reserve space for new link
       
   655     iLinkList.ReserveL( iLinkList.Count() + 1 );
       
   656 
       
   657     RichText()->ApplyCharFormatL( iFormat,
       
   658                                   iFormatMask,
       
   659                                   aLink->StartPos(),
       
   660                                   aLink->Length() );
       
   661 
       
   662     // Insert aLink to link list. Space has been reserved, so this cannot fail.
       
   663     // InsertL panics if aPosition is illegal.
       
   664     iLinkList.InsertL( aLink, aPosition );
       
   665 
       
   666     if ( highlight )
       
   667         {
       
   668         HighlightLink( *aLink );
       
   669         }
   705         }
   670     }
   706     }
   671 
   707 
   672 // -----------------------------------------------------------------------------
   708 // -----------------------------------------------------------------------------
   673 // CESMRRichTextViewer::GetSelectedLink
   709 // CESMRRichTextViewer::GetSelectedLink
   674 // -----------------------------------------------------------------------------
   710 // -----------------------------------------------------------------------------
   675 //
   711 //
   676 EXPORT_C const CESMRRichTextLink* CESMRRichTextViewer::GetSelectedLink( ) const
   712 EXPORT_C TInt CESMRRichTextViewer::GetFocusLink( ) const
   677     {
   713     {
   678     FUNC_LOG;
   714     FUNC_LOG;
   679     if (iCurrentLinkIndex >= 0 && iCurrentLinkIndex < iLinkList.Count ( ) )
   715     // "-1" stand for no link be selected now.
   680         {
   716     TInt linkIndex( KErrNotFound );
   681         return iLinkList[iCurrentLinkIndex];
   717     if ( 0 == iLinkList.Count() )
   682         }
   718         {
   683     else
   719         return linkIndex;
   684         {
   720         }
   685         return NULL;
   721     
   686         }
   722     TCursorSelection currentSelection = Selection();
   687     }
   723 
   688 
   724     for ( TInt i = 0; i < iLinkList.Count(); ++i )
   689 // -----------------------------------------------------------------------------
   725         {
   690 // CESMRRichTextViewer::GetLinkTextL
   726         CESMRRichTextLink* tempLink = iLinkList[i];
   691 // -----------------------------------------------------------------------------
   727         TInt startPos = tempLink->StartPos();
   692 //
   728         TInt length = tempLink->Length();
   693 EXPORT_C HBufC* CESMRRichTextViewer::GetLinkTextL(
   729 
   694         const CESMRRichTextLink& aLink ) const
   730         TCursorSelection linkSelection( startPos, startPos + length );
   695     {
   731 
   696     FUNC_LOG;
   732         if( currentSelection.iCursorPos == linkSelection.iCursorPos &&
   697     return RichText()->Read( aLink.StartPos ( ), aLink.Length ( ) ).AllocL();
   733                 currentSelection.iAnchorPos == linkSelection.iAnchorPos )
       
   734             {
       
   735             linkIndex = i;
       
   736             break;
       
   737             }
       
   738         }
       
   739 
       
   740     return linkIndex;
   698     }
   741     }
   699 
   742 
   700 // -----------------------------------------------------------------------------
   743 // -----------------------------------------------------------------------------
   701 // CESMRRichTextViewer::CESMRRichTextViewer
   744 // CESMRRichTextViewer::CESMRRichTextViewer
   702 // -----------------------------------------------------------------------------
   745 // -----------------------------------------------------------------------------
   703 //
   746 //
   704 EXPORT_C void CESMRRichTextViewer::SetListObserver(
       
   705         MESMRListObserver* aObserver )
       
   706     {
       
   707     FUNC_LOG;
       
   708     iObserver = aObserver;
       
   709     }
       
   710 
       
   711 // -----------------------------------------------------------------------------
       
   712 // CESMRRichTextViewer::RowHeight
       
   713 // -----------------------------------------------------------------------------
       
   714 //
       
   715 EXPORT_C TInt CESMRRichTextViewer::RowHeight()
       
   716     {
       
   717     FUNC_LOG;
       
   718     TInt bandHeight = TextLayout()->BandHeight();
       
   719     // Starts from zero, so let's increase the count by one.
       
   720     TInt lineNumberCount = TextLayout()->GetLineNumber( TextLength() ) + 1;
       
   721 
       
   722     return ( bandHeight / lineNumberCount );
       
   723     }
       
   724 
       
   725 // -----------------------------------------------------------------------------
       
   726 // CESMRRichTextViewer::LineCount
       
   727 // -----------------------------------------------------------------------------
       
   728 //
       
   729 EXPORT_C TInt CESMRRichTextViewer::LineCount()
       
   730     {
       
   731     FUNC_LOG;
       
   732     return iNumberOfLines;
       
   733     }
       
   734 // -----------------------------------------------------------------------------
       
   735 // CESMRRichTextViewer::CurrentLineNumber
       
   736 // -----------------------------------------------------------------------------
       
   737 //
       
   738 EXPORT_C TInt CESMRRichTextViewer::CurrentLineNumber()
       
   739     {
       
   740     FUNC_LOG;
       
   741     // first line is zero, let's increase it by one
       
   742     return TextLayout()->GetLineNumber( CursorPos() ) + 1;
       
   743     }
       
   744 
       
   745 // -----------------------------------------------------------------------------
       
   746 // CESMRRichTextViewer::CESMRRichTextViewer
       
   747 // -----------------------------------------------------------------------------
       
   748 //
       
   749 EXPORT_C void CESMRRichTextViewer::SetActionMenuStatus( TBool aStatus )
       
   750     {
       
   751     FUNC_LOG;
       
   752     iActionMenuStatus = aStatus;
       
   753     }
       
   754 
       
   755 // -----------------------------------------------------------------------------
       
   756 // CESMRRichTextViewer::CESMRRichTextViewer
       
   757 // -----------------------------------------------------------------------------
       
   758 //
       
   759 CESMRRichTextViewer::CESMRRichTextViewer( )
   747 CESMRRichTextViewer::CESMRRichTextViewer( )
   760 :   iActionMenuStatus( ETrue ), iActionMenuOpen( EFalse )
       
   761     {
   748     {
   762     FUNC_LOG;
   749     FUNC_LOG;
   763     }
   750     }
   764 
   751 
   765 // -----------------------------------------------------------------------------
   752 // -----------------------------------------------------------------------------
   777     if( !aParent )
   764     if( !aParent )
   778         {
   765         {
   779         flags |= CEikEdwin::EOwnsWindow;
   766         flags |= CEikEdwin::EOwnsWindow;
   780         }
   767         }
   781 
   768 
   782     CEikRichTextEditor::ConstructL (aParent, 1, 1, flags );
   769     CEikRichTextEditor::ConstructL( aParent, 1, 1, flags );
   783     SetSuppressBackgroundDrawing (ETrue );
   770     SetSuppressBackgroundDrawing( ETrue );
   784 
   771 
   785     User::LeaveIfError(
   772     iESMRStatic.ConnectL();
   786             NMRBitmapManager::GetSkinBasedBitmap(
       
   787                     NMRBitmapManager::EMRBitmapRightClickArrow, iActionMenuIcon,
       
   788                     iActionMenuIconMask, KIconSize ) );
       
   789 
       
   790     iESMRStatic.ConnectL ( );
       
   791     iCntMenuHdlr = &iESMRStatic.ContactMenuHandlerL();
   773     iCntMenuHdlr = &iESMRStatic.ContactMenuHandlerL();
   792     iCurrentLinkIndex = KErrNotFound;
   774     iRichTextLinkFormatMask.SetAttrib( EAttFontUnderline );
   793     iFormatMask.SetAttrib( EAttFontUnderline );
   775     iRichTextLinkFormat.iFontPresentation.iUnderline = EUnderlineOn;
   794     iFormat.iFontPresentation.iUnderline = EUnderlineOn;
   776     iRichTextLinkFormatMask.SetAttrib( EAttColor );
   795     iFormatMask.SetAttrib( EAttColor );
   777     iRichTextLinkFormat.iFontPresentation.iTextColor =
   796     iFormat.iFontPresentation.iTextColor = KRgbBlue;
   778         NMRColorManager::Color(
   797 
   779                 NMRColorManager::EMRCutCopyPasteHighlightColor );
   798     iLongTapDetector = CAknLongTapDetector::NewL(this);
   780     }
   799     }
   781 
   800 
   782 // -----------------------------------------------------------------------------
   801 // -----------------------------------------------------------------------------
   783 // CESMRRichTextViewer::HighlightLinkL
   802 // CESMRRichTextViewer::Draw
   784 // -----------------------------------------------------------------------------
   803 // -----------------------------------------------------------------------------
   785 //
   804 //
   786 void CESMRRichTextViewer::HighlightLinkL(const CESMRRichTextLink& aLink )
   805 void CESMRRichTextViewer::Draw( const TRect& aRect ) const
   787     {
   806     {
   788     FUNC_LOG;
   807     FUNC_LOG;
       
   808     CEikEdwin::Draw( aRect );
       
   809     if (IsFocused ( ) && iActionMenuStatus )
       
   810         {
       
   811         const CESMRRichTextLink* link = GetSelectedLink ( );
       
   812         if (link && link->TriggerKey ( )== CESMRRichTextLink::ETriggerKeyRight )
       
   813             {
       
   814             TRAP_IGNORE(DrawRightClickIconL(*link));
       
   815             }
       
   816         }
       
   817     }
       
   818 
       
   819 // -----------------------------------------------------------------------------
       
   820 // CESMRRichTextViewer::DrawRightClickIconL
       
   821 // -----------------------------------------------------------------------------
       
   822 //
       
   823 void CESMRRichTextViewer::DrawRightClickIconL(
       
   824 		const CESMRRichTextLink& aLink ) const
       
   825     {
       
   826     FUNC_LOG;
       
   827     TTmDocPosSpec posSpec;
       
   828     TTmPosInfo2 posInfo;
       
   829 
       
   830     posSpec.iPos = aLink.StartPos ( )+ aLink.Length ( );
       
   831     posSpec.iType = TTmDocPosSpec::ETrailing;
       
   832 
       
   833     if (TextView()->FindDocPosL (posSpec, posInfo ) )
       
   834         {
       
   835         TPoint pt = posInfo.iEdge;
       
   836         pt -= iActionMenuIcon->SizeInPixels ( );
       
   837 
       
   838         pt.iY = pt.iY + KArrowUpperMargin;
       
   839         pt.iX = Parent()->Rect().iBr.iX -
       
   840                 iActionMenuIcon->SizeInPixels().iWidth - KArrowRightMargin;
       
   841         TRect dst(pt, iActionMenuIcon->SizeInPixels ( ));
       
   842         TRect src(TPoint (0, 0 ), iActionMenuIcon->SizeInPixels ( ));
       
   843 
       
   844         CWindowGc& gc = SystemGc ( );
       
   845         gc.DrawBitmapMasked (dst, iActionMenuIcon, src, iActionMenuIconMask,
       
   846                 EFalse );
       
   847         }
       
   848     }
       
   849 
       
   850 // -----------------------------------------------------------------------------
       
   851 // CESMRRichTextViewer::HighlightLink
       
   852 // -----------------------------------------------------------------------------
       
   853 //
       
   854 void CESMRRichTextViewer::HighlightLink(const CESMRRichTextLink& aLink )
       
   855     {
       
   856     FUNC_LOG;
       
   857     TInt error = KErrNone;
       
   858     TCursorSelection selection( aLink.StartPos(), aLink.StartPos() + aLink.Length() );
   789     TCursorSelection selection( aLink.StartPos(), aLink.StartPos() + aLink.Length() );
   859 
   790 
   860     // If TextView is not constructed yet.
   791     // If TextView is not constructed yet.
   861     if ( !TextView() )
   792     if ( !TextView() )
   862         {
   793         {
   863         TRAP( error, SetSelectionL( selection.iCursorPos, selection.iAnchorPos ) );
   794         SetSelectionL( selection.iCursorPos, selection.iAnchorPos );
   864         }
   795         }
   865     else
   796     else
   866         {
   797         {
   867         TextView()->SetPendingSelection( selection );
   798         TextView()->SetPendingSelection( selection );
   868         }
   799         }
   869 
   800 
   870     if ( error == KErrNone )
   801     SetValueL( aLink );
   871         {
   802     ChangeMiddleSoftkeyL( aLink );
   872         TRAP( error, SetValueL( aLink ) );
       
   873         if ( error != KErrNone )
       
   874             {
       
   875             CEikonEnv::Static()->// codescanner::eikonenvstatic
       
   876                 HandleError( error );
       
   877             }
       
   878         }
       
   879     }
   803     }
   880 
   804 
   881 // -----------------------------------------------------------------------------
   805 // -----------------------------------------------------------------------------
   882 // CESMRRichTextViewer::SetValueL
   806 // CESMRRichTextViewer::SetValueL
   883 // -----------------------------------------------------------------------------
   807 // -----------------------------------------------------------------------------
   906             		CESMRContactMenuHandler::EValueTypeURL );
   830             		CESMRContactMenuHandler::EValueTypeURL );
   907             break;
   831             break;
   908             }
   832             }
   909         case CESMRRichTextLink::ETypeAttachment:
   833         case CESMRRichTextLink::ETypeAttachment:
   910             {
   834             {
   911             // Set this as command observer.
   835 
   912             // Commands from contact menu handler are
       
   913             // processed in ProcessCommandL and forwarded
       
   914             // as field command events
       
   915             // <cmail>
       
   916             //iCntMenuHdlr->SetCommandObserver( this );
       
   917             // </cmail>
       
   918             iCntMenuHdlr->SetValueL( aLink.Value(),
       
   919             		CESMRContactMenuHandler::EValueTypeAttachment );
       
   920             break;
   836             break;
   921             }
   837             }
   922         default:
   838         default:
   923             {
   839             {
   924             break;
   840             break;
  1003     }
   919     }
  1004 
   920 
  1005 // -----------------------------------------------------------------------------
   921 // -----------------------------------------------------------------------------
  1006 // CESMRRichTextViewer::CopyCurrentLinkToClipBoardL
   922 // CESMRRichTextViewer::CopyCurrentLinkToClipBoardL
  1007 // -----------------------------------------------------------------------------
   923 // -----------------------------------------------------------------------------
       
   924 //
  1008 EXPORT_C void CESMRRichTextViewer::CopyCurrentLinkToClipBoardL() const
   925 EXPORT_C void CESMRRichTextViewer::CopyCurrentLinkToClipBoardL() const
  1009     {
   926     {
  1010     FUNC_LOG;
   927     FUNC_LOG;
  1011     const CESMRRichTextLink* link = GetSelectedLink();
   928     const CESMRRichTextLink* link = GetSelectedLink();
  1012 
   929     HBufC* clipBoardText = NULL;
  1013     if( link )
   930 
  1014         {
   931     if ( link )
  1015     	HBufC* clipBoardText = GetLinkTextL(*link);
   932     	{
  1016 
   933     	clipBoardText = GetLinkTextLC( *link );
  1017     	if ( clipBoardText )
   934     	}
  1018     	    {
   935 
  1019     	    CleanupStack::PushL( clipBoardText );
   936     if ( clipBoardText )
  1020     	    CClipboard* cb =
   937         {
  1021             CClipboard::NewForWritingLC( CCoeEnv::Static()->FsSession() );
   938         CClipboard* cb =
  1022             cb->StreamDictionary().At( KClipboardUidTypePlainText );
       
  1023             CPlainText* plainText = CPlainText::NewL();
       
  1024             CleanupStack::PushL( plainText );
       
  1025             plainText->InsertL( 0 , *clipBoardText);
       
  1026             plainText->CopyToStoreL( cb->Store(),
       
  1027                     cb->StreamDictionary(), 0, plainText->DocumentLength());
       
  1028             CleanupStack::PopAndDestroy( plainText );
       
  1029             cb->CommitL();
       
  1030             CleanupStack::PopAndDestroy( cb );
       
  1031             CleanupStack::PopAndDestroy( clipBoardText );
       
  1032     	    }
       
  1033         }
       
  1034     }
       
  1035 
       
  1036 // -----------------------------------------------------------------------------
       
  1037 // CESMRRichTextViewer::CopyCurrentLinkValueToClipBoardL
       
  1038 // -----------------------------------------------------------------------------
       
  1039 EXPORT_C void CESMRRichTextViewer::CopyCurrentLinkValueToClipBoardL() const
       
  1040     {
       
  1041     FUNC_LOG;
       
  1042     const CESMRRichTextLink* link = GetSelectedLink();
       
  1043 
       
  1044     if( link )
       
  1045         {
       
  1046     	TDesC& clipBoardText = link->Value();
       
  1047 
       
  1048 	    CClipboard* cb =
       
  1049         CClipboard::NewForWritingLC( CCoeEnv::Static()->FsSession() );
   939         CClipboard::NewForWritingLC( CCoeEnv::Static()->FsSession() );
  1050         cb->StreamDictionary().At( KClipboardUidTypePlainText );
   940         cb->StreamDictionary().At( KClipboardUidTypePlainText );
  1051         CPlainText* plainText = CPlainText::NewL();
   941         CPlainText* plainText = CPlainText::NewL();
  1052         CleanupStack::PushL( plainText );
   942         CleanupStack::PushL( plainText );
  1053         plainText->InsertL( 0 , clipBoardText);
   943         plainText->InsertL( 0 , *clipBoardText);
  1054         plainText->CopyToStoreL( cb->Store(),
   944         plainText->CopyToStoreL( cb->Store(),
  1055                 cb->StreamDictionary(), 0, plainText->DocumentLength());
   945         		cb->StreamDictionary(), 0, plainText->DocumentLength());
  1056         CleanupStack::PopAndDestroy( plainText );
   946         CleanupStack::PopAndDestroy( plainText );
  1057         cb->CommitL();
   947         cb->CommitL();
  1058         CleanupStack::PopAndDestroy( cb );
   948         CleanupStack::PopAndDestroy( cb );
  1059         }
   949         CleanupStack::PopAndDestroy( clipBoardText );
  1060     }
   950         }
  1061 
   951     }
  1062 
   952 
  1063 // -----------------------------------------------------------------------------
   953 // -----------------------------------------------------------------------------
  1064 // CESMRRichTextViewer::ResetActionMenu
   954 // CESMRRichTextViewer::ResetActionMenu
  1065 // -----------------------------------------------------------------------------
   955 // -----------------------------------------------------------------------------
  1066 EXPORT_C void CESMRRichTextViewer::ResetActionMenuL() const // codescanner::LFunctionCantLeave
   956 EXPORT_C void CESMRRichTextViewer::ResetActionMenuL() const // codescanner::LFunctionCantLeave
  1067     {
   957     {
  1068     FUNC_LOG;
   958     FUNC_LOG;
  1069     if(iCntMenuHdlr)
   959     if ( iCntMenuHdlr )
  1070         {
   960         {
  1071         iCntMenuHdlr->Reset();
   961         iCntMenuHdlr->Reset();
  1072         }
   962         }
  1073     }
   963     }
  1074 
   964 
  1093     TBool linkSelected = EFalse;
   983     TBool linkSelected = EFalse;
  1094 
   984 
  1095     const CESMRRichTextLink* link = GetSelectedLink();
   985     const CESMRRichTextLink* link = GetSelectedLink();
  1096     if ( link )
   986     if ( link )
  1097         {
   987         {
  1098         iActionMenuOpen = ETrue;
       
  1099         switch ( link->TriggerKey() )
   988         switch ( link->TriggerKey() )
  1100             {
   989             {
  1101             case CESMRRichTextLink::ETriggerKeyRight:
   990             case CESMRRichTextLink::ETriggerKeyRight:
  1102                 {
   991                 {
  1103                 if ( !iLinkObserver ||
   992                 if ( !iLinkObserver ||
  1104                      !iLinkObserver->HandleRichTextLinkSelection(link) )
   993                      !iLinkObserver->HandleRichTextLinkSelection(link) )
  1105                     {
   994                     {
  1106                     iCntMenuHdlr->ShowActionMenuL();
   995                     ShowContextMenuL();
  1107                     }
   996                     }
  1108                 linkSelected = ETrue;
   997                 linkSelected = ETrue;
  1109                 break;
   998                 break;
  1110                 }
   999                 }
  1111             case CESMRRichTextLink::ETriggerKeyOk:
  1000             case CESMRRichTextLink::ETriggerKeyOk:
  1112                 {
  1001                 {
  1113                 if (iLinkObserver &&
  1002                 if (iLinkObserver &&
  1114                     iLinkObserver->HandleRichTextLinkSelection (link ) )
  1003                     iLinkObserver->HandleRichTextLinkSelection( link ) )
  1115                     {
  1004                     {
  1116                     linkSelected = ETrue;
  1005                     linkSelected = ETrue;
  1117                     }
  1006                     }
  1118                 break;
  1007                 break;
  1119                 }
  1008                 }
  1120             default:
  1009             default:
  1121                 {
  1010                 {
  1122                 break;
  1011                 break;
  1123                 }
  1012                 }
  1124             }
  1013             }
  1125         iActionMenuOpen = EFalse;
       
  1126         }
  1014         }
  1127 
  1015 
  1128     return linkSelected;
  1016     return linkSelected;
  1129     }
  1017     }
  1130 
       
  1131 
  1018 
  1132 // -----------------------------------------------------------------------------
  1019 // -----------------------------------------------------------------------------
  1133 // CESMRRichTextViewer::ProcessCommandL
  1020 // CESMRRichTextViewer::ProcessCommandL
  1134 // -----------------------------------------------------------------------------
  1021 // -----------------------------------------------------------------------------
  1135 //
  1022 //
  1155 void CESMRRichTextViewer::ActivateL()
  1042 void CESMRRichTextViewer::ActivateL()
  1156     {
  1043     {
  1157     FUNC_LOG;
  1044     FUNC_LOG;
  1158     CEikRichTextEditor::ActivateL();
  1045     CEikRichTextEditor::ActivateL();
  1159 
  1046 
  1160     // Make sure correct font color is in use.
       
  1161     SetFontColorL( IsFocused() );
       
  1162 
       
  1163     // CEikEdwin::ActivateL removes selection, re-set highlight
  1047     // CEikEdwin::ActivateL removes selection, re-set highlight
  1164     // if focused and there's a selected link.
  1048     // if focused and there's a selected link.
  1165     if ( IsFocused() && GetSelectedLink() )
  1049     const CESMRRichTextLink* link = GetSelectedLink();
  1166         {
  1050     if ( link && IsFocused() )
  1167         HighlightLink( *GetSelectedLink() );
  1051         {
       
  1052         HighlightLinkL( *link );
  1168         DrawDeferred();
  1053         DrawDeferred();
  1169         }
  1054         }
  1170     }
  1055     }
  1171 
  1056 
  1172 // -----------------------------------------------------------------------------
  1057 // -----------------------------------------------------------------------------
  1173 // CESMRRichTextViewer::HandlePointerEventL
  1058 // CESMRRichTextViewer::ContactActionQueryComplete
  1174 // -----------------------------------------------------------------------------
  1059 // -----------------------------------------------------------------------------
  1175 //
  1060 //
  1176 void CESMRRichTextViewer::HandlePointerEventL(const TPointerEvent& aPointerEvent)
  1061 void CESMRRichTextViewer::ContactActionQueryComplete()
  1177     {
  1062     {
  1178     TBool linkTapped( EFalse );
  1063     FUNC_LOG;
  1179     CESMRRichTextLink* link = NULL;
  1064     if ( iOpenActionMenu )
  1180     // fetch the current line number:
  1065         {
  1181     TInt currentLineNumber = TextLayout()->GetLineNumber( CursorPos() );
  1066         // Activate link as actions have been discovered
  1182     // find out tapped position
  1067         TRAP_IGNORE(  LinkSelectedL() );
  1183     TPoint touchPoint = aPointerEvent.iPosition;
  1068         }
  1184 
  1069 
  1185     TInt tappedPos = TextView()->XyPosToDocPosL( touchPoint );
  1070     // Reset menu observer
  1186     for (TInt i = 0; i<iLinkList.Count(); i++)
  1071     iCntMenuHdlr->SetContactMenuObserver( NULL );
  1187         {
  1072     iOpenActionMenu = EFalse;
  1188         link = iLinkList[ i ];
  1073     }
  1189         TInt linkStart = link->StartPos();
  1074 
  1190         TInt linkEnd = link->StartPos() + link->Length() - 1;
  1075 // -----------------------------------------------------------------------------
  1191         if ( tappedPos >= linkStart && tappedPos <= linkEnd )
  1076 // CESMRRichTextViewer::ShowContextMenuL
  1192             {
  1077 // -----------------------------------------------------------------------------
  1193             // link tapped
  1078 //
  1194             linkTapped = ETrue;
  1079 void CESMRRichTextViewer::ShowContextMenuL()
  1195             iCurrentLinkIndex = i;
  1080     {
       
  1081     FUNC_LOG;
       
  1082     iOpenActionMenu = EFalse;
       
  1083     ProcessCommandL( EAknSoftkeyContextOptions );
       
  1084     }
       
  1085 
       
  1086 // -----------------------------------------------------------------------------
       
  1087 // CESMRRichTextViewer::GetLinkAreaL
       
  1088 // -----------------------------------------------------------------------------
       
  1089 //
       
  1090 void CESMRRichTextViewer::GetLinkAreaL(
       
  1091         TRegion& aRegion,
       
  1092         const CESMRRichTextLink& aLink ) const
       
  1093     {
       
  1094     FUNC_LOG;
       
  1095     TTmDocPosSpec posSpec;
       
  1096     TTmPosInfo2 posInfo;
       
  1097 
       
  1098     posSpec.iPos = aLink.StartPos();
       
  1099     posSpec.iType = TTmDocPosSpec::ELeading;
       
  1100 
       
  1101     aRegion.Clear();
       
  1102 
       
  1103     if ( TextView()->FindDocPosL( posSpec, posInfo ) )
       
  1104         {
       
  1105         TRect linkRect( 0, 0, 0, 0 );
       
  1106 
       
  1107         // Create link surrounding rectangle
       
  1108         HBufC* text = GetLinkTextLC( aLink );
       
  1109         TInt textWidth = AknBidiTextUtils::MeasureTextBoundsWidth(
       
  1110                 *iFont,
       
  1111                 *text,
       
  1112                 CFont::TMeasureTextInput::EFVisualOrder );
       
  1113 
       
  1114         TPoint tl( posInfo.iEdge );
       
  1115 
       
  1116         if ( AknLayoutUtils::LayoutMirrored() )
       
  1117             {
       
  1118             // move top left x to end of text
       
  1119             tl.iX -= textWidth;
       
  1120             }
       
  1121 
       
  1122         tl.iY -= iFont->FontMaxAscent();
       
  1123         TPoint br( tl.iX + textWidth, tl.iY + iFont->FontMaxHeight() );
       
  1124 
       
  1125         TRect rect( Rect() );
       
  1126 
       
  1127         while ( ( tl.iX < rect.iTl.iX || br.iX > rect.iBr.iX )
       
  1128                 && !aRegion.CheckError() )
       
  1129             {
       
  1130             // Link on multiple lines
       
  1131 
       
  1132             tl.iX = Max( rect.iTl.iX, tl.iX );
       
  1133             br.iX = Min( br.iX, rect.iBr.iX );
       
  1134             linkRect.SetRect( tl, br );
       
  1135             aRegion.AddRect( linkRect );
       
  1136 
       
  1137             TPtrC remainder( text->Mid( posSpec.iPos - aLink.StartPos() ) );
       
  1138             TInt numChars = iFont->TextCount( remainder,
       
  1139                                               linkRect.Width() );
       
  1140             posSpec.iPos += numChars;
       
  1141             remainder.Set( remainder.Mid( numChars) );
       
  1142 
       
  1143             if ( TextView()->FindDocPosL( posSpec, posInfo ) )
       
  1144                 {
       
  1145                 textWidth = AknBidiTextUtils::MeasureTextBoundsWidth(
       
  1146                                 *iFont,
       
  1147                                 remainder,
       
  1148                                 CFont::TMeasureTextInput::EFVisualOrder );
       
  1149 
       
  1150                 tl = posInfo.iEdge;
       
  1151 
       
  1152                 if ( AknLayoutUtils::LayoutMirrored() )
       
  1153                     {
       
  1154                     // move top left x to end of text
       
  1155                     tl.iX -= textWidth;
       
  1156                     }
       
  1157 
       
  1158                 tl.iY -= iFont->FontMaxAscent();
       
  1159                 br.SetXY( tl.iX + textWidth, tl.iY + iFont->FontMaxHeight() );
       
  1160                 }
       
  1161             }
       
  1162 
       
  1163         linkRect.SetRect( tl, br );
       
  1164         aRegion.AddRect( linkRect );
       
  1165 
       
  1166         CleanupStack::PopAndDestroy( text );
       
  1167         }
       
  1168     }
       
  1169 
       
  1170 // -----------------------------------------------------------------------------
       
  1171 // CESMRRichTextViewer::ChangeMiddleSoftkeyL
       
  1172 // -----------------------------------------------------------------------------
       
  1173 //
       
  1174 void CESMRRichTextViewer::ChangeMiddleSoftkeyL( const CESMRRichTextLink& aLink )
       
  1175     {
       
  1176     FUNC_LOG;
       
  1177     CESMRField* field = static_cast< CESMRField* >( Parent() );
       
  1178 
       
  1179     if ( field )
       
  1180         {
       
  1181         field->ChangeMiddleSoftKeyL( aLink.MSKCommand(), aLink.MSKText() );
       
  1182         }
       
  1183     }
       
  1184 
       
  1185 // -----------------------------------------------------------------------------
       
  1186 // CESMRRichTextViewer::UpdateViewL
       
  1187 // -----------------------------------------------------------------------------
       
  1188 //
       
  1189 void CESMRRichTextViewer::UpdateViewL( const TKeyEvent &aKeyEvent )
       
  1190     {
       
  1191     FUNC_LOG;
       
  1192     const CESMRRichTextLink* selectedLink = GetSelectedLink();
       
  1193 
       
  1194     if( !selectedLink )
       
  1195         {
       
  1196         return;
       
  1197         }
       
  1198 
       
  1199     RRegion linkRegion;
       
  1200     CleanupClosePushL( linkRegion );
       
  1201 
       
  1202     GetLinkAreaL( linkRegion, *selectedLink );
       
  1203     TRect linkRect = linkRegion.BoundingRect();
       
  1204 
       
  1205     CleanupStack::PopAndDestroy( &linkRegion );
       
  1206 
       
  1207     TRect viewableAreaRect = iObserver->ViewableAreaRect();
       
  1208 
       
  1209 
       
  1210     switch ( aKeyEvent.iCode )
       
  1211         {
       
  1212         case EKeyLeftArrow:
       
  1213         case EKeyUpArrow:
       
  1214             {
       
  1215             if( linkRect.iTl.iY < viewableAreaRect.iTl.iY )
       
  1216                 {
       
  1217                 // Move fields down
       
  1218                 iObserver->RePositionFields(
       
  1219                         -( linkRect.iTl.iY - viewableAreaRect.iTl.iY ) );
       
  1220                 }
       
  1221 
  1196             break;
  1222             break;
  1197             }
  1223             }
  1198         }
  1224         case EKeyRightArrow:
  1199 
  1225         case EKeyDownArrow:
  1200     if ( aPointerEvent.iType == TPointerEvent::EButton1Down )
  1226             {
  1201         {
  1227             if( linkRect.iBr.iY > viewableAreaRect.iBr.iY )
  1202         if ( linkTapped )
  1228                 {
  1203             {
  1229                 // Move fields up
  1204             // tactile feedback
  1230                 iObserver->RePositionFields(
  1205             MTouchFeedback* feedback = MTouchFeedback::Instance();
  1231                         -( linkRect.iBr.iY - viewableAreaRect.iBr.iY ) );
  1206             if ( feedback )
  1232                 }
  1207                 {
  1233             break;
  1208                 feedback->InstantFeedback( this, ETouchFeedbackBasic );
  1234             }
  1209                 }
  1235         default:
  1210 
  1236             break;
  1211             TPointerEvent pointerEvent = aPointerEvent;
  1237         }
  1212             pointerEvent.iParentPosition = pointerEvent.iPosition
  1238     }
  1213                 + DrawableWindow()->AbsPosition();
  1239 
  1214             iLongTapDetector->PointerEventL( pointerEvent );
       
  1215             HighlightLink( *link );
       
  1216             if ( Parent() )
       
  1217                 {
       
  1218                 Parent()->DrawDeferred();
       
  1219                 }
       
  1220             else
       
  1221                 {
       
  1222                 DrawDeferred();
       
  1223                 }
       
  1224             }
       
  1225         }
       
  1226     else
       
  1227         {
       
  1228         TPointerEvent pointerEvent = aPointerEvent;
       
  1229         pointerEvent.iParentPosition = pointerEvent.iPosition
       
  1230             + DrawableWindow()->AbsPosition();
       
  1231         iLongTapDetector->PointerEventL( pointerEvent );
       
  1232 
       
  1233         if ( aPointerEvent.iType  == TPointerEvent::EButton1Up )
       
  1234             {
       
  1235             if ( linkTapped && !iActionMenuOpen )
       
  1236                 {
       
  1237                 // tapped highlighted field, execute action
       
  1238                 LinkSelectedL();
       
  1239                 }
       
  1240             }
       
  1241         }
       
  1242     }
       
  1243 
       
  1244 // -----------------------------------------------------------------------------
       
  1245 // CESMRRichTextViewer::HandleLongTapEventL
       
  1246 // -----------------------------------------------------------------------------
       
  1247 //
       
  1248 void CESMRRichTextViewer::HandleLongTapEventL( const TPoint& /*aPenEventLocation*/,
       
  1249                                               const TPoint& /*aPenEventScreenLocation*/ )
       
  1250     {
       
  1251     if ( !iActionMenuOpen )
       
  1252         {
       
  1253         LinkSelectedL();
       
  1254         }
       
  1255     }
       
  1256 // EOF
  1240 // EOF
  1257 
  1241