uifw/AvKon/src/AknPhedView.cpp
changeset 0 2f259fa3e83a
child 12 941195f2d488
equal deleted inserted replaced
-1:000000000000 0:2f259fa3e83a
       
     1 /*
       
     2 * Copyright (c) 2002 - 2008 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description: 
       
    15 *
       
    16 */
       
    17 
       
    18 #include "AknPhedView.h"
       
    19 #include "AknPhoneNumberEditor.h"
       
    20 
       
    21 #include <AknsDrawUtils.h>
       
    22 
       
    23 #include <gfxtranseffect/gfxtranseffect.h>
       
    24 #include <akntransitionutils.h>
       
    25 #include <avkondomainpskeys.h>
       
    26 #include <e32property.h>
       
    27 
       
    28 // Helper class that monitor redirection changes
       
    29 class CRedirectionListener : public CBase, public MAknTransitionUtilsObserver
       
    30     {
       
    31 private:
       
    32     TInt AknTransitionCallback( TInt aEvent, TInt aState,
       
    33                                 const TDesC8* /*aParams*/ )
       
    34         {
       
    35         if ( aEvent == CAknTransitionUtils::EEventWsBufferRedirection )
       
    36             {
       
    37             iRedirected = aState;
       
    38             if ( iCursorEnabled )
       
    39                 {
       
    40                 if ( iRedirected )
       
    41                     {
       
    42                     if ( iWg && iCursorStatus )
       
    43                         {
       
    44                         iWg->CancelTextCursor();
       
    45                         }
       
    46                     iCursorStatus = EFalse;
       
    47                     }
       
    48                 else
       
    49                     {
       
    50                     iOwner.EnableCursor();
       
    51                     }
       
    52                 }
       
    53             }
       
    54         return 0;
       
    55         }
       
    56 
       
    57 public:
       
    58     CRedirectionListener( CAknPhedView& aOwner ) : iOwner( aOwner )
       
    59         {
       
    60         iRedirected = 0;
       
    61         TInt serverrunning;
       
    62         TInt ret=RProperty::Get( KPSUidAvkonDomain, KAknTfxServerStatus,
       
    63                  serverrunning );
       
    64         if(KErrNone == ret && ETfxSrvRunning == serverrunning) 
       
    65 	        {
       
    66 	        RProperty::Get( KPSUidAvkonDomain, KAknTfxServerRedirectionStatus,
       
    67 	                        iRedirected );
       
    68 	        iRedirected &= ETfxScreenRedirected;
       
    69 	        }
       
    70         }
       
    71     inline void EnableCursor()
       
    72         {
       
    73         iCursorEnabled = ETrue;
       
    74         }
       
    75     void DisableCursor()
       
    76         {
       
    77         if ( iWg && iCursorStatus )
       
    78             {
       
    79             iWg->CancelTextCursor();
       
    80             }
       
    81         iCursorEnabled = EFalse;
       
    82         iCursorStatus = EFalse;
       
    83         }
       
    84     void UpdateCursor( const TTextCursor& aCursor )
       
    85         {
       
    86         TInt redirected=0; // init the value
       
    87         //judge the server status, if server is not running, it is no need to get redirect value.
       
    88         TInt serverrunning;
       
    89         TInt ret=RProperty::Get( KPSUidAvkonDomain, KAknTfxServerStatus,
       
    90                  serverrunning );
       
    91 
       
    92         if(KErrNone == ret && ETfxSrvRunning == serverrunning) 
       
    93             {
       
    94             ret=RProperty::Get( KPSUidAvkonDomain, KAknTfxServerRedirectionStatus,
       
    95                         redirected );
       
    96 
       
    97             if( KErrNone != ret)
       
    98                 redirected = 0;
       
    99  
       
   100             redirected &= ETfxScreenRedirected;
       
   101             if ( redirected != iRedirected && redirected )
       
   102                 {
       
   103                 AknTransitionCallback( CAknTransitionUtils::EEventWsBufferRedirection,
       
   104                                        1, NULL );
       
   105                 return;
       
   106                 }
       
   107             }
       
   108 
       
   109         iRedirected = redirected;
       
   110         
       
   111         if ( iCursorEnabled && iWg && iWindow && !iRedirected )
       
   112             {
       
   113             iWg->SetTextCursor( *iWindow,
       
   114                                 iOwner.CursorPosition() + TPoint( -1, 0 ),
       
   115                                 aCursor );
       
   116             iCursorStatus = ETrue;
       
   117             }
       
   118         }
       
   119         
       
   120     inline void SetWindows( RWindowGroup* aWg, RWindowBase* aWindow )
       
   121         {
       
   122         iWg = aWg;
       
   123         iWindow = aWindow;
       
   124         }
       
   125         
       
   126 private:
       
   127     TBool iRedirected;
       
   128     TBool iCursorEnabled;
       
   129     TBool iCursorStatus;
       
   130     RWindowGroup* iWg;
       
   131     RWindowBase* iWindow;
       
   132     CAknPhedView& iOwner;
       
   133     };
       
   134 
       
   135 enum TAknPhedViewPanic
       
   136     {
       
   137     EFormatNullLines,
       
   138     EFormatTooManyLines,
       
   139     EFormatTooFewLines,
       
   140     EEventNullLines,
       
   141     ELineNoCursor
       
   142     };
       
   143 
       
   144 void PhedViewPanic( TAknPhedViewPanic aPanic )
       
   145     {
       
   146     _LIT( KAknPhedView,"AknPhedView" );
       
   147     User::Panic( KAknPhedView, aPanic );
       
   148     }
       
   149 
       
   150 
       
   151 
       
   152 TAknPhedViewLine::TAknPhedViewLine()
       
   153     {
       
   154     Mem::FillZ( this, sizeof( *this ) );
       
   155     iCursor = CAknPhedView::KNoPos;
       
   156     SetRedrawRequired();
       
   157     }
       
   158 
       
   159 void TAknPhedViewLine::SetFormat( const CFont* aFont, const TRect& aRect, TInt aBaseline )
       
   160     {
       
   161     iFont = aFont;
       
   162     iRect = aRect;
       
   163     SetTruncation( iTruncation );
       
   164     iBaseline = aBaseline;
       
   165     }
       
   166     
       
   167 TRect TAknPhedViewLine::Rect() const
       
   168     {
       
   169     return iRect;
       
   170     }
       
   171 
       
   172 void TAknPhedViewLine::SetLeftPos( TInt aPos )
       
   173     {
       
   174     SetRedrawRequired();
       
   175     iLeftPos = aPos;
       
   176 
       
   177     if ( InRange(aPos, iModel->Length(), 0 ) )
       
   178         {
       
   179         if( iLeftPos > 0 && iLeftPos < iModel->Length() && iModel->Language() )
       
   180             {
       
   181             if ( iModel->ReverseText( iLeftPos ).Length() == 
       
   182                  iModel->ReverseText( iLeftPos - 1 ).Length() && !iLeftLine ) 
       
   183                 {
       
   184                 iLeftPos++; 
       
   185                 }
       
   186             else if ( iModel->ReverseText( iLeftPos ).Length() == 
       
   187                       iModel->ReverseText( iLeftPos - 1 ).Length() && iLeftLine ) 
       
   188                 {
       
   189                 iLeftPos--; 
       
   190                 }
       
   191             }
       
   192         // count characters that will fit to the right of this new left position
       
   193         iRightPos = iLeftPos - CountChars( MaxText(), IsTruncatedLeft(), 
       
   194                     !iRightLine, iLeftPos );
       
   195         if( iRightPos > 0 && iRightPos < iModel->Length() && iModel->Language() )
       
   196             {
       
   197             if ( iModel->ReverseText( iRightPos ).Length() == 
       
   198                  iModel->ReverseText( iRightPos + 1 ).Length() ) 
       
   199                 {
       
   200                 iRightPos++; 
       
   201                 }
       
   202             }
       
   203         
       
   204         }
       
   205     else
       
   206         {
       
   207         iRightPos = aPos;
       
   208         }
       
   209 
       
   210     // propogate change of left hand side to right hand neighbor
       
   211     if ( iRightLine )
       
   212         iRightLine->SetLeftPos( iRightPos );
       
   213     }
       
   214 
       
   215 void TAknPhedViewLine::SetRightPos( TInt aPos )
       
   216     {
       
   217     SetRedrawRequired();
       
   218     TInt nLength = iModel->Length();
       
   219     
       
   220     iRightPos = aPos;
       
   221  
       
   222     if ( InRange( aPos, nLength, 0 ) )
       
   223         {
       
   224         if( iRightPos > 0 && iRightPos < iModel->Length() && iModel->Language() )
       
   225             {
       
   226             
       
   227             if ( iModel->ReverseText( iRightPos ).Length() == 
       
   228                  iModel->ReverseText( iRightPos +1 ).Length() ) 
       
   229                 {
       
   230                 iRightPos++; 
       
   231                 }
       
   232             }
       
   233                                   
       
   234         // count characters that will fit to the left of this new right position
       
   235         iLeftPos = iRightPos + CountChars( MaxReverseText(), 
       
   236                                            IsTruncatedRight(), 
       
   237                                            !iLeftLine,
       
   238                                            iMirror.Mirror( iRightPos ) );
       
   239         if( iLeftPos > 0 && iLeftPos < iModel->Length() && iModel->Language() )
       
   240             {
       
   241             if ( iModel->ReverseText( iLeftPos ).Length() == 
       
   242                  iModel->ReverseText( iLeftPos - 1 ).Length() && !iLeftLine ) 
       
   243                 {
       
   244                 iLeftPos++; 
       
   245                 }
       
   246             else if ( iModel->ReverseText( iLeftPos ).Length() == 
       
   247                       iModel->ReverseText( iLeftPos - 1 ).Length() && iLeftLine ) 
       
   248                 {
       
   249                 iLeftPos--; 
       
   250                 }
       
   251             }
       
   252         }
       
   253     else
       
   254         {
       
   255         iLeftPos = aPos;
       
   256         }
       
   257 
       
   258     // propogate change of right hand side to left hand neighbor
       
   259     if ( iLeftLine )
       
   260         iLeftLine->SetRightPos( iLeftPos );
       
   261     }
       
   262 
       
   263 TBool TAknPhedViewLine::HandleTextChange( TInt aStart, TInt aEnd )
       
   264     {
       
   265     // If the text change happens somewhere to the right of my LHS, handle it.
       
   266     TBool handled = EFalse;
       
   267     if ( aStart == aEnd && !iLeftLine && aStart > iLeftPos)
       
   268         {
       
   269         iLeftPos = aStart;
       
   270         }
       
   271     if ( !iRightLine && iRightPos > aStart )
       
   272         {
       
   273         iRightPos = aStart;
       
   274         }
       
   275     
       
   276     TInt chars = CountChars( MaxReverseText(), 
       
   277                              IsTruncatedRight(), 
       
   278                              !iLeftLine, 
       
   279                              iMirror.Mirror( iRightPos ) );
       
   280     if( iLeftPos < chars )
       
   281         {
       
   282         iLeftPos = chars;   
       
   283         }
       
   284         
       
   285     if ( iLeftPos >= aStart || ( !iLeftLine && aStart > iLeftPos ) )
       
   286         {
       
   287         if( iRightLine )
       
   288             {
       
   289             iRightLine->SetLeftPos( Max( iRightPos - 1, iRightLine->LeftPos() ) );
       
   290             TAknPhedViewLine * firstLine = this;
       
   291             while ( firstLine->iRightLine )
       
   292                 {
       
   293                 firstLine = firstLine->iRightLine;
       
   294                 }
       
   295             firstLine->SetRightPos( firstLine->RightPos() );
       
   296             }
       
   297         else
       
   298             {
       
   299             SetRightPos( iRightPos );
       
   300             }
       
   301         handled = ETrue;
       
   302         }
       
   303     else if ( !iLeftLine || iLeftLine->LineWidth() == 0 )
       
   304         {
       
   305         SetLeftPos( aEnd );        
       
   306         }
       
   307     return handled;
       
   308     }
       
   309 
       
   310 TBool TAknPhedViewLine::HandleCursorChange( TInt aCursor )
       
   311     {
       
   312     // cursor rule: cursor goes on bottom most line that can contain it (order is
       
   313     // specified by loop order in CAknPhedView::CursorChangeFormat).
       
   314     if ( LineContains( aCursor ) )
       
   315         {
       
   316         iCursor = aCursor;
       
   317         return ETrue;
       
   318         }
       
   319     else
       
   320         {
       
   321         iCursor = CAknPhedView::KNoPos;
       
   322         return EFalse;
       
   323         }
       
   324     }
       
   325 
       
   326 void TAknPhedViewLine::HandleSelectionChange( TInt aLeft, TInt aRight )
       
   327     {
       
   328     if (InRange( iLeftPos, aLeft, aRight ) || LineContains( aLeft ) || aLeft == aRight )
       
   329         {
       
   330         SetRedrawRequired();
       
   331         }
       
   332     }
       
   333 
       
   334 TInt TAknPhedViewLine::CountChars( const TDesC& aDes, 
       
   335                                    TBool aStartTruncated, 
       
   336                                    TBool aAllowEndTruncation, 
       
   337                                    TInt aCharsToEnd) const
       
   338     {
       
   339     // reduce width for start truncation
       
   340     TInt width = iRect.Width();
       
   341     if ( aStartTruncated )
       
   342         {
       
   343         width -= TruncationWidth();
       
   344         }
       
   345 
       
   346     TInt chars = TextCountWithTranslation( aDes, width );
       
   347 
       
   348     if ( aAllowEndTruncation && chars < aCharsToEnd )
       
   349         {
       
   350         // reduce with for end truncation and recalculate number of chars that will fit
       
   351         width -= TruncationWidth();
       
   352         chars = TextCountWithTranslation( aDes, width );
       
   353         }
       
   354 
       
   355     return chars;
       
   356     }
       
   357 
       
   358 void TAknPhedViewLine::SetTruncation( const TDesC& aTruncation )
       
   359     {
       
   360     SetRedrawRequired();
       
   361     iTruncation.Set( aTruncation );
       
   362     if ( iFont )
       
   363         iTruncationWidth = TextWidthInPixelsWithTranslation( iTruncation );
       
   364     }
       
   365 
       
   366 TBool TAknPhedViewLine::HasSelection() const
       
   367     { 
       
   368     return SelectionStart() != CAknPhedView::KNoPos; 
       
   369     }
       
   370 
       
   371 TInt TAknPhedViewLine::SelectionStart() const
       
   372     {
       
   373     TInt start = CAknPhedView::KNoPos;
       
   374     if ( iModel->SelectionExists() )
       
   375         {
       
   376         // This line has selection in it if there is a definite overlap between
       
   377         // the line and the selection
       
   378         TInt leftMark = iMirror.LeftMark();
       
   379         TInt rightMark = iMirror.RightMark();
       
   380         if ( InRange( iRightPos, leftMark-1, rightMark ) )
       
   381             start = iRightPos;
       
   382         else if ( InRange( rightMark, iLeftPos-1, iRightPos ) )
       
   383             start = rightMark;
       
   384         }
       
   385     return start;
       
   386     }
       
   387 
       
   388 TInt TAknPhedViewLine::SelectionEnd() const
       
   389     {
       
   390     TInt end = CAknPhedView::KNoPos;
       
   391     if ( iModel->SelectionExists() )
       
   392         {
       
   393         // This line has selection in it if there is a definite overlap between
       
   394         // the line and the selection
       
   395         TInt leftMark = iMirror.LeftMark();
       
   396         TInt rightMark = iMirror.RightMark();
       
   397         if ( InRange(iLeftPos, leftMark, rightMark+1 ) )
       
   398             end = iLeftPos;
       
   399         else if ( InRange( leftMark, iLeftPos, iRightPos+1 ) )
       
   400             end = leftMark;
       
   401         }
       
   402     return end;
       
   403     }
       
   404 
       
   405 TInt TAknPhedViewLine::CursorPosToXPos( TInt aCursorPos ) const
       
   406     {
       
   407     TInt xPos = iRect.iBr.iX;
       
   408     if ( IsTruncatedRight() )
       
   409         xPos -= TruncationWidth();
       
   410     xPos -= TextWidthInPixelsWithTranslation( ReverseText().Left( aCursorPos - iRightPos ) );
       
   411     return --xPos;
       
   412     }
       
   413 
       
   414 TInt TAknPhedViewLine::XPosToCursorPos( TInt aXPos ) const
       
   415     {
       
   416     if ( IsTruncatedRight() )
       
   417         aXPos += TruncationWidth();
       
   418     TInt cursor = iRightPos + TextCountWithTranslation( ReverseText(), iRect.iBr.iX - aXPos );
       
   419 
       
   420     // cursor rule: Cursor can not be beyond the left end of the line
       
   421     if ( cursor > iLeftPos )
       
   422         cursor = iLeftPos;
       
   423 
       
   424     // cursor rule: Cursor should not be on the right end of a line, except the rightmost line
       
   425     if ( cursor == iRightPos && cursor < iLeftPos && iRightLine )
       
   426         cursor++;
       
   427 
       
   428     return cursor;
       
   429     }
       
   430 
       
   431 void TAknPhedViewLine::Draw( CWindowGc& aGc, MAknsSkinInstance* aSkin,
       
   432     MAknsControlContext* aContext, const CCoeControl* aControl ) const
       
   433     {
       
   434     TBool useSkin = AknsDrawUtils::Background( aSkin, aContext, aControl, 
       
   435         aGc, iRect );
       
   436     // set up colors and styles 
       
   437     if( useSkin )
       
   438         {        
       
   439         aGc.SetBrushStyle( CGraphicsContext::ENullBrush );
       
   440         }
       
   441     else
       
   442         {
       
   443         aGc.SetBrushStyle( CGraphicsContext::ESolidBrush );
       
   444         }
       
   445     aGc.SetPenStyle( CGraphicsContext::ESolidPen );
       
   446     aGc.SetPenColor( KRgbBlack );
       
   447     aGc.SetBrushColor( KRgbWhite );
       
   448 
       
   449     // draw the text, including truncation
       
   450     TRect rect = iRect;
       
   451     TInt baseline =  Baseline() - iRect.iTl.iY;
       
   452     
       
   453     if ( IsTruncatedRight() )
       
   454         {
       
   455         DrawText( aGc, iTruncation, baseline, rect );
       
   456         }    
       
   457     if ( IsTruncatedLeft() )
       
   458         {
       
   459         TInt textWidth = iFont->TextWidthInPixels( Text() );
       
   460         TInt truncationWidth = iFont->TextWidthInPixels( iTruncation );
       
   461 
       
   462         if ( textWidth + truncationWidth > rect.Width() && Text().Length() >= 1 )    
       
   463             {        
       
   464             TPtrC text( Text() );
       
   465             DrawText(aGc, text.Right( text.Length() - 1 ), baseline, rect );            
       
   466             }
       
   467         else
       
   468             {
       
   469             DrawText( aGc, Text(), baseline, rect );
       
   470             }
       
   471         DrawText( aGc, iTruncation, baseline, rect );        
       
   472         }
       
   473     else
       
   474         {
       
   475         DrawText( aGc, Text(), baseline, rect );        
       
   476         }
       
   477     
       
   478 
       
   479     // blank the rest of the line
       
   480     if( !useSkin )
       
   481         {
       
   482         aGc.SetPenStyle( CGraphicsContext::ENullPen );
       
   483         aGc.DrawRect( rect );
       
   484         }
       
   485 
       
   486     // invert any selection by xoring with white
       
   487     if ( HasSelection() )
       
   488         {
       
   489         DrawHighlightText( aGc, useSkin );
       
   490         }
       
   491 
       
   492     iRedraw = EFalse;
       
   493     }
       
   494 
       
   495 void TAknPhedViewLine::DrawText( CGraphicsContext& aGc, 
       
   496                                  const TDesC& aText, 
       
   497                                  TInt aBaseline, 
       
   498                                  TRect& aRect) const
       
   499     {
       
   500     TRgb color = KRgbBlack;
       
   501     AknsUtils::GetCachedColor( AknsUtils::SkinInstance(), color,
       
   502                 KAknsIIDQsnTextColors, EAknsCIQsnTextColorsCG51 );
       
   503     aGc.SetPenColor( color );
       
   504     // This function shifts the RHS of aRect left by the width of the text drawn.
       
   505     // It temporarily limits the draw rectangle to the text width to prevent flicker.
       
   506     TPtr buf( TranslatedText( aText ) );
       
   507     
       
   508     TInt width = iFont->TextWidthInPixels( buf );
       
   509     TInt x = aRect.iTl.iX;
       
   510     aRect.iTl.iX = aRect.iBr.iX - width;
       
   511 
       
   512 
       
   513     aGc.DrawText( buf, aRect, aBaseline, CGraphicsContext::ERight );
       
   514     aRect.iBr.iX -= width;
       
   515     aRect.iTl.iX = x;
       
   516     }
       
   517 
       
   518 void TAknPhedViewLine::DrawTextWithTranslation( CGraphicsContext& aGc, 
       
   519                                                 const TDesC& aText, 
       
   520                                                 TInt aBaseline, 
       
   521                                                 TRect& aRect ) const
       
   522     {
       
   523     TRgb color;
       
   524     color = KRgbBlack;
       
   525     AknsUtils::GetCachedColor( AknsUtils::SkinInstance(), color,
       
   526                 KAknsIIDQsnTextColors, EAknsCIQsnTextColorsCG51 );
       
   527     aGc.SetPenColor( color );
       
   528     TPtr buf( TranslatedText( aText ) );
       
   529     aGc.DrawText( buf, aRect, aBaseline, CGraphicsContext::ERight );
       
   530     }
       
   531 
       
   532 TInt TAknPhedViewLine::TextCountWithTranslation( const TDesC& aText, TInt aWidth ) const
       
   533     {
       
   534     TPtr buf( TranslatedText( aText ) );
       
   535     return iFont->TextCount( buf, aWidth );
       
   536     }
       
   537 
       
   538 TInt TAknPhedViewLine::TextWidthInPixelsWithTranslation( const TDesC& aText ) const
       
   539     {
       
   540     TPtr buf( TranslatedText( aText ) );
       
   541     return iFont->TextWidthInPixels( buf );
       
   542     }
       
   543 
       
   544 TPoint TAknPhedViewLine::CursorPosition() const
       
   545     {
       
   546     __ASSERT_DEBUG( iCursor != CAknPhedView::KNoPos, PhedViewPanic( ELineNoCursor ) );
       
   547     return TPoint( CursorPosToXPos( iCursor ), Baseline() );
       
   548     }
       
   549 
       
   550 // ---------------------------------------------------------------------------
       
   551 // TAknPhedViewLine::DrawHighlightText
       
   552 // ---------------------------------------------------------------------------
       
   553 // 
       
   554 void TAknPhedViewLine::DrawHighlightText( CGraphicsContext& aGc, 
       
   555     TBool aUseSkin ) const
       
   556     {
       
   557     TInt baseline =  Baseline() - iRect.iTl.iY;
       
   558     TRect rect( iRect );
       
   559     rect.iBr.iX = CursorPosToXPos( SelectionStart() );
       
   560     rect.iTl.iX = CursorPosToXPos( SelectionEnd() );
       
   561     
       
   562     TRgb penColor( KRgbWhite );
       
   563     TRgb brushColor( KRgbBlue );
       
   564     if ( aUseSkin )
       
   565         {
       
   566         MAknsSkinInstance* skin = AknsUtils::SkinInstance();
       
   567         AknsUtils::GetCachedColor( skin, penColor, KAknsIIDQsnTextColors, 
       
   568             EAknsCIQsnTextColorsCG24);
       
   569         AknsUtils::GetCachedColor( skin, brushColor, KAknsIIDQsnHighlightColors, 
       
   570             EAknsCIQsnHighlightColorsCG2 );
       
   571         }
       
   572     aGc.SetBrushStyle( CGraphicsContext::ESolidBrush );
       
   573     aGc.SetBrushColor( brushColor );
       
   574     aGc.DrawRect( rect );
       
   575     aGc.SetPenStyle( CGraphicsContext::ESolidPen );
       
   576     aGc.SetPenColor( penColor );
       
   577     TInt selStart( iModel->LeftMark() );
       
   578     TInt endPos( iModel->Length() - SelectionStart() );
       
   579     TInt startPos( iModel->Length() - SelectionEnd() );
       
   580     TPtrC text( TranslatedText( iModel->Selection().Mid( startPos - selStart, 
       
   581         endPos - startPos ) ) );
       
   582     aGc.DrawText( text, rect, baseline, CGraphicsContext::ERight );
       
   583     }
       
   584 
       
   585 TPtr TAknPhedViewLine::TranslatedText( const TDesC& aText ) const
       
   586     {
       
   587     TPtr buf( iModel->TranslationBuffer() );
       
   588     // to make sure that the buffer does not overflow.
       
   589     TInt maxLength = buf.MaxLength();
       
   590     buf.Copy( aText.Left( maxLength ) );
       
   591     // this routine will not expand the contents of the buffer:
       
   592     AknTextUtils::DisplayTextLanguageSpecificNumberConversion( buf );
       
   593     return buf;
       
   594     }
       
   595 
       
   596 CAknPhedView::CAknPhedView( CAknPhedModel* aModel ) : iModel( aModel )
       
   597     {
       
   598     iMirror.SetPhedModel( iModel );
       
   599     iMirror.SetObserver( this );
       
   600     }
       
   601 
       
   602 CAknPhedView::~CAknPhedView()
       
   603     {
       
   604     CRedirectionListener* listener = ( CRedirectionListener* )
       
   605                                     CAknTransitionUtils::GetData( (TInt) this );
       
   606     if ( listener )
       
   607         {
       
   608         CAknTransitionUtils::RemoveObserver( listener,
       
   609                                 CAknTransitionUtils::EEventWsBufferRedirection );
       
   610         CAknTransitionUtils::RemoveData( (TInt) this );
       
   611         delete listener;
       
   612         }
       
   613     delete iLines;
       
   614     delete iTruncation;
       
   615     }
       
   616 
       
   617 void CAknPhedView::ConstructL( TInt aMaxLines, const TDesC& aTruncation )
       
   618     {
       
   619     iTruncation = aTruncation.AllocL();
       
   620     iLines = new(ELeave) CAknPhedViewLineArray( aMaxLines );
       
   621     iLines->ResizeL(aMaxLines);
       
   622     for ( TInt ii=0; ii<aMaxLines; ii++ )
       
   623         {
       
   624         iLines->At( ii ).SetModel( iModel );
       
   625         iLines->At( ii ).SetTruncation( *iTruncation );
       
   626         }
       
   627     // Create listener that listen for redirection changes
       
   628     CRedirectionListener* listener = new (ELeave) CRedirectionListener( *this );
       
   629     User::LeaveIfError( CAknTransitionUtils::SetData( (TInt) this,
       
   630                                                       (TDesC8*) listener ) );
       
   631     User::LeaveIfError( CAknTransitionUtils::AddObserver( listener,
       
   632                             CAknTransitionUtils::EEventWsBufferRedirection ) );
       
   633 	}
       
   634 
       
   635 void CAknPhedView::SetFormat( TInt aLines, 
       
   636                               const CFont* aFont, 
       
   637                               const TRect& aRect, 
       
   638                               TInt aBottomBaselineOffset, 
       
   639                               TInt aBaselineSeparation)
       
   640     {
       
   641     __ASSERT_DEBUG(iLines, PhedViewPanic(EFormatNullLines));
       
   642     __ASSERT_DEBUG(aLines <= iLines->Count(), PhedViewPanic(EFormatTooManyLines));
       
   643     __ASSERT_DEBUG(aLines > 0, PhedViewPanic(EFormatTooFewLines));
       
   644 
       
   645     iNumLines = aLines;
       
   646     iFont = aFont;
       
   647     iRect = aRect;
       
   648 
       
   649     TRect rect(aRect);
       
   650     TInt baseline(rect.iBr.iY - aBottomBaselineOffset);
       
   651     for (TInt ii=0; ii<aLines; ii++)
       
   652         {
       
   653         TAknPhedViewLine& line = iLines->At(ii);
       
   654         
       
   655         // give each line a part of the rectangle aBaselineSeparation high
       
   656         if ( iNumLines > 1)
       
   657             {
       
   658             rect.iTl.iY = rect.iBr.iY - aBaselineSeparation;
       
   659             }
       
   660         line.SetFormat(aFont, rect, baseline);
       
   661         rect.iBr.iY = rect.iTl.iY;
       
   662         baseline -= aBaselineSeparation;
       
   663 
       
   664         SetConnectingLines(line, ii);
       
   665         }
       
   666 
       
   667     SetCursorFormat(aFont);
       
   668 
       
   669     FullFormat();
       
   670     }
       
   671 
       
   672 void CAknPhedView::SetConnectingLines(TAknPhedViewLine& aLine, TInt aLineNum)
       
   673     {
       
   674     // connect up lines. Line 0 is the bottom line.
       
   675     aLine.SetLeftLine(aLineNum >= iNumLines-1 ? NULL : &iLines->At(aLineNum+1));
       
   676     aLine.SetRightLine(aLineNum <= 0 ? NULL : &iLines->At(aLineNum - 1));
       
   677     }
       
   678 
       
   679 void CAknPhedView::HandlePhedDataEvent( const TAknPhedDataEvent& aEvent, 
       
   680                                         CAknPhedModel* /*aPhedData*/)
       
   681     {
       
   682     __ASSERT_DEBUG( iLines, PhedViewPanic( EEventNullLines ) );
       
   683 
       
   684     if ( aEvent.TextChanged() )
       
   685         {
       
   686         TInt start;
       
   687         TInt end;
       
   688         aEvent.TextChangeRange( start, end );
       
   689         TextChangeFormat( start, end );
       
   690         }
       
   691     // text change handling also repositions cursor, so don't handle it twice
       
   692     else if ( aEvent.CursorChanged() )
       
   693         {
       
   694         CursorChangeFormat( iMirror.CursorPosition() );
       
   695         }
       
   696 
       
   697     if ( aEvent.SelectionChanged() )
       
   698         {
       
   699         SelectionChangeFormat( iMirror.LeftMark(), iMirror.RightMark() );
       
   700         }
       
   701 
       
   702     // report that the editor has changed to the containing control, so that it
       
   703     // can report to it's observer.
       
   704     if ( iChangeReceiver )
       
   705         iChangeReceiver->StateChanged();
       
   706     }
       
   707 
       
   708 void CAknPhedView::FullFormat()
       
   709     {
       
   710     TextChangeFormat( 0, iModel->Length() );
       
   711     SelectionChangeFormat( iMirror.LeftMark(), iMirror.RightMark() );
       
   712     }
       
   713 
       
   714 void CAknPhedView::TextChangeFormat( TInt aStart, TInt aEnd )
       
   715     {
       
   716     // Let the lines handle the change. 
       
   717     // Stops after the first line able to handle the change, because it will tell the rest
       
   718     for ( TInt ii=0; ii<iNumLines; ii++ )
       
   719         {
       
   720         if ( iLines->At(ii).HandleTextChange( aStart, aEnd ) )
       
   721             break;
       
   722         }
       
   723     
       
   724     // Make as much text fit on screen, to the RHS as possible
       
   725     TAknPhedViewLine& leftLine = iLines->At( iNumLines-1 );
       
   726     TAknPhedViewLine& rightLine = iLines->At( 0 );
       
   727     if ( rightLine.IsTruncatedRight() && !leftLine.IsTruncatedLeft() && aStart <0 )
       
   728         {
       
   729         SetLeftPos( 0 );
       
   730         }
       
   731     if ( rightLine.IsTruncatedRight() && !leftLine.IsTruncatedLeft() )
       
   732         {
       
   733         SetLeftPos(leftLine.LeftPos());
       
   734         }
       
   735 
       
   736     // Cursor positioning must be affected by all that
       
   737     CursorChangeFormat( iMirror.CursorPosition() );
       
   738     }
       
   739 
       
   740 void CAknPhedView::CursorChangeFormat( TInt aCursor )
       
   741     {
       
   742     if ( aCursor < 0 )
       
   743         {
       
   744         return;
       
   745         }
       
   746     // Shift the text so that the cursor appears on the screen
       
   747     TAknPhedViewLine& leftLine = iLines->At( iNumLines-1 );
       
   748     TAknPhedViewLine& rightLine = iLines->At( 0 );    
       
   749     
       
   750     if ( aCursor < rightLine.RightPos() )
       
   751         {
       
   752         rightLine.SetRightPos( aCursor );
       
   753         }
       
   754     else if ( aCursor >= leftLine.LeftPos() && leftLine.LineWidth() != 0 &&
       
   755         leftLine.IsTruncatedLeft() )
       
   756         {
       
   757         
       
   758         // cursor rule: cursor should not be a LHS of left truncated line
       
   759         if ( aCursor == iModel->Length() )
       
   760             SetLeftPos( aCursor );
       
   761         else
       
   762             SetLeftPos( aCursor+1 );
       
   763         }
       
   764     else if ( aCursor >= leftLine.LeftPos() )
       
   765         {
       
   766     	SetLeftPos( aCursor );
       
   767         }
       
   768     // Tell each line about the cursor.
       
   769     // Bottom most line to handle the event claims the cursor
       
   770     for ( TInt ii=0; ii<iNumLines; ii++ )
       
   771         {
       
   772         if ( iLines->At( ii ).HandleCursorChange( aCursor ) )
       
   773             {
       
   774             iCursorLine = ii;
       
   775             aCursor = KNoPos;
       
   776             }
       
   777         }
       
   778 
       
   779     UpdateCursor();
       
   780     }
       
   781 
       
   782 void CAknPhedView::SelectionChangeFormat( TInt aLeft, TInt aRight )
       
   783     {
       
   784     // Tell each line about the selection change
       
   785     for ( TInt ii=0; ii<iNumLines; ii++ )
       
   786         {
       
   787         iLines->At( ii ).HandleSelectionChange( aLeft, aRight );
       
   788         }
       
   789     }
       
   790 
       
   791 void CAknPhedView::Draw( CWindowGc& aGc, TBool aRedrawAll,
       
   792     const CCoeControl* aControl ) const
       
   793     {
       
   794     MAknsSkinInstance* skin = AknsUtils::SkinInstance();
       
   795     MAknsControlContext* cc = AknsDrawUtils::ControlContext( aControl );
       
   796 
       
   797     aGc.UseFont( iFont );
       
   798     for ( TInt ii=0; ii<iNumLines; ii++ )
       
   799         {
       
   800         TAknPhedViewLine& line = iLines->At( ii );
       
   801         if ( aRedrawAll || line.IsRedrawRequired() )
       
   802             {
       
   803             line.Draw( aGc, skin, cc, aControl );
       
   804             }
       
   805         }
       
   806     aGc.DiscardFont();
       
   807     }
       
   808 
       
   809 void CAknPhedView::MoveCursorToLine( TInt aLineNo, TInt aTargetCursorPos )
       
   810     {
       
   811     // Used by up and down cursor move functions. Scroll one line if necessary
       
   812     if ( aLineNo < 0 )
       
   813         {
       
   814         TAknPhedViewLine& line = iLines->At( 0 );
       
   815         line.SetLeftPos(line.RightPos());
       
   816 		iMirror.SetCompensatedCursorPosition(line.XPosToCursorPos(aTargetCursorPos));
       
   817         line.SetRightPos( line.RightPos() );
       
   818         }
       
   819     else if ( aLineNo >= iNumLines )
       
   820         {
       
   821         TAknPhedViewLine& line = iLines->At( iNumLines-1 );
       
   822         line.SetRightPos( line.LeftPos() );
       
   823 		iMirror.SetCompensatedCursorPosition(line.XPosToCursorPos(aTargetCursorPos));
       
   824         SetLeftPos( line.LeftPos() );
       
   825         }
       
   826     else
       
   827         {
       
   828         iMirror.SetCompensatedCursorPosition(
       
   829             iLines->At( aLineNo ).XPosToCursorPos( aTargetCursorPos ) );
       
   830         }
       
   831 
       
   832     UpdateCursor();
       
   833 	}
       
   834 
       
   835 
       
   836 TBool CAknPhedView::CursorUp( TInt aTargetCursorPos )
       
   837     {
       
   838     // cursor rule: if at top LHS, wrap to bottom RHS, otherwise up one line
       
   839     if ( iMirror.CursorPosition() == iModel->Length() )
       
   840         {
       
   841 		// This code should be setting the real cursor position, but there is 
       
   842 		// a bug in the real cursor position function, in that it works in "compensated/formatted" space.
       
   843 		iMirror.SetCompensatedCursorPosition(0);
       
   844         return EFalse;
       
   845         }
       
   846     else
       
   847         {
       
   848         MoveCursorToLine( iCursorLine + 1, aTargetCursorPos );
       
   849         return ( iMirror.CursorPosition() != iModel->Length() );
       
   850         }
       
   851     }
       
   852 
       
   853 TBool CAknPhedView::CursorDown( TInt aTargetCursorPos )
       
   854     {
       
   855     // cursor rule: if at bottom RHS, wrap to top LHS, otherwise down one line
       
   856     if ( iMirror.CursorPosition() == 0 )
       
   857         {
       
   858 		// This code depends on the fact that there is a bug in the real cursor
       
   859 		// position function, in that it works in "compensated/formatted" space.
       
   860 		iMirror.SetRealCursorPosition(iModel->Length());
       
   861         return EFalse;
       
   862         }
       
   863     else
       
   864         {
       
   865         MoveCursorToLine( iCursorLine - 1, aTargetCursorPos );
       
   866         return ( iMirror.CursorPosition() != 0 );
       
   867         }
       
   868     }
       
   869 
       
   870 TBool CAknPhedView::SelectUp( TInt aTargetCursorPos )
       
   871     {
       
   872     TInt anchor = iModel->AnchorPosition();
       
   873     TBool targetPosUsed = CursorUp( aTargetCursorPos );
       
   874     iModel->SetAnchorPosition( anchor );
       
   875     return targetPosUsed;
       
   876     }
       
   877 
       
   878 TBool CAknPhedView::SelectDown( TInt aTargetCursorPos )
       
   879     {
       
   880     TInt anchor = iModel->AnchorPosition();
       
   881     TBool targetPosUsed = CursorDown( aTargetCursorPos );
       
   882     iModel->SetAnchorPosition( anchor );
       
   883     return targetPosUsed;
       
   884     }
       
   885 
       
   886 void CAknPhedView::EnableCursor()
       
   887     {
       
   888     CRedirectionListener* listener = ( CRedirectionListener* )
       
   889                                     CAknTransitionUtils::GetData( (TInt) this );
       
   890     listener->EnableCursor();
       
   891     UpdateCursor();
       
   892     }
       
   893 
       
   894 void CAknPhedView::DisableCursor()
       
   895     {
       
   896     CRedirectionListener* listener = ( CRedirectionListener* )
       
   897                                     CAknTransitionUtils::GetData( (TInt) this );
       
   898     listener->DisableCursor();
       
   899     }
       
   900 
       
   901 void CAknPhedView::UpdateCursor()
       
   902     {
       
   903     CRedirectionListener* listener = ( CRedirectionListener* )
       
   904                                     CAknTransitionUtils::GetData( (TInt) this );
       
   905     listener->UpdateCursor( iCursor );
       
   906     }
       
   907 
       
   908 void CAknPhedView::SetWindows( RWindowGroup* aWg, RWindowBase* aWindow )
       
   909     {
       
   910     CRedirectionListener* listener = ( CRedirectionListener* )
       
   911                                     CAknTransitionUtils::GetData( (TInt) this );
       
   912     listener->SetWindows( aWg, aWindow );
       
   913     }
       
   914 
       
   915 TPoint CAknPhedView::CursorPosition() const
       
   916     {
       
   917     return iLines->At( iCursorLine ).CursorPosition();
       
   918     }
       
   919 
       
   920 void CAknPhedView::SetCursorFormat( const CFont* aFont )
       
   921     {
       
   922     iCursor.iType   = TTextCursor::ETypeRectangle;
       
   923     iCursor.iHeight = AknLayoutUtils::CursorHeightFromFont( aFont->FontSpecInTwips() );
       
   924     iCursor.iAscent = AknLayoutUtils::CursorAscentFromFont( aFont->FontSpecInTwips() );
       
   925     iCursor.iWidth  = AknLayoutUtils::CursorWidthFromFont ( aFont->FontSpecInTwips() );
       
   926     iCursor.iFlags  = 0;
       
   927     iCursor.iColor  = KRgbWhite;
       
   928     }
       
   929 
       
   930 TBool CAknPhedView::IsTruncated() const
       
   931     {
       
   932     return iLines->At( 0 ).IsTruncatedRight() || iLines->At( iNumLines-1 ).IsTruncatedLeft();
       
   933     }
       
   934 
       
   935 void CAknPhedView::SetLeftPos( TInt aPos )
       
   936     {
       
   937     iLines->At( iNumLines-1 ).SetLeftPos( aPos );
       
   938 
       
   939     // format rule: always justify to bottom right, if not truncated
       
   940     TAknPhedViewLine& rightLine = iLines->At( 0 );
       
   941     if ( !rightLine.IsTruncated() )
       
   942         {
       
   943         rightLine.SetRightPos( 0 );
       
   944         }
       
   945     }
       
   946 
       
   947 void CAknPhedView::SetChangeReceiver( CAknPhoneNumberEditor* aChangeReceiver )
       
   948     {
       
   949     iChangeReceiver = aChangeReceiver;
       
   950     }
       
   951 
       
   952 TRect CAknPhedView::Rect() const
       
   953     {
       
   954     return iRect;
       
   955     }
       
   956 
       
   957 TInt CAknPhedView::CursorLine() const
       
   958     {
       
   959     return iCursorLine;
       
   960     }
       
   961 
       
   962 // ---------------------------------------------------------------------------
       
   963 // CAknPhedView::GetCursorPosByPoint
       
   964 // ---------------------------------------------------------------------------
       
   965 // 
       
   966 TInt CAknPhedView::GetCursorPosByPoint( const TPoint& aPt )
       
   967     {
       
   968     TInt posLine = -1, cursor = -1;
       
   969     //check which line the pointer position is within.
       
   970     for ( TInt i = 0; i < iNumLines; i++ )        
       
   971         {
       
   972         if ( iLines->At( i ).Rect().Contains( aPt ) )
       
   973             {
       
   974             posLine = i;
       
   975             break;
       
   976             }
       
   977         }
       
   978     if ( posLine < 0 )
       
   979         {
       
   980         // if pointer position is out of right border of line but its
       
   981         // Y coordinates is within range of the line, the iRightPos of
       
   982         // the line should be returned to preserve the selection made
       
   983         // by user, otherwise a negative value will be returned.
       
   984         TInt rectBrX = iLines->At( 0 ).Rect().iBr.iX;
       
   985         if ( aPt.iX > rectBrX )
       
   986             {
       
   987             for ( TInt i = 0; i < iNumLines; i++ )
       
   988                 {
       
   989                 TInt topY = iLines->At( i ).Rect().iTl.iY;
       
   990                 TInt bottomY = iLines->At( i ).Rect().iBr.iY;
       
   991                 if ( aPt.iY >= topY && aPt.iY <= bottomY )
       
   992                     {
       
   993                     posLine = i;
       
   994                     break;
       
   995                     }
       
   996                 }
       
   997             if ( posLine >= 0 && iLines->At( posLine ).LineWidth() > 0 )
       
   998                 {
       
   999                 TInt rightPos = iLines->At( posLine ).RightPos();
       
  1000                 cursor = iModel->Length() - rightPos;
       
  1001                 }
       
  1002             }            
       
  1003         return cursor;
       
  1004         } 
       
  1005     // only handle pointer event when the line has data
       
  1006     if ( iLines->At( posLine ).LineWidth() > 0)
       
  1007         {
       
  1008         iCursorLine = posLine;        
       
  1009         TInt pos = iLines->At( iCursorLine ).XPosToCursorPos( aPt.iX );        
       
  1010         cursor = iModel->Length() - pos;
       
  1011         
       
  1012         const TReal32 KHalfRatio = 0.5;        
       
  1013         TInt rightX = iLines->At( iCursorLine ).CursorPosToXPos( pos );
       
  1014         TInt leftX = iLines->At( iCursorLine ).CursorPosToXPos( pos + 1 );        
       
  1015         TInt rightPos = iLines->At( iCursorLine ).RightPos();  
       
  1016         TInt leftPos = iLines->At( iCursorLine ).LeftPos(); 
       
  1017         if ( aPt.iX < iLines->At( iCursorLine ).CursorPosToXPos( leftPos ) 
       
  1018             && aPt.iX > 0 )
       
  1019             {
       
  1020             return cursor;
       
  1021             } 
       
  1022              
       
  1023         if ( aPt.iX > rightX && rightPos > 0 )
       
  1024             {
       
  1025             leftX = rightX;
       
  1026             rightX = iLines->At( iCursorLine ).Rect().iBr.iX;
       
  1027             cursor++;            
       
  1028             }        
       
  1029         if ( ( aPt.iX - leftX ) < ( ( rightX - leftX ) * KHalfRatio ) )
       
  1030             {
       
  1031             cursor--;
       
  1032             }        
       
  1033         }    
       
  1034     return cursor;
       
  1035     }
       
  1036 
       
  1037 // End of File