uifw/AvKon/src/eikfrlb.cpp
changeset 0 2f259fa3e83a
child 4 8ca85d2f0db7
equal deleted inserted replaced
-1:000000000000 0:2f259fa3e83a
       
     1 /*
       
     2 * Copyright (c) 2002-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 * Description: 
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 #include <eikfrlb.h>
       
    20 #include <barsread.h>
       
    21 #include <gulicon.h>
       
    22 #include <AknUtils.h>
       
    23 #include <AknsControlContext.h>
       
    24 #include <AknBidiTextUtils.h>
       
    25 #include <aknlists.h>
       
    26 #include <aknlayoutscalable_avkon.cdl.h>
       
    27 
       
    28 #include <AknTasHook.h>
       
    29 #ifdef RD_UI_TRANSITION_EFFECTS_LIST
       
    30 #include <aknlistloadertfx.h>
       
    31 #include <aknlistboxtfxinternal.h>
       
    32 #include <aknlistboxtfx.h>
       
    33 #endif //RD_UI_TRANSITION_EFFECTS_LIST
       
    34 
       
    35 #ifdef RD_UI_TRANSITION_EFFECTS_POPUPS
       
    36 #include <akntransitionutils.h>
       
    37 #endif
       
    38 
       
    39 #include "akntrace.h"
       
    40 
       
    41 _LIT(KMarkReplacementString, "%S");
       
    42 //
       
    43 // CFormattedCellListBoxItemDrawer
       
    44 //
       
    45 
       
    46 EXPORT_C 
       
    47 CFormattedCellListBoxItemDrawer::CFormattedCellListBoxItemDrawer(MTextListBoxModel* aTextListBoxModel, 
       
    48                                  const CFont* aFont, 
       
    49                                  CFormattedCellListBoxData* aFormattedCellData)
       
    50     : CTextListItemDrawer(aTextListBoxModel, aFont)
       
    51     {
       
    52     _AKNTRACE_FUNC_ENTER;
       
    53     SetData(aFormattedCellData);
       
    54     _AKNTRACE_FUNC_EXIT;
       
    55     }
       
    56 
       
    57 EXPORT_C 
       
    58 CFormattedCellListBoxItemDrawer::~CFormattedCellListBoxItemDrawer()
       
    59     {   
       
    60     _AKNTRACE_FUNC_ENTER;
       
    61     delete iPropertyArray;
       
    62     _AKNTRACE_FUNC_EXIT;
       
    63     }
       
    64 
       
    65 EXPORT_C CFormattedCellListBoxData* 
       
    66 CFormattedCellListBoxItemDrawer::FormattedCellData() const
       
    67     {
       
    68     return STATIC_CAST(CFormattedCellListBoxData*,iData);
       
    69     }
       
    70 EXPORT_C CFormattedCellListBoxData* 
       
    71 CFormattedCellListBoxItemDrawer::ColumnData() const
       
    72     {
       
    73     return STATIC_CAST(CFormattedCellListBoxData*,iData);
       
    74     }
       
    75 
       
    76 
       
    77 EXPORT_C void CFormattedCellListBoxView::DrawEmptyList(const TRect &aClientRect) const 
       
    78     {
       
    79     _AKNTRACE_FUNC_ENTER;    
       
    80     if ( RedrawDisabled() || !IsVisible() )
       
    81         {
       
    82         _AKNTRACE( "[%s][%s] RedrawDisabled or view invisible","CFormattedCellListBoxView",__FUNCTION__);
       
    83         _AKNTRACE_FUNC_EXIT;
       
    84         return;
       
    85         }
       
    86 
       
    87 #ifdef RD_UI_TRANSITION_EFFECTS_POPUPS
       
    88     CWindowGc* systemGc = ( CWindowGc* )CAknTransitionUtils::GetData( ( TInt )this );
       
    89     AknDrawWithSkins::DrawEmptyList( aClientRect,
       
    90                                      systemGc ? *systemGc : *iGc,
       
    91                                      *EmptyListText(),
       
    92                                      ((CFormattedCellListBoxItemDrawer*)ItemDrawer())->FormattedCellData()->Control() );
       
    93 #else
       
    94     AknDrawWithSkins::DrawEmptyList( aClientRect,
       
    95                                      *iGc,
       
    96                                      *EmptyListText(),
       
    97                                      ((CFormattedCellListBoxItemDrawer*)ItemDrawer())->FormattedCellData()->Control() );
       
    98 #endif
       
    99     _AKNTRACE_FUNC_EXIT;
       
   100     }
       
   101 
       
   102 EXPORT_C void CFormattedCellListBoxView::CalcBottomItemIndex()
       
   103     {
       
   104     CListBoxView::CalcBottomItemIndex();
       
   105 
       
   106     CFormattedCellListBoxItemDrawer* itemDrawer = 
       
   107         STATIC_CAST(CFormattedCellListBoxItemDrawer*,iItemDrawer);
       
   108     if (itemDrawer && itemDrawer->FormattedCellData() &&
       
   109         itemDrawer->FormattedCellData()->Control())
       
   110         {
       
   111         CEikFormattedCellListBox* listbox = STATIC_CAST(CEikFormattedCellListBox*, 
       
   112             itemDrawer->FormattedCellData()->Control());
       
   113         listbox->SetIconSizes();
       
   114         }
       
   115 
       
   116     // The next piece of code removes filtering from find box when
       
   117     // new list items are added.
       
   118     if (Flags() & CListBoxView::EItemCountModified)
       
   119     {
       
   120     CAknFilteredTextListBoxModel *model = STATIC_CAST(CAknFilteredTextListBoxModel*,iModel);
       
   121     CAknListBoxFilterItems *filter = model ? model->Filter() : 0;
       
   122     if (filter) 
       
   123         {
       
   124         TRAP_IGNORE(filter->ResetFilteringL());
       
   125         }
       
   126     }
       
   127     }
       
   128 
       
   129 EXPORT_C TAny* CFormattedCellListBoxView::Reserved_1()
       
   130     {
       
   131     return NULL;
       
   132     }
       
   133 
       
   134 EXPORT_C void
       
   135 CFormattedCellListBoxItemDrawer::DrawEmptyItem( TInt /*aItemIndex*/,
       
   136                                                 TPoint aItemRectPos,
       
   137                                                 TBool /*aViewIsDimmed*/ ) const
       
   138     {
       
   139     _AKNTRACE_FUNC_ENTER;
       
   140 #ifdef RD_UI_TRANSITION_EFFECTS_LIST
       
   141     MAknListBoxTfxInternal* transApi = CAknListLoader::TfxApiInternal( iGc );
       
   142     if ( transApi )
       
   143         {
       
   144         transApi->StartDrawing( MAknListBoxTfxInternal::EListView );
       
   145         }
       
   146 #endif //RD_UI_TRANSITION_EFFECTS_LIST
       
   147     TRect r( aItemRectPos, iItemCellSize );
       
   148     CCoeControl* control = FormattedCellData()->Control();
       
   149     
       
   150     const MCoeControlBackground* backgroundDrawer = control->FindBackground();
       
   151     
       
   152     if ( control )
       
   153         {
       
   154         MAknsControlContext *cc = AknsDrawUtils::ControlContext( control );
       
   155 
       
   156         if ( !cc )
       
   157             {
       
   158             cc = FormattedCellData()->SkinBackgroundContext();
       
   159             }
       
   160 
       
   161         if ( backgroundDrawer )
       
   162             {
       
   163             backgroundDrawer->Draw( *iGc, *control, r );
       
   164             }
       
   165         else if ( CAknEnv::Static()->TransparencyEnabled() )
       
   166             {
       
   167             AknsDrawUtils::Background( AknsUtils::SkinInstance(), cc, control, *iGc, r,
       
   168                                    KAknsDrawParamNoClearUnderImage );
       
   169             }
       
   170         else
       
   171             {
       
   172             AknsDrawUtils::Background( AknsUtils::SkinInstance(), cc, control, *iGc, r,
       
   173                                    KAknsDrawParamNoClearUnderImage |
       
   174                                    KAknsDrawParamBottomLevelRGBOnly );
       
   175             }
       
   176         }
       
   177     else
       
   178         {
       
   179         iGc->Clear( r );
       
   180         }
       
   181 #ifdef RD_UI_TRANSITION_EFFECTS_LIST
       
   182     if ( transApi )
       
   183         {
       
   184         transApi->StopDrawing();
       
   185         }
       
   186 #endif //RD_UI_TRANSITION_EFFECTS_LIST
       
   187     _AKNTRACE_FUNC_EXIT;
       
   188     }
       
   189 
       
   190 struct TLafTable;
       
   191 const TLafTable &BgListPaneTable();
       
   192 
       
   193 EXPORT_C
       
   194 void CFormattedCellListBoxItemDrawer::DrawItemText( TInt aItemIndex,
       
   195                                                     const TRect& aItemTextRect,
       
   196                                                     TBool aItemIsCurrent,
       
   197                                                     TBool aViewIsEmphasized, 
       
   198                                                     TBool aItemIsSelected) const
       
   199     {
       
   200     _AKNTRACE_FUNC_ENTER;
       
   201 #ifdef RD_UI_TRANSITION_EFFECTS_LIST
       
   202     MAknListBoxTfxInternal* transApi = CAknListLoader::TfxApiInternal( iGc );
       
   203     if ( transApi )
       
   204         {
       
   205         transApi->StartDrawing( MAknListBoxTfxInternal::EListNotSpecified );
       
   206         }
       
   207 #endif //RD_UI_TRANSITION_EFFECTS_LIST
       
   208     iGc->SetPenColor(iTextColor);
       
   209     iGc->SetBrushColor(iBackColor);
       
   210 
       
   211     TPtrC temp=iModel->ItemText(aItemIndex);
       
   212 
       
   213     SetupGc(aItemIndex);
       
   214 #ifdef RD_UI_TRANSITION_EFFECTS_LIST
       
   215     if ( transApi )
       
   216         {
       
   217         transApi->StopDrawing();
       
   218         }
       
   219 #endif //RD_UI_TRANSITION_EFFECTS_LIST
       
   220 
       
   221     TBool removeicon = (!aItemIsSelected && !ItemMarkReverse()) || (aItemIsSelected && ItemMarkReverse());
       
   222 
       
   223     CFormattedCellListBoxData::TColors colors;
       
   224     colors.iText=iTextColor;
       
   225     colors.iBack=iBackColor;
       
   226     colors.iHighlightedText=iHighlightedTextColor;
       
   227     colors.iHighlightedBack=iHighlightedBackColor;
       
   228 
       
   229     DrawBackgroundAndSeparatorLines( aItemTextRect );
       
   230    
       
   231     TBool highlightShown = ETrue;
       
   232     
       
   233     if (FormattedCellData()->RespectFocus() && !aViewIsEmphasized)
       
   234         {
       
   235 #ifdef RD_UI_TRANSITION_EFFECTS_LIST
       
   236         if ( transApi )
       
   237             {
       
   238             transApi->Remove( MAknListBoxTfxInternal::EListHighlight );
       
   239             }
       
   240 #endif //RD_UI_TRANSITION_EFFECTS_LIST
       
   241 
       
   242         highlightShown = EFalse;
       
   243         }
       
   244         
       
   245     if (FormattedCellData()->IsMarqueeOn() && FormattedCellData()->CurrentMarqueeItemIndex() != aItemIndex && aItemIsCurrent)
       
   246         {
       
   247         FormattedCellData()->ResetMarquee();
       
   248         FormattedCellData()->SetCurrentMarqueeItemIndex(aItemIndex);
       
   249         }
       
   250     
       
   251     if ( aItemIsCurrent )
       
   252         {
       
   253         FormattedCellData()->SetCurrentItemIndex( aItemIndex );
       
   254         }
       
   255         
       
   256     FormattedCellData()->SetCurrentlyDrawnItemIndex( aItemIndex );
       
   257     
       
   258     // drawing with mark icon
       
   259     if ( Flags() & EDrawMarkSelection && ItemMarkPosition() != -1 && removeicon)
       
   260         {
       
   261         // Try to allocate buffer dynamically. If out of memory, just use normal drawing
       
   262         // without mark icon.
       
   263         // (+2 is for the possible 2 additional column separators)
       
   264         TPtrC repl;
       
   265         repl.Set( ItemMarkReplacement() );        
       
   266         TInt size = temp.Length() + repl.Length() + 2;
       
   267         //TBufC<KMaxTotalDataLength> target(KNullDesC);
       
   268         HBufC* buffer = HBufC::New( size );
       
   269 
       
   270         if( buffer )
       
   271             {
       
   272             TPtr des = buffer->Des();
       
   273             TInt markPos = ItemMarkPosition(); // -1 if not set
       
   274             TInt startPos(0);
       
   275             TInt endPos(0);
       
   276             
       
   277             while( endPos < temp.Length() && markPos >= 0 )
       
   278                 {
       
   279                 if( temp[endPos] == '\t' )
       
   280                     {
       
   281                     markPos--;
       
   282                     if( markPos == 0 )
       
   283                         {
       
   284                         startPos = endPos + 1; // +1 for column separator
       
   285                         }
       
   286                     }
       
   287                 endPos++;
       
   288                 }
       
   289 
       
   290             if( markPos > 0 ) // mark icon will go somewhere after item string...
       
   291                 {
       
   292                 startPos = temp.Length();
       
   293                 endPos = temp.Length();
       
   294                 des.Append( temp.Left( startPos ) ); // first part of string
       
   295                 des.Append( '\t' ); // column separator before mark icon was missing                
       
   296                 }
       
   297             else
       
   298                 {
       
   299                 des.Append( temp.Left( startPos ) ); // first part of string
       
   300                 }
       
   301 
       
   302             TInt replace = repl.FindF(KMarkReplacementString);
       
   303             if (replace != KErrNotFound) // moving subcell
       
   304                 {
       
   305                 des.Append( repl.Left( replace ) );
       
   306                 // now we have first part of string + mark subcell
       
   307                 // then add 1 moved subcell
       
   308                 des.Append( temp.Mid( startPos, endPos-startPos ) );
       
   309 
       
   310                 // skip second moved subcell and add rest of the string
       
   311                 while( endPos < temp.Length() )
       
   312                     {
       
   313                     if( temp[endPos] == '\t' )
       
   314                         {
       
   315                         break;
       
   316                         }
       
   317                     endPos++;
       
   318                     }
       
   319                 if( endPos < temp.Length() ) // this cuts off '\t'
       
   320                     {
       
   321                     endPos++;
       
   322                     }
       
   323                 des.Append( temp.Mid( endPos ) );
       
   324                 
       
   325                 //is this needed - currently not used in S60?
       
   326                 //buffer.Append(aReplacement->Mid(replace+2)); // 2 == length of %s
       
   327                 }
       
   328             else // just replacement
       
   329                 {
       
   330                 des.Append( repl ); // no '%s' in replacement string
       
   331                 des.Append( '\t' );
       
   332                 des.Append( temp.Mid( endPos ) );
       
   333                 }
       
   334 
       
   335             des.Set( buffer->Des() );
       
   336             FormattedCellData()->Draw( Properties(aItemIndex),
       
   337                                        *iGc,
       
   338                                        &des,
       
   339                                        aItemTextRect,
       
   340                                        aItemIsCurrent && highlightShown,
       
   341                                        colors );
       
   342             delete buffer;
       
   343             return;
       
   344             }
       
   345         }
       
   346 
       
   347     // normal drawing without mark icon
       
   348     FormattedCellData()->Draw( Properties(aItemIndex),
       
   349                                *iGc,
       
   350                                &temp,
       
   351                                aItemTextRect,
       
   352                                aItemIsCurrent && highlightShown,
       
   353                                colors );
       
   354     _AKNTRACE_FUNC_EXIT;
       
   355     }
       
   356 
       
   357 EXPORT_C TSize 
       
   358 CFormattedCellListBoxItemDrawer::MinimumCellSize() const 
       
   359     {
       
   360     CFormattedCellListBoxData* data=FormattedCellData();
       
   361     const TInt cells=data->LastSubCell();
       
   362     if (cells==-1)
       
   363         return CTextListItemDrawer::MinimumCellSize();
       
   364     TInt width=0;
       
   365     TInt height=0;
       
   366     for(TInt ii=0;ii<cells;ii++) 
       
   367         {
       
   368         TPoint endpos( data->SubCellPosition(ii) + data->SubCellSize(ii) );
       
   369         if (endpos.iX > width) width = endpos.iX;
       
   370         if (endpos.iY > height) height = endpos.iY;
       
   371         }
       
   372     height+=VerticalInterItemGap();
       
   373     return TSize(width,height);
       
   374     }
       
   375 
       
   376 
       
   377 EXPORT_C void CFormattedCellListBoxItemDrawer::DrawItemMark(TBool /*aItemIsSelected*/, TBool /*aViewIsDimmed*/, const TPoint& /*aMarkPos*/) const
       
   378     {
       
   379     }
       
   380 
       
   381 
       
   382 EXPORT_C TInt 
       
   383 CFormattedCellListBoxItemDrawer::ItemWidthInPixels(TInt) const
       
   384     {
       
   385     TInt itemWidth = MinimumCellSize().iWidth;
       
   386     
       
   387     if (iDrawMark)
       
   388         itemWidth += (iMarkColumnWidth + iMarkGutter);
       
   389     return itemWidth;
       
   390     }
       
   391 
       
   392 EXPORT_C void CFormattedCellListBoxItemDrawer::SetItemCellSize(
       
   393     const TSize& aSizeInPixels )
       
   394     {
       
   395     CTextListItemDrawer::SetItemCellSize( aSizeInPixels );
       
   396 
       
   397     // Data needs the cell size to create/reconfigure highlight animations
       
   398     FormattedCellData()->SetItemCellSize( iItemCellSize );
       
   399     }
       
   400 
       
   401 EXPORT_C void CFormattedCellListBoxItemDrawer::SetTopItemIndex(TInt aTop)
       
   402     {
       
   403     iTopItemIndex = aTop;
       
   404     }
       
   405 
       
   406 void 
       
   407 CFormattedCellListBoxItemDrawer::DrawCurrentItemRect(const TRect& aRect) const
       
   408     {
       
   409     _AKNTRACE_FUNC_ENTER;    
       
   410     iGc->SetClippingRect(iViewRect);
       
   411     iGc->SetBrushStyle(CGraphicsContext::ENullBrush);
       
   412     iGc->SetPenColor(iHighlightedBackColor);
       
   413     iGc->DrawRect(aRect);
       
   414     iGc->CancelClippingRect();
       
   415     _AKNTRACE_FUNC_EXIT;
       
   416     }
       
   417 
       
   418 
       
   419 //
       
   420 // CEikFormattedCellListBox
       
   421 //
       
   422 
       
   423 EXPORT_C 
       
   424 CEikFormattedCellListBox::CEikFormattedCellListBox()
       
   425     {
       
   426     AKNTASHOOK_ADD( this, "CEikFormattedCellListBox" );
       
   427     }
       
   428 
       
   429 EXPORT_C void 
       
   430 CEikFormattedCellListBox::ConstructFromResourceL(TResourceReader& aReader)
       
   431     {
       
   432     RestoreCommonListBoxPropertiesL(aReader);   
       
   433     iRequiredCellCharWidth=aReader.ReadInt16();
       
   434 
       
   435     iModel=new(ELeave) CAknFilteredTextListBoxModel;
       
   436     TInt array_id=aReader.ReadInt32();
       
   437     if (!array_id)
       
   438         {
       
   439         ((CTextListBoxModel*)iModel)->ConstructL();
       
   440         }
       
   441     else
       
   442         {
       
   443         CDesCArray* desArray=iCoeEnv->ReadDesCArrayResourceL(array_id);
       
   444         CleanupStack::PushL(desArray);
       
   445 
       
   446         ((CTextListBoxModel*)iModel)->ConstructL(desArray);
       
   447         CleanupStack::Pop();
       
   448         }
       
   449     CreateItemDrawerL();
       
   450     iItemDrawer->SetDrawMark(EFalse);
       
   451 
       
   452     EnableExtendedDrawingL();
       
   453 
       
   454     ((CFormattedCellListBoxItemDrawer*)iItemDrawer)->SetCellWidthInChars(iRequiredCellCharWidth);
       
   455     CreateViewL();
       
   456     }
       
   457 
       
   458 EXPORT_C void 
       
   459 CEikFormattedCellListBox::ConstructL(const CCoeControl* aParent, 
       
   460                     TInt aFlags)
       
   461     {
       
   462     CAknFilteredTextListBoxModel* model=new(ELeave) CAknFilteredTextListBoxModel;
       
   463     iModel=model;
       
   464     model->ConstructL();
       
   465     CreateItemDrawerL();
       
   466 
       
   467     EnableExtendedDrawingL();
       
   468 
       
   469     iItemDrawer->SetDrawMark(EFalse);
       
   470     CEikListBox::ConstructL(aParent,aFlags);
       
   471     }
       
   472 
       
   473 EXPORT_C CTextListBoxModel* 
       
   474 CEikFormattedCellListBox::Model() const
       
   475     {
       
   476     return(CTextListBoxModel*)iModel;
       
   477     }
       
   478 
       
   479 EXPORT_C CFormattedCellListBoxItemDrawer* 
       
   480 CEikFormattedCellListBox::ItemDrawer() const
       
   481     {
       
   482     return(CFormattedCellListBoxItemDrawer*)iItemDrawer;
       
   483     }
       
   484 
       
   485 EXPORT_C void CEikFormattedCellListBox::UseLogicalToVisualConversion(
       
   486     TBool aUseConversion )
       
   487     {
       
   488     static_cast<CFormattedCellListBoxItemDrawer*>( iItemDrawer )->
       
   489         FormattedCellData()->UseLogicalToVisualConversion(
       
   490             aUseConversion );
       
   491     }
       
   492 
       
   493 /**
       
   494 * Note that it must be possible to call this method multiple times.
       
   495 */
       
   496 EXPORT_C void CEikFormattedCellListBox::EnableExtendedDrawingL()
       
   497     {
       
   498     // Assert that the item drawer has been created before calling this method.
       
   499     __ASSERT_DEBUG( ItemDrawer() && ItemDrawer()->FormattedCellData(),
       
   500         Panic( EAknPanicListBoxItemDrawerNotCreated ) );
       
   501 
       
   502     CFormattedCellListBoxData* data = ItemDrawer()->FormattedCellData();
       
   503 
       
   504     data->SetControl( this );
       
   505     // Can be created only after the control has been set.
       
   506     data->CreatePictographInterfaceL();
       
   507     // Can be created only after the control has been set.
       
   508     data->CreateMarqueeControlL();
       
   509     }
       
   510 
       
   511 #ifdef RD_LIST_STRETCH
       
   512 EXPORT_C void CEikFormattedCellListBox::EnableStretching( const TBool aEnabled )
       
   513     {
       
   514     if ( ItemDrawer()->FormattedCellData()->StretchingEnabled() != aEnabled )
       
   515         {
       
   516         ItemDrawer()->FormattedCellData()->EnableStretching( aEnabled );
       
   517         SizeChanged();
       
   518         }
       
   519     }
       
   520 #else
       
   521 EXPORT_C void CEikFormattedCellListBox::EnableStretching( const TBool /*aEnabled*/ )
       
   522     {
       
   523     }
       
   524 #endif // RD_LIST_STRETCH
       
   525 
       
   526 #ifdef RD_LIST_STRETCH
       
   527 EXPORT_C void CEikFormattedCellListBox::HideSecondRow( const TBool aHide )
       
   528     {
       
   529     if ( ItemDrawer()->FormattedCellData()->SecondRowHidden() != aHide )
       
   530         {
       
   531         ItemDrawer()->FormattedCellData()->HideSecondRow( aHide );
       
   532         SizeChanged();
       
   533         }
       
   534     }
       
   535 #else
       
   536 EXPORT_C void CEikFormattedCellListBox::HideSecondRow( const TBool /*aHide*/ )
       
   537     {
       
   538     }
       
   539 #endif // RD_LIST_STRETCH
       
   540 
       
   541 EXPORT_C void 
       
   542 CEikFormattedCellListBox::CreateItemDrawerL()
       
   543     {
       
   544     CFormattedCellListBoxData* cellData=CFormattedCellListBoxData::NewL();
       
   545     CleanupStack::PushL( cellData );
       
   546     iItemDrawer=new(ELeave) CFormattedCellListBoxItemDrawer(Model(), iEikonEnv->NormalFont(), cellData);
       
   547     CleanupStack::Pop();
       
   548     }
       
   549 
       
   550 EXPORT_C TInt CEikFormattedCellListBox::AdjustRectHeightToWholeNumberOfItems(TRect &aRect) const
       
   551     {
       
   552     TInt remainder = aRect.Height() % iItemHeight;
       
   553     aRect.iBr.iY -= remainder;
       
   554 
       
   555     return remainder;
       
   556     }
       
   557 
       
   558 EXPORT_C CListBoxView*
       
   559 CEikFormattedCellListBox::MakeViewClassInstanceL()
       
   560     {
       
   561     return (new(ELeave) CFormattedCellListBoxView);
       
   562     }
       
   563 
       
   564 EXPORT_C void CEikFormattedCellListBox::FocusChanged( TDrawNow aDrawNow )
       
   565     {
       
   566     CEikTextListBox::FocusChanged( aDrawNow );
       
   567 
       
   568     // Data needs focus change information to control animations.
       
   569     if( IsFocused() )
       
   570         {
       
   571         ItemDrawer()->FormattedCellData()->FocusGained();
       
   572         }
       
   573     else
       
   574         {
       
   575         ItemDrawer()->FormattedCellData()->FocusLost();
       
   576         }
       
   577     }
       
   578 
       
   579 EXPORT_C void 
       
   580 CEikFormattedCellListBox::GetColorUseListL(CArrayFix<TCoeColorUse>& aColorUseList) const
       
   581     {
       
   582     CEikTextListBox::GetColorUseListL(aColorUseList);
       
   583     }
       
   584 
       
   585 EXPORT_C void 
       
   586 CEikFormattedCellListBox::HandleResourceChange(TInt aType)
       
   587     {
       
   588     _AKNTRACE_FUNC_ENTER;
       
   589     if ( aType == KEikDynamicLayoutVariantSwitch )
       
   590         {
       
   591         _AKNTRACE("CEikFormattedCellListBox::HandleResourceChange type=KEikDynamicLayoutVariantSwitch");
       
   592         TRAP_IGNORE(
       
   593                ItemDrawer()->FormattedCellData()->SetupSkinContextL() );
       
   594         }
       
   595     	
       
   596     CEikTextListBox::HandleResourceChange(aType);
       
   597     ItemDrawer()->FormattedCellData()->HandleResourceChange( aType );
       
   598     _AKNTRACE_FUNC_EXIT;
       
   599     }
       
   600 
       
   601 EXPORT_C TTypeUid::Ptr CEikFormattedCellListBox::MopSupplyObject(TTypeUid aId)
       
   602     {
       
   603     if ( aId.iUid == MAknsControlContext::ETypeId )
       
   604         {
       
   605         return MAknsControlContext::SupplyMopObject(
       
   606             aId, ItemDrawer()->ColumnData()->SkinBackgroundContext() );
       
   607         }
       
   608     return CEikTextListBox::MopSupplyObject( aId );
       
   609     }
       
   610 
       
   611 // This helper function sets icon sizes for visible list items.
       
   612 void CEikFormattedCellListBox::SetIconSizes()
       
   613     {
       
   614     // No icon size setting when kinetic scrolling enabled
       
   615     if ( ItemDrawer()->ColumnData()->KineticScrollingEnabled() )
       
   616     	{
       
   617         return;    	
       
   618     	}
       
   619     // if you modify this method, check also eikclb.cpp
       
   620     if (!IsReadyToDraw())
       
   621         {
       
   622         return; // can't access listdata yet
       
   623         }
       
   624 
       
   625     TInt numOfItems = Model()->NumberOfItems();
       
   626     // we have a filtered list, and it's item count might not be correct
       
   627     // since this is called when filtered model and text list box model
       
   628     // have yet not synced their item count
       
   629     CAknListBoxFilterItems *filter = STATIC_CAST(CAknFilteredTextListBoxModel*,Model())->Filter();
       
   630     if (filter)
       
   631     //if ( Model()->MatchableTextArray() )  // read as: if ( HaveFilter() )
       
   632         {
       
   633         // so we need to use this ugly hack
       
   634         TInt n = Model()->MatchableTextArray()->MdcaCount();
       
   635         numOfItems = n > numOfItems ? numOfItems : n;
       
   636         }
       
   637 
       
   638     
       
   639     if (numOfItems == 0) // no need to parse anything
       
   640         return;
       
   641 
       
   642     CArrayPtr<CGulIcon>* icons = ItemDrawer()->FormattedCellData()->IconArray();
       
   643 
       
   644     if (!icons || icons->Count() == 0) // no icons set yet
       
   645         return;
       
   646 
       
   647     TPtrC iconText;
       
   648     TInt iconIndex;
       
   649     TSize iconSize(0,0);
       
   650 
       
   651     for (TInt row=View()->TopItemIndex(); row <= View()->BottomItemIndex(); row++)
       
   652         {
       
   653         if (row >= numOfItems)
       
   654             {
       
   655             continue; // grid may have bottomitemindex bigger than item count
       
   656             }
       
   657         const TDesC &txt = Model()->ItemText(row);
       
   658 
       
   659         for (TInt subCell=0; subCell<6; subCell++)
       
   660             {
       
   661             iconSize = ItemDrawer()->FormattedCellData()->GetSubCellIconSize(subCell);
       
   662             // only those subcells that have icons, have also icon size set
       
   663             if (iconSize.iWidth == 0 || iconSize.iHeight == 0)
       
   664                 {
       
   665                 continue; // no need to set icon size
       
   666                 }
       
   667             TextUtils::ColumnText(iconText, subCell, &txt); // get icon index(text)
       
   668 
       
   669             TLex iconLex(iconText);
       
   670 
       
   671             if (iconLex.Val(iconIndex) != KErrNone)
       
   672                 {
       
   673                 iconIndex = -1;
       
   674                 }
       
   675 
       
   676             CGulIcon *icon;
       
   677             CFbsBitmap *bitmap;
       
   678             TInt realIndex;
       
   679             
       
   680             while(iconIndex >= 0)
       
   681                 {
       
   682                 if (iconIndex > 0xffff)
       
   683                     {
       
   684                     realIndex = iconIndex >> 16; // first set highlight icon
       
   685                     iconIndex = iconIndex & 0xffff;
       
   686                     }
       
   687                 else
       
   688                     {
       
   689                     realIndex = iconIndex;
       
   690                     iconIndex = -1;
       
   691                     }
       
   692                     
       
   693                 if ( realIndex > icons->Count() -1 )
       
   694                     {
       
   695                     break;
       
   696                     }
       
   697                 icon = (*icons)[realIndex];
       
   698                 if (!icon)
       
   699                     {
       
   700                     break;
       
   701                     }
       
   702                 bitmap = icon->Bitmap();
       
   703                 if (!bitmap)
       
   704                     {
       
   705                     break;
       
   706                     }
       
   707                 /* note, that SetSize() must be called with
       
   708                 *  EAspectRatioPreservedAndUnusedSpaceRemoved,
       
   709                 *  otherwise centering/aligning code in CColumnListBoxData::Draw()
       
   710                 *  will not work. Default EAspectRatioPreserved parameter
       
   711                 *  will fill icon with blank extra space, and icon will then
       
   712                 *  be exactly same size as space reserved for it. Extra blank
       
   713                 *  space would be added to right side of the icon.
       
   714                 */
       
   715                 AknIconUtils::SetSize( bitmap,
       
   716                                        iconSize,
       
   717                                        EAspectRatioPreservedAndUnusedSpaceRemoved );
       
   718                 }
       
   719         
       
   720             
       
   721             
       
   722             /*switch(1)
       
   723                 {
       
   724                 case 1:
       
   725                 default:
       
   726                     if ( iconIndex < 0 || iconIndex > icons->Count() -1 )
       
   727                         {
       
   728                         break;
       
   729                         }
       
   730 
       
   731                     icon = (*icons)[iconIndex];
       
   732                     if (!icon)
       
   733                         {
       
   734                         break;
       
   735                         }
       
   736             
       
   737                     bitmap = icon->Bitmap();
       
   738             
       
   739                     if (!bitmap)
       
   740                         {
       
   741                         break;
       
   742                         }*/
       
   743                     /* note, that SetSize() must be called with
       
   744                     *  EAspectRatioPreservedAndUnusedSpaceRemoved,
       
   745                     *  otherwise centering/aligning code in CColumnListBoxData::Draw()
       
   746                     *  will not work. Default EAspectRatioPreserved parameter
       
   747                     *  will fill icon with blank extra space, and icon will then
       
   748                     *  be exactly same size as space reserved for it. Extra blank
       
   749                     *  space would be added to right side of the icon.
       
   750                     */
       
   751 //                    AknIconUtils::SetSize( bitmap,
       
   752 //                                           iconSize,
       
   753 //                                           EAspectRatioPreservedAndUnusedSpaceRemoved );
       
   754 //                }
       
   755             } // end subCell for
       
   756         } // end row for
       
   757     }
       
   758 
       
   759 EXPORT_C void CEikFormattedCellListBox::HandlePointerEventL(const TPointerEvent& aPointerEvent) 
       
   760     { 
       
   761     _AKNTRACE_FUNC_ENTER;
       
   762     CEikTextListBox::HandlePointerEventL(aPointerEvent);
       
   763     _AKNTRACE_FUNC_EXIT;
       
   764     }
       
   765 
       
   766 EXPORT_C void* CEikFormattedCellListBox::ExtensionInterface( TUid /*aInterface*/ ) 
       
   767     { 
       
   768     return NULL;
       
   769     }
       
   770 
       
   771 EXPORT_C void CEikFormattedCellListBox::CEikListBox_Reserved() 
       
   772     {
       
   773     }
       
   774 
       
   775 #define ITEM_EXISTS_BEGIN TInt no_of_items__ = iModel->NumberOfItems()
       
   776 #define ITEM_EXISTS(x) (((x) > -1) && ((x) < no_of_items__))
       
   777 
       
   778 #define ITEM_EXISTS_ONCE(x) (((x) > -1) && ((x) < iModel->NumberOfItems()))
       
   779 
       
   780 EXPORT_C void
       
   781 CFormattedCellListBoxView::Draw(const TRect* clipRect) const
       
   782     {
       
   783     _AKNTRACE_FUNC_ENTER;
       
   784     if ( RedrawDisabled() || !IsVisible() )
       
   785         {
       
   786         _AKNTRACE("CFormattedCellListBoxView::Draw return because redraw disabled or invisible");
       
   787         _AKNTRACE_FUNC_EXIT;
       
   788         return;
       
   789         }
       
   790 
       
   791    if(clipRect && clipRect->IsEmpty())
       
   792         {
       
   793         _AKNTRACE("CFormattedCellListBoxView::Draw return because clip rect is empty");
       
   794         _AKNTRACE_FUNC_EXIT;
       
   795         return;
       
   796         }
       
   797                 
       
   798     TInt i = iTopItemIndex;
       
   799     CFormattedCellListBoxItemDrawer *itemDrawer = static_cast<CFormattedCellListBoxItemDrawer*>( iItemDrawer );
       
   800     MAknsSkinInstance *skin = AknsUtils::SkinInstance();
       
   801     CCoeControl* control = itemDrawer->FormattedCellData()->Control();
       
   802     MAknsControlContext *cc = AknsDrawUtils::ControlContext( control );
       
   803     
       
   804     if ( !cc )
       
   805         {
       
   806         cc = itemDrawer->FormattedCellData()->SkinBackgroundContext();
       
   807         }
       
   808     
       
   809     itemDrawer->SetTopItemIndex( iTopItemIndex );
       
   810 
       
   811     if ( iModel->NumberOfItems() > 0 )
       
   812         {
       
   813 		TBool drawingInitiated = ETrue;
       
   814 		
       
   815 #ifdef RD_UI_TRANSITION_EFFECTS_LIST
       
   816         MAknListBoxTfxInternal* transApi =
       
   817             CAknListLoader::TfxApiInternal( iGc );
       
   818 #endif // RD_UI_TRANSITION_EFFECTS_LIST
       
   819 		
       
   820 		if ( CAknEnv::Static()->TransparencyEnabled() )
       
   821 		    {
       
   822     		if ( iWin && iWin->GetDrawRect() == TRect::EUninitialized )
       
   823 	    		{
       
   824 #ifdef RD_UI_TRANSITION_EFFECTS_LIST
       
   825                 drawingInitiated = transApi && !transApi->EffectsDisabled();
       
   826 #else
       
   827                 drawingInitiated = EFalse;
       
   828 #endif
       
   829     			}
       
   830 
       
   831 	    	if ( !drawingInitiated )
       
   832 		    	{
       
   833     			iWin->Invalidate( *clipRect );
       
   834 	    		iWin->BeginRedraw( *clipRect );
       
   835 		    	}
       
   836 		    }
       
   837 
       
   838         TInt lastPotentialItemIndex = Min( iModel->NumberOfItems(), iTopItemIndex + NumberOfItemsThatFitInRect( iViewRect ) );
       
   839 
       
   840         while ( i < lastPotentialItemIndex )      
       
   841             {
       
   842 #ifdef RD_UI_TRANSITION_EFFECTS_LIST
       
   843             if ( transApi )
       
   844                 {
       
   845                 transApi->StartDrawing( MAknListBoxTfxInternal::EListNotSpecified );
       
   846                 }
       
   847 #endif // RD_UI_TRANSITION_EFFECTS_LIST
       
   848 
       
   849             iGc->SetClippingRect( iViewRect );
       
   850             
       
   851 #ifdef RD_UI_TRANSITION_EFFECTS_LIST
       
   852             if ( transApi )
       
   853                 {
       
   854                 transApi->StopDrawing();
       
   855                 }
       
   856 #endif // RD_UI_TRANSITION_EFFECTS_LIST
       
   857 
       
   858             DrawItem( i++ );
       
   859 
       
   860 #ifdef RD_UI_TRANSITION_EFFECTS_LIST
       
   861             if ( transApi )
       
   862                 {
       
   863                 transApi->StartDrawing( MAknListBoxTfxInternal::EListNotSpecified );
       
   864                 }
       
   865 #endif // RD_UI_TRANSITION_EFFECTS_LIST
       
   866 
       
   867             iGc->CancelClippingRect();
       
   868             
       
   869 #ifdef RD_UI_TRANSITION_EFFECTS_LIST
       
   870             if ( transApi )
       
   871                 {
       
   872                 transApi->StopDrawing();
       
   873                 }
       
   874 #endif // RD_UI_TRANSITION_EFFECTS_LIST
       
   875             }
       
   876 
       
   877 #ifdef RD_UI_TRANSITION_EFFECTS_LIST
       
   878         if ( transApi )
       
   879             {
       
   880             transApi->StartDrawing( MAknListBoxTfxInternal::EListView );
       
   881             }
       
   882         if ( i > iBottomItemIndex + 1 )
       
   883             {
       
   884             i = iBottomItemIndex + 1;
       
   885             }
       
   886         TRect usedPortionOfViewRect( iViewRect.iTl+TSize(0,iVerticalOffset), TSize( iViewRect.Width(), ( i - iTopItemIndex ) * iItemHeight ) );
       
   887 #else
       
   888         // clear the unused portion of the viewing area
       
   889         TRect usedPortionOfViewRect( iViewRect.iTl.iX, iViewRect.iTl.iY + iVerticalOffset, iViewRect.Width(), ItemPos( lastPotentialItemIndex ).iY );
       
   890         
       
   891         if ( clipRect )
       
   892             {
       
   893             usedPortionOfViewRect.iBr.iX = clipRect->iBr.iX;
       
   894             }
       
   895 
       
   896 #endif
       
   897 
       
   898         // also clear area behind scroll bar.
       
   899         // this is a terrible hack, which is unfortunately needed since layouts
       
   900         // leave 2 pixel (in double res) wide margins to both sides of the
       
   901         // scroll bar, and there is no other way to do this. This hack is
       
   902         // only really valid for main pane lists, but it does not seem to
       
   903         // break popup lists, popup field lists or setting page radiobutton
       
   904         // lists.
       
   905         // See also: eikslb.cpp, eikclb.cpp
       
   906         TRect sbbg( iViewRect );   // whole area behind scroll bar
       
   907         TRect margin( iViewRect ); // it gets even worse in mirrored layouts
       
   908         
       
   909         if ( AknLayoutUtils::LayoutMirrored() )
       
   910             {
       
   911             _AKNTRACE("CFormattedCellListBoxView::Draw Layout mirrored");
       
   912             sbbg.iBr.iX = iViewRect.iBr.iX - itemDrawer->LafItemSize().iWidth;
       
   913 
       
   914             // in mirrored layouts we also need to draw a margin slice in right
       
   915             TRect mainPane;
       
   916             AknLayoutUtils::LayoutMetricsRect( AknLayoutUtils::EMainPane,
       
   917                                                mainPane );
       
   918             TAknLayoutRect listscrollAppPane;
       
   919             listscrollAppPane.LayoutRect( mainPane,
       
   920                                           AknLayoutScalable_Avkon::listscroll_app_pane( 0 ) );
       
   921 
       
   922             TInt rMargin = mainPane.iBr.iX - listscrollAppPane.Rect().iBr.iX;
       
   923             margin.iTl.iX = margin.iBr.iX - rMargin;
       
   924             }
       
   925         else
       
   926             {
       
   927             sbbg.iTl.iX = iViewRect.iTl.iX + itemDrawer->LafItemSize().iWidth;
       
   928             }
       
   929         
       
   930         // Unused portion will be cleared only if listbox background is drawn.
       
   931         if ( itemDrawer->ColumnData()->IsBackgroundDrawingEnabled() ) 
       
   932             {
       
   933             if ( control )
       
   934                 {
       
   935                 if ( !control->FindBackground() )
       
   936                     {
       
   937                     AknsDrawUtils::BackgroundBetweenRects( skin, 
       
   938                                                        cc, 
       
   939                                                        control, 
       
   940                                                        *iGc, 
       
   941                                                        iViewRect, 
       
   942                                                        usedPortionOfViewRect );
       
   943 
       
   944                     AknsDrawUtils::Background( skin, cc, control, *iGc, sbbg );
       
   945                 
       
   946                     if ( AknLayoutUtils::LayoutMirrored() )
       
   947                         {
       
   948                         AknsDrawUtils::Background( skin, cc, control, *iGc, margin );
       
   949                         }
       
   950                     }
       
   951                 }
       
   952             else
       
   953                 {
       
   954                 iGc->SetBrushColor( BackColor() );
       
   955                 DrawUtils::ClearBetweenRects( *iGc, iViewRect, usedPortionOfViewRect );
       
   956                 iGc->Clear( sbbg );
       
   957                 
       
   958                 if ( AknLayoutUtils::LayoutMirrored() )
       
   959                     {
       
   960                     iGc->Clear( margin );
       
   961                     }
       
   962                 }
       
   963             }
       
   964 
       
   965 #ifdef RD_UI_TRANSITION_EFFECTS_LIST  
       
   966     if ( transApi )
       
   967         {
       
   968         transApi->StopDrawing();
       
   969         }
       
   970 #endif //RD_UI_TRANSITION_EFFECTS_LIST      
       
   971 
       
   972 
       
   973 		if ( CAknEnv::Static()->TransparencyEnabled() && !drawingInitiated )
       
   974 			{
       
   975 			iWin->EndRedraw();
       
   976 			}
       
   977         }
       
   978     _AKNTRACE_FUNC_EXIT;
       
   979     }
       
   980 
       
   981 EXPORT_C void CFormattedCellListBoxItemDrawer::ClearAllPropertiesL()
       
   982     {
       
   983     delete iPropertyArray;
       
   984     iPropertyArray = NULL;
       
   985     iPropertyArray = new (ELeave) CArrayFixFlat<SListProperties>(2);    
       
   986     }
       
   987 
       
   988 EXPORT_C void CFormattedCellListBoxItemDrawer::SetPropertiesL(TInt aItemIndex, TListItemProperties aProperty)
       
   989     {
       
   990     if (!iPropertyArray) ClearAllPropertiesL();
       
   991     TInt index;
       
   992     TKeyArrayFix key(0,ECmpTInt);
       
   993     SListProperties prop;
       
   994     prop.iItem = aItemIndex;
       
   995     TInt error = iPropertyArray->FindIsq(prop, key, index);
       
   996     if (error)
       
   997     { // not found, error is nonzero.
       
   998     iPropertyArray->InsertIsqL(prop, key);
       
   999     iPropertyArray->FindIsq(prop, key, index);
       
  1000     }
       
  1001     iPropertyArray->At(index).iProperties = aProperty;
       
  1002     }
       
  1003 
       
  1004 EXPORT_C 
       
  1005 TListItemProperties CFormattedCellListBoxItemDrawer::Properties(TInt aItemIndex) const
       
  1006     {
       
  1007 
       
  1008     if (!iPropertyArray) return CTextListItemDrawer::Properties(aItemIndex);
       
  1009     CAknListBoxFilterItems *filter = STATIC_CAST(CAknFilteredTextListBoxModel*,iModel)->Filter();
       
  1010     if (filter)
       
  1011     {
       
  1012     aItemIndex = filter->FilteredItemIndex(aItemIndex);
       
  1013     }
       
  1014     TKeyArrayFix key(0,ECmpTInt);
       
  1015     SListProperties prop;
       
  1016     prop.iItem = aItemIndex;
       
  1017     TInt index;
       
  1018     TInt error = iPropertyArray->FindIsq(prop, key, index);
       
  1019     if (error) return CTextListItemDrawer::Properties(aItemIndex);
       
  1020     return iPropertyArray->At(index).iProperties;
       
  1021     }
       
  1022 
       
  1023 
       
  1024 static TBool WasClippedHack( const TDesC& aColumntowrap,
       
  1025                              const TDesC& aWrappedText,
       
  1026                              const TDesC& aSecondLine )
       
  1027 
       
  1028     {
       
  1029     // this seems to be only way of chekcing if WrapToArrayL() clipped
       
  1030     // text or not. Unless you rewrite half of AknBidiTextUtils &&
       
  1031     // AknTextWrapper. sigh.
       
  1032     TBool clipped2( EFalse );
       
  1033     TInt len ( aColumntowrap.Length() ); // length of given text
       
  1034     TInt wl( aWrappedText.Length() ); // length of 1st + 2nd line
       
  1035     
       
  1036     // text will be wrapped at \n or ' ' and that whitespace will be
       
  1037     // discarded. a BIG assumption is made here, that there are no
       
  1038     // double spaces in item string at wrapping point. If there are,
       
  1039     // this does not work as intended.
       
  1040     len--;
       
  1041     
       
  1042     if (  len > wl ) 
       
  1043         {
       
  1044         clipped2 = ETrue;
       
  1045         }
       
  1046     else if ( len == wl )
       
  1047         {
       
  1048         // border case. Only way to check the wrapping is really to
       
  1049         // check for ellipsis... too bad that WrapToArrayL() does not
       
  1050         // return any info about clipping. Ellipsis will be either at
       
  1051         // end of the 2nd string or at start of 2nd string, if
       
  1052         // mirrored layout is used. Of course, this fails, if length
       
  1053         // is suitable and there is a ellipsis in the item string. Or
       
  1054         // if someone manages to create a item string with say arabic
       
  1055         // & latin characters in such way, that WrapToArrayL() inserts
       
  1056         // ellipsis in the middle of the string.
       
  1057         if ( aSecondLine[0] == KEllipsis || aSecondLine[aSecondLine.Length() - 1] == KEllipsis )
       
  1058             {
       
  1059             clipped2 = ETrue;
       
  1060             }
       
  1061         }
       
  1062     return clipped2;
       
  1063     }
       
  1064 
       
  1065 void
       
  1066 CFormattedCellListBoxItemDrawer::WordWrapListItem( TPtr& aTarget,
       
  1067                                                    const TDesC &aItemString,
       
  1068                                                    TInt aFirstIndex,
       
  1069                                                    TInt aSecondIndex,
       
  1070                                                    TInt aItemIndex ) const
       
  1071     {
       
  1072     TPtrC columntowrap;
       
  1073     TextUtils::ColumnText(columntowrap, aFirstIndex, &aItemString);
       
  1074 
       
  1075     if ( !columntowrap.Length() )
       
  1076         {
       
  1077         // if nothing to wrap, return string unmodified. Wrapping
       
  1078         // empty string results in chaos.
       
  1079         aTarget.Append( aItemString );
       
  1080         return;
       
  1081         }
       
  1082     
       
  1083     // Set to real values after wrapping successfully done
       
  1084     TInt firstWordWrappedSubcellIndex = -1;
       
  1085     TInt secondWordWrappedSubcellIndex = -1;
       
  1086 
       
  1087     // for informing CurrentItemTextWasClipped() about clipping performed here
       
  1088     TBool clipped1( EFalse );
       
  1089     TBool clipped2( EFalse );
       
  1090     // must be cleared, otherwize this will leave bits on
       
  1091     FormattedCellData()->SetClippedByWrap( 0, EFalse );
       
  1092 
       
  1093     // we have to adjust column widths here if there are any optional icons shown
       
  1094     TRect firstRect( FormattedCellData()->SubCellPosition(aFirstIndex),
       
  1095                      FormattedCellData()->SubCellSize(aFirstIndex) );
       
  1096     TRect secondRect( FormattedCellData()->SubCellPosition(aSecondIndex),
       
  1097                       FormattedCellData()->SubCellSize(aSecondIndex) );
       
  1098     TRect overlapRect;
       
  1099     TInt lastSC = FormattedCellData()->LastSubCell();
       
  1100 
       
  1101     TPtrC scString;
       
  1102     TBool firstClippedLeft = EFalse;
       
  1103     TBool firstClippedRight = EFalse;
       
  1104     TBool secondClippedLeft = EFalse;
       
  1105     TBool secondClippedRight = EFalse;
       
  1106 
       
  1107     // this should be rewritten for drawformatted_simple - no need to
       
  1108     // compare rects when layoutdata provides info directly.
       
  1109     // it might be possible to get rid of compabitility code in
       
  1110     // SetGraphic|Text|ConditionalSubcell then, altough
       
  1111     // some exported methods in Eikfrlbd.cpp might benefit from them
       
  1112 
       
  1113     for (TInt subCell=0; subCell <= lastSC; subCell++ )
       
  1114         {
       
  1115         TextUtils::ColumnText(scString, subCell, &aItemString);
       
  1116         if ( scString.Length()
       
  1117              && FormattedCellData()->SubCellIsNotAlwaysDrawn(subCell) )
       
  1118             {
       
  1119             // we have possible overlapping subcell, adjust both firstWidth and
       
  1120             // secondWidth accordingly
       
  1121             overlapRect.SetRect( FormattedCellData()->SubCellPosition(subCell),
       
  1122                                  FormattedCellData()->SubCellSize(subCell) );
       
  1123             if (firstRect.Intersects(overlapRect))
       
  1124                 {
       
  1125                 if ((overlapRect.iTl.iX-firstRect.iTl.iX) > (firstRect.iBr.iX-overlapRect.iBr.iX))
       
  1126                     {
       
  1127                     // overlapping rect is on the right side of first rect
       
  1128                     firstRect.iBr.iX = overlapRect.iTl.iX;
       
  1129                     firstClippedRight = ETrue;
       
  1130                     }
       
  1131                 else
       
  1132                     {
       
  1133                     // overlapping rect is on the left side of first rect
       
  1134                     firstRect.iTl.iX = overlapRect.iBr.iX;
       
  1135                     firstClippedLeft = ETrue;
       
  1136                     }
       
  1137                 }
       
  1138             if (secondRect.Intersects(overlapRect))
       
  1139                 {
       
  1140                 if ((overlapRect.iTl.iX-firstRect.iTl.iX) > (firstRect.iBr.iX-overlapRect.iBr.iX))
       
  1141                     {
       
  1142                     // overlapping rect is on the right side of second rect
       
  1143                     secondRect.iBr.iX = overlapRect.iTl.iX;
       
  1144                     secondClippedRight = ETrue;
       
  1145                     }
       
  1146                 else
       
  1147                     {
       
  1148                     // overlapping rect is on the left side of second rect
       
  1149                     secondRect.iTl.iX = overlapRect.iBr.iX;
       
  1150                     secondClippedLeft = ETrue;
       
  1151                     }
       
  1152                 }
       
  1153             }
       
  1154         else
       
  1155             {
       
  1156             continue;
       
  1157             }
       
  1158         }
       
  1159 
       
  1160     
       
  1161     TRAPD( error,
       
  1162         {
       
  1163         TPtrC firstString=columntowrap;
       
  1164         TPtrC secondString;
       
  1165         TextUtils::ColumnText(secondString, aSecondIndex, &aItemString);
       
  1166 
       
  1167         TInt firstWidth = firstRect.Width();
       
  1168         if (!firstClippedLeft)
       
  1169             {
       
  1170             firstWidth -= FormattedCellData()->SubCellMargins(aFirstIndex).iLeft;
       
  1171             }
       
  1172         if (!firstClippedRight)
       
  1173             {
       
  1174             firstWidth -= FormattedCellData()->SubCellMargins(aFirstIndex).iRight;
       
  1175             }
       
  1176 
       
  1177         TInt secondWidth = secondRect.Width();
       
  1178         if (!secondClippedLeft)
       
  1179             {
       
  1180             secondWidth -= FormattedCellData()->SubCellMargins(aSecondIndex).iLeft;
       
  1181             }
       
  1182         if (!secondClippedRight)
       
  1183             {
       
  1184             secondWidth -= FormattedCellData()->SubCellMargins(aSecondIndex).iRight;
       
  1185             }
       
  1186 
       
  1187         CArrayFixFlat<TPtrC>* resultArray = new( ELeave ) CArrayFixFlat<TPtrC>( 2 );
       
  1188         CleanupStack::PushL( resultArray );
       
  1189 
       
  1190         HBufC *wrapped = HBufC::NewLC( KMaxTotalDataLength + 2 * KAknBidiExtraSpacePerLine );
       
  1191         HBufC *temptarget = HBufC::NewLC( KMaxTotalDataLength );
       
  1192 
       
  1193         // java, among others, may use separate fonts for each row
       
  1194         const CFont* font1 = FormattedCellData()->RowAndSubCellFont( aItemIndex, aFirstIndex )
       
  1195             ? FormattedCellData()->RowAndSubCellFont( aItemIndex, aFirstIndex )
       
  1196             : FormattedCellData()->SubCellFont( aFirstIndex );
       
  1197 
       
  1198         const CFont* font2 = FormattedCellData()->RowAndSubCellFont( aItemIndex, aSecondIndex )
       
  1199             ? FormattedCellData()->RowAndSubCellFont( aItemIndex, aSecondIndex )
       
  1200             : FormattedCellData()->SubCellFont( aSecondIndex );
       
  1201 
       
  1202         // If second string is not empty, truncate both first and second
       
  1203         // line separately in their own lines. It is assumed here that these 2 lines
       
  1204         // are completely separate and do not share any context.
       
  1205 
       
  1206         if ( secondString.Length() )
       
  1207             {
       
  1208             HBufC* convertedLine1 = HBufC::NewLC( firstString.Size()
       
  1209                                                   + KAknBidiExtraSpacePerLine );
       
  1210 
       
  1211             TPtr ptr1 = convertedLine1->Des();
       
  1212 
       
  1213             HBufC* convertedLine2 = HBufC::NewLC( secondString.Size()
       
  1214                                                   + KAknBidiExtraSpacePerLine );
       
  1215 
       
  1216             TPtr ptr2 = convertedLine2->Des();
       
  1217 
       
  1218             clipped1 = AknBidiTextUtils::ConvertToVisualAndClip(
       
  1219                 firstString,
       
  1220                 ptr1,
       
  1221                 font1 ? *font1 : *LatinBold13(),
       
  1222                 firstWidth,
       
  1223                 firstWidth );
       
  1224             
       
  1225             resultArray->AppendL( TPtrC( *convertedLine1 ) ); 
       
  1226 
       
  1227             clipped2 = AknBidiTextUtils::ConvertToVisualAndClip(
       
  1228                 secondString,
       
  1229                 ptr2,
       
  1230                 font2 ? *font2 : *LatinBold13(),
       
  1231                 secondWidth,
       
  1232                 secondWidth );
       
  1233 
       
  1234             resultArray->AppendL( TPtrC( *convertedLine2 ) ); 
       
  1235             }
       
  1236         else         // Otherwise, wrap the first string in 2 lines
       
  1237             {
       
  1238             CArrayFixFlat<TInt>* lineWidthArray =
       
  1239                 new( ELeave ) CArrayFixFlat<TInt>( 2 );
       
  1240             CleanupStack::PushL( lineWidthArray );
       
  1241             
       
  1242             lineWidthArray->AppendL(firstWidth);
       
  1243             lineWidthArray->AppendL(secondWidth);
       
  1244 
       
  1245             *wrapped = columntowrap.Left( KMaxTotalDataLength );
       
  1246             TPtr ptr = wrapped->Des();
       
  1247 
       
  1248             // this fails to truncate correctly, if lines use different fonts
       
  1249             AknBidiTextUtils::ConvertToVisualAndWrapToArrayL(
       
  1250                 ptr,
       
  1251                 *lineWidthArray,
       
  1252                 font1 ? *font1 : *LatinBold13(),
       
  1253                 *resultArray,
       
  1254                 ETrue );
       
  1255 
       
  1256             CleanupStack::PopAndDestroy(); // lineWidthArray
       
  1257             }
       
  1258         
       
  1259         TInt count = resultArray->Count();
       
  1260         if (count > 0)
       
  1261             {
       
  1262             TPtr ttp = temptarget->Des();
       
  1263             AknLAFUtils::ReplaceColumn( ttp,
       
  1264                                         CONST_CAST(TDesC*,&aItemString),
       
  1265                                         &resultArray->At(0),
       
  1266                                         '\t',
       
  1267                                         aFirstIndex );
       
  1268             
       
  1269             firstWordWrappedSubcellIndex = aFirstIndex;
       
  1270             
       
  1271             if (count > 1)
       
  1272                 {
       
  1273                 AknLAFUtils::ReplaceColumn( aTarget,
       
  1274                                             temptarget,
       
  1275                                             &resultArray->At(1),
       
  1276                                             '\t',
       
  1277                                             aSecondIndex );
       
  1278                 secondWordWrappedSubcellIndex = aSecondIndex;
       
  1279                 }
       
  1280             else
       
  1281                 {
       
  1282                 TPtrC empty = secondString;
       
  1283                 AknLAFUtils::ReplaceColumn( aTarget,
       
  1284                                             temptarget,
       
  1285                                             &empty,
       
  1286                                             '\t',
       
  1287                                             aSecondIndex );
       
  1288                 }
       
  1289             
       
  1290             // unfortunately, ConvertToVisualAndWrapToArrayL() does
       
  1291             // not tell if last line was clipped. Hack around.
       
  1292             if ( count > 1 )
       
  1293                 {
       
  1294                 clipped2 = WasClippedHack( columntowrap, wrapped->Des(), resultArray->At(1) );
       
  1295                 }
       
  1296             }
       
  1297         else
       
  1298             {
       
  1299             // Error, use default
       
  1300             TPtrC empty = firstString;
       
  1301             AknLAFUtils::ReplaceColumn( aTarget, &empty, &empty,
       
  1302                                         '\t', aFirstIndex );                 
       
  1303             }
       
  1304         
       
  1305         CleanupStack::PopAndDestroy(); // temptarget
       
  1306         if (secondString.Length())
       
  1307             {
       
  1308             CleanupStack::PopAndDestroy(2); // convertedLine1, convertedLine2
       
  1309             }
       
  1310         
       
  1311         CleanupStack::PopAndDestroy(2); // wrapped, resultArray
       
  1312         } 
       
  1313 
       
  1314         ); // end of TRAP
       
  1315     if ( error != KErrNone )
       
  1316         {
       
  1317         aTarget.Append(aItemString);
       
  1318         }
       
  1319 
       
  1320     // Inform drawing routine of word wrapped subcells, which are already
       
  1321     // converted from logical to visual form.
       
  1322     // This method is called for each list item before drawing it.
       
  1323     FormattedCellData()->SetWordWrappedSubcellIndices( 
       
  1324         firstWordWrappedSubcellIndex,
       
  1325         secondWordWrappedSubcellIndex );
       
  1326 
       
  1327     // pass info for CurrentItemTextWasClipped()
       
  1328     TInt clippedCells( 0 );
       
  1329     
       
  1330     if ( clipped1 )
       
  1331         {
       
  1332         clippedCells |= ( 1 << firstWordWrappedSubcellIndex );
       
  1333         }
       
  1334 
       
  1335     if ( clipped2 )
       
  1336         {
       
  1337         clippedCells |= ( 1 << secondWordWrappedSubcellIndex );
       
  1338         }
       
  1339     
       
  1340     FormattedCellData()->SetClippedByWrap( clippedCells, ETrue );
       
  1341     }
       
  1342 
       
  1343 EXPORT_C void CFormattedCellListBoxItemDrawer::CFormattedCellListBoxItemDrawer_Reserved()
       
  1344     {
       
  1345     }
       
  1346 
       
  1347 void CFormattedCellListBoxItemDrawer::DrawBackgroundAndSeparatorLines( const TRect& aItemTextRect ) const
       
  1348     {
       
  1349     MAknsSkinInstance *skin = AknsUtils::SkinInstance();
       
  1350     CCoeControl* control = FormattedCellData()->Control();
       
  1351     MAknsControlContext *cc = AknsDrawUtils::ControlContext( control );
       
  1352 
       
  1353     if ( !cc )
       
  1354         {
       
  1355         cc = FormattedCellData()->SkinBackgroundContext();
       
  1356         }
       
  1357 
       
  1358 #ifdef RD_UI_TRANSITION_EFFECTS_LIST
       
  1359     MAknListBoxTfxInternal* transApi = CAknListLoader::TfxApiInternal( iGc );
       
  1360     
       
  1361     if ( transApi && !transApi->EffectsDisabled() )
       
  1362         {
       
  1363         MAknListBoxTfx* tfxApi = CAknListLoader::TfxApi( iGc );
       
  1364 
       
  1365         if ( tfxApi )
       
  1366             {
       
  1367             tfxApi->EnableEffects( FormattedCellData()->IsBackgroundDrawingEnabled() );
       
  1368             }
       
  1369         }
       
  1370 #endif // RD_UI_TRANSITION_EFFECTS_LIST
       
  1371 
       
  1372     // background
       
  1373     if ( FormattedCellData()->IsBackgroundDrawingEnabled() )
       
  1374         {
       
  1375 #ifdef RD_UI_TRANSITION_EFFECTS_LIST
       
  1376         MAknListBoxTfxInternal* transApi = CAknListLoader::TfxApiInternal( iGc );
       
  1377         if ( transApi )
       
  1378             {
       
  1379             transApi->StartDrawing( MAknListBoxTfxInternal::EListView );
       
  1380             }
       
  1381 #endif // RD_UI_TRANSITION_EFFECTS_LIST
       
  1382         TBool bgDrawn( EFalse );
       
  1383         if ( control )
       
  1384             {
       
  1385             const MCoeControlBackground* backgroundDrawer =
       
  1386                 control->FindBackground();
       
  1387             
       
  1388             if ( backgroundDrawer )
       
  1389                 {
       
  1390                 backgroundDrawer->Draw( *iGc, *control, aItemTextRect );
       
  1391                 bgDrawn = ETrue;
       
  1392                 }
       
  1393             else if ( CAknEnv::Static()->TransparencyEnabled() )
       
  1394                 {
       
  1395                 bgDrawn = AknsDrawUtils::Background(
       
  1396                     skin, cc, control, *iGc, aItemTextRect,
       
  1397                     KAknsDrawParamNoClearUnderImage );
       
  1398                 }
       
  1399             else
       
  1400                 {
       
  1401                 bgDrawn = AknsDrawUtils::Background(
       
  1402                     skin, cc, control, *iGc, aItemTextRect,
       
  1403                     KAknsDrawParamNoClearUnderImage | 
       
  1404                     KAknsDrawParamBottomLevelRGBOnly );
       
  1405                 }
       
  1406             }
       
  1407         if ( !bgDrawn )
       
  1408             {
       
  1409             iGc->Clear( aItemTextRect );
       
  1410             }
       
  1411 #ifdef RD_UI_TRANSITION_EFFECTS_LIST  
       
  1412         if ( transApi )
       
  1413             {
       
  1414             transApi->StopDrawing();
       
  1415             }
       
  1416 #endif // RD_UI_TRANSITION_EFFECTS_LIST
       
  1417         }
       
  1418     }
       
  1419 
       
  1420 // End of File