imstutils/imconversationview/imcvuiapp/src/cimcvapprichtextcontainer.cpp
branchRCL_3
changeset 29 9a48e301e94b
equal deleted inserted replaced
28:3104fc151679 29:9a48e301e94b
       
     1 /*
       
     2 * Copyright (c) 2009 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 * 
       
    15 * Description:
       
    16 * Export help related files.
       
    17 *
       
    18 */
       
    19 
       
    20 
       
    21 
       
    22 
       
    23 // INCLUDE FILES
       
    24 #include    "cimcvapprichtextcontainer.h"
       
    25 #include    "cimcvappmessagewrapper.h"
       
    26 #include    "mimcvapptextview.h"
       
    27 #include    "cimcvappui.h"
       
    28 #include    "mimcvenginemessage.h"
       
    29 #include    "cimcvappmessageextensionshandler.h"
       
    30 
       
    31 #include    <AknIconUtils.h>
       
    32 #include    <txtrich.h>     // CRichtText
       
    33 #include    <AknSettingCache.h>
       
    34 #include    <aknenv.h>
       
    35 #include    <aknconsts.h>
       
    36 #include    <finditemengine.h>
       
    37 #include    <barsread.h> // resourcereader
       
    38 #include    <StringLoader.h>
       
    39 
       
    40 #include    <AknsDrawUtils.h>
       
    41 #include    <AknsUtils.h>
       
    42 #include    <AknUtils.h>
       
    43 #include 	"imcvlogger.h"
       
    44 #include	"cimcvapppicture.h"
       
    45 #include 	<imcvuiapp.mbg>
       
    46 #include	"cimcvappsmileiconutility.h"
       
    47 #include    <imcvuiapp.rsg>
       
    48 
       
    49 // CONSTANTS
       
    50 const TInt KIMCVHighlightColor = 244;
       
    51 const TInt KTimeStampMaxLength = 15;     // max length of timestamp text
       
    52 const TInt KUnicodeRLM         = 0x200F; // Right-to-Left Mark
       
    53 const TInt KUnicodeLRM         = 0x200E; // Left-to-Right Mark
       
    54 //Received message maximum length is 400 character,
       
    55 //this must always be in sync with imconnectionprovider KReceiveMsgMaxLength
       
    56 const TInt KReceiveMsgMaxLength = 400; 
       
    57 const TInt KMsgMaxLength = 450; //Received message maximum length is 400 character + truncation message 
       
    58 _LIT( KSeparator, ": " );
       
    59 _LIT(KSpace, " ");
       
    60 
       
    61 
       
    62 // ============================ MEMBER FUNCTIONS ===============================
       
    63 
       
    64 // -----------------------------------------------------------------------------
       
    65 // CIMCVAppRichTextContainer::CIMCVAppRichTextContainer
       
    66 // C++ default constructor can NOT contain any code, that
       
    67 // might leave.
       
    68 // -----------------------------------------------------------------------------
       
    69 //
       
    70 CIMCVAppRichTextContainer::CIMCVAppRichTextContainer(MIMCVAppUi* aAppUi,
       
    71         MIMCVAppTextView* aTextView, 
       
    72         CIMCVAppMessageExtensionsHandler* aExtensionsHandler,
       
    73         CGulIcon* aFromMe,
       
    74         CGulIcon* aToMe,
       
    75         MGraphicsDeviceMap* aMap, 
       
    76         TInt aServiceId,
       
    77         TBool aScrollOver /*= ETrue*/):
       
    78     iAppUi(aAppUi),
       
    79     iTextView( aTextView ), 
       
    80     iItemHighlight( ETrue ), 
       
    81     iHighlightState( ENoHighlight ),
       
    82     iExtensionsHandler( aExtensionsHandler ),
       
    83     iScrollOver( aScrollOver ),
       
    84     iFromMe( aFromMe ), 
       
    85     iToMe( aToMe ),
       
    86     iMap(aMap),
       
    87     iServiceId( aServiceId )
       
    88 	    {
       
    89 	    }
       
    90 
       
    91 // -----------------------------------------------------------------------------
       
    92 // CIMCVAppRichTextContainer::Initialize
       
    93 // Initializes iTextView
       
    94 // -----------------------------------------------------------------------------
       
    95 //
       
    96 void CIMCVAppRichTextContainer::Initialize( MIMCVAppUi* aAppUi,
       
    97         MIMCVAppTextView* aTextView, 
       
    98         CIMCVAppMessageExtensionsHandler* aExtensionsHandler,
       
    99         CGulIcon* aFromMe,
       
   100         CGulIcon* aToMe,
       
   101         MGraphicsDeviceMap* aMap,                              
       
   102         TBool aScrollOver /*= ETrue*/ )
       
   103     {
       
   104     iAppUi = aAppUi;
       
   105     iTextView = aTextView;   
       
   106     iExtensionsHandler = aExtensionsHandler;
       
   107     iFromMe = aFromMe;
       
   108     iToMe = aToMe;
       
   109     iMap = aMap;
       
   110     iScrollOver = aScrollOver;
       
   111     }
       
   112 
       
   113 // -----------------------------------------------------------------------------
       
   114 // CIMCVAppRichTextContainer::ConstructL
       
   115 // Symbian 2nd phase constructor can leave.
       
   116 // -----------------------------------------------------------------------------
       
   117 //
       
   118 void CIMCVAppRichTextContainer::ConstructL(const TDesC& aPrimaryKey)
       
   119     {
       
   120     
       
   121     iPrimaryKey = aPrimaryKey.AllocL();
       
   122     
       
   123     iAppUi->AddLayoutChangeObserver( this );
       
   124     iAppUi->AddResourceChangeObserver( this );
       
   125        // setup layout
       
   126     TAknLayoutId layoutId;
       
   127     CAknEnv::Static()->GetCurrentLayoutId( layoutId );
       
   128     
       
   129       
       
   130     iPrimaryFont = AknLayoutUtils::FontFromId( EAknLogicalFontPrimaryFont, 
       
   131     	NULL );
       
   132     iSecondaryFont = AknLayoutUtils::FontFromId( EAknLogicalFontPrimarySmallFont, 
       
   133     	NULL );
       
   134 
       
   135     CParaFormat paraFormat;
       
   136     TParaFormatMask paraFormatMask;
       
   137 	paraFormat.iLanguage = CAknEnv::Static()->SettingCache().InputLanguage();
       
   138 	paraFormatMask.SetAttrib( EAttParaLanguage );
       
   139 
       
   140     paraFormat.iFillColor = KRgbWhite;
       
   141     paraFormatMask.SetAttrib( EAttFillColor );
       
   142     
       
   143     paraFormat.iLeftMarginInTwips = 100;
       
   144     paraFormat.iIndentInTwips = -100;
       
   145     paraFormatMask.SetAttrib( EAttLeftMargin );    
       
   146     paraFormatMask.SetAttrib( EAttIndent );    
       
   147 
       
   148     TCharFormat charFormat;
       
   149     TCharFormatMask charFormatMask;
       
   150     charFormat.iFontSpec = iSecondaryFont->FontSpecInTwips();
       
   151     charFormatMask.SetAttrib( EAttFontTypeface );
       
   152     charFormatMask.SetAttrib( EAttFontHeight );
       
   153 
       
   154     // Text color
       
   155     TRgb defaultSkinTextColor( KRgbBlack );
       
   156     AknsUtils::GetCachedColor( AknsUtils::SkinInstance(), 
       
   157                                defaultSkinTextColor,
       
   158                                KAknsIIDQsnTextColors,
       
   159                                EAknsCIQsnTextColorsCG6 );
       
   160     charFormat.iFontPresentation.iTextColor = defaultSkinTextColor;
       
   161     charFormatMask.SetAttrib( EAttColor );
       
   162 
       
   163    	charFormat.iFontPresentation.iPictureAlignment = 
       
   164    	    TFontPresentation::EAlignTop;
       
   165    	charFormatMask.SetAttrib( EAttFontPictureAlignment );
       
   166     
       
   167     charFormat.iFontSpec.iFontStyle.SetStrokeWeight( EStrokeWeightNormal );
       
   168     charFormatMask.SetAttrib( EAttFontStrokeWeight );
       
   169     
       
   170 
       
   171     iParaFormatLayer = CParaFormatLayer::NewL( &paraFormat, paraFormatMask );
       
   172     iCharFormatLayer = CCharFormatLayer::NewL( charFormat, charFormatMask );
       
   173 
       
   174     iRichText = CRichText::NewL( iParaFormatLayer, iCharFormatLayer );    
       
   175     IM_CV_LOGS(TXT("CIMCVAppRichTextContainer::ConstructL()	end" ));
       
   176     }
       
   177 
       
   178 // -----------------------------------------------------------------------------
       
   179 // CIMCVAppRichTextContainer::NewL
       
   180 // Two-phased constructor.
       
   181 // -----------------------------------------------------------------------------
       
   182 //
       
   183 CIMCVAppRichTextContainer* CIMCVAppRichTextContainer::NewL( MIMCVAppUi* aAppUi,
       
   184                               MIMCVAppTextView* aTextView, 
       
   185                               CIMCVAppMessageExtensionsHandler* aExtensionsHandler,
       
   186                               CGulIcon* aFromMe,
       
   187                               CGulIcon* aToMe,
       
   188 							  MGraphicsDeviceMap* aMap,                              
       
   189                               const TDesC& aPrimaryKey,
       
   190                               TInt aServiceId,
       
   191                               TBool aScrollOver /*= ETrue*/)
       
   192     {    
       
   193     IM_CV_LOGS(TXT("CIMCVAppRichTextContainer::NewL()	start" ));
       
   194     CIMCVAppRichTextContainer* self = new( ELeave ) CIMCVAppRichTextContainer(aAppUi,
       
   195                                         aTextView, 
       
   196 									    aExtensionsHandler, aFromMe, aToMe, aMap,aServiceId,
       
   197 									    aScrollOver );
       
   198 
       
   199     CleanupStack::PushL( self );
       
   200     self->ConstructL(aPrimaryKey);
       
   201     CleanupStack::Pop( self );
       
   202     IM_CV_LOGS(TXT("CIMCVAppRichTextContainer::NewL()	end" ));
       
   203     return self;
       
   204     }
       
   205 
       
   206 
       
   207 // Destructor
       
   208 CIMCVAppRichTextContainer::~CIMCVAppRichTextContainer()
       
   209     {
       
   210     if(iPrimaryKey)
       
   211         {
       
   212         delete iPrimaryKey;
       
   213         iPrimaryKey = NULL;
       
   214         }
       
   215     delete iParaFormatLayer;
       
   216     delete iCharFormatLayer;
       
   217     delete iRichText;
       
   218     iMessages.ResetAndDestroy();
       
   219     if(iAppUi)
       
   220         {
       
   221         iAppUi->RemoveLayoutChangeObserver( this );  
       
   222         iAppUi->RemoveResourceChangeObserver( this );  
       
   223         }
       
   224     }
       
   225 
       
   226 
       
   227 // -----------------------------------------------------------------------------
       
   228 // CIMCVAppRichTextContainer::SelectedItem
       
   229 // (other items were commented in a header).
       
   230 // -----------------------------------------------------------------------------
       
   231 //
       
   232 HBufC* CIMCVAppRichTextContainer::SelectedItemL()
       
   233     {
       
   234     IM_CV_LOGS(TXT("CIMCVAppRichTextContainer::SelectedItemL()	start" ));
       
   235     if( iHighlightState == EItemSelected )
       
   236         {
       
   237         TCursorSelection curSel( iMessages[iSelected]->Selection() );
       
   238         
       
   239         // calculate item highlight position        
       
   240         TCursorSelection itemSel( 
       
   241         					iMessages[iSelected]->Highlights()[iSelectedItem] );
       
   242 
       
   243         TInt messageStart( curSel.LowerPos() );
       
   244         curSel.iAnchorPos = itemSel.iAnchorPos + messageStart;
       
   245         curSel.iCursorPos = itemSel.iCursorPos + messageStart;
       
   246         
       
   247         HBufC* text = HBufC::NewMaxL( curSel.Length() );
       
   248         TPtr ptr( text->Des() );
       
   249         iRichText->Extract(	ptr, curSel.LowerPos(), curSel.Length() );
       
   250 	    IM_CV_LOGS(TXT("CIMCVAppRichTextContainer::SelectedItemL()	end" ));
       
   251         return text;
       
   252         }
       
   253     else
       
   254         {
       
   255 	    IM_CV_LOGS(TXT("CIMCVAppRichTextContainer::SelectedItemL()	end" ));
       
   256         return KNullDesC().AllocL();
       
   257         }
       
   258     }
       
   259     
       
   260 // -----------------------------------------------------------------------------
       
   261 // CIMCVAppRichTextContainer::SelectedItemType
       
   262 // (other items were commented in a header).
       
   263 // -----------------------------------------------------------------------------
       
   264 //
       
   265 TInt CIMCVAppRichTextContainer::SelectedItemType()
       
   266     {
       
   267     IM_CV_LOGS(TXT("CIMCVAppRichTextContainer::SelectedItemType()	start" ));
       
   268     if( (iHighlightState == EItemSelected) && ( iMessages.Count() >0  )
       
   269     	&& (iSelected >= 0  ) )
       
   270         {
       
   271 	    IM_CV_LOGS(TXT("CIMCVAppRichTextContainer::SelectedItemType()	end" ));
       
   272 	    
       
   273         return iMessages[iSelected]->HighlightTypes()[iSelectedItem];
       
   274         }
       
   275     else
       
   276         {
       
   277     	IM_CV_LOGS(TXT("CIMCVAppRichTextContainer::SelectedItemType()	end" ));
       
   278         return KErrNotFound;
       
   279         }
       
   280     }
       
   281 
       
   282 // -----------------------------------------------------------------------------
       
   283 // CIMCVAppRichTextContainer::RichText
       
   284 // (other items were commented in a header).
       
   285 // -----------------------------------------------------------------------------
       
   286 //
       
   287 MLayDoc* CIMCVAppRichTextContainer::TextLayout()
       
   288     {
       
   289     return iRichText;
       
   290     }
       
   291 // -----------------------------------------------------------------------------
       
   292 // CIMCVAppRichTextContainer::RichText
       
   293 // (other items were commented in a header).
       
   294 // -----------------------------------------------------------------------------
       
   295 //
       
   296 TInt CIMCVAppRichTextContainer::ServiceId() const
       
   297     {
       
   298     return iServiceId;
       
   299     }
       
   300 // -----------------------------------------------------------------------------
       
   301 // CIMCVAppRichTextContainer::SetItemHighlight
       
   302 // (other items were commented in a header).
       
   303 // -----------------------------------------------------------------------------
       
   304 //
       
   305 void CIMCVAppRichTextContainer::SetItemHighlight( TBool aItemHighlight )
       
   306     {
       
   307     iItemHighlight = aItemHighlight;
       
   308 	TInt richTextDocumentLength = iRichText->DocumentLength();
       
   309 	if (!richTextDocumentLength)
       
   310 		return;
       
   311 	
       
   312 	if (aItemHighlight)
       
   313 	{
       
   314 		HBufC* text = HBufC::NewMaxLC( richTextDocumentLength );
       
   315 		TPtr txt( text->Des() );
       
   316 
       
   317 		iRichText->Extract( txt);
       
   318 		CFindItemEngine* findItem = CFindItemEngine::NewL( txt, 
       
   319 									CFindItemEngine::TFindItemSearchCase(
       
   320 									CFindItemEngine::EFindItemSearchPhoneNumberBin |
       
   321 									CFindItemEngine::EFindItemSearchMailAddressBin |
       
   322 									CFindItemEngine::EFindItemSearchURLBin/* |
       
   323 									CFindItemEngine::EFindItemSearchScheme*/ )
       
   324 									);									   
       
   325 		
       
   326 		CleanupStack::PushL( findItem );
       
   327 		const CArrayFixFlat<CFindItemEngine::SFoundItem>* items = findItem->ItemArray();
       
   328 		TInt count( items->Count() );
       
   329 		
       
   330 		for( TInt i(0); i<count; ++i )
       
   331 			{
       
   332 			const CFindItemEngine::SFoundItem item = items->At(i);
       
   333 			
       
   334 			// selection in rich text
       
   335 			TCursorSelection realSel( item.iStartPos + item.iLength, item.iStartPos );
       
   336 			
       
   337 			HighLightItemL( realSel );
       
   338 			}
       
   339 
       
   340 		CleanupStack::PopAndDestroy( findItem );
       
   341 		CleanupStack::PopAndDestroy( text);
       
   342 	
       
   343 	}
       
   344 	else
       
   345     {
       
   346     	TCharFormat charFormat;
       
   347 		TCharFormatMask charFormatMask;
       
   348 		charFormatMask.SetAttrib( EAttFontUnderline );
       
   349 
       
   350 		charFormat.iFontPresentation.iUnderline = EUnderlineOff;
       
   351 
       
   352 		iRichText->ApplyCharFormatL ( charFormat, charFormatMask, 0, richTextDocumentLength);
       
   353 	}
       
   354     }
       
   355 // -----------------------------------------------------------------------------
       
   356 // CIMCVAppRichTextContainer::MoveHighlightL
       
   357 // (other items were commented in a header).
       
   358 // -----------------------------------------------------------------------------
       
   359 //
       
   360 TInt CIMCVAppRichTextContainer::MoveHighlightL( THighlightMovement aDirection )
       
   361     {
       
   362     IM_CV_LOGS(TXT("CIMCVAppRichTextContainer::MoveHighlightL()	start" ));
       
   363     TBool up( aDirection == EPrevious );
       
   364     TInt messageCount( iMessages.Count() );    
       
   365     if( messageCount == 0 )
       
   366         {
       
   367         // no messages, nothing to highlight
       
   368         //but make highlight state as EMessageBottom 
       
   369         //so that tabs can be switched when there is no conversation in text container.
       
   370         if(iHighlightState == EMessageBottom)
       
   371             {
       
   372             iHighlightState = ENoHighlight;            
       
   373             }
       
   374         else
       
   375             {
       
   376             iHighlightState = EMessageBottom;   
       
   377             }
       
   378         return KErrNone;
       
   379         }
       
   380     
       
   381    
       
   382     TInt highlightCount( iMessages[iSelected]->Highlights().Count() );
       
   383     
       
   384     if( !iItemHighlight )
       
   385         {
       
   386         // if item highlighting is not on, clear the item count
       
   387         highlightCount = 0;
       
   388         }    
       
   389         
       
   390     // if message is highlighted, but it doesn't fit to screen
       
   391     // scroll it line by line
       
   392     if( iHighlightState == EMessageTop || iHighlightState == EMessageBottom )
       
   393         {
       
   394         TCursorSelection& sel = iMessages[iSelected]->Selection();
       
   395         if( up )
       
   396             {
       
   397             // up
       
   398             if( !iTextView->IsVisible( sel.LowerPos() ) )
       
   399                 {
       
   400                 // we're scrolling up and top line is not shown, 
       
   401                 // so scroll messages down by one line
       
   402                 iTextView->ScrollLinesL( 1 );
       
   403                 return KErrNone;
       
   404                 }
       
   405             }
       
   406         else if( !iTextView->IsVisible( sel.HigherPos() ) )
       
   407             {
       
   408             // we're scrolling down and bottom line is not shown,
       
   409             // so scroll messages up by one line
       
   410             iTextView->ScrollLinesL( -1 );
       
   411             return KErrNone;
       
   412             }        
       
   413         }
       
   414 
       
   415     // update highlight position    
       
   416     switch( iHighlightState )
       
   417         {
       
   418         case ENoHighlight:  // no highlight, select last  or first message
       
   419             {
       
   420             if( up )
       
   421                 {
       
   422                 iSelected = messageCount - 1;
       
   423                 
       
   424                 // Get highlight count of prev message
       
   425                 // if item highlighting is on
       
   426                 if ( iItemHighlight )                
       
   427                     {
       
   428                     highlightCount = iMessages[iSelected]->Highlights().Count();
       
   429                     }                
       
   430                     
       
   431                 if ( highlightCount > 0 )
       
   432                     {
       
   433                     // highlight items inside last message (if any)
       
   434                     iHighlightState = EItemSelected;
       
   435                     iSelectedItem = highlightCount - 1;
       
   436                     }
       
   437                 else
       
   438                     {
       
   439                     // bottom of last message
       
   440                     iHighlightState = EMessageBottom;
       
   441                     }
       
   442                 }
       
   443             else
       
   444                 {
       
   445                 // top of first message
       
   446                 iHighlightState = EMessageTop;
       
   447                 iSelected = 0;
       
   448                 }            
       
   449             break;
       
   450             }
       
   451         case EItemSelected: // highlighting items            
       
   452             {
       
   453             if( up )
       
   454                 {
       
   455                 // up, previous item
       
   456                 --iSelectedItem;
       
   457                 if( iSelectedItem < 0 )
       
   458                     {
       
   459                     // end of highlights, focus message
       
   460                     iHighlightState = EMessageTop;
       
   461                     }
       
   462                 }
       
   463             else
       
   464                 {
       
   465                 // down, next item
       
   466                 ++iSelectedItem;
       
   467                 if( iSelectedItem >= highlightCount )
       
   468                     {
       
   469                     // end of highlights
       
   470                     if ( iSelected < messageCount - 1 )
       
   471                         {
       
   472                         // focus next message
       
   473                         ++iSelected;
       
   474                         iHighlightState = EMessageTop;
       
   475                         }
       
   476                     else if ( iScrollOver )
       
   477                         {
       
   478                         // going down from last message,
       
   479                         // disable highlight so editor can take the focus
       
   480                         DisableHighlightL();
       
   481                         return KErrNone;
       
   482                         }
       
   483                     else
       
   484                         {
       
   485                         // Loop back to beginning
       
   486                         iSelected = 0;
       
   487                         iSelectedItem = 0;
       
   488                         iHighlightState = EMessageTop;
       
   489                         }
       
   490                     
       
   491                     }
       
   492                 }
       
   493             break;
       
   494             }
       
   495         case EMessageTop:   // highlighting message ("top" of it)
       
   496             {
       
   497             if( up )
       
   498                 {
       
   499                 // up, highlighting previous message
       
   500                 if( iSelected > 0 )
       
   501                     {
       
   502                     // prev
       
   503                     --iSelected;
       
   504                     
       
   505                     // get highlight count of prev message
       
   506                     // if item highlighting is on                
       
   507                     if ( iItemHighlight )                
       
   508                         {
       
   509                         highlightCount = iMessages[iSelected]->Highlights().Count();
       
   510                         }
       
   511                     
       
   512                     if ( highlightCount > 0 )
       
   513                         {
       
   514                         // highlight items inside prev message (if any)
       
   515                         iHighlightState = EItemSelected;
       
   516                         iSelectedItem = highlightCount - 1;
       
   517                         }
       
   518                     else
       
   519                         {
       
   520                         // highlight whole prev message
       
   521                         iHighlightState = EMessageBottom;
       
   522                         }    
       
   523                     }
       
   524                 else if ( iScrollOver )
       
   525                     {
       
   526                     // going up from first message,
       
   527                     // disable highlight, so editor can take the focus
       
   528                     DisableHighlightL();
       
   529                     return KErrNone;
       
   530                     }
       
   531                 else
       
   532                     {
       
   533                     // Loop to last message
       
   534                     iSelected = messageCount-1;
       
   535                     highlightCount = 0;
       
   536                     
       
   537                     // Get highlight count of last message
       
   538                     // if item highlighting is on
       
   539                     if ( iItemHighlight )                
       
   540                         {
       
   541                         highlightCount =
       
   542                             iMessages[iSelected]->Highlights().Count();
       
   543                         }
       
   544                     
       
   545                     if ( highlightCount > 0 )
       
   546                         {
       
   547                         // Highlight items inside last message (if any)
       
   548                         iHighlightState = EItemSelected;
       
   549                         iSelectedItem = highlightCount - 1;
       
   550                         }
       
   551                     else
       
   552                         {
       
   553                         // Highlight whole last message
       
   554                         iHighlightState = EMessageBottom;
       
   555                         }
       
   556                     }                      
       
   557                 }
       
   558             else
       
   559                 {
       
   560                 // down, highlight items inside this message (if any)
       
   561                 if( highlightCount > 0 )
       
   562                     {
       
   563                     iSelectedItem = 0;
       
   564                     iHighlightState = EItemSelected;
       
   565                     }
       
   566                 else if( iSelected < messageCount-1 )
       
   567                     {
       
   568                     // next
       
   569                     ++iSelected;
       
   570                     iHighlightState = EMessageTop;
       
   571                     }
       
   572                 else if( iScrollOver )
       
   573                     {
       
   574                     // going down from last message,
       
   575                     // disable highlight, so editor can take the focus
       
   576                     DisableHighlightL();
       
   577                     return KErrNone;
       
   578                     }
       
   579                 else
       
   580                     {
       
   581                     // Loop back to beginning
       
   582                     iSelected = 0;
       
   583                     iSelectedItem = 0;
       
   584                     iHighlightState = EMessageTop;
       
   585                     }
       
   586                 }
       
   587             break;
       
   588             }
       
   589         case EMessageBottom:   // highlighting message ("bottom" of it)
       
   590             {
       
   591             if( up )
       
   592                 {
       
   593                 // up, highlight items inside this message (if any)
       
   594                 if( highlightCount > 0 )
       
   595                     {
       
   596                     iSelectedItem = highlightCount-1;
       
   597                     iHighlightState = EItemSelected;
       
   598                     }
       
   599                 else if( iSelected > 0 )
       
   600                     {
       
   601                     // prev
       
   602                     --iSelected;
       
   603                     
       
   604                     // get highlight count of prev message
       
   605                     // if item highlighting is on                
       
   606                     if ( iItemHighlight )                
       
   607                         {
       
   608                         highlightCount = iMessages[iSelected]->Highlights().Count();
       
   609                         }
       
   610                     
       
   611                     if ( highlightCount > 0 )
       
   612                         {
       
   613                         // highlight items inside prev message (if any)
       
   614                         iHighlightState = EItemSelected;
       
   615                         iSelectedItem = highlightCount - 1;
       
   616                         }
       
   617                     else
       
   618                         {
       
   619                         iHighlightState = EMessageBottom;
       
   620                         }    
       
   621                     }
       
   622                 else if( iScrollOver )
       
   623                     {
       
   624                     // going up from first message,
       
   625                     // disable highlight, so editor can take the focus
       
   626                     DisableHighlightL();
       
   627                     return KErrNone;
       
   628                     }
       
   629                 else
       
   630                     {
       
   631                     // Loop to last message
       
   632                     iSelected = messageCount-1;
       
   633                     highlightCount = 0;
       
   634                     
       
   635                     // Get highlight count of last message
       
   636                     // if item highlighting is on
       
   637                     if ( iItemHighlight )                
       
   638                         {
       
   639                         highlightCount =
       
   640                             iMessages[iSelected]->Highlights().Count();
       
   641                         }
       
   642                     
       
   643                     if ( highlightCount > 0 )
       
   644                         {
       
   645                         // Highlight items inside last message (if any)
       
   646                         iHighlightState = EItemSelected;
       
   647                         iSelectedItem = highlightCount - 1;
       
   648                         }
       
   649                     else
       
   650                         {
       
   651                         // Highlight whole last message
       
   652                         iHighlightState = EMessageBottom;
       
   653                         }
       
   654                     }
       
   655                 }
       
   656             else
       
   657                 {
       
   658                 // down, highlighting next message
       
   659                 if( iSelected < messageCount-1 )
       
   660                     {
       
   661                     // next
       
   662                     ++iSelected;
       
   663                     iHighlightState = EMessageTop;
       
   664                     }
       
   665                 else if( iScrollOver )
       
   666                     {                    
       
   667                     // going down from last message,
       
   668                     // disable highlight, so editor can take the focus
       
   669                     DisableHighlightL();
       
   670                     return KErrNone;
       
   671                     }
       
   672                 else
       
   673                     {
       
   674                     // Loop back to beginning
       
   675                     iSelected = 0;
       
   676                     iSelectedItem = 0;
       
   677                     iHighlightState = EMessageTop;
       
   678                     }
       
   679                 }
       
   680             break;
       
   681             }
       
   682         default:
       
   683             {
       
   684         
       
   685             break;
       
   686             }
       
   687         }
       
   688 
       
   689     // get the selection
       
   690     TCursorSelection curSel( CurrentSelection() );    
       
   691     
       
   692     // remove colors from old highlight
       
   693     TInt textLen( iRichText->DocumentLength() );
       
   694     if( iPrevious.iAnchorPos < textLen &&
       
   695         iPrevious.iCursorPos <= textLen )
       
   696         {
       
   697         BackColorL( iPrevious, KRgbWhite );
       
   698         TextBackColorL( iPrevious, KRgbWhite );        
       
   699         }
       
   700         
       
   701     // and set new one
       
   702     if ( iHighlightState == EItemSelected )
       
   703         {
       
   704         MAknsSkinInstance* skin = AknsUtils::SkinInstance();
       
   705         TRgb color;
       
   706 
       
   707         TInt error = AknsUtils::GetCachedColor( skin,
       
   708                 color,
       
   709                 KAknsIIDQsnHighlightColors,
       
   710                 EAknsCIQsnHighlightColorsCG2 );
       
   711 
       
   712         if ( !error )
       
   713             {
       
   714             // No error, use skinned background color
       
   715             TextBackColorL( curSel, color );
       
   716             }
       
   717         else
       
   718             {
       
   719             TextBackColorL( curSel, AKN_LAF_COLOR_STATIC( KIMCVHighlightColor ) );        
       
   720             }
       
   721         }
       
   722     else
       
   723         {
       
   724         MAknsSkinInstance* skin = AknsUtils::SkinInstance();
       
   725         TRgb color;
       
   726 
       
   727         TInt error = AknsUtils::GetCachedColor( skin,
       
   728                 color,
       
   729                 KAknsIIDQsnHighlightColors,
       
   730                 EAknsCIQsnHighlightColorsCG2 );
       
   731         
       
   732         if ( !error )
       
   733             {
       
   734             // No error, use skinned background color
       
   735             BackColorL( curSel, color );
       
   736             }
       
   737         else
       
   738             {
       
   739             BackColorL( curSel, AKN_LAF_COLOR_STATIC( KIMCVHighlightColor ) );
       
   740             }
       
   741         }
       
   742 
       
   743     // handle changed format
       
   744     TCursorSelection changed( Union( iPrevious, curSel ) );
       
   745     
       
   746 
       
   747     iTextView->HandleFormatChangedL( changed, ETrue );
       
   748 
       
   749     iTextView->ScrollVisibleL( curSel, ETrue );
       
   750     
       
   751     iPrevious = curSel;  
       
   752     IM_CV_LOGS(TXT("CIMCVAppRichTextContainer::MoveHighlightL()	end" ));
       
   753     return KErrNone;
       
   754     }
       
   755 
       
   756 
       
   757 // -----------------------------------------------------------------------------
       
   758 // CIMCVAppRichTextContainer::DisableHighlightL
       
   759 // (other items were commented in a header).
       
   760 // -----------------------------------------------------------------------------
       
   761 //
       
   762 void CIMCVAppRichTextContainer::DisableHighlightL()
       
   763     {
       
   764     IM_CV_LOGS(TXT("CIMCVAppRichTextContainer::DisableHighlightL()	start" ));
       
   765     iHighlightState = ENoHighlight;
       
   766     
       
   767     TCursorSelection sel( 0,0 );
       
   768     TInt count( iMessages.Count() );
       
   769     if( count > 0 )
       
   770         {
       
   771         sel = iMessages[count-1]->Selection();
       
   772         }
       
   773     
       
   774     // remove colors from old highlight (if any)    
       
   775     TInt textLen( iRichText->DocumentLength() );
       
   776     if( iPrevious.iAnchorPos < textLen &&
       
   777         iPrevious.iCursorPos <= textLen )
       
   778         {
       
   779         BackColorL( iPrevious, KRgbWhite );
       
   780         TextBackColorL( iPrevious, KRgbWhite );
       
   781         iTextView->HandleFormatChangedL( iPrevious );
       
   782         }
       
   783     
       
   784     // set focus to last message
       
   785     iTextView->ScrollVisibleL( sel, EFalse );
       
   786     IM_CV_LOGS(TXT("CIMCVAppRichTextContainer::DisableHighlightL()	end" ));
       
   787     }
       
   788 
       
   789     
       
   790 // -----------------------------------------------------------------------------
       
   791 // CIMCVAppRichTextContainer::Highlighted
       
   792 // (other items were commented in a header).
       
   793 // -----------------------------------------------------------------------------
       
   794 //
       
   795 TBool CIMCVAppRichTextContainer::Highlighted()
       
   796     {
       
   797     return iHighlightState != ENoHighlight;
       
   798     }
       
   799 
       
   800 // -----------------------------------------------------------------------------
       
   801 // CIMCVAppRichTextContainer::Highlighted
       
   802 // (other items were commented in a header).
       
   803 // -----------------------------------------------------------------------------
       
   804 //
       
   805 TInt CIMCVAppRichTextContainer::HighlightItemAtPosL( TInt aPos )
       
   806     {
       
   807     IM_CV_LOGS(TXT("CIMCVAppRichTextContainer::HighlightItemAtPosL()	start" ));
       
   808     TInt messagecount = iMessages.Count();
       
   809     if( messagecount == 0 )
       
   810         {
       
   811         // no messages
       
   812         return KErrNotFound;
       
   813         }
       
   814     
       
   815     // Store old values
       
   816     TInt oldSelectedMessage = iSelected;
       
   817     TInt oldSelectedItem = iSelectedItem;
       
   818     THighlightState oldHighlight = iHighlightState;
       
   819     
       
   820     // Find message in position aPos
       
   821     TBool found = EFalse;
       
   822     for( TInt i = 0; i < messagecount; ++i )
       
   823         {
       
   824         TCursorSelection sel = iMessages[ i ]->WholeSelection();
       
   825         if( aPos >= sel.LowerPos() && 
       
   826             aPos <= sel.HigherPos() )
       
   827             {
       
   828             // Found the message
       
   829             iSelected = i;
       
   830             iHighlightState = EMessageTop;
       
   831             found = ETrue;
       
   832             // stop searching
       
   833             break;
       
   834             }
       
   835         }
       
   836     
       
   837     if( !found )
       
   838         {
       
   839         // not found
       
   840         return KErrNotFound;
       
   841         }
       
   842     
       
   843     // Check if there are items inside the message that can be highlighted.
       
   844     if( iItemHighlight )
       
   845         {
       
   846         TInt hlCount = iMessages[ iSelected ]->Highlights().Count();
       
   847         TInt relativePos = 
       
   848             aPos - iMessages[ iSelected ]->WholeSelection().LowerPos();
       
   849         
       
   850         for( TInt i = 0; i < hlCount; ++i )
       
   851             {
       
   852             TCursorSelection sel = iMessages[ iSelected ]->Highlights()[ i ];
       
   853             
       
   854             // Highlight's selection is relative to message
       
   855             if( relativePos >= sel.LowerPos() && 
       
   856                 relativePos <= sel.HigherPos() )
       
   857                 {
       
   858                 // Found an item
       
   859                 iHighlightState = EItemSelected;
       
   860                 iSelectedItem = i;
       
   861                 // stop searching
       
   862                 break;
       
   863                 }
       
   864             }
       
   865         }
       
   866     
       
   867     // Update UI only if selection has changed
       
   868     if( iSelected != oldSelectedMessage ||
       
   869         iSelectedItem != oldSelectedItem || 
       
   870         oldHighlight != iHighlightState )
       
   871         {
       
   872         UpdateSelectionL();
       
   873         return KErrNone;
       
   874         }
       
   875     // Already highlighted
       
   876     IM_CV_LOGS(TXT("CIMCVAppRichTextContainer::HighlightItemAtPosL()	end" ));
       
   877     return KErrAlreadyExists;
       
   878     }
       
   879 
       
   880 // -----------------------------------------------------------------------------
       
   881 // CIMCVAppRichTextContainer::UpdateSelection
       
   882 // (other items were commented in a header).
       
   883 // -----------------------------------------------------------------------------
       
   884 //
       
   885 void CIMCVAppRichTextContainer::UpdateSelectionL()
       
   886     {
       
   887     IM_CV_LOGS(TXT("CIMCVAppRichTextContainer::UpdateSelectionL()	start" ));
       
   888     // get the selection
       
   889     TCursorSelection curSel( CurrentSelection() );    
       
   890     
       
   891     // remove colors from old highlight
       
   892     TInt textLen( iRichText->DocumentLength() );
       
   893     if( iPrevious.iAnchorPos < textLen &&
       
   894         iPrevious.iCursorPos <= textLen )
       
   895         {
       
   896         BackColorL( iPrevious, KRgbWhite );
       
   897         TextBackColorL( iPrevious, KRgbWhite );        
       
   898         }
       
   899         
       
   900     // and set new one
       
   901     if ( iHighlightState == EItemSelected )
       
   902         {
       
   903         MAknsSkinInstance* skin = AknsUtils::SkinInstance();
       
   904         TRgb color;
       
   905 
       
   906         TInt error = AknsUtils::GetCachedColor( skin,
       
   907                 color,
       
   908                 KAknsIIDQsnHighlightColors,
       
   909                 EAknsCIQsnHighlightColorsCG2 );
       
   910 
       
   911         if ( !error )
       
   912             {
       
   913             // No error, use skinned background color
       
   914             TextBackColorL( curSel, color );
       
   915             }
       
   916         else
       
   917             {
       
   918             TextBackColorL( curSel, AKN_LAF_COLOR_STATIC( KIMCVHighlightColor ) );        
       
   919             }
       
   920         }
       
   921     else
       
   922         {
       
   923         MAknsSkinInstance* skin = AknsUtils::SkinInstance();
       
   924         TRgb color;
       
   925 
       
   926         TInt error = AknsUtils::GetCachedColor( skin,
       
   927                 color,
       
   928                 KAknsIIDQsnHighlightColors,
       
   929                 EAknsCIQsnHighlightColorsCG2 );
       
   930         
       
   931         if ( !error )
       
   932             {
       
   933             // No error, use skinned background color
       
   934             BackColorL( curSel, color );
       
   935             }
       
   936         else
       
   937             {
       
   938             BackColorL( curSel, AKN_LAF_COLOR_STATIC( KIMCVHighlightColor ) );
       
   939             }
       
   940         }
       
   941 
       
   942     // handle changed format
       
   943     TCursorSelection changed( Union( iPrevious, curSel ) );
       
   944 
       
   945     iTextView->HandleFormatChangedL( changed );
       
   946     iTextView->ScrollVisibleL( curSel, ETrue );
       
   947 
       
   948     
       
   949     iPrevious = curSel;    
       
   950     IM_CV_LOGS(TXT("CIMCVAppRichTextContainer::UpdateSelectionL()	end" ));
       
   951     }
       
   952 
       
   953 // -----------------------------------------------------------------------------
       
   954 // CIMCVAppRichTextContainer::InsertTimeStampL
       
   955 // (other items were commented in a header).
       
   956 // -----------------------------------------------------------------------------
       
   957 //
       
   958 TCursorSelection CIMCVAppRichTextContainer::InsertTimeStampL( 
       
   959 										CIMCVAppMessageWrapper& aMessageWrapper )
       
   960     {
       
   961     IM_CV_LOGS(TXT("CIMCVAppRichTextContainer::InsertTimeStampL()	start" ));
       
   962     TInt start = 0;
       
   963     TCursorSelection timeSel( start, start );
       
   964    
       
   965   
       
   966     // format time
       
   967     HBufC* timeStamp = HBufC::NewLC( KTimeStampMaxLength + KSpace().Length() );
       
   968     TPtr timePtr( timeStamp->Des() );
       
   969     
       
   970     HBufC* timeStampFormat = NULL;
       
   971     timeStampFormat = StringLoader::LoadLC( R_QTN_TIME_USUAL_WITH_ZERO );
       
   972     
       
   973     TTime time = aMessageWrapper.Message().TimeStamp();
       
   974     TRAPD( err, time.FormatL( timePtr, *timeStampFormat ) );
       
   975     if ( err == KErrOverflow )
       
   976         {
       
   977         // Reserved text space was not enough.
       
   978         // Adjust the KTimeStampMaxLength!
       
   979     
       
   980 
       
   981         // in release builds return without timestamp
       
   982         CleanupStack::PopAndDestroy( 2, timeStamp ); // timeStamp, timeStampFormat
       
   983         return timeSel;
       
   984         }
       
   985     
       
   986     // Convert numbers to local language
       
   987     AknTextUtils::LanguageSpecificNumberConversion( timePtr );
       
   988     
       
   989     // Set Alignment of Pm/Am from local setting
       
   990     // This keeps the am/pm text close to the time.
       
   991     timePtr.Append( AknLayoutUtils::LayoutMirrored() ? 
       
   992                     KUnicodeRLM : KUnicodeLRM );
       
   993     // append time to rich text
       
   994     timePtr.Append( KSpace );
       
   995     iRichText->InsertL( start, timePtr );
       
   996     
       
   997     CleanupStack::PopAndDestroy( 2, timeStamp ); // timeStamp, timeStampFormat
       
   998     timeSel.SetSelection( start, timePtr.Length() - 1 );
       
   999 
       
  1000     // bold the time
       
  1001     if ( timeSel.Length() > 0 )
       
  1002         {
       
  1003         BoldL( timeSel );
       
  1004         }
       
  1005     IM_CV_LOGS(TXT("CIMCVAppRichTextContainer::InsertTimeStampL()	end" ));
       
  1006     return timeSel;
       
  1007     }
       
  1008 
       
  1009 // -----------------------------------------------------------------------------
       
  1010 // CIMCVAppRichTextContainer::InsertContentL
       
  1011 // (other items were commented in a header).
       
  1012 // -----------------------------------------------------------------------------
       
  1013 //
       
  1014 TInt CIMCVAppRichTextContainer::InsertContentL( CIMCVAppMessageWrapper& aMessageWrapper )
       
  1015     {    
       
  1016     IM_CV_LOGS(TXT("CIMCVAppRichTextContainer::InsertContentL()	start" ));
       
  1017     MIMCVEngineMessage& message = aMessageWrapper.Message();
       
  1018 
       
  1019     MIMCVEngineMessage::TContentType type( message.ContentType() );
       
  1020     switch( type ) 
       
  1021         {
       
  1022         case MIMCVEngineMessage::EContentText:
       
  1023             {
       
  1024             TInt oldLen = iRichText->DocumentLength();
       
  1025             
       
  1026             // Insert text
       
  1027             TPtrC msg( message.Text() );
       
  1028             
       
  1029             HBufC* tempMsg = NULL;
       
  1030             
       
  1031             TInt paraBreak = msg.Locate( CEditableText::EParagraphDelimiter );
       
  1032             // Replace all paragraph delimiters with line breaks
       
  1033             // to keep alingment consistent
       
  1034             if ( paraBreak != KErrNotFound )
       
  1035                 {
       
  1036                 tempMsg = msg.AllocLC();
       
  1037                 TPtr ptr( tempMsg->Des() );
       
  1038                 ptr.Zero();
       
  1039                 
       
  1040                 ReplaceParaDelimsWithLineBreaks( msg, ptr );
       
  1041                 msg.Set( ptr );
       
  1042                 }
       
  1043 
       
  1044             HBufC* numberConv = NULL;
       
  1045             
       
  1046             // Convert numerals to local language
       
  1047             // 1) date item
       
  1048             if ( aMessageWrapper.Message().SystemMessageType() ==
       
  1049                 MIMCVEngineMessage::ESystemMessageDateChange )
       
  1050                 {
       
  1051                 // Don't touch the original message
       
  1052                 numberConv = msg.AllocLC();
       
  1053                 TPtr ptr( numberConv->Des() );
       
  1054                 AknTextUtils::LanguageSpecificNumberConversion( ptr );
       
  1055                 msg.Set( ptr );
       
  1056                 }
       
  1057 
       
  1058             iRichText->InsertL( 0, msg );
       
  1059              
       
  1060             TInt textEnd = msg.Length();
       
  1061                 
       
  1062             // Check for extensions (smileys)
       
  1063             TCursorSelection selection( 0, textEnd );
       
  1064             TInt bfrConv = iRichText->DocumentLength();
       
  1065             iExtensionsHandler->ConvertSelectionToExtensionL( *iRichText, 
       
  1066             												 selection,
       
  1067             												 iServiceId );
       
  1068             
       
  1069             // Move textEnd index if extensions were found
       
  1070             textEnd -= ( bfrConv - iRichText->DocumentLength() );
       
  1071             
       
  1072             // Add nbs to preserve formatting
       
  1073             iRichText->InsertL( textEnd,
       
  1074                                 CEditableText::EZeroWidthNoBreakSpace );
       
  1075             
       
  1076             // If this is system message, it should be bold
       
  1077             if( message.MessageType() == MIMCVEngineMessage::EMessageSystem )
       
  1078                 {
       
  1079                 TCursorSelection sel( 0, textEnd );
       
  1080                 BoldL( sel );
       
  1081                 // System messages need different kind of alignment
       
  1082                 CParaFormat paraFormat;
       
  1083                 TParaFormatMask paraFormatMask;
       
  1084                 paraFormat.iLeftMarginInTwips = 0;
       
  1085                 paraFormatMask.SetAttrib( EAttLeftMargin );    
       
  1086                 iRichText->ApplyParaFormatL( &paraFormat, paraFormatMask,
       
  1087                                              0, textEnd + 1 );
       
  1088                 }
       
  1089             else
       
  1090                 {
       
  1091                 // Apply alignment for "normal" messages
       
  1092                 CParaFormat paraFormat;
       
  1093                 TParaFormatMask paraFormatMask;
       
  1094                 paraFormat.iLeftMarginInTwips = 100;
       
  1095                 paraFormatMask.SetAttrib( EAttLeftMargin );    
       
  1096                 iRichText->ApplyParaFormatL( &paraFormat, paraFormatMask,
       
  1097                                              0, textEnd + 1 );
       
  1098                 
       
  1099                 // Remove bolding from message content
       
  1100                 TCharFormat charFormat;
       
  1101                 TCharFormatMask charFormatMask;
       
  1102                 charFormat.iFontSpec.iFontStyle.SetStrokeWeight( EStrokeWeightNormal );
       
  1103                 charFormatMask.SetAttrib( EAttFontStrokeWeight );
       
  1104                 iRichText->ApplyCharFormatL( charFormat, charFormatMask, 
       
  1105                                  0, textEnd + 1 );
       
  1106                 }
       
  1107             
       
  1108             // Cleanup
       
  1109             if ( numberConv )
       
  1110                 {
       
  1111                 CleanupStack::PopAndDestroy( numberConv );
       
  1112                 }
       
  1113             if ( tempMsg )
       
  1114                 {
       
  1115                 CleanupStack::PopAndDestroy( tempMsg );
       
  1116                 }
       
  1117             
       
  1118             return iRichText->DocumentLength() - oldLen;            
       
  1119             }
       
  1120         default:
       
  1121             {
       
  1122             // Unsupported type
       
  1123          
       
  1124             break;
       
  1125             }
       
  1126         }
       
  1127     IM_CV_LOGS(TXT("CIMCVAppRichTextContainer::InsertContentL()	end" ));
       
  1128     return 0;
       
  1129     }
       
  1130     
       
  1131 // -----------------------------------------------------------------------------
       
  1132 // CIMCVAppRichTextContainer::InsertNickL
       
  1133 // (other items were commented in a header).
       
  1134 // -----------------------------------------------------------------------------
       
  1135 //
       
  1136 TCursorSelection CIMCVAppRichTextContainer::InsertNickL( 
       
  1137 										CIMCVAppMessageWrapper& aMessageWrapper )
       
  1138     {
       
  1139     IM_CV_LOGS(TXT("CIMCVAppRichTextContainer::InsertNickL()	start" ));
       
  1140     // insert nick    
       
  1141     MIMCVEngineMessage& message = aMessageWrapper.Message();
       
  1142     TPtrC sender;
       
  1143     TPtrC recipient;
       
  1144     if ( message.MessageType() == MIMCVEngineMessage::EMessageGroup ||
       
  1145          message.MessageType() == MIMCVEngineMessage::EMessageWhisper )
       
  1146         {
       
  1147         sender.Set( message.Sender() );
       
  1148         recipient.Set( message.Recipient() );
       
  1149         }
       
  1150    
       
  1151     TCursorSelection nickSel( 0,0 );
       
  1152     
       
  1153     IM_CV_LOGS(TXT("CIMCVAppRichTextContainer::InsertNickL()	end" ));
       
  1154     return nickSel;
       
  1155     }
       
  1156         
       
  1157 // -----------------------------------------------------------------------------
       
  1158 // CIMCVAppRichTextContainer::LayoutChangedL
       
  1159 // (other items were commented in a header).
       
  1160 // -----------------------------------------------------------------------------
       
  1161 //
       
  1162 void CIMCVAppRichTextContainer::LayoutChangedL( TInt aType)
       
  1163     {
       
  1164     #if 0
       
  1165     //if layout change.. then dont update skin text color.
       
  1166     if (aType == KAknsMessageSkinChange)
       
  1167     	{
       
  1168     	UpdateSkinnedTextColourL();
       
  1169     	}
       
  1170 	#endif
       
  1171     }
       
  1172 
       
  1173 // -----------------------------------------------------------------------------
       
  1174 // CCARichTextContainer::ResourceChangedL
       
  1175 // (other items were commented in a header).
       
  1176 // -----------------------------------------------------------------------------
       
  1177 //
       
  1178 void CIMCVAppRichTextContainer::ResourceChangedL()
       
  1179     {
       
  1180     // When resource changes (branding):
       
  1181     // clear content, so that old pictures don't cause any problems.
       
  1182     // we are reloaded anyway.
       
  1183     iRichText->DeleteL( 0, iRichText->DocumentLength() );
       
  1184     iTextView->HandleGlobalChangeNoRedrawL();
       
  1185     }
       
  1186 // CIMCVAppRichTextContainer::AddMessageL
       
  1187 // (other items were commented in a header).
       
  1188 // -----------------------------------------------------------------------------
       
  1189 //
       
  1190 void CIMCVAppRichTextContainer::AddMessageL( MIMCVEngineMessage& aMessage )
       
  1191     {   
       
  1192     IM_CV_LOGS(TXT("CIMCVAppRichTextContainer::AddMessageL()	start" ));
       
  1193     if( !iShowTimeStamps &&
       
  1194         aMessage.SystemMessageType() == MIMCVEngineMessage::ESystemMessageDateChange )
       
  1195         {
       
  1196         // if timestamp setting is OFF we don't show day change items
       
  1197         return;
       
  1198         }
       
  1199     
       
  1200     TInt oldCount = iMessages.Count();
       
  1201     
       
  1202     // create wrapper
       
  1203     CIMCVAppMessageWrapper* wrapper = CIMCVAppMessageWrapper::NewL( aMessage );
       
  1204                 
       
  1205     CleanupStack::PushL( wrapper );
       
  1206     iMessages.AppendL( wrapper );   // takes the ownership
       
  1207     CleanupStack::Pop( wrapper );
       
  1208     
       
  1209     
       
  1210     // start new paragraph
       
  1211     TInt lineStart = iRichText->DocumentLength();
       
  1212     if( lineStart != 0 )
       
  1213         {
       
  1214         iRichText->InsertL( lineStart, CEditableText::EParagraphDelimiter );
       
  1215         }
       
  1216     
       
  1217     // Set Alignment from local layout
       
  1218     iRichText->InsertL( iRichText->DocumentLength(),
       
  1219             AknLayoutUtils::LayoutMirrored() ? KUnicodeRLM : KUnicodeLRM );
       
  1220         
       
  1221     // add message to rich text    
       
  1222     TInt startPos( iRichText->DocumentLength() );
       
  1223     TCursorSelection timeSel = AddTimeStampL( *wrapper );
       
  1224     TCursorSelection nickSel = AddNickL( *wrapper );
       
  1225     AddContentL( startPos, *wrapper );
       
  1226     TInt endPos( iRichText->DocumentLength() );    
       
  1227     
       
  1228     // set selection for highlight and the whole selection 
       
  1229     // (so that this can be removed)
       
  1230     // append deletioncount to new messages
       
  1231     wrapper->Selection().SetSelection(    endPos - 1, startPos );
       
  1232     wrapper->WholeSelection().SetSelection( endPos, lineStart );
       
  1233     wrapper->MessageSelection().SetSelection( endPos - 1, nickSel.HigherPos() );
       
  1234     
       
  1235     
       
  1236     // append coloring
       
  1237     TCursorSelection& sel = iColorWholeMessage ? wrapper->Selection() : nickSel;
       
  1238     TInt len( sel.Length() );
       
  1239    
       
  1240 
       
  1241     // Make sure the background (highlight) is not copied from 
       
  1242     // previous message.
       
  1243     BackColorL( sel, KRgbWhite );
       
  1244     TextBackColorL( sel, KRgbWhite );        
       
  1245     
       
  1246     if( len > 0 && 
       
  1247         aMessage.MessageType() != MIMCVEngineMessage::EMessageSystem )
       
  1248         {
       
  1249         // custom colors
       
  1250         if( aMessage.MessagerType() == MIMCVEngineMessage::EMessageSent )
       
  1251             {
       
  1252             // own msg
       
  1253             if( iOwnMsgColorInUse )
       
  1254                 {
       
  1255                 TextColorL( sel, iOwnMsgColor );
       
  1256                 }
       
  1257             }
       
  1258         else if( aMessage.MessagerType() == MIMCVEngineMessage::EMessageReceived )
       
  1259             {
       
  1260             // other msg
       
  1261             if( iMsgColorInUse )
       
  1262                 {
       
  1263                 TextColorL( sel, iMsgColor );
       
  1264                 }
       
  1265             }    
       
  1266         }
       
  1267         
       
  1268 #ifdef RD_30_COMPATIBILITY_MODE    
       
  1269     if( lineStart == 0 )
       
  1270         {
       
  1271         // This is needed only in 3.0 backport so that the alignment
       
  1272         // character doesn't cause a virtual linebreak.
       
  1273         TRAP_IGNORE( iTextView->HandleFormatChangedL( 
       
  1274                         wrapper->WholeSelection() ) );
       
  1275         }
       
  1276 #endif // RD_30_COMPATIBILITY_MODE
       
  1277     
       
  1278     // inform of inserted rich text
       
  1279     TCursorSelection curSel( CurrentSelection() );
       
  1280     TRAPD( error, iTextView->HandleAdditionL( lineStart == 0, curSel, EFalse ) );
       
  1281     if( error != KErrNone )
       
  1282         {
       
  1283                
       
  1284         // Remove failed text
       
  1285         TCursorSelection del = wrapper->WholeSelection();
       
  1286         iRichText->DeleteL( del.LowerPos(), del.Length() );
       
  1287         
       
  1288         // Remove the failed wrapper and leave
       
  1289         TInt index = iMessages.Find( wrapper );
       
  1290         if( index != KErrNotFound )
       
  1291             {
       
  1292             delete wrapper;
       
  1293             iMessages.Remove( index );
       
  1294             }
       
  1295         
       
  1296         // Try to handle changes once more
       
  1297         TRAPD( updateErr, iTextView->HandleGlobalChangeNoRedrawL() );
       
  1298         if( !updateErr )
       
  1299             {
       
  1300             TCursorSelection curSel( CurrentSelection() );
       
  1301             TRAP_IGNORE( iTextView->ScrollVisibleL( curSel, EFalse ) );
       
  1302             }
       
  1303         User::Leave( error );
       
  1304         }
       
  1305     
       
  1306     // and scroll (unless in highlight-mode)
       
  1307     if( iHighlightState == ENoHighlight )
       
  1308         {
       
  1309         TCursorSelection curSel( CurrentSelection() );    
       
  1310         iTextView->ScrollVisibleL( curSel, EFalse );
       
  1311         
       
  1312         // If this is recorded chat container (iScrollOver == EFalse)
       
  1313         // and added message was first move highlight 
       
  1314         // so we have focus on the topmost item.
       
  1315         if ( oldCount == 0 && !iScrollOver )
       
  1316             {
       
  1317             MoveHighlightL( ENext );
       
  1318             }
       
  1319         }
       
  1320     IM_CV_LOGS(TXT("CIMCVAppRichTextContainer::AddMessageL()	end" ));
       
  1321     }
       
  1322 
       
  1323 
       
  1324 
       
  1325 // -----------------------------------------------------------------------------
       
  1326 // CIMCVAppRichTextContainer::InsertMessageL
       
  1327 // (other items were commented in a header).
       
  1328 // -----------------------------------------------------------------------------
       
  1329 //
       
  1330 void CIMCVAppRichTextContainer::InsertMessageL( MIMCVEngineMessage& aMessage )
       
  1331     {
       
  1332     IM_CV_LOGS(TXT("CIMCVAppRichTextContainer::InsertMessageL()	start" ));
       
  1333     if ( !iShowTimeStamps &&
       
  1334         aMessage.SystemMessageType() == MIMCVEngineMessage::ESystemMessageDateChange )
       
  1335         {
       
  1336         // if timestamp setting is OFF we don't show day change items
       
  1337         return;
       
  1338         }
       
  1339     
       
  1340     // create wrapper
       
  1341     CIMCVAppMessageWrapper* wrapper = CIMCVAppMessageWrapper::NewL( aMessage );
       
  1342                 
       
  1343     CleanupStack::PushL( wrapper );
       
  1344     iMessages.InsertL( wrapper, 0 ); // takes the ownership
       
  1345     CleanupStack::Pop( wrapper );
       
  1346     
       
  1347         
       
  1348     TInt oldLen = iRichText->DocumentLength();
       
  1349     
       
  1350     // Insert paragraph break if this is not the last message
       
  1351     TInt paraBreak = 0;
       
  1352     if ( iMessages.Count() > 1 )
       
  1353         {
       
  1354         iRichText->InsertL( 0, CEditableText::EParagraphDelimiter );
       
  1355         paraBreak = 1;
       
  1356         }
       
  1357     
       
  1358     // Insert message to rich text in reverse order compared to adding
       
  1359     TInt contentLen = InsertContentL( *wrapper );
       
  1360     TCursorSelection nickSel = InsertNickL( *wrapper );
       
  1361     TCursorSelection timeSel = InsertTimeStampL( *wrapper );
       
  1362 
       
  1363     // Set Alignment from local layout
       
  1364     TInt dirChrLen = iRichText->DocumentLength();
       
  1365     iRichText->InsertL( 0, AknLayoutUtils::LayoutMirrored() ? 
       
  1366                            KUnicodeRLM : KUnicodeLRM );
       
  1367     dirChrLen = iRichText->DocumentLength() - dirChrLen;
       
  1368     
       
  1369     wrapper->SetInserted( ETrue );
       
  1370 
       
  1371     // Update timestamp selection
       
  1372     timeSel.iAnchorPos += dirChrLen;
       
  1373     timeSel.iCursorPos += dirChrLen;
       
  1374     // Update nick selection
       
  1375     nickSel.iAnchorPos += timeSel.HigherPos();
       
  1376     nickSel.iCursorPos += timeSel.HigherPos();
       
  1377     // Update thumb pos
       
  1378     TCursorSelection& thumbPos = wrapper->ThumbPos();
       
  1379     thumbPos.iAnchorPos += nickSel.HigherPos() + KSeparator().Length();
       
  1380     thumbPos.iCursorPos += nickSel.HigherPos() + KSeparator().Length();
       
  1381     
       
  1382     TInt addedLen = iRichText->DocumentLength() - oldLen;
       
  1383     
       
  1384     // parse text for highlights and store positions to messagewrapper
       
  1385     HBufC* text = HBufC::NewMaxLC( contentLen );
       
  1386     TPtr txt( text->Des() );
       
  1387     iRichText->Extract( txt,
       
  1388         nickSel.HigherPos() + KSeparator().Length() + 1, // Don't extract separator and space
       
  1389         contentLen );
       
  1390     ParseTextL( txt, nickSel.HigherPos() + KSeparator().Length() + 1,
       
  1391                 nickSel.HigherPos() + KSeparator().Length() + 1, *wrapper );
       
  1392     CleanupStack::PopAndDestroy( text );
       
  1393     
       
  1394     // Set selection for highlight and the whole selection
       
  1395     // so that this message can be removed   
       
  1396     wrapper->Selection().SetSelection( addedLen - 1 - paraBreak, 0 );
       
  1397     wrapper->WholeSelection().SetSelection( addedLen - 1, 0 );
       
  1398     wrapper->MessageSelection().SetSelection( addedLen - 1,
       
  1399                                                nickSel.HigherPos() + 1 );
       
  1400     
       
  1401     if ( iHighlightState != ENoHighlight )
       
  1402         {
       
  1403         BackColorL( wrapper->WholeSelection(), KRgbWhite );
       
  1404         TextBackColorL( wrapper->WholeSelection(), KRgbWhite );
       
  1405         }
       
  1406         
       
  1407     // Update wrappers after this if there is any
       
  1408     if ( iMessages.Count() > 1 )
       
  1409         {
       
  1410         UpdateWrappers( 1, addedLen );
       
  1411         }
       
  1412     
       
  1413     // Append coloring
       
  1414     TCursorSelection& sel = iColorWholeMessage ? wrapper->Selection() : nickSel;
       
  1415     TInt len( sel.Length() );
       
  1416        
       
  1417     if ( len > 0 && 
       
  1418          aMessage.MessageType() != MIMCVEngineMessage::EMessageSystem )
       
  1419         {
       
  1420         // Custom colors
       
  1421         if ( aMessage.MessagerType() == MIMCVEngineMessage::EMessageSent )
       
  1422             {
       
  1423             // Own msg
       
  1424             if( iOwnMsgColorInUse )
       
  1425                 {
       
  1426                 TextColorL( sel, iOwnMsgColor );
       
  1427                 }
       
  1428             }
       
  1429         else if ( aMessage.MessagerType() == MIMCVEngineMessage::EMessageReceived )
       
  1430             {
       
  1431             // Other msg
       
  1432             if( iMsgColorInUse )
       
  1433                 {
       
  1434                 TextColorL( sel, iMsgColor );
       
  1435                 }
       
  1436             }    
       
  1437         }
       
  1438     
       
  1439     // Inform of inserted rich text
       
  1440     TInt error = KErrNone;
       
  1441     if ( oldLen == 0 )
       
  1442         {
       
  1443         TCursorSelection curSel( CurrentSelection() );
       
  1444         // First message inserted, format the whole text
       
  1445         TRAP( error, iTextView->HandleAdditionL( ETrue, curSel, EFalse ) );
       
  1446         }
       
  1447     else
       
  1448         {
       
  1449         TCursorSelection curSel( CurrentSelection() );
       
  1450         // There might be a faster method to handle text addition, but 
       
  1451         // this works for now.
       
  1452         TRAP( error, iTextView->HandleAdditionL( ETrue, curSel, EFalse) );
       
  1453         }    
       
  1454     // And scroll (unless in highlight-mode)
       
  1455     if ( iHighlightState == ENoHighlight )
       
  1456         {
       
  1457         TCursorSelection curSel( CurrentSelection() );    
       
  1458         iTextView->ScrollVisibleL( curSel, EFalse );
       
  1459         }
       
  1460     else
       
  1461         {
       
  1462         // In highlight mode, message inserted -> increase selected
       
  1463         // message index and previous selection indexes
       
  1464         iSelected++;
       
  1465         iPrevious.iAnchorPos += addedLen;
       
  1466         iPrevious.iCursorPos += addedLen;
       
  1467             
       
  1468         TCursorSelection curSel( CurrentSelection() );
       
  1469         iTextView->ScrollVisibleL( curSel, EFalse );     
       
  1470         }
       
  1471     IM_CV_LOGS(TXT("CIMCVAppRichTextContainer::InsertMessageL()	end" ));
       
  1472     }
       
  1473     
       
  1474 // -----------------------------------------------------------------------------
       
  1475 // CIMCVAppRichTextContainer::UpdateWrappers
       
  1476 // (other items were commented in a header).
       
  1477 // -----------------------------------------------------------------------------
       
  1478 //
       
  1479 void CIMCVAppRichTextContainer::UpdateWrappers( TInt aFirstIndex, TInt aChange )
       
  1480     {
       
  1481     IM_CV_LOGS(TXT("CIMCVAppRichTextContainer::UpdateWrappers()	start" ));
       
  1482     TInt count( iMessages.Count() );
       
  1483     for( TInt i( aFirstIndex ); i<count; ++i )
       
  1484         {
       
  1485         CIMCVAppMessageWrapper* wrapper = iMessages[i];
       
  1486         TCursorSelection& selection = wrapper->Selection();
       
  1487         TCursorSelection& wholeSelection = wrapper->WholeSelection();
       
  1488         TCursorSelection& thumbPos = wrapper->ThumbPos();
       
  1489         selection.iAnchorPos += aChange;
       
  1490         selection.iCursorPos += aChange;
       
  1491         wholeSelection.iAnchorPos += aChange;
       
  1492         wholeSelection.iCursorPos += aChange;
       
  1493         thumbPos.iAnchorPos += aChange;
       
  1494         thumbPos.iCursorPos += aChange;
       
  1495         }
       
  1496     IM_CV_LOGS(TXT("CIMCVAppRichTextContainer::UpdateWrappers()	end" ));
       
  1497     }
       
  1498     
       
  1499 // -----------------------------------------------------------------------------
       
  1500 // CIMCVAppRichTextContainer::Union
       
  1501 // (other items were commented in a header).
       
  1502 // -----------------------------------------------------------------------------
       
  1503 //
       
  1504 TCursorSelection CIMCVAppRichTextContainer::Union( const TCursorSelection& aSel1, 
       
  1505 												const TCursorSelection& aSel2 )
       
  1506     {
       
  1507     IM_CV_LOGS(TXT("CIMCVAppRichTextContainer::Union()	start" ));
       
  1508     // make union of selections
       
  1509     TCursorSelection changed;
       
  1510     changed.iAnchorPos = aSel1.LowerPos();
       
  1511     changed.iCursorPos = aSel1.HigherPos();
       
  1512 
       
  1513     TInt low(  aSel2.LowerPos() );
       
  1514     TInt high( aSel2.HigherPos() );
       
  1515     if( low < changed.iAnchorPos )
       
  1516         {
       
  1517         changed.iAnchorPos = low;
       
  1518         }
       
  1519     if( high > changed.iCursorPos )
       
  1520         {
       
  1521         changed.iCursorPos = high;
       
  1522         }
       
  1523     IM_CV_LOGS(TXT("CIMCVAppRichTextContainer::Union()	 end" ));
       
  1524     return changed;
       
  1525     }
       
  1526     
       
  1527 // -----------------------------------------------------------------------------
       
  1528 // CIMCVAppRichTextContainer::CurrentSelection
       
  1529 // (other items were commented in a header).
       
  1530 // -----------------------------------------------------------------------------
       
  1531 //
       
  1532 TCursorSelection CIMCVAppRichTextContainer::CurrentSelection() const
       
  1533     {
       
  1534     IM_CV_LOGS(TXT("CIMCVAppRichTextContainer::CurrentSelection()	 start" ));
       
  1535     TCursorSelection sel( 0,0 );
       
  1536     if( iHighlightState == ENoHighlight )
       
  1537         {
       
  1538         // if nothing highlighted, return last message
       
  1539         TInt count( iMessages.Count() );
       
  1540         if( count > 0 )
       
  1541             {
       
  1542             sel = iMessages[count-1]->Selection();
       
  1543             }    
       
  1544         }
       
  1545     else
       
  1546         {
       
  1547         // something highlighted, start with current message
       
  1548         sel = iMessages[iSelected]->Selection();
       
  1549         
       
  1550         // check if the highlighted selection is item inside message
       
  1551         if( iHighlightState == EItemSelected )
       
  1552             {
       
  1553             // calculate item highlight position
       
  1554             TCursorSelection itemSel( 
       
  1555             			iMessages[iSelected]->Highlights()[iSelectedItem] );
       
  1556 
       
  1557             TInt messageStart( sel.LowerPos() );
       
  1558             sel.iAnchorPos = itemSel.iAnchorPos + messageStart;
       
  1559             sel.iCursorPos = itemSel.iCursorPos + messageStart;
       
  1560             }
       
  1561         }
       
  1562     IM_CV_LOGS(TXT("CIMCVAppRichTextContainer::CurrentSelection()	 end" ));
       
  1563     return sel;
       
  1564     }
       
  1565     
       
  1566 
       
  1567 // -----------------------------------------------------------------------------
       
  1568 // CIMCVAppRichTextContainer::TextBackColorL
       
  1569 // (other items were commented in a header).
       
  1570 // -----------------------------------------------------------------------------
       
  1571 //
       
  1572 void CIMCVAppRichTextContainer::TextBackColorL( const TCursorSelection& aSel, 
       
  1573 											const TRgb& aColor )
       
  1574     {
       
  1575     IM_CV_LOGS(TXT("CIMCVAppRichTextContainer::TextBackColorL()	 start" ));
       
  1576     TCharFormat charFormat;
       
  1577     TCharFormatMask charFormatMask;
       
  1578     charFormatMask.SetAttrib( EAttFontHighlightColor );
       
  1579     charFormatMask.SetAttrib( EAttFontHighlightStyle );
       
  1580     
       
  1581     charFormat.iFontPresentation.iHighlightColor = aColor;
       
  1582     charFormat.iFontPresentation.iHighlightStyle = aColor == KRgbWhite ? 
       
  1583                                     TFontPresentation::EFontHighlightNone :
       
  1584                                     TFontPresentation::EFontHighlightNormal;
       
  1585     
       
  1586     iRichText->ApplyCharFormatL( charFormat, charFormatMask, 
       
  1587                                  aSel.LowerPos(), 
       
  1588                                  aSel.Length() );
       
  1589     IM_CV_LOGS(TXT("CIMCVAppRichTextContainer::TextBackColorL()	 end" ));                         
       
  1590     }
       
  1591 
       
  1592 // -----------------------------------------------------------------------------
       
  1593 // CIMCVAppRichTextContainer::TextColorL
       
  1594 // (other items were commented in a header).
       
  1595 // -----------------------------------------------------------------------------
       
  1596 //
       
  1597 void CIMCVAppRichTextContainer::TextColorL( const TCursorSelection& aSel, 
       
  1598 										const TRgb& aColor )
       
  1599     {
       
  1600 	IM_CV_LOGS(TXT("CIMCVAppRichTextContainer::TextColorL()	 start" ));
       
  1601     TCharFormat charFormat;
       
  1602     TCharFormatMask charFormatMask;
       
  1603     charFormatMask.SetAttrib( EAttColor );    
       
  1604     charFormat.iFontPresentation.iTextColor = aColor;
       
  1605 
       
  1606     iRichText->ApplyCharFormatL( charFormat, charFormatMask, 
       
  1607                                  aSel.LowerPos(), 
       
  1608                                  aSel.Length() );
       
  1609     IM_CV_LOGS(TXT("CIMCVAppRichTextContainer::TextColorL()	 end" ));
       
  1610     }
       
  1611 
       
  1612 // -----------------------------------------------------------------------------
       
  1613 // CIMCVAppRichTextContainer::BackColorL
       
  1614 // (other items were commented in a header).
       
  1615 // -----------------------------------------------------------------------------
       
  1616 //
       
  1617 void CIMCVAppRichTextContainer::BackColorL( const TCursorSelection& aSel, 
       
  1618 										const TRgb& aColor )
       
  1619     {
       
  1620 	IM_CV_LOGS(TXT("CIMCVAppRichTextContainer::BackColorL()	 start" ));
       
  1621     CParaFormat paraFormat;
       
  1622     TParaFormatMask paraFormatMask;
       
  1623     paraFormatMask.SetAttrib( EAttFillColor );
       
  1624 
       
  1625     paraFormat.iFillColor = aColor;
       
  1626     iRichText->ApplyParaFormatL( &paraFormat, paraFormatMask, 
       
  1627                                  aSel.LowerPos(), 
       
  1628                                  aSel.Length() );
       
  1629     IM_CV_LOGS(TXT("CIMCVAppRichTextContainer::BackColorL()	 end" ));
       
  1630     }
       
  1631 
       
  1632 // -----------------------------------------------------------------------------
       
  1633 // CIMCVAppRichTextContainer::HighLightItemL
       
  1634 // (other items were commented in a header).
       
  1635 // -----------------------------------------------------------------------------
       
  1636 //
       
  1637 void CIMCVAppRichTextContainer::HighLightItemL( const TCursorSelection& aSel )
       
  1638     {
       
  1639 
       
  1640     TCharFormat charFormat;
       
  1641     TCharFormatMask charFormatMask;
       
  1642     charFormatMask.SetAttrib( EAttFontUnderline );
       
  1643     
       
  1644     charFormat.iFontPresentation.iUnderline = EUnderlineOn;
       
  1645     
       
  1646     iRichText->ApplyCharFormatL( charFormat, charFormatMask, 
       
  1647                                  aSel.LowerPos(), 
       
  1648                                  aSel.Length() );
       
  1649     }
       
  1650 
       
  1651 
       
  1652 // -----------------------------------------------------------------------------
       
  1653 // CIMCVAppRichTextContainer::GetMessageCount
       
  1654 // (other items were commented in a header).
       
  1655 // -----------------------------------------------------------------------------
       
  1656 //
       
  1657 TInt CIMCVAppRichTextContainer::GetMessageCount()
       
  1658 	{
       
  1659 	return iMessages.Count();	
       
  1660 	}
       
  1661 
       
  1662 // -----------------------------------------------------------------------------
       
  1663 // CIMCVAppRichTextContainer::BoldL
       
  1664 // (other items were commented in a header).
       
  1665 // -----------------------------------------------------------------------------
       
  1666 //
       
  1667 void CIMCVAppRichTextContainer::BoldL( const TCursorSelection& aSel )
       
  1668     {
       
  1669     IM_CV_LOGS(TXT("CIMCVAppRichTextContainer::BoldL()	 start" ));
       
  1670 #ifdef _DEBUG
       
  1671     TInt len( iRichText->DocumentLength() );
       
  1672     
       
  1673 #endif //_DEBUG
       
  1674 
       
  1675     TCharFormat charFormat;
       
  1676     TCharFormatMask charFormatMask;    
       
  1677     
       
  1678     charFormat.iFontSpec.iFontStyle.SetStrokeWeight( EStrokeWeightBold );
       
  1679     charFormatMask.SetAttrib( EAttFontStrokeWeight );
       
  1680     
       
  1681     iRichText->ApplyCharFormatL( charFormat, charFormatMask, 
       
  1682                                  aSel.LowerPos(),
       
  1683                                  aSel.Length() );
       
  1684     IM_CV_LOGS(TXT("CIMCVAppRichTextContainer::BoldL()	 end" ));
       
  1685     }
       
  1686     
       
  1687 // -----------------------------------------------------------------------------
       
  1688 // CIMCVAppRichTextContainer::ParseTextL
       
  1689 // (other items were commented in a header).
       
  1690 // -----------------------------------------------------------------------------
       
  1691 //
       
  1692 void CIMCVAppRichTextContainer::ParseTextL( const TDesC& aText, TInt aStartPos, 
       
  1693 						TInt aRelativePos, CIMCVAppMessageWrapper& aMessageWrapper )
       
  1694     {
       
  1695     IM_CV_LOGS(TXT("CIMCVAppRichTextContainer::ParseTextL()	 start" ));
       
  1696     CFindItemEngine* findItem = CFindItemEngine::NewL( aText, 
       
  1697                                 CFindItemEngine::TFindItemSearchCase(
       
  1698                                 CFindItemEngine::EFindItemSearchPhoneNumberBin |
       
  1699                                 CFindItemEngine::EFindItemSearchMailAddressBin |
       
  1700                                 CFindItemEngine::EFindItemSearchURLBin/* |
       
  1701                                 CFindItemEngine::EFindItemSearchScheme*/ )
       
  1702                                 );                                     
       
  1703 
       
  1704     CleanupStack::PushL( findItem );
       
  1705     
       
  1706     // reset array
       
  1707     RArray<TCursorSelection>& highlights = aMessageWrapper.Highlights();
       
  1708     RArray<TInt>& types = aMessageWrapper.HighlightTypes();
       
  1709     highlights.Reset();
       
  1710     types.Reset();
       
  1711     
       
  1712     // get found items
       
  1713     const CArrayFixFlat<CFindItemEngine::SFoundItem>* items = 
       
  1714     	findItem->ItemArray();
       
  1715     TInt count( items->Count() );
       
  1716     
       
  1717     for( TInt i(0); i<count; ++i )
       
  1718         {
       
  1719         const CFindItemEngine::SFoundItem item = items->At(i);
       
  1720         
       
  1721         // selection in rich text
       
  1722         TCursorSelection realSel( aStartPos + item.iStartPos + item.iLength,
       
  1723                                   aStartPos + item.iStartPos );
       
  1724                               
       
  1725         // relative selection inside one message
       
  1726         TCursorSelection relativeSel( aRelativePos + item.iStartPos + 
       
  1727         							  item.iLength,
       
  1728                                       aRelativePos + item.iStartPos );
       
  1729 
       
  1730         highlights.AppendL( relativeSel );
       
  1731         types.AppendL( item.iItemType );
       
  1732         
       
  1733         // apply highlight item formatting
       
  1734         if( iItemHighlight )
       
  1735         	{
       
  1736 			HighLightItemL( realSel );
       
  1737         	}
       
  1738         }
       
  1739     
       
  1740     CleanupStack::PopAndDestroy( findItem );
       
  1741     IM_CV_LOGS(TXT("CIMCVAppRichTextContainer::ParseTextL()	 end" ));
       
  1742     }
       
  1743     
       
  1744 // -----------------------------------------------------------------------------
       
  1745 // CIMCVAppRichTextContainer::AddNickL
       
  1746 // (other items were commented in a header).
       
  1747 // -----------------------------------------------------------------------------
       
  1748 //
       
  1749 TCursorSelection CIMCVAppRichTextContainer::AddNickL( 
       
  1750 										CIMCVAppMessageWrapper& aMessageWrapper )
       
  1751     {
       
  1752     IM_CV_LOGS(TXT("CIMCVAppRichTextContainer::AddNickL()	 start" ));
       
  1753     // insert nick    
       
  1754     MIMCVEngineMessage& message = aMessageWrapper.Message();
       
  1755     TPtrC sender;
       
  1756     TPtrC recipient;
       
  1757     if( message.MessageType() == MIMCVEngineMessage::EMessageGroup ||
       
  1758         message.MessageType() == MIMCVEngineMessage::EMessageWhisper )
       
  1759         {
       
  1760         sender.Set( message.Sender() );
       
  1761         recipient.Set( message.Recipient() );
       
  1762         }
       
  1763     // need to implements todo
       
  1764     TCursorSelection nickSel( 0,0 );
       
  1765     //============================================================================
       
  1766     if( message.MessagerType() == MIMCVEngineMessage::EMessageSent && 
       
  1767     message.MessageType() == MIMCVEngineMessage::EMessagePTOP)
       
  1768 	    {
       
  1769 	    CIMCVAppPicture* pic = new( ELeave )CIMCVAppPicture( *iMap, iFromMe );
       
  1770 	    TPictureHeader header;
       
  1771 		header.iPicture = TSwizzle<CPicture>(pic );
       
  1772 		iRichText->InsertL( iRichText->DocumentLength(), header );// takes ownership
       
  1773 		iRichText->InsertL( iRichText->DocumentLength(), KSeparator );
       
  1774 	    }
       
  1775 	 
       
  1776      else if( message.MessageType() == MIMCVEngineMessage::EMessagePTOP &&
       
  1777          message.MessagerType() == MIMCVEngineMessage::EMessageReceived )
       
  1778 	    {
       
  1779 	    // received p2p message and we want to display icon
       
  1780 	    // insert "to me" icon and separator
       
  1781 	    CIMCVAppPicture* pic = new( ELeave )CIMCVAppPicture( *iMap,iToMe );
       
  1782 	    TPictureHeader header;
       
  1783 	    header.iPicture = TSwizzle<CPicture>( pic ); 
       
  1784 	    iRichText->CancelInsertCharFormat(); // to prevent ETEXT 31 panic
       
  1785 	    iRichText->InsertL( iRichText->DocumentLength(), header ); // takes ownership
       
  1786 	    iRichText->InsertL( iRichText->DocumentLength(), KSeparator );
       
  1787 	    }
       
  1788     //============================================================================
       
  1789     IM_CV_LOGS(TXT("CIMCVAppRichTextContainer::AddNickL()	 end" ));
       
  1790     return nickSel;
       
  1791     }
       
  1792     
       
  1793 // -----------------------------------------------------------------------------
       
  1794 // CIMCVAppSmileIconUtility::LoadDefaultBitmapL
       
  1795 // (other items were commented in a header).
       
  1796 // -----------------------------------------------------------------------------
       
  1797 //
       
  1798 CGulIcon* CIMCVAppRichTextContainer::LoadDefaultBitmapL( TInt aBitmapId, TInt aMaskId, 
       
  1799                                 const TDesC& aFullPath, TBool/* aOverrideBrand */)
       
  1800 	{
       
  1801     
       
  1802     IM_CV_LOGS(TXT("CIMCVAppSmileIconUtility::LoadDefaultBitmapL() start") );
       
  1803     CFbsBitmap* bitmap = NULL;
       
  1804     CFbsBitmap* mask = NULL;
       
  1805 	
       
  1806 	MAknsSkinInstance* skin = AknsUtils::SkinInstance();	
       
  1807 
       
  1808 	TAknsItemID itemId( KAknsIIDNone );
       
  1809     
       
  1810     AknsUtils::CreateIconLC( skin, 
       
  1811                 itemId, 
       
  1812                 bitmap, mask, aFullPath, aBitmapId, aMaskId );    
       
  1813 
       
  1814     CGulIcon* gulIcon = CGulIcon::NewL( bitmap, mask );
       
  1815     CleanupStack::Pop( 2 ); // bitmap, mask
       
  1816     IM_CV_LOGS(TXT("CIMCVAppSmileIconUtility::LoadDefaultBitmapL() end") );
       
  1817     return gulIcon;
       
  1818     }
       
  1819 
       
  1820 // -----------------------------------------------------------------------------
       
  1821 // CIMCVAppRichTextContainer::AddTimeStampL
       
  1822 // (other items were commented in a header).
       
  1823 // -----------------------------------------------------------------------------
       
  1824 //
       
  1825 TCursorSelection CIMCVAppRichTextContainer::AddTimeStampL( 
       
  1826 										CIMCVAppMessageWrapper& aMessageWrapper )
       
  1827     {
       
  1828     IM_CV_LOGS(TXT("CIMCVAppRichTextContainer::AddTimeStampL()	 start" ));
       
  1829     TInt start = iRichText->DocumentLength();
       
  1830     
       
  1831     TCursorSelection timeSel( start, start );
       
  1832    
       
  1833     
       
  1834     // format time
       
  1835     HBufC* timeStamp = HBufC::NewLC( KTimeStampMaxLength + KSpace().Length() );
       
  1836     TPtr timePtr( timeStamp->Des() );
       
  1837     
       
  1838     HBufC* timeStampFormat = NULL;
       
  1839     timeStampFormat = StringLoader::LoadLC( R_QTN_TIME_USUAL_WITH_ZERO );
       
  1840     
       
  1841     TTime time = aMessageWrapper.Message().TimeStamp();
       
  1842     TRAPD( err, time.FormatL( timePtr, *timeStampFormat ) );
       
  1843     if( err == KErrOverflow )
       
  1844         {
       
  1845         // Reserved text space was not enough.
       
  1846         // Adjust the KTimeStampMaxLength!
       
  1847          // in release builds return without timestamp
       
  1848         CleanupStack::PopAndDestroy( 2, timeStamp); // timeStamp, timeStampFormat
       
  1849         return timeSel;
       
  1850         }
       
  1851     
       
  1852     // Convert numbers to local language
       
  1853     AknTextUtils::LanguageSpecificNumberConversion( timePtr );
       
  1854    
       
  1855     // Set Alignment of Pm/Am from local setting
       
  1856     // This keeps the am/pm text close to the time.
       
  1857     timePtr.Append( AknLayoutUtils::LayoutMirrored() ? 
       
  1858                     KUnicodeRLM : KUnicodeLRM );
       
  1859         
       
  1860     // append time to rich text
       
  1861     timePtr.Append( KSpace );
       
  1862     iRichText->InsertL( start, timePtr );
       
  1863     
       
  1864     CleanupStack::PopAndDestroy( 2, timeStamp); // timeStamp, timeStampFormat
       
  1865     timeSel.SetSelection( start, iRichText->DocumentLength() - 1 );
       
  1866 
       
  1867     // bold the time
       
  1868     if( timeSel.Length() > 0 )
       
  1869         {
       
  1870         BoldL( timeSel );
       
  1871         }
       
  1872     IM_CV_LOGS(TXT("CIMCVAppRichTextContainer::AddTimeStampL()	 end" ));
       
  1873     return timeSel;
       
  1874     }
       
  1875     
       
  1876 // -----------------------------------------------------------------------------
       
  1877 // CIMCVAppRichTextContainer::AddContentL
       
  1878 // (other items were commented in a header).
       
  1879 // -----------------------------------------------------------------------------
       
  1880 //
       
  1881 void CIMCVAppRichTextContainer::AddContentL( TInt aMsgStart, 
       
  1882 										CIMCVAppMessageWrapper& aMessageWrapper )
       
  1883     {  
       
  1884     IM_CV_LOGS(TXT("CIMCVAppRichTextContainer::AddContentL()	 start" ));  
       
  1885     MIMCVEngineMessage& message = aMessageWrapper.Message();
       
  1886 
       
  1887     MIMCVEngineMessage::TContentType type( message.ContentType() );
       
  1888     switch( type ) 
       
  1889         {
       
  1890         case MIMCVEngineMessage::EContentText:
       
  1891             {
       
  1892             // insert text
       
  1893             //If received message is longer than 400 characters it will be truncated in imconnectionprovider
       
  1894             //so append truncation message to inform user that received message is truncated 
       
  1895             HBufC* newmsg = HBufC::NewLC(KMsgMaxLength);
       
  1896             TPtr msg = newmsg->Des();
       
  1897             if(message.Text().Length() > KReceiveMsgMaxLength)
       
  1898                 {              
       
  1899                 msg.Append(message.Text().Left(KReceiveMsgMaxLength));
       
  1900                 HBufC* addText  = StringLoader::LoadLC( R_QTN_CONVIEW_TRUNCATED );
       
  1901                 msg.Append(addText->Des());
       
  1902                 CleanupStack::PopAndDestroy(addText);//addText             
       
  1903                 }
       
  1904             else
       
  1905                 {
       
  1906                 msg.Append(message.Text());
       
  1907                 }
       
  1908           //  TPtrC msg( message.Text() );
       
  1909             HBufC* tempMsg = NULL;
       
  1910             
       
  1911             TInt paraBreak = msg.Locate( CEditableText::EParagraphDelimiter );
       
  1912             // Replace all paragraph delimiters with line breaks
       
  1913             // to keep alingment consistent
       
  1914             if ( paraBreak != KErrNotFound )
       
  1915                 {
       
  1916                 tempMsg = msg.AllocLC();
       
  1917                 TPtr ptr( tempMsg->Des() );
       
  1918                 ptr.Zero();
       
  1919                 
       
  1920                 ReplaceParaDelimsWithLineBreaks( msg, ptr );
       
  1921                 msg.Set( ptr );
       
  1922                 }
       
  1923 
       
  1924             HBufC* numberConv = NULL;
       
  1925             
       
  1926             // Convert numerals to local language
       
  1927             // 1) date item
       
  1928             if( aMessageWrapper.Message().SystemMessageType() ==
       
  1929                 MIMCVEngineMessage::ESystemMessageDateChange )
       
  1930             {
       
  1931                 // don't touch the original message
       
  1932                 numberConv = msg.AllocLC();
       
  1933                 TPtr ptr( numberConv->Des() );
       
  1934                 AknTextUtils::LanguageSpecificNumberConversion( ptr );
       
  1935                 msg.Set( ptr );
       
  1936             }
       
  1937 
       
  1938             TInt textStart( iRichText->DocumentLength() );
       
  1939             iRichText->InsertL( textStart, msg );
       
  1940                 
       
  1941             CleanupStack::PopAndDestroy(newmsg);//newmsg
       
  1942             // check for extensions (smileys)
       
  1943             TCursorSelection selection( iRichText->DocumentLength(), 
       
  1944             							textStart );
       
  1945             iExtensionsHandler->ConvertSelectionToExtensionL( *iRichText, 
       
  1946             													selection ,
       
  1947             													iServiceId );
       
  1948             
       
  1949             TInt textEnd( iRichText->DocumentLength() );
       
  1950                 
       
  1951             // add nbs to preserve formatting
       
  1952             iRichText->InsertL( iRichText->DocumentLength(), 
       
  1953             					CEditableText::EZeroWidthNoBreakSpace );
       
  1954             
       
  1955             // if this is system message, it should be bold
       
  1956             if( message.MessageType() == MIMCVEngineMessage::EMessageSystem )
       
  1957                 {
       
  1958                 TCursorSelection sel( textStart, textEnd );
       
  1959                 BoldL( sel );
       
  1960                 // System messages need different kind of alignment
       
  1961                 CParaFormat paraFormat;
       
  1962                 TParaFormatMask paraFormatMask;
       
  1963                 paraFormat.iLeftMarginInTwips = 0;
       
  1964                 paraFormatMask.SetAttrib( EAttLeftMargin );    
       
  1965                 iRichText->ApplyParaFormatL( &paraFormat, paraFormatMask,
       
  1966                                              textStart, sel.Length() );
       
  1967                 }
       
  1968             else
       
  1969                 {
       
  1970                 // Apply alignment for "normal" messages
       
  1971                 CParaFormat paraFormat;
       
  1972                 TParaFormatMask paraFormatMask;
       
  1973                 paraFormat.iLeftMarginInTwips = 100;
       
  1974                 paraFormatMask.SetAttrib( EAttLeftMargin );    
       
  1975                 iRichText->ApplyParaFormatL( &paraFormat, paraFormatMask,
       
  1976                                              textStart, textEnd - textStart );
       
  1977                 }
       
  1978 
       
  1979             // parse text for highlights and store positions to messagewrapper
       
  1980             HBufC* text = HBufC::NewMaxLC( textEnd-textStart );
       
  1981             TPtr txt( text->Des() );
       
  1982             iRichText->Extract( txt, textStart, textEnd-textStart );
       
  1983             ParseTextL( txt, textStart, textStart-aMsgStart, aMessageWrapper );
       
  1984             CleanupStack::PopAndDestroy( text );
       
  1985             
       
  1986             // Cleanup
       
  1987             if( numberConv )
       
  1988                 {
       
  1989                 CleanupStack::PopAndDestroy( numberConv );
       
  1990                 }
       
  1991             if ( tempMsg )
       
  1992                 {
       
  1993                 CleanupStack::PopAndDestroy( tempMsg );
       
  1994                 }
       
  1995             break;            
       
  1996             }
       
  1997        
       
  1998         default:
       
  1999             {
       
  2000             // unsupported type
       
  2001         
       
  2002             break;
       
  2003             }
       
  2004         }
       
  2005     IM_CV_LOGS(TXT("CIMCVAppRichTextContainer::AddContentL()	 end" ));  
       
  2006     }
       
  2007 
       
  2008 
       
  2009 // -----------------------------------------------------------------------------
       
  2010 // CIMCVAppRichTextContainer::UpdateSkinnedTextColourL
       
  2011 // (other items were commented in a header).
       
  2012 // -----------------------------------------------------------------------------
       
  2013 //
       
  2014 void CIMCVAppRichTextContainer::UpdateSkinnedTextColourL()  
       
  2015     {
       
  2016     IM_CV_LOGS(TXT("CIMCVAppRichTextContainer::UpdateSkinnedTextColourL()	 start" ));  
       
  2017     // Get current text's color
       
  2018     TRgb defaultSkinTextColor( KRgbBlack );
       
  2019     AknsUtils::GetCachedColor( AknsUtils::SkinInstance(),
       
  2020                                defaultSkinTextColor,
       
  2021                                KAknsIIDQsnTextColors,
       
  2022                                EAknsCIQsnTextColorsCG6 );
       
  2023 
       
  2024     TCharFormat charFormat;
       
  2025     TCharFormatMask charFormatMask;
       
  2026     charFormat.iFontPresentation.iTextColor = defaultSkinTextColor;
       
  2027     charFormatMask.SetAttrib( EAttColor );
       
  2028 
       
  2029 	// also appended messages should have new colour
       
  2030 	TInt richTextDocumentLength = iRichText->DocumentLength();
       
  2031 
       
  2032 	iRichText->ApplyCharFormatL ( charFormat, charFormatMask, 0, richTextDocumentLength);
       
  2033 	TCursorSelection cursorSelection(0, richTextDocumentLength);
       
  2034 	iTextView->HandleFormatChangedL (cursorSelection);
       
  2035     IM_CV_LOGS(TXT("CIMCVAppRichTextContainer::UpdateSkinnedTextColourL()	 end" ));  
       
  2036     }
       
  2037 
       
  2038 // -----------------------------------------------------------------------------
       
  2039 // CIMCVAppRichTextContainer::SkinColoredSelection
       
  2040 // (other items were commented in a header).
       
  2041 // -----------------------------------------------------------------------------
       
  2042 //
       
  2043 TCursorSelection CIMCVAppRichTextContainer::SkinColoredSelection(  
       
  2044                                             CIMCVAppMessageWrapper& aMessageWrapper,
       
  2045                                             TBool aUseDefaultColors, 
       
  2046                                             TBool aCustomDefinedColor )
       
  2047     {   
       
  2048     IM_CV_LOGS(TXT("CIMCVAppRichTextContainer::SkinColoredSelection()	 start" ));  
       
  2049     // This logic determines which part of the message is colored by the theme
       
  2050     if( !aCustomDefinedColor && aUseDefaultColors )
       
  2051         {
       
  2052         return aMessageWrapper.WholeSelection();
       
  2053         }
       
  2054         
       
  2055     if( !iColorWholeMessage )
       
  2056         {
       
  2057         return aMessageWrapper.MessageSelection();
       
  2058         }
       
  2059     IM_CV_LOGS(TXT("CIMCVAppRichTextContainer::SkinColoredSelection()	 end" ));  
       
  2060     return TCursorSelection( 0, 0 );    
       
  2061     }
       
  2062 
       
  2063 // -----------------------------------------------------------------------------
       
  2064 // CIMCVAppRichTextContainer::ReplaceParaDelimsWithLineBreaks
       
  2065 // (other items were commented in a header).
       
  2066 // -----------------------------------------------------------------------------
       
  2067 //
       
  2068 void CIMCVAppRichTextContainer::ReplaceParaDelimsWithLineBreaks(
       
  2069                                             const TPtrC& aSource,
       
  2070                                             TPtr& aTarget ) const
       
  2071     {
       
  2072     IM_CV_LOGS(TXT("CIMCVAppRichTextContainer::ReplaceParaDelimsWithLineBreaks()	 start" ));  
       
  2073 #ifdef _DEBUG
       
  2074     TPtrC target;
       
  2075     target.Set( aTarget );
       
  2076    
       
  2077 #endif
       
  2078     
       
  2079     TInt paraBreak = aSource.Mid( aTarget.Length() ).Locate(
       
  2080                         CEditableText::EParagraphDelimiter );
       
  2081     
       
  2082     if ( paraBreak == KErrNotFound )
       
  2083         {
       
  2084         // No more paragraph delimiters, append what's left
       
  2085         aTarget.Append( aSource.Mid( aTarget.Length() ) );
       
  2086         // And break away from recursion
       
  2087         return;
       
  2088         }
       
  2089     
       
  2090     aTarget.Append( aSource.Mid( aTarget.Length(), paraBreak ) );
       
  2091     aTarget.Append( CEditableText::ELineBreak );
       
  2092 
       
  2093 #ifdef _DEBUG
       
  2094     target.Set( aTarget );
       
  2095    
       
  2096 #endif
       
  2097 
       
  2098     ReplaceParaDelimsWithLineBreaks( aSource, aTarget );
       
  2099     IM_CV_LOGS(TXT("CIMCVAppRichTextContainer::ReplaceParaDelimsWithLineBreaks()	 end" ));  
       
  2100     }
       
  2101 
       
  2102 // -----------------------------------------------------------------------------
       
  2103 // CIMCVAppRichTextContainer::GetPrimaryKey
       
  2104 // (other items were commented in a header).
       
  2105 // -----------------------------------------------------------------------------
       
  2106 //
       
  2107 
       
  2108 const TDesC& CIMCVAppRichTextContainer::GetPrimaryKey()
       
  2109     {
       
  2110     if( iPrimaryKey)
       
  2111         {
       
  2112         return *iPrimaryKey;
       
  2113         }
       
  2114     return KNullDesC;
       
  2115     }
       
  2116 //  End of File