idlehomescreen/xmluirendering/renderingplugins/xntextfactory/src/xntextadapter.cpp
changeset 0 f72a12da539e
child 15 ff572dfe6d86
equal deleted inserted replaced
-1:000000000000 0:f72a12da539e
       
     1 /*
       
     2 * Copyright (c) 2005-2006 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:  Implementation for wrapper for a label
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 #include <e32base.h>
       
    20 #include <coecntrl.h>
       
    21 #include <barsread.h>
       
    22 #include <gulcolor.h>
       
    23 #include <utf.h>
       
    24 
       
    25 #include <AknsUtils.h>
       
    26 #include <AknPictographInterface.h> // for japanese variants.
       
    27 #include <AknBidiTextUtils.h>
       
    28 #include <AknUtils.h>
       
    29 #include <AknLayoutFont.h>
       
    30 
       
    31 #include "xnnodepluginif.h"
       
    32 #include "xndompropertyvalue.h"
       
    33 #include "xndomproperty.h"
       
    34 #include "xndomlist.h"
       
    35 #include "xnproperty.h"
       
    36 #include "xncomponent.h"
       
    37 #include "xnuienginepluginif.h"
       
    38 #include "xncomponent.h"
       
    39 #include "xncontroladapter.h"
       
    40 #include "c_xnutils.h"
       
    41 #include "xntype.h"
       
    42 #include "xntextadapter.h"
       
    43 #include "xncomponentnodeimpl.h"
       
    44 #include "xnviewnodeimpl.h"
       
    45 #include "xneditmode.h"
       
    46 
       
    47 namespace XnText
       
    48     {
       
    49     const TUint8 KClip = 0x01;   
       
    50     const TUint8 KEllipse = 0x02; 
       
    51     const TUint8 KWrap = 0x04;    
       
    52     const TUint8 KOverflowVisible = 0x08; 
       
    53     const TUint8 KLtr = 0x10;     
       
    54     const TUint8 KConstructText = 0x20;
       
    55 
       
    56     _LIT8( tooltip, "tooltip" );
       
    57     _LIT8( clock, "clock" );
       
    58     }
       
    59     
       
    60 // -----------------------------------------------------------------------------
       
    61 // IsBitSet
       
    62 // Test whether bit is set in a flag
       
    63 // -----------------------------------------------------------------------------
       
    64 static TBool IsBitSet(TUint8 aBit,TUint8 aFlag)
       
    65     {
       
    66     return ( aFlag & aBit );    
       
    67     }
       
    68     
       
    69 // -----------------------------------------------------------------------------
       
    70 // SetLabelTextL
       
    71 // Prepares text to label, wraps or clips if needed
       
    72 // -----------------------------------------------------------------------------
       
    73 static void SetLabelTextL( CEikLabel& aLabel, const TDesC& aSource, TInt aMaxLineWidth, 
       
    74                            TInt aMaxLines, TUint8 aFlags, TBool aMeasureOnly = EFalse )    
       
    75     {   
       
    76     // By default, let the label do the logical to visual conversion                
       
    77     TBool conversion( ETrue );
       
    78     
       
    79     if( IsBitSet( XnText::KOverflowVisible, aFlags ) || aSource == KNullDesC )
       
    80         {        
       
    81         // no clipping or wrapping needed if,
       
    82         // overflow is visible
       
    83         // no text or no space,
       
    84         // or text fits to given space
       
    85         aLabel.SetTextL( aSource );                        
       
    86         }
       
    87     else
       
    88         {
       
    89         AknBidiTextUtils::TParagraphDirectionality dir( AknBidiTextUtils::EImplicit );
       
    90         
       
    91         const CFont* font( aLabel.Font() );
       
    92         
       
    93         HBufC* buffer( NULL );
       
    94         
       
    95         if( IsBitSet( XnText::KEllipse, aFlags ) )
       
    96     	    {	    
       
    97             buffer = aSource.AllocLC();
       
    98     	    
       
    99     	    TPtr ptr( buffer->Des() );
       
   100     	    	    	    
       
   101             AknBidiTextUtils::ConvertToVisualAndClipL(
       
   102     	                ptr, *font, aMaxLineWidth, aMaxLineWidth, dir );
       
   103 
       
   104             
       
   105             // The text is already in visual form, no need for conversion
       
   106             conversion = EFalse;            
       
   107             
       
   108             aLabel.SetTextL( *buffer );            
       
   109             
       
   110             CleanupStack::PopAndDestroy( buffer );	        	                                    
       
   111     	    }
       
   112     	else if( IsBitSet( XnText::KWrap, aFlags ) )
       
   113     	    {        	    
       
   114     	    if( aMaxLines > 0 )
       
   115     	        {
       
   116         	    CArrayFixFlat< TInt >* array = new ( ELeave ) CArrayFixFlat< TInt >( 8 );
       
   117         	    CleanupStack::PushL( array );
       
   118     	        
       
   119         	    for( TInt i = 0; i < aMaxLines; i++ )
       
   120         	        {
       
   121         	        array->AppendL( aMaxLineWidth );
       
   122         	        }
       
   123         	        
       
   124                 buffer = HBufC::NewLC( aSource.Length() + aMaxLines * 
       
   125                                         ( KAknBidiExtraSpacePerLine + 1 ) );
       
   126                 
       
   127                 TPtr ptr( buffer->Des() );
       
   128                 
       
   129         	    AknBidiTextUtils::ConvertToVisualAndWrapToStringL(
       
   130         	                aSource, *array, *font, ptr, ETrue, dir );    	        
       
   131     	        }
       
   132             else
       
   133                 {
       
   134         	    CArrayFixFlat< TPtrC >* array = new ( ELeave ) CArrayFixFlat< TPtrC >( 8 );
       
   135         	    CleanupStack::PushL( array );
       
   136                 
       
   137                 HBufC* temp = AknBidiTextUtils::ConvertToVisualAndWrapToArrayL(
       
   138                             aSource, aMaxLineWidth, *font, *array, dir );
       
   139                             
       
   140                 CleanupStack::PushL( temp );
       
   141                 
       
   142                 TInt lineCount( array->Count() );
       
   143                 
       
   144                 buffer = HBufC::NewLC( temp->Length() + ( lineCount - 1 ) );
       
   145                 
       
   146                 TPtr ptr( buffer->Des() );
       
   147                                                 
       
   148                 for( TInt i = 0; i < lineCount; i++ )
       
   149                     {
       
   150                     TPtrC line( array->At( i ) );
       
   151                     
       
   152                     ptr.Append( line );
       
   153                     
       
   154                     if( i + 1 < lineCount )
       
   155                         {
       
   156                         ptr.Append( '\n' );
       
   157                         }                    
       
   158                     }
       
   159                     
       
   160                 CleanupStack::Pop();
       
   161                 CleanupStack::PopAndDestroy( temp );
       
   162                 CleanupStack::PushL( buffer );                                                    
       
   163                 }    	        
       
   164 
       
   165             // The text is already in visual form, no need for conversion
       
   166             conversion = EFalse;
       
   167 
       
   168             aLabel.SetTextL( *buffer );            
       
   169                         
       
   170             CleanupStack::PopAndDestroy( 2 ); // buffer, array                                       
       
   171     	    }
       
   172         else
       
   173             {
       
   174             aLabel.SetTextL( aSource );            
       
   175             }    	                   
       
   176         } 
       
   177     
       
   178     if( !aMeasureOnly )
       
   179         {     
       
   180         // Text is truly set, set conversion and defer draw
       
   181         aLabel.UseLogicalToVisualConversion( conversion );                    
       
   182         }
       
   183     }
       
   184       
       
   185 // -----------------------------------------------------------------------------
       
   186 // CopyBitmapData
       
   187 // Copies a data from source bitmap to target bitmap.
       
   188 // -----------------------------------------------------------------------------
       
   189 //
       
   190 static TInt CopyBitmapData(
       
   191     CFbsBitmap& aTarget,
       
   192     const CFbsBitmap& aSource,
       
   193     TPoint aSourcePoint)
       
   194 	{
       
   195     TSize targetSize(aTarget.SizeInPixels());
       
   196     TSize sourceSize(aSource.SizeInPixels());
       
   197     TInt lineLength(targetSize.iWidth);
       
   198     TInt maxSourceLineLength(sourceSize.iWidth - aSourcePoint.iX);
       
   199     if(lineLength > maxSourceLineLength)
       
   200         {
       
   201         lineLength = maxSourceLineLength;
       
   202         }
       
   203     TInt rowCount(targetSize.iHeight);
       
   204     TInt maxSourceRowCount(sourceSize.iHeight - aSourcePoint.iY);
       
   205     if(rowCount > maxSourceRowCount)
       
   206         {
       
   207         rowCount = maxSourceRowCount;
       
   208         }
       
   209 
       
   210     // Get bitmap display mode
       
   211 	TDisplayMode displayMode(aSource.DisplayMode());
       
   212 
       
   213     // Create buffer for a scan line
       
   214 	HBufC8* scanLine = HBufC8::New(
       
   215         aSource.ScanLineLength(lineLength, displayMode));
       
   216     if(!scanLine)
       
   217     	{
       
   218     	return KErrNoMemory;
       
   219     	}
       
   220      
       
   221 	TPtr8 scanPtr(scanLine->Des());
       
   222 
       
   223     // Copy all rows to destination bitmap
       
   224 	for(TInt row(0); row < rowCount; row++)
       
   225 		{
       
   226 		aSource.GetScanLine(scanPtr,
       
   227             TPoint(aSourcePoint.iX, aSourcePoint.iY + row),
       
   228             lineLength, displayMode);
       
   229 		aTarget.SetScanLine(scanPtr, row);
       
   230 		}
       
   231     delete scanLine;
       
   232 	return KErrNone;
       
   233 	}        
       
   234 
       
   235 // ============================ MEMBER FUNCTIONS ===============================
       
   236 
       
   237 // -----------------------------------------------------------------------------
       
   238 // CXnTextAdapter::NewL
       
   239 // Symbian static 1st phase constructor
       
   240 // -----------------------------------------------------------------------------
       
   241 //
       
   242 CXnTextAdapter* CXnTextAdapter::NewL(CXnControlAdapter* aParent, CXnNodePluginIf& aNode)
       
   243     {
       
   244 	CXnTextAdapter* self = new( ELeave ) CXnTextAdapter( aParent, aNode );
       
   245 
       
   246     CleanupStack::PushL( self );
       
   247     self->ConstructL();
       
   248     CleanupStack::Pop();
       
   249 
       
   250     return self;	
       
   251     }
       
   252     
       
   253 // -----------------------------------------------------------------------------
       
   254 // CXnTextAdapter::CXnTextAdapter
       
   255 // C++ default constructor
       
   256 // -----------------------------------------------------------------------------
       
   257 //
       
   258 CXnTextAdapter::CXnTextAdapter(CXnControlAdapter* aParent, CXnNodePluginIf& aNode)
       
   259     : iParent( aParent ), iNode( aNode )
       
   260     {
       
   261     }
       
   262 
       
   263 // -----------------------------------------------------------------------------
       
   264 // CXnTextAdapter::~CXnTextAdapter
       
   265 // C++ destructor
       
   266 // -----------------------------------------------------------------------------
       
   267 //
       
   268 CXnTextAdapter::~CXnTextAdapter()
       
   269     {    
       
   270     delete iLabel;
       
   271     
       
   272     delete iText;
       
   273     
       
   274     if( iFont && iReleaseFont )
       
   275         {
       
   276         CWsScreenDevice* dev = iCoeEnv->ScreenDevice();
       
   277         dev->ReleaseFont( iFont ); 
       
   278         }
       
   279         
       
   280     if( iPictographInterface )
       
   281     	{
       
   282     	delete iPictographInterface;
       
   283     	}
       
   284 
       
   285     delete iBackgroundBitmap;
       
   286     }
       
   287 
       
   288 // -----------------------------------------------------------------------------
       
   289 // CXnTextAdapter::ConstructL
       
   290 // Symbian 2nd phase constructor can leave.
       
   291 // -----------------------------------------------------------------------------
       
   292 //
       
   293 void CXnTextAdapter::ConstructL()
       
   294     {
       
   295     iGc = &SystemGc();
       
   296        
       
   297     iLabel = new ( ELeave ) CEikLabel;
       
   298     iLabel->SetContainerWindowL( *iParent );
       
   299     iLabel->SetTextL( KNullDesC );
       
   300     
       
   301     CXnControlAdapter::ConstructL( iNode );
       
   302             
       
   303     iPictographInterface = CAknPictographInterface::NewL( *iLabel, *this );
       
   304     iLabel->EnablePictographsL( *iPictographInterface );
       
   305                             
       
   306     SetTextPropertiesL( iNode );
       
   307     UpdateTextL( iNode.GetPCData() );    
       
   308 	}
       
   309 
       
   310 // -----------------------------------------------------------------------------
       
   311 // CXnTextAdapter::ConstructTextL
       
   312 // Construct the text component according to properties.
       
   313 // -----------------------------------------------------------------------------
       
   314 //    
       
   315 void CXnTextAdapter::ConstructTextL()
       
   316     {   
       
   317     if( !iText )        
       
   318         {
       
   319         // CEikLabel will panic in ::Draw if text is not set
       
   320         SetLabelTextL( *iLabel, KNullDesC, 0, 0, 0 );
       
   321         return;
       
   322         }
       
   323     
       
   324     if( !( iFlags & XnText::KConstructText ) )
       
   325         {
       
   326         return;
       
   327         }
       
   328                                    
       
   329     TRect rect( iNode.Rect() );
       
   330 
       
   331 	SetLineSpacingL( rect.Height() );
       
   332 	
       
   333 	TInt flags( iFlags );
       
   334 	               
       
   335     // Now we must restrict side into parent        
       
   336     flags = RestrictSizeL();
       
   337                                                                                                                   
       
   338     SetLabelTextL( *iLabel, *iText, iLabel->Rect().Width(), iMaxLines, flags );                       
       
   339     }
       
   340     
       
   341 // -----------------------------------------------------------------------------
       
   342 // CXnTextAdapter::SetTextPropertiesL
       
   343 // Sets text properties, such as color, font, etc.
       
   344 // (other items were commented in a header).
       
   345 // -----------------------------------------------------------------------------
       
   346 //
       
   347 TBool CXnTextAdapter::SetTextPropertiesL( CXnNodePluginIf& aNode )
       
   348     {
       
   349     // Store current state
       
   350     const CFont* font( iFont );
       
   351     TInt flags( iFlags );
       
   352     TInt maxLines( iMaxLines );
       
   353     
       
   354     if( iFont && iReleaseFont )
       
   355         {
       
   356         CWsScreenDevice* dev = iCoeEnv->ScreenDevice();
       
   357         dev->ReleaseFont( iFont ); 
       
   358         iFont = NULL;
       
   359         }
       
   360     
       
   361     // Find out the font and set it
       
   362     CXnUtils::CreateFontL( aNode, iFont, iReleaseFont );
       
   363     iLabel->SetFont( iFont );
       
   364     
       
   365     // Turn off all graphic context effects
       
   366     iLabel->SetUnderlining( EFalse );
       
   367     iLabel->SetStrikethrough( EFalse );
       
   368     
       
   369     //following data types are used due to we are handling text via CEikLabel instead of direct
       
   370     //font color and effects manipulation via graphics context.
       
   371     //We manipulate pen and brush colors indirectly via
       
   372     //Label's OverrideColorL method applying EColorControlBackground and EColorLabelText parameters
       
   373     //with corresponding RGB value.
       
   374     TRgb textColor;
       
   375     TRgb effectsColor;
       
   376     TBool textColorSet( EFalse );
       
   377     TBool effectsColorSet( EFalse );
       
   378     TBool effectsDevColorSet( EFalse );
       
   379     
       
   380     CXnProperty* colorProperty = aNode.GetPropertyL( XnPropertyNames::appearance::common::KColor );
       
   381     
       
   382     if( colorProperty != NULL )
       
   383         {
       
   384         CXnDomProperty* domProperty = colorProperty->Property();
       
   385         
       
   386         if( domProperty )
       
   387             {
       
   388             TInt error( KErrNotSupported );
       
   389 
       
   390             CXnDomPropertyValue* value = static_cast< CXnDomPropertyValue* >
       
   391                                             ( domProperty->PropertyValueList().Item( 0 ) );
       
   392             
       
   393             if( value->IsAutoIdent() )
       
   394                 {
       
   395                 MAknsSkinInstance* skinInstance = AknsUtils::SkinInstance();
       
   396                 error = AknsUtils::GetCachedColor(skinInstance, textColor, KAknsIIDQsnTextColors,
       
   397                 EAknsCIQsnTextColorsCG6);
       
   398                 }
       
   399             else if( value->PrimitiveValueType() == CXnDomPropertyValue::ERgbColor )
       
   400                 {
       
   401                 textColor = value->RgbColorValueL();
       
   402                 error = KErrNone;
       
   403                 }
       
   404             else
       
   405             	{
       
   406                 HBufC* colorString = colorProperty->StringValueL();
       
   407                 CleanupStack::PushL( colorString );
       
   408                 
       
   409                 CXnUtils::StripQuotes( colorString );
       
   410                 
       
   411                 TInt index = 0;
       
   412                 TAknsItemID skinID;
       
   413                 
       
   414                 TBool idResolved = CXnUtils::ResolveSkinItemIDL( colorString->Des(), skinID, index );
       
   415                 
       
   416                 if( idResolved )
       
   417                 	{
       
   418                 	MAknsSkinInstance* skinInstance = AknsUtils::SkinInstance();
       
   419                 	error = AknsUtils::GetCachedColor( skinInstance, textColor, skinID, index );
       
   420                 	}
       
   421                 else // use auto value if skin id is invalid.
       
   422                 	{
       
   423 	                MAknsSkinInstance* skinInstance = AknsUtils::SkinInstance();
       
   424 	                error = AknsUtils::GetCachedColor(skinInstance, textColor, KAknsIIDQsnTextColors,
       
   425 	                EAknsCIQsnTextColorsCG6);
       
   426 	                }
       
   427             	CleanupStack::PopAndDestroy( colorString );                	
       
   428             	}
       
   429             if (error == KErrNone)
       
   430                 {
       
   431                 textColorSet = ETrue;
       
   432                 }
       
   433             }
       
   434         }
       
   435     
       
   436     CXnProperty* effectsProperty = aNode.GetPropertyL(XnPropertyNames::appearance::common::KTextEffects);
       
   437     if ( effectsProperty )
       
   438         {
       
   439         TInt error(KErrNotSupported);
       
   440         effectsDevColorSet = ETrue; //some color needed, device color by default
       
   441         CXnProperty* effectsColorProperty = aNode.GetPropertyL(XnPropertyNames::appearance::common::KEffectsColor);
       
   442         if (effectsColorProperty)
       
   443             {
       
   444             CXnDomProperty* domProperty = effectsColorProperty->Property();
       
   445             if( domProperty )
       
   446                 {
       
   447                 CXnDomPropertyValue* value = static_cast<CXnDomPropertyValue*>(domProperty->PropertyValueList().Item(0));
       
   448                     if (value->IsAutoIdent())
       
   449                         {
       
   450                         MAknsSkinInstance* skinInstance = AknsUtils::SkinInstance();
       
   451                         error = AknsUtils::GetCachedColor(skinInstance, effectsColor, KAknsIIDQsnTextColors,
       
   452                         EAknsCIQsnTextColorsCG6);
       
   453                         }
       
   454                     else if (value->PrimitiveValueType() == CXnDomPropertyValue::ERgbColor)
       
   455                         {
       
   456                         effectsColor = value->RgbColorValueL();
       
   457                         error = KErrNone;
       
   458                         }
       
   459                         else
       
   460                         	{
       
   461                             HBufC* colorString = effectsColorProperty->StringValueL();
       
   462                             CleanupStack::PushL( colorString );
       
   463                             CXnUtils::StripQuotes( colorString );
       
   464                             
       
   465                             TInt index = 0;
       
   466                             TAknsItemID skinID;
       
   467                             
       
   468                             TBool idResolved = CXnUtils::ResolveSkinItemIDL( colorString->Des(), skinID, index );
       
   469                             if( idResolved )
       
   470                             	{
       
   471                             	MAknsSkinInstance* skinInstance = AknsUtils::SkinInstance();
       
   472                             	error = AknsUtils::GetCachedColor( skinInstance, effectsColor, skinID, index );
       
   473                             	}
       
   474                             else // use auto value if skin id is invalid.
       
   475                             	{
       
   476             	                MAknsSkinInstance* skinInstance = AknsUtils::SkinInstance();
       
   477             	                error = AknsUtils::GetCachedColor(skinInstance, effectsColor, KAknsIIDQsnTextColors,
       
   478             	                EAknsCIQsnTextColorsCG6);
       
   479             	                }
       
   480                         	CleanupStack::PopAndDestroy( colorString );                	
       
   481                         	}
       
   482                 if ( error == KErrNone )
       
   483                 	{
       
   484                     effectsColorSet = ETrue; //theme color found
       
   485                     effectsDevColorSet = EFalse;//device color not needed
       
   486                     }
       
   487                 }
       
   488             }
       
   489         }
       
   490 
       
   491     if ( textColorSet )
       
   492         {
       
   493         if ( effectsColorSet )
       
   494             {//theme font color and theme effects color
       
   495             iLabel->OverrideColorL(EColorControlBackground, textColor);
       
   496             iLabel->OverrideColorL(EColorLabelText, effectsColor);
       
   497             }
       
   498         else if ( effectsDevColorSet )
       
   499             {//theme font color and device effects color
       
   500             iLabel->OverrideColorL(EColorControlBackground, textColor);
       
   501             }
       
   502         else
       
   503             {//theme font color, but no effects defined
       
   504             iLabel->OverrideColorL(EColorLabelText, textColor);
       
   505             }
       
   506         }
       
   507     else if ( effectsColorSet )
       
   508             {//device font color and theme effects color
       
   509             iLabel->OverrideColorL(EColorLabelText, effectsColor);
       
   510             }//else device font color and device effects color (default)
       
   511 
       
   512     CXnProperty* textDecorationProp = aNode.GetPropertyL( XnPropertyNames::appearance::common::KTextDecoration );
       
   513     
       
   514     if( textDecorationProp )
       
   515         {
       
   516         CXnDomList& propertyValueList = textDecorationProp->Property()->PropertyValueList();
       
   517         
       
   518         TInt valueCount = propertyValueList.Length();
       
   519         
       
   520         for( TInt i = 0; i < valueCount; ++i )
       
   521             {
       
   522             CXnDomPropertyValue* value = static_cast< CXnDomPropertyValue* >( propertyValueList.Item( i ) );
       
   523             
       
   524             if( value->StringValueL() == XnPropertyNames::appearance::common::textdecoration::KUnderline )
       
   525                 {
       
   526                 iLabel->SetUnderlining( ETrue );
       
   527                 }
       
   528 
       
   529             if( value->StringValueL() == XnPropertyNames::appearance::common::textdecoration::KLinethrough )
       
   530                 {
       
   531                 iLabel->SetStrikethrough( ETrue );
       
   532                 }
       
   533             }
       
   534         }
       
   535        
       
   536     iFlags = 0;
       
   537     iFlags |= XnText::KEllipse; //default
       
   538     iFlags |= XnText::KLtr; 
       
   539     iMaxLines = 0;
       
   540     
       
   541     TGulAlignmentValue alignment = CXnUtils::TextAlignment( aNode );
       
   542     
       
   543     TInt labelAlignment( ELayoutAlignLeft ); // all are vertically top aligned by default (avkon)
       
   544     
       
   545     switch( alignment )
       
   546         {
       
   547         case EHCenterVCenter:            
       
   548             labelAlignment = ELayoutAlignCenter;                 
       
   549             break;
       
   550         case EHRightVCenter:            
       
   551             labelAlignment = ELayoutAlignRight;                
       
   552             break;
       
   553         default: 
       
   554             break;    
       
   555         }
       
   556     
       
   557     iLabel->SetLabelAlignment( labelAlignment ); // avkon extension needs this, it modifys horizontal alignment
       
   558     iLabel->SetAlignment( alignment ); // call to have vertical alignment
       
   559   
       
   560     CXnProperty* direction = iNode.GetPropertyL( XnPropertyNames::style::common::KDirection );
       
   561     const TDesC8* directionValue = &XnPropertyNames::style::common::direction::KLTR;
       
   562     
       
   563     if( direction )
       
   564         {
       
   565         directionValue = &direction->StringValue();    
       
   566         }
       
   567     
       
   568     if( *directionValue == XnPropertyNames::style::common::direction::KRTL )
       
   569         {
       
   570         iLabel->SetLabelAlignment( ELayoutAlignBidi );     
       
   571         iFlags &= ~XnText::KLtr;
       
   572         }
       
   573         	            
       
   574     CXnProperty* overflowProp = aNode.GetPropertyL( XnPropertyNames::appearance::common::KTextOverflowMode );
       
   575     
       
   576     if( overflowProp )
       
   577         {
       
   578         CXnDomList& propertyValueList = overflowProp->Property()->PropertyValueList();
       
   579         
       
   580         TInt valueCount = propertyValueList.Length();
       
   581         
       
   582         for( TInt i = 0; i < valueCount; ++i )
       
   583             {
       
   584             CXnDomPropertyValue* value = static_cast< CXnDomPropertyValue* >( propertyValueList.Item( i ) );
       
   585             
       
   586             if( value->StringValueL() == XnPropertyNames::appearance::common::textoverflow::KClipMode )
       
   587                 {
       
   588                 iFlags |= XnText::KClip;
       
   589                 iFlags &= ~XnText::KWrap;
       
   590                 iFlags &= ~XnText::KEllipse;                
       
   591                 }
       
   592             else if( value->StringValueL() == XnPropertyNames::appearance::common::textoverflow::KWrapMode )
       
   593                 {
       
   594                 iFlags |= XnText::KWrap;
       
   595                 iFlags &= ~XnText::KClip;
       
   596                 iFlags &= ~XnText::KEllipse;
       
   597                 }                
       
   598             }
       
   599             
       
   600         //Get max lines amount for wrap
       
   601         if( iFlags & XnText::KWrap )
       
   602             {
       
   603             CXnProperty* maxlinesProp = aNode.GetPropertyL( XnPropertyNames::appearance::common::textoverflow::KMaxLineAmount );
       
   604             
       
   605             if( maxlinesProp )
       
   606                 {
       
   607                 iMaxLines = static_cast< TInt >( maxlinesProp->FloatValueL() );
       
   608                 }
       
   609             }
       
   610         }
       
   611         
       
   612     CXnProperty* overflowProperty = iNode.GetPropertyL( XnPropertyNames::style::common::KOverflow );
       
   613     
       
   614     if( overflowProperty )
       
   615         {
       
   616         const TDesC8& overflowValue = overflowProperty->StringValue();
       
   617         
       
   618         if( overflowValue == XnPropertyNames::style::common::visibility::KVisible )
       
   619             {
       
   620             iFlags |= XnText::KOverflowVisible;
       
   621             }
       
   622         }
       
   623         
       
   624     if( flags & XnText::KConstructText )
       
   625         {
       
   626         iFlags |= XnText::KConstructText;
       
   627         }
       
   628         
       
   629     if( font != iFont || flags != iFlags || maxLines != iMaxLines )
       
   630         {
       
   631         return ETrue;
       
   632         }
       
   633         
       
   634     return EFalse;        
       
   635     }
       
   636         
       
   637 // -----------------------------------------------------------------------------
       
   638 // CXnTextAdapter::SetTextL
       
   639 // Sets the new content to the underlying CEikLabel
       
   640 // -----------------------------------------------------------------------------
       
   641 //
       
   642 void CXnTextAdapter::SetTextL( const TDesC& aText )
       
   643     {      
       
   644     UpdateTextL( &aText );          
       
   645     }
       
   646 	
       
   647 // -----------------------------------------------------------------------------
       
   648 // CXnTextAdapter::Text
       
   649 // Returns the text contained in the underlying CEikLabel
       
   650 // -----------------------------------------------------------------------------
       
   651 //
       
   652 const TDesC* CXnTextAdapter::Text() const
       
   653     {
       
   654     if( iFlags & XnText::KConstructText )
       
   655         {
       
   656         return iText;
       
   657         }
       
   658     else
       
   659         {
       
   660         return iLabel->Text();
       
   661         }            
       
   662     }
       
   663     
       
   664 // -----------------------------------------------------------------------------
       
   665 // CXnTextAdapter::CountComponentControls
       
   666 // Returns the number of component controls.
       
   667 // -----------------------------------------------------------------------------
       
   668 //
       
   669 TInt CXnTextAdapter::CountComponentControls() const
       
   670     {
       
   671     return 1;
       
   672     }
       
   673     
       
   674 // -----------------------------------------------------------------------------
       
   675 // CXnTextAdapter::ComponentControl
       
   676 // Returns the component control of the given index
       
   677 // -----------------------------------------------------------------------------
       
   678 //
       
   679 CCoeControl* CXnTextAdapter::ComponentControl(TInt aIndex) const
       
   680     {
       
   681     if( aIndex == 0 )
       
   682         {
       
   683         return iLabel;
       
   684         }
       
   685 
       
   686     return NULL;
       
   687     }
       
   688 
       
   689 // -----------------------------------------------------------------------------
       
   690 // CXnTextAdapter::DoHandlePropertyChangeL
       
   691 // -----------------------------------------------------------------------------
       
   692 //
       
   693 void CXnTextAdapter::DoHandlePropertyChangeL(CXnProperty* aProperty)
       
   694     {        
       
   695     if( aProperty )
       
   696         {
       
   697         const TDesC8& name( aProperty->Property()->Name() );
       
   698         
       
   699         if( name == XnPropertyNames::style::common::KDisplay || 
       
   700             name == XnPropertyNames::style::common::KVisibility ||
       
   701             name == XnPropertyNames::style::common::KWidth ||
       
   702             name == XnPropertyNames::style::common::KHeight )
       
   703             {
       
   704             return;
       
   705             }
       
   706         
       
   707         if( name == XnPropertyNames::common::KPCData )
       
   708             {
       
   709             UpdateTextL( iNode.GetPCData() );
       
   710             }
       
   711         }
       
   712                
       
   713     if( SetTextPropertiesL( iNode ) )
       
   714         {
       
   715         iFlags |= XnText::KConstructText;
       
   716         }
       
   717     }
       
   718 
       
   719 // -----------------------------------------------------------------------------
       
   720 // CXnTextAdapter::HandleResourceChange
       
   721 // -----------------------------------------------------------------------------
       
   722 //
       
   723 void CXnTextAdapter::HandleScreenDeviceChangedL()
       
   724     {
       
   725     if( SetTextPropertiesL( iNode ) )
       
   726         {
       
   727         iFlags |= XnText::KConstructText;
       
   728         }
       
   729 
       
   730     CXnControlAdapter::HandleScreenDeviceChangedL();        
       
   731     }
       
   732 
       
   733 // -----------------------------------------------------------------------------
       
   734 // CXnTextAdapter::HandlePointerEventL
       
   735 // (other items were commented in a header).
       
   736 // -----------------------------------------------------------------------------
       
   737 // 
       
   738 void CXnTextAdapter::HandlePointerEventL( const TPointerEvent& aPointerEvent )
       
   739     {
       
   740 	if( AknLayoutUtils::PenEnabled() )
       
   741 	    {
       
   742 	    CXnControlAdapter::HandlePointerEventL( aPointerEvent );
       
   743 	    }
       
   744     }
       
   745 
       
   746 // ---------------------------------------------------------
       
   747 // CXnTextAdapter::SizeChanged()
       
   748 // Called by framework when the view size is changed
       
   749 // (other items were commented in a header).
       
   750 // ---------------------------------------------------------
       
   751 //
       
   752 void CXnTextAdapter::SizeChanged()
       
   753     {
       
   754     TRAP_IGNORE( SizeChangedL() );
       
   755     }
       
   756     
       
   757  // ---------------------------------------------------------
       
   758 // CXnTextAdapter::SizeChangedL()
       
   759 // ---------------------------------------------------------
       
   760 //
       
   761 void CXnTextAdapter::SizeChangedL()
       
   762     {
       
   763     if( SetTextPropertiesL( iNode ) )
       
   764         {
       
   765         iFlags |= XnText::KConstructText;
       
   766         }
       
   767     
       
   768     TRect rect( iNode.Rect() );
       
   769 
       
   770     TRect labelRect( iLabel->Rect() );
       
   771     iLabel->SetRect( rect );
       
   772     
       
   773     if( iText )
       
   774         {
       
   775     	TInt textWidth( iLabel->Font()->TextWidthInPixels( *iText ) );
       
   776            
       
   777         TInt rectWidth( rect.Width() );
       
   778                 
       
   779         if( iFlags & XnText::KOverflowVisible ) 
       
   780             {            
       
   781             TBool isTooltip( iNode.ParentL()->Type()->Type() == XnText::tooltip );
       
   782 
       
   783             // Tooltip can grow and shrink, others just grow                        
       
   784             if( isTooltip || textWidth > rectWidth ) 
       
   785                 {    
       
   786                 rect = Rect();
       
   787                                         
       
   788                 TInt dx( textWidth - rectWidth );
       
   789                                                                                                                         
       
   790                 if( dx != 0 )
       
   791                     {                
       
   792                     rect.Resize( dx, 0 );
       
   793                     SetSizeWithoutNotification( rect.Size() );                                                                
       
   794 
       
   795                     // Update                 
       
   796                     iLabel->SetRect( rect );                               
       
   797                     }                       
       
   798                 }
       
   799             }            
       
   800         }
       
   801     if( labelRect != iLabel->Rect() )
       
   802     	{
       
   803         iFlags |= XnText::KConstructText;
       
   804     	}
       
   805     }
       
   806 
       
   807 // ---------------------------------------------------------
       
   808 // CXnTextAdapter::SkinChanged()
       
   809 // Called by framework when the skin is changed
       
   810 // (other items were commented in a header).
       
   811 // ---------------------------------------------------------
       
   812 //
       
   813 void CXnTextAdapter::SkinChanged()
       
   814     {    
       
   815     TRAP_IGNORE
       
   816         ( 
       
   817         if( SetTextPropertiesL( iNode ) )
       
   818             {
       
   819             iFlags |= XnText::KConstructText;
       
   820             }
       
   821         );    
       
   822     }
       
   823 
       
   824 // -----------------------------------------------------------------------------
       
   825 // CXnTextAdapter::Draw
       
   826 // Draws the text component
       
   827 // -----------------------------------------------------------------------------
       
   828 //
       
   829 void CXnTextAdapter::Draw(const TRect& aRect) const
       
   830     {   
       
   831     CXnTextAdapter* adapter = const_cast< CXnTextAdapter* >( this );
       
   832 
       
   833     if( iFlags & XnText::KConstructText )
       
   834         {
       
   835         TRAPD( err, adapter->ConstructTextL() );                        
       
   836         
       
   837         adapter->iFlags &= ~XnText::KConstructText;
       
   838         
       
   839         if( err )
       
   840             {
       
   841             return;
       
   842             }
       
   843         }
       
   844                                
       
   845     CXnControlAdapter::Draw( aRect );
       
   846     
       
   847     if( iPictographInterface )
       
   848     	{
       
   849 	    TRAP_IGNORE( UpdateBackgroundL() );
       
   850 	    iGc->BitBlt( iNode.Rect().iTl, iBackgroundBitmap );
       
   851     	}
       
   852     }
       
   853     
       
   854 // -----------------------------------------------------------------------------
       
   855 // CXnTextAdapter::DrawPictographArea
       
   856 // Draws the text component
       
   857 // -----------------------------------------------------------------------------
       
   858 //    
       
   859 void CXnTextAdapter::DrawPictographArea()
       
   860     {
       
   861     DrawNow();	
       
   862     }
       
   863 	
       
   864 // -----------------------------------------------------------------------------
       
   865 // CXnTextAdapter::UpdateBackgroundL
       
   866 // -----------------------------------------------------------------------------
       
   867 //   	
       
   868 void CXnTextAdapter::UpdateBackgroundL() const
       
   869 	{
       
   870 	CGraphicsDevice* gdevice = iGc->Device();
       
   871 	TDisplayMode displayMode = gdevice->DisplayMode();
       
   872 	
       
   873 	// create "screenshot" from the background appearance
       
   874 	if( iBackgroundBitmap )
       
   875 		{
       
   876 		delete iBackgroundBitmap;
       
   877 		iBackgroundBitmap = NULL;
       
   878 		}
       
   879 
       
   880 	iBackgroundBitmap = new (ELeave) CFbsBitmap();
       
   881 	iBackgroundBitmap->Create( iNode.Rect().Size(), displayMode );
       
   882 	CFbsBitmap* tmpBitmap = new (ELeave) CFbsBitmap;
       
   883 	CleanupStack::PushL( tmpBitmap );
       
   884 	
       
   885 	CWsScreenDevice* scrDevice = static_cast<CWsScreenDevice*>( iGc->Device() );
       
   886 	TSize tmpSize = scrDevice->SizeInPixels();
       
   887 	tmpBitmap->Create( tmpSize, displayMode );
       
   888 	
       
   889 	CFbsBitmapDevice* tmpDevice = CFbsBitmapDevice::NewL( tmpBitmap );
       
   890 	CleanupStack::PushL( tmpDevice );
       
   891 	CBitmapContext* bc( NULL );
       
   892 	tmpDevice->CreateBitmapContext( bc );
       
   893 	CleanupStack::PushL( bc );
       
   894 	DrawBackground( iNode.Rect(), reinterpret_cast<CWindowGc&>( *bc ) );
       
   895 	CopyBitmapData( *iBackgroundBitmap, *tmpBitmap, iNode.Rect().iTl );
       
   896 	CleanupStack::PopAndDestroy( 3 );
       
   897 	}
       
   898 	
       
   899 // -----------------------------------------------------------------------------
       
   900 // CXnTextAdapter::DrawBackground
       
   901 // -----------------------------------------------------------------------------
       
   902 //   	
       
   903 void CXnTextAdapter::DrawBackground(const TRect& aRect, CWindowGc& aGc) const
       
   904 	{
       
   905 	RPointerArray<CXnControlAdapter> adapters;
       
   906 
       
   907 	for( CXnNodePluginIf* node = &iNode; node; )
       
   908 		{
       
   909         TRAP_IGNORE( 
       
   910 		    CXnControlAdapter* adapter( node->Control() );
       
   911 
       
   912 		    if ( adapter )
       
   913     		    {
       
   914 	    	    adapters.AppendL( adapter );  
       
   915 		        }
       
   916 
       
   917 		    node = node->ParentL()
       
   918 		    );
       
   919         }
       
   920 
       
   921     for( TInt i = adapters.Count() - 1; i >= 0; --i )
       
   922         {
       
   923         adapters[i]->Draw( aRect, aGc );
       
   924         }
       
   925 
       
   926     adapters.Reset();
       
   927 	}    
       
   928 
       
   929 // -----------------------------------------------------------------------------
       
   930 // CXnTextAdapter::MeasureAdaptiveContentL
       
   931 // -----------------------------------------------------------------------------
       
   932 // 
       
   933 TSize CXnTextAdapter::MeasureAdaptiveContentL( const TSize& aAvailableSize )
       
   934     {         
       
   935     TSize size;
       
   936     
       
   937     if( ( aAvailableSize.iWidth > 0 ) && ( aAvailableSize.iHeight > 0 ) )
       
   938         {  
       
   939         size = MeasureTextL( aAvailableSize );           
       
   940         }
       
   941         
       
   942     return size;
       
   943     }
       
   944 
       
   945 // -----------------------------------------------------------------------------
       
   946 // CXnTextAdapter::RestrictSizeL
       
   947 // -----------------------------------------------------------------------------
       
   948 //     
       
   949 TInt CXnTextAdapter::RestrictSizeL()
       
   950     {        
       
   951     CXnNodePluginIf* parent( iNode.ParentL() );
       
   952     
       
   953     if( !parent )
       
   954         {
       
   955         // No parent where to restrict own size
       
   956         return iFlags;
       
   957         }
       
   958        
       
   959     TRect parentRect( parent->Rect() );
       
   960     
       
   961     if( parentRect.IsEmpty() )
       
   962         {
       
   963         return iFlags;
       
   964         }
       
   965     
       
   966     TRect rect( Rect() );
       
   967     
       
   968     TInt dx( 0 );
       
   969     TInt dy( 0 );
       
   970             
       
   971     // Restrict own size inside parent rect to prevent flowing outside parent's rect
       
   972     if( rect.iBr.iX > parentRect.iBr.iX )
       
   973         {
       
   974         dx = rect.iBr.iX - parentRect.iBr.iX;       
       
   975         }
       
   976         
       
   977     if( rect.iBr.iY > parentRect.iBr.iY )
       
   978         {
       
   979         dy = rect.iBr.iY - parentRect.iBr.iY;
       
   980         }
       
   981 
       
   982     if( dx == 0 && dy == 0 )
       
   983         {
       
   984         // No need to change sizes
       
   985         return iFlags;
       
   986         }
       
   987                 
       
   988     TInt flags( iFlags );
       
   989     
       
   990     if( parent->Type()->Type() == XnText::tooltip )
       
   991         {
       
   992         // Remove temporarily to allow tooltip truncation
       
   993         flags &= ~XnText::KOverflowVisible;
       
   994         }
       
   995     
       
   996     // Clip text again, parent size restriction may result in re-clipping    
       
   997     if( !IsBitSet( XnText::KOverflowVisible, flags ) )
       
   998         {
       
   999         TSize size( rect.Size() );
       
  1000         
       
  1001         size.iWidth -= dx;
       
  1002         size.iHeight -= dy;
       
  1003         
       
  1004         // Update own size ...    
       
  1005         SetSizeWithoutNotification( size );
       
  1006 
       
  1007         // ... and label        
       
  1008         rect = iLabel->Rect();
       
  1009         
       
  1010         rect.Resize( -dx, -dy );
       
  1011             
       
  1012         iLabel->SetRect( rect );               
       
  1013         }
       
  1014         
       
  1015     return flags;                                
       
  1016     }
       
  1017         
       
  1018 // -----------------------------------------------------------------------------
       
  1019 // CXnTextAdapter::SetLineSpacingL
       
  1020 // -----------------------------------------------------------------------------
       
  1021 //     
       
  1022 void CXnTextAdapter::SetLineSpacingL( TInt aReference )
       
  1023     {
       
  1024     // Set linespacing, one pixel is the default
       
  1025     TInt lineSpace( 1 );
       
  1026     
       
  1027     CXnProperty* lineSpaceProp( 
       
  1028         iNode.GetPropertyL( XnPropertyNames::appearance::common::KFontLineSpace ) );
       
  1029 
       
  1030     if( lineSpaceProp )
       
  1031         {        
       
  1032         lineSpace = iNode.UiEngineL()->VerticalPixelValueL( lineSpaceProp, aReference );
       
  1033         }
       
  1034         
       
  1035     if( lineSpace < 1 )
       
  1036         {
       
  1037         // Must be at least 1
       
  1038         lineSpace = 1;
       
  1039         }
       
  1040 
       
  1041     const CAknLayoutFont* layoutFont( CAknLayoutFont::AsCAknLayoutFontOrNull( iFont ) );         
       
  1042         
       
  1043     if( layoutFont )
       
  1044         {
       
  1045         TInt textPaneHeight = layoutFont->TextPaneHeight();
       
  1046         
       
  1047         lineSpace += ( textPaneHeight - iFont->HeightInPixels() );        
       
  1048         }
       
  1049     /* end of CEikLabel fix */        
       
  1050     
       
  1051     iLabel->SetPixelGapBetweenLines( lineSpace );   
       
  1052     }
       
  1053 
       
  1054 // -----------------------------------------------------------------------------
       
  1055 // MeasureTextL
       
  1056 // Measures the text dimensions fitted to available size
       
  1057 // -----------------------------------------------------------------------------
       
  1058 //    
       
  1059 TSize CXnTextAdapter::MeasureTextL( const TSize& aAvailableSize )    
       
  1060     {
       
  1061     TSize size;
       
  1062     
       
  1063     if( !iText || *iText == KNullDesC )
       
  1064         {
       
  1065         return size;
       
  1066         }
       
  1067                                               
       
  1068     // Save the current text before measure
       
  1069     HBufC* original( iLabel->Text()->AllocLC() );
       
  1070 
       
  1071     SetLineSpacingL( 0 );
       
  1072                                                                                                                                                       
       
  1073     SetLabelTextL( *iLabel, *iText, aAvailableSize.iWidth, iMaxLines, iFlags, ETrue );
       
  1074     
       
  1075     TPtrC text( *iLabel->Text() );
       
  1076                     
       
  1077     // help CEikLabel to calculate its content size more precisely
       
  1078     iLabel->iMargin.iBottom = iLabel->Font()->DescentInPixels();
       
  1079 
       
  1080     // Get the size needed for the text                        
       
  1081     size = iLabel->CalcMinimumSize( text );            
       
  1082     
       
  1083     // Restore original text
       
  1084     iLabel->SetTextL( *original );
       
  1085     CleanupStack::PopAndDestroy( original );        
       
  1086            
       
  1087     return size;                            	                  
       
  1088     }
       
  1089 
       
  1090 // -----------------------------------------------------------------------------
       
  1091 // UpdateTextL
       
  1092 // -----------------------------------------------------------------------------
       
  1093 //    
       
  1094 void CXnTextAdapter::UpdateTextL( const TDesC8& aText )
       
  1095     {
       
  1096     HBufC* text( CnvUtfConverter::ConvertToUnicodeFromUtf8L( aText ) );
       
  1097     
       
  1098     CleanupStack::PushL( text );
       
  1099     
       
  1100     UpdateTextL( text );
       
  1101     
       
  1102     CleanupStack::PopAndDestroy( text );
       
  1103     }
       
  1104 
       
  1105 // -----------------------------------------------------------------------------
       
  1106 // UpdateTextL
       
  1107 // -----------------------------------------------------------------------------
       
  1108 //    
       
  1109 void CXnTextAdapter::UpdateTextL( const TDesC* aText )
       
  1110     {
       
  1111     if( aText )
       
  1112         {
       
  1113         if( iText && *iText == *aText )
       
  1114             {
       
  1115             // New text is same as current
       
  1116             return;
       
  1117             }
       
  1118             
       
  1119         if( iText && iText->Des().MaxLength() >= aText->Length() )
       
  1120             {
       
  1121             // New text fits to earlier allocated space
       
  1122             *iText = *aText;
       
  1123             }
       
  1124         else
       
  1125             {
       
  1126             // Need to reserve space for new text
       
  1127             delete iText;
       
  1128             iText = NULL;
       
  1129             iText = aText->AllocL();
       
  1130             }            
       
  1131            
       
  1132     	TPtr ptr( iText->Des() );
       
  1133     	
       
  1134     	CXnUtils::CollapseWhiteSpace( iNode, ptr );	             
       
  1135             
       
  1136         iFlags |= XnText::KConstructText;
       
  1137         
       
  1138         iNode.SetDirtyL();
       
  1139         
       
  1140         const TDesC8& parentType( iNode.ParentL()->Type()->Type() );
       
  1141         
       
  1142         if( parentType == XnText::tooltip )
       
  1143         	{
       
  1144         	// Force tooltip text size to be recalculted by layout algorithm
       
  1145         	SetSizeWithoutNotification( TSize() );
       
  1146         	}
       
  1147         else if( parentType == XnText::clock )
       
  1148             {
       
  1149             iNode.ParentL()->SetDirtyL();
       
  1150             }
       
  1151         }
       
  1152     }
       
  1153 
       
  1154 // End of file
       
  1155