calendarui/views/src/calendaylistboxmodel.cpp
branchRCL_3
changeset 66 bd7edf625bdd
child 67 1539a383d7b6
equal deleted inserted replaced
65:12af337248b1 66:bd7edf625bdd
       
     1 /*
       
     2 * Copyright (c) 2002 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: List Box Model class for Calendar Day view  
       
    15  *
       
    16 */
       
    17 
       
    18 #include <calencommands.hrh>            // Calendar commands
       
    19 #include <AknBidiTextUtils.h>
       
    20 #include <AknUtils.h>
       
    21 #include <eikenv.h>
       
    22 #include <PUAcodes.hrh>
       
    23 #include <StringLoader.h>
       
    24 #include <txtrich.h>
       
    25 #include <calentry.h>
       
    26 #include <calinstance.h>
       
    27 #include <calrrule.h>
       
    28 #include <calalarm.h>
       
    29 #include <centralrepository.h>
       
    30 #include <Calendar.rsg>
       
    31 #include <calsession.h>
       
    32 #include <caleninstanceid.h>            // TCalenInstanceId
       
    33 #include <calenviewutils.h>
       
    34 #include <calenagendautils.h>
       
    35 #include "CalendarVariant.hrh"
       
    36 #ifdef RD_CALEN_MIDNIGHT_VISUALIZATION
       
    37 #include <calendateutils.h>
       
    38 #endif // RD_CALEN_MIDNIGHT_VISUALIZATION
       
    39 #include <calcalendarinfo.h>
       
    40 #include <calenservices.h>
       
    41 
       
    42 //debug
       
    43 #include "calendarui_debug.h"
       
    44 #include "calendaylistboxmodel.h"
       
    45 #include "calencontroller.h"
       
    46 #include "CalendarVariant.hrh"
       
    47 #include "calendaylistbox.h"
       
    48 #include "calentodoview.h" // for priorities
       
    49 #include "calendar.hrh"
       
    50 #include "CalendarPrivateCRKeys.h"
       
    51 #include "calenglobaldata.h"
       
    52 
       
    53 // LOCAL CONSTANTS AND MACROS
       
    54 _LIT(KDesTimeSpace, " ");
       
    55 _LIT(KDesSeparator, "\t");
       
    56 _LIT(KIconSeperatorFormat, "%d\t"); // Day LB icon seperator format
       
    57 
       
    58 #ifdef RD_CALEN_MIDNIGHT_VISUALIZATION
       
    59 _LIT(KUnicodeRightwardsArrow, "\x2192"); // ->
       
    60 _LIT(KUnicodeLeftwardsArrow, "\x2190");  // <-
       
    61 _LIT(K24hFmt12am, " 00"); // already starts at hr 00
       
    62 _LIT(K24hFmt12pm, "24 ");
       
    63 #endif // RD_CALEN_MIDNIGHT_VISUALIZATION
       
    64 
       
    65 
       
    66 const TInt KTimedNoteMaxLines(4);
       
    67 const TInt KHypenBufSize(4);
       
    68 const TInt KNonTimedNoteMaxLines(1);
       
    69 
       
    70 // KMaxColumnDataLength is Avkon defined minimal maximum length for column texts.
       
    71 const TInt KMaxLengthOfDisplayedText(KTimedNoteMaxLines * KMaxColumnDataLength);
       
    72 
       
    73 // =========================== MEMBER FUNCTIONS ===============================
       
    74 
       
    75 // ----------------------------------------------------------------------------
       
    76 // CCalenDayListBoxModel::CCalenDayListBoxModel
       
    77 // C++ default constructor can NOT contain any code, that
       
    78 // might leave.
       
    79 // ----------------------------------------------------------------------------
       
    80 //
       
    81 CCalenDayListBoxModel::CCalenDayListBoxModel()
       
    82     {
       
    83     TRACE_ENTRY_POINT;
       
    84     TRACE_EXIT_POINT;
       
    85     }
       
    86 
       
    87 // -----------------------------------------------------------------------------
       
    88 // CCalenDayListBoxModel::ConstructL
       
    89 // Symbian 2nd phase constructor can leave.
       
    90 // -----------------------------------------------------------------------------
       
    91 //
       
    92 void CCalenDayListBoxModel::ConstructL( const CCalenDayContainer* aDayContainer )
       
    93     {
       
    94     TRACE_ENTRY_POINT;
       
    95 
       
    96     iDayContainer = aDayContainer;
       
    97     iItemTextArray = new(ELeave) CDesCArrayFlat(5);
       
    98 
       
    99     // Read time formats
       
   100     iTimeFormat = StringLoader::LoadL( R_QTN_TIME_USUAL_WITH_ZERO );
       
   101 
       
   102     TRACE_EXIT_POINT;
       
   103     }
       
   104 
       
   105 void CCalenDayListBoxModel::UpdateLayoutValues( TInt aLayoutVariant,
       
   106 TBool aMidnightVisualization)
       
   107     {
       
   108     TRACE_ENTRY_POINT;
       
   109 
       
   110     CCalenDayListBox::ReadLayout(
       
   111         aLayoutVariant,
       
   112         iLocale,
       
   113         iLaf.iGfxA,
       
   114         iLaf.iTextA,
       
   115         iLaf.iTextB,
       
   116         iLaf.iTextC,
       
   117         iLaf.iIconA,
       
   118         iLaf.iIconB,
       
   119         aMidnightVisualization );
       
   120 
       
   121     TRACE_EXIT_POINT;
       
   122     }
       
   123 
       
   124 // Destructor
       
   125 CCalenDayListBoxModel::~CCalenDayListBoxModel()
       
   126     {
       
   127     TRACE_ENTRY_POINT;
       
   128 
       
   129     delete iTimeFormat;
       
   130     delete iItemTextArray;
       
   131 
       
   132     TRACE_EXIT_POINT;
       
   133     }
       
   134 
       
   135 // -----------------------------------------------------------------------------
       
   136 // CCalenDayListBoxModel::NewL
       
   137 // Two-phased constructor.
       
   138 // -----------------------------------------------------------------------------
       
   139 //
       
   140 CCalenDayListBoxModel* CCalenDayListBoxModel::NewL( const CCalenDayContainer* aDayContainer )
       
   141     {
       
   142     TRACE_ENTRY_POINT;
       
   143 
       
   144     CCalenDayListBoxModel* self =
       
   145         new( ELeave ) CCalenDayListBoxModel();
       
   146 
       
   147     CleanupStack::PushL( self );
       
   148     self->ConstructL( aDayContainer );
       
   149     CleanupStack::Pop( self );
       
   150 
       
   151     TRACE_EXIT_POINT;
       
   152     return self;
       
   153     }
       
   154 
       
   155 // ----------------------------------------------------------------------------
       
   156 // CCalenDayListBoxModel::?member_function
       
   157 // ?implementation_description
       
   158 // (other items were commented in a header).
       
   159 // ----------------------------------------------------------------------------
       
   160 //
       
   161 CDesCArrayFlat* CCalenDayListBoxModel::ItemTextArray()
       
   162     {
       
   163     TRACE_ENTRY_POINT;
       
   164 
       
   165     TRACE_EXIT_POINT;
       
   166     return iItemTextArray;
       
   167     }
       
   168 
       
   169 // ----------------------------------------------------------------------------
       
   170 // CCalenDayListBoxModel::?member_function
       
   171 // ?implementation_description
       
   172 // (other items were commented in a header).
       
   173 // ----------------------------------------------------------------------------
       
   174 //
       
   175 void CCalenDayListBoxModel::GetEntryTextDataL(CCalEntry& aEntry,
       
   176                                               TDes& aBuf) const
       
   177     {
       
   178     TRACE_ENTRY_POINT;
       
   179 
       
   180     const TInt maxLen( aBuf.MaxLength() - KTimedNoteMaxLines * KAknBidiExtraSpacePerLine );
       
   181     CalenViewUtils::GetSummaryLocationTextL( aEntry, aBuf, maxLen );
       
   182 
       
   183     TRACE_EXIT_POINT;
       
   184     }
       
   185 
       
   186 #ifndef RD_CALEN_MIDNIGHT_VISUALIZATION
       
   187 // ----------------------------------------------------------------------------
       
   188 // CCalenDayListBoxModel::?member_function
       
   189 // ?implementation_description
       
   190 // (other items were commented in a header).
       
   191 // ----------------------------------------------------------------------------
       
   192 //
       
   193 void CCalenDayListBoxModel::LimitStartAndEndTime(TTime& aCurrentDay,
       
   194                                                  TTime& aStart,
       
   195                                                  TTime& aEnd)
       
   196     {
       
   197     TRACE_ENTRY_POINT;
       
   198 
       
   199     TTimeIntervalDays days(aCurrentDay.DaysFrom(TTime(TInt64(0))));
       
   200     TTimeIntervalDays startDays(aStart.DaysFrom(TTime(TInt64(0))));
       
   201     TTimeIntervalDays endDays(aEnd.DaysFrom(TTime(TInt64(0))));
       
   202 
       
   203     // set start time to 00:00, if event starts before current day
       
   204     if (startDays != days)
       
   205         {
       
   206         aStart = TTime(TInt64(0)) + startDays;
       
   207         }
       
   208 
       
   209     // Set end time to 23:59, if event continues to next day
       
   210     if (endDays != days)
       
   211         {
       
   212         TDateTime endDate = aEnd.DateTime();
       
   213         endDate.SetHour(ECalenMaxHour);
       
   214         endDate.SetMinute(ECalenMaxMinute);
       
   215         aEnd = endDate;
       
   216         }
       
   217 
       
   218     TRACE_EXIT_POINT;
       
   219     }
       
   220 
       
   221 // ----------------------------------------------------------------------------
       
   222 // CCalenDayListBoxModel::?member_function
       
   223 // ?implementation_description
       
   224 // (other items were commented in a header).
       
   225 // ----------------------------------------------------------------------------
       
   226 //
       
   227 void CCalenDayListBoxModel::InsertTimeL(TDes& aBuf,
       
   228                                         const TTime& aTime)
       
   229     {
       
   230     TRACE_ENTRY_POINT;
       
   231 
       
   232     TBuf<32> timeDes;
       
   233     aTime.FormatL( timeDes, *iTimeFormat );
       
   234     AknTextUtils::DisplayTextLanguageSpecificNumberConversion( timeDes );
       
   235     AknBidiTextUtils::ConvertToVisualAndClipL( timeDes,
       
   236                                                *iLaf.iTextA.Font(),
       
   237                                                iLaf.iTextA.TextRect().Width(),
       
   238                                                iLaf.iTextA.TextRect().Width() );
       
   239     aBuf.Append(timeDes);
       
   240 
       
   241     TRACE_EXIT_POINT;
       
   242     }
       
   243 
       
   244 #else // Midnight is ON
       
   245 
       
   246 void CCalenDayListBoxModel::InsertTimeL(TDes& aBuf, const TTime& aTime, const TTimeStringFormat aInsert)
       
   247     {
       
   248     TRACE_ENTRY_POINT;
       
   249 
       
   250     TBuf<32> timeDes;
       
   251     switch(aInsert)
       
   252         {
       
   253             case EInsertTimeGiven:
       
   254                 aTime.FormatL( timeDes, *iTimeFormat );
       
   255                 break;
       
   256 
       
   257             case EInsert00:
       
   258                 timeDes = K24hFmt12am();
       
   259                 break;
       
   260 
       
   261             case EInsert24:
       
   262                 timeDes = K24hFmt12pm();
       
   263                 break;
       
   264 
       
   265             default:
       
   266                 ASSERT(KErrArgument);
       
   267         }
       
   268 
       
   269 
       
   270     AknTextUtils::DisplayTextLanguageSpecificNumberConversion( timeDes );
       
   271     AknBidiTextUtils::ConvertToVisualAndClipL( timeDes,
       
   272                                                *iLaf.iTextA.Font(),
       
   273                                                iLaf.iTextA.TextRect().Width(),
       
   274                                                iLaf.iTextA.TextRect().Width() );
       
   275     aBuf.Append(timeDes);
       
   276 
       
   277     TRACE_EXIT_POINT;
       
   278     }
       
   279 
       
   280 
       
   281 #endif // RD_CALEN_MIDNIGHT_VISUALIZATION
       
   282 
       
   283 
       
   284 // ----------------------------------------------------------------------------
       
   285 // CCalenDayListBoxModel::?member_function
       
   286 // ?implementation_description
       
   287 // (other items were commented in a header).
       
   288 // ----------------------------------------------------------------------------
       
   289 //
       
   290 #ifdef RD_CALEN_MIDNIGHT_VISUALIZATION
       
   291 void CCalenDayListBoxModel::InsertHyphenL(TDes& aBuf,
       
   292                                                const TTime& aStart,
       
   293                                                const TTime& aEnd)
       
   294 
       
   295 #else // keep the old definition
       
   296 void CCalenDayListBoxModel::InsertHyphen(TDes& aBuf,
       
   297                                                const TTime& aStart,
       
   298                                                const TTime& aEnd)
       
   299 #endif //RD_CALEN_MIDNIGHT_VISUALIZATION
       
   300     {
       
   301     TRACE_ENTRY_POINT;
       
   302 
       
   303     if (aStart != aEnd)
       
   304         {
       
   305 
       
   306         TBuf<KHypenBufSize> hyphen;
       
   307         hyphen.Append(TChar(KPuaCodeNarrowDash));
       
   308 
       
   309 #ifdef RD_CALEN_MIDNIGHT_VISUALIZATION
       
   310 
       
   311         AknBidiTextUtils::ConvertToVisualAndClipL( hyphen,
       
   312                                               *iLaf.iTextB.Font(),
       
   313                                                iLaf.iTextB.TextRect().Width(),
       
   314                                                iLaf.iTextB.TextRect().Width() );
       
   315         aBuf.Append(hyphen);
       
   316 #else
       
   317         aBuf.Append(hyphen);
       
   318 #endif // RD_CALEN_MIDNIGHT_VISUALIZATION
       
   319         }
       
   320 
       
   321     TRACE_EXIT_POINT;
       
   322     }
       
   323 
       
   324 // ---------------------------------------------------------
       
   325 // CCalenDayListBoxModel::LastLineWidth
       
   326 // Calculates a last line width
       
   327 // (other items were commented in a header).
       
   328 // ---------------------------------------------------------
       
   329 //
       
   330 TInt CCalenDayListBoxModel::LastLineWidthL(TInt aWidth, CCalEntry& aEntry) const
       
   331     {
       
   332     TRACE_ENTRY_POINT;
       
   333 
       
   334     CCalAlarm* alarmObj = aEntry.AlarmL();
       
   335     TBool alarm( alarmObj ? ETrue : EFalse );
       
   336     delete alarmObj;
       
   337 
       
   338     TCalRRule ignore;
       
   339     TBool repeat(CalenAgendaUtils::IsRepeatingL(aEntry));
       
   340 
       
   341     TBool priority( EFalse );
       
   342 
       
   343     if( aEntry.EntryTypeL() == CCalEntry::ETodo &&
       
   344         aEntry.PriorityL() != ETodoPriorityNormal )
       
   345         {
       
   346         priority = ETrue;
       
   347         }
       
   348     
       
   349     // Check if this entry has any geovalues for the location field
       
   350     CCalGeoValue* geovalue = aEntry.GeoValueL();  
       
   351     TBool mapIcon( geovalue ? ETrue : EFalse);
       
   352     delete geovalue;
       
   353     
       
   354     TInt width( aWidth );
       
   355 
       
   356     // FIXME, actually these should be read from LAF!
       
   357 
       
   358     if( alarm && repeat || alarm && priority || repeat && priority || mapIcon && alarm || mapIcon && repeat || mapIcon && priority)
       
   359         {
       
   360         width = aWidth -( iLaf.iIconB.Rect().Width() + iLaf.iIconA.Rect().Width() );
       
   361         }
       
   362     else if( alarm || repeat || priority || mapIcon)
       
   363         {
       
   364             width = aWidth - iLaf.iIconA.Rect().Width();
       
   365         }
       
   366     width = width - KAknBidiExtraSpacePerLine;
       
   367 
       
   368     TRACE_EXIT_POINT;
       
   369     return width;
       
   370     }
       
   371 
       
   372 // ---------------------------------------------------------
       
   373 // CCalenDayListBoxModel::WrapTextL
       
   374 // (other items were commented in a header).
       
   375 // ---------------------------------------------------------
       
   376 //
       
   377 HBufC* CCalenDayListBoxModel::WrapTextL(
       
   378     CCalEntry& aEntry,
       
   379     CArrayFixFlat<TPtrC>& aLineArray) const
       
   380     {
       
   381     TRACE_ENTRY_POINT;
       
   382 
       
   383     // This is rather complicated algorithm to calculate how many
       
   384     // lines given text takes.
       
   385     //
       
   386     // (Note: in below description of problem and solution we for simplicity
       
   387     // consider only meeting entries with maximum of 4 lines of text, but
       
   388     // code handles Todos, Day Events and Anniversaries with max 1 line
       
   389     // of text. It should be easy to adapt it to have different maximum number
       
   390     // of lines.)
       
   391     //
       
   392     // As UI spec says, textual representation of entry
       
   393     // (subject + location) takes as many lines as it needs.
       
   394     // If it doesn't fit to maximum number of lines (4), it is
       
   395     // truncated.
       
   396     //
       
   397     // Problem is that last line of entry might contain less space for
       
   398     // text than previous lines, as it can contain icons for alarm, repeat
       
   399     // and priority. Because Avkon APIs for text wrapping and truncating
       
   400     // cannot handle situation, in which line count is not defined AND
       
   401     // last line length varies, we have to programmatically try
       
   402     // to wrap and fit text first to 1 line, then to 2 lines, then to
       
   403     // 3 lines and finally truncate it to 4 lines.
       
   404 
       
   405     TBool isTimed =
       
   406         aEntry.EntryTypeL() == CCalEntry::EAppt ||
       
   407         aEntry.EntryTypeL() == CCalEntry::EReminder;
       
   408     const TInt KMaxLines =
       
   409         isTimed ? KTimedNoteMaxLines : KNonTimedNoteMaxLines;
       
   410 
       
   411     const TInt KLineWidth = iLaf.iTextC.TextRect().Width();
       
   412 
       
   413     CArrayFixFlat<TInt>* lineWidths = new( ELeave )CArrayFixFlat<TInt>( 5 );
       
   414     CleanupStack::PushL( lineWidths );
       
   415 
       
   416     // last line width is always dependent on icons and is thus calculated.
       
   417     // We insert last line width to line widths buffer here, and try to fit
       
   418     // text to this single line. After that we always add line with normal
       
   419     // width BEFORE this last line.
       
   420     // I.e.
       
   421     //  1st try: { LastLineWidth }
       
   422     //  2nd try: { NormalLineWidth, LastLineWidth }
       
   423     //  3rd try: { NormalLineWidth, NormalLineWidth, LastLineWidth }
       
   424     //  ...
       
   425     lineWidths->AppendL( LastLineWidthL( KLineWidth, aEntry ) );
       
   426 
       
   427     // Get entry text
       
   428     HBufC* text = HBufC::NewLC( KMaxLengthOfDisplayedText );
       
   429     TPtr textPtr = text->Des();
       
   430     GetEntryTextDataL( aEntry, textPtr );
       
   431 
       
   432     // First we try to fit text to [1, max_lines - 1] (i.e. 1,2 or 3 lines)
       
   433     TBool doesFit = EFalse;
       
   434     HBufC* visualText = NULL;
       
   435     while ( ! doesFit && lineWidths->Count() < KMaxLines  )
       
   436         {
       
   437         // Convert*WholeTextL wraps all text, so that if it doesn't
       
   438         // fit to given lines, it uses last line width to wrap remaining
       
   439         // texts. This is useful, because we then know did it fit or not.
       
   440         //
       
   441         // Note that it constructs new text buffer (visualText) that
       
   442         // has to be destroyed, if it's not used. If it's used, this
       
   443         // text has to be returned to caller and caller takes care of
       
   444         // destroying. This memory management is unfortunately complicated,
       
   445         // so be careful if you modify.
       
   446         visualText  =
       
   447             AknBidiTextUtils::ConvertToVisualAndWrapToArrayWholeTextL(
       
   448             *text,
       
   449             *lineWidths,
       
   450             *iLaf.iTextC.Font(),
       
   451             aLineArray);
       
   452         CleanupStack::PushL( visualText );
       
   453 
       
   454         // If amount of splitted lines is same (or less than) currently
       
   455         // tried lines, we can fit text to this amount of lines.
       
   456         TInt triedLines = lineWidths->Count();
       
   457         if ( aLineArray.Count() <= triedLines )
       
   458             {
       
   459             doesFit = ETrue;
       
   460             // In case Avkon method wraps text to less lines than we tried
       
   461             // it means that text fits to less lines, but icons has to
       
   462             // be put to empty line after text!
       
   463             // We have to manually add that empty line.
       
   464             if ( aLineArray.Count() < triedLines )
       
   465                 {
       
   466                 aLineArray.AppendL( TPtrC(KNullDesC) );
       
   467                 }
       
   468             break; // exit from loop, we could fit text.
       
   469             }
       
   470         else
       
   471             {
       
   472             // Release visualText buffer and reset line array, because
       
   473             // we couldn't fit text on this try.
       
   474             CleanupStack::PopAndDestroy( visualText );
       
   475             visualText = NULL;
       
   476             aLineArray.Reset();
       
   477 
       
   478             // Prepend normal line width, and try again with more lines.
       
   479             // (Note: last line width stays last, because we prepend)
       
   480             lineWidths->InsertL( 0, KLineWidth );
       
   481             }
       
   482         }
       
   483 
       
   484     HBufC* result = NULL;
       
   485     if ( doesFit )
       
   486         {
       
   487         if ( aLineArray.Count() == 1 )
       
   488             {
       
   489             aLineArray.AppendL( TPtrC(KNullDesC) );
       
   490             }
       
   491             
       
   492         // If we could fit, we return visualText and caller has
       
   493         // to memory manage it. TPtrs in aLineArray points to this text
       
   494         // buffer.
       
   495         result = visualText;
       
   496         CleanupStack::Pop( visualText );
       
   497         CleanupStack::PopAndDestroy( text );
       
   498         }
       
   499     else
       
   500         {
       
   501         // If we couldn't fit before, we wrap text to max lines and truncate
       
   502         // it with ellipsis.
       
   503         TInt triedLines = lineWidths->Count();
       
   504 
       
   505         // truncate and add ellipsis
       
   506         TPtr truncatedText = text->Des();
       
   507         const TBool KUseEllipsis = ETrue;
       
   508         AknBidiTextUtils::ConvertToVisualAndWrapToArrayL(
       
   509             truncatedText,
       
   510             *lineWidths,
       
   511             *iLaf.iTextC.Font(),
       
   512             aLineArray,
       
   513             KUseEllipsis );
       
   514 
       
   515         // In case Avkon method wrapped text to less lines than we tried
       
   516         // it means that text fits to less lines, but icons has to
       
   517         // be put to empty line after text!
       
   518         // We have to manually add that empty line.
       
   519         if ( aLineArray.Count() < triedLines )
       
   520             {
       
   521             aLineArray.AppendL( TPtrC(KNullDesC) );
       
   522             }
       
   523             
       
   524         if ( aLineArray.Count() == 1 )
       
   525             {
       
   526             aLineArray.AppendL( TPtrC(KNullDesC) );
       
   527             }
       
   528 
       
   529         // We return original text, because
       
   530         // AknBidiTextUtils::ConvertToVisualAndWrapToArrayL
       
   531         // modifies that and TPtrs in aLineArray points to that buffer
       
   532         result = text;
       
   533         CleanupStack::Pop( text );
       
   534         }
       
   535 
       
   536     CleanupStack::PopAndDestroy( lineWidths );
       
   537 
       
   538     TRACE_EXIT_POINT;
       
   539     return result;
       
   540     };
       
   541 
       
   542 // ----------------------------------------------------------------------------
       
   543 // CCalenDayListBoxModel::?member_function
       
   544 // ?implementation_description
       
   545 // (other items were commented in a header).
       
   546 // ----------------------------------------------------------------------------
       
   547 //
       
   548 void CCalenDayListBoxModel::CreateListBoxDataL(
       
   549     CArrayFixFlat<CCalenDayContainer::SItemInfo>& aLayoutTable,
       
   550     CArrayFixFlat<TInt>& aCellArray,
       
   551     MCalenServices& aServices,
       
   552     /*CCalInstanceView* aInstanceView*/
       
   553     TTime aCurrentDay)
       
   554     {
       
   555     TRACE_ENTRY_POINT;
       
   556 
       
   557     iItemTextArray->Reset();
       
   558     TBool isAllDayEvent;
       
   559     RPointerArray<CCalCalendarInfo> calendarInfoList;
       
   560     aServices.GetAllCalendarInfoL(calendarInfoList);
       
   561     CleanupClosePushL(calendarInfoList);
       
   562 
       
   563     HBufC* listItemData = HBufC::NewLC(ECalenCharsInLine);
       
   564 
       
   565     // iterate layout
       
   566     for (TInt loop(0); loop < aLayoutTable.Count(); ++loop)
       
   567         {
       
   568         CCalenDayContainer::SItemInfo& itemInfo = aLayoutTable[loop];
       
   569 
       
   570         CCalEntry& entry = itemInfo.iTmpInstance->Entry();
       
   571         isAllDayEvent = EFalse;
       
   572         if (entry.EntryTypeL() == CCalEntry::EAppt || entry.EntryTypeL()
       
   573                 == CCalEntry::EEvent)
       
   574             {
       
   575             isAllDayEvent = CalenViewUtils::IsAlldayEventL(
       
   576                     *itemInfo.iTmpInstance);
       
   577             }
       
   578         TCalCollectionId collectionId =
       
   579                 itemInfo.iTmpInstance->InstanceIdL().iCollectionId;
       
   580         HBufC* calendarFileName = aServices.GetCalFileNameForCollectionId(collectionId).AllocLC();
       
   581         TInt index = calendarInfoList.Find( *calendarFileName,
       
   582                 CCalenDayListBoxModel::CalendarInfoIdentifierL );
       
   583         
       
   584         CleanupStack::PopAndDestroy(calendarFileName);
       
   585         
       
   586         if (index != KErrNotFound && calendarInfoList[index]->Enabled())
       
   587             {
       
   588             itemInfo.iColor = calendarInfoList[index]->Color().Value();
       
   589             TPtr ptr = listItemData->Des();
       
   590             ptr.Zero();
       
   591 
       
   592             TTime start(TInt64(0));
       
   593             TTime end(TInt64(0));
       
   594 
       
   595             if ((entry.EntryTypeL() == CCalEntry::EAppt || entry.EntryTypeL()
       
   596                     == CCalEntry::EReminder) && (!isAllDayEvent))
       
   597                 {
       
   598                 // meeting notes
       
   599                 // \t14:00\t-\t
       
   600                 // 0 1      2
       
   601                 //
       
   602                 // no icon
       
   603                 ptr.Append(KDesSeparator);
       
   604 
       
   605                 TTimeIntervalMinutes duration;
       
   606                 entry.EndTimeL().TimeLocalL().MinutesFrom(
       
   607                         entry.StartTimeL().TimeLocalL(), duration);
       
   608                 start = itemInfo.iTmpInstance->Time().TimeLocalL();
       
   609                 end = start + duration;
       
   610 #ifdef RD_CALEN_MIDNIGHT_VISUALIZATION
       
   611                 InsertStartTimeL(ptr, start, aCurrentDay);
       
   612 #else
       
   613                 LimitStartAndEndTime( aCurrentDay, start, end );
       
   614 
       
   615                 InsertTimeL(ptr, start);
       
   616 #endif // RD_CALEN_MIDNIGHT_VISUALIZATION
       
   617                 if (!AknLayoutUtils::LayoutMirrored())
       
   618                     {
       
   619                     ptr.Append(KDesSeparator);
       
   620                     }
       
   621 
       
   622 #ifdef RD_CALEN_MIDNIGHT_VISUALIZATION
       
   623                 InsertHyphenL(ptr, start, end);
       
   624 #else               
       
   625                 InsertHyphen(ptr, start, end);
       
   626 #endif // RD_CALEN_MIDNIGHT_VISUALIZATION
       
   627                 if (AknLayoutUtils::LayoutMirrored())
       
   628                     {
       
   629                     ptr.Append(KDesSeparator);
       
   630                     }
       
   631 
       
   632                 ptr.Append(KDesSeparator);
       
   633                 }
       
   634             else
       
   635             // Set icons and times for entry            
       
   636                 {
       
   637                 // non-timed notes
       
   638                 TBuf<3> icon;
       
   639                 icon.Num(
       
   640                         static_cast<TInt64> (iDayContainer->IconIndexFromEntryL(
       
   641                                 entry, isAllDayEvent)));
       
   642                 // icon\t\t\t
       
   643                 // 0     1 2
       
   644                 // gfxA  textA textB
       
   645                 ptr.Append(icon);
       
   646                 ptr.Append(KDesSeparator);
       
   647                 ptr.Append(KDesSeparator);
       
   648                 ptr.Append(KDesSeparator);
       
   649                 }
       
   650 
       
   651             // textLines contain
       
   652             CArrayFixFlat<TPtrC>* textLines = new (ELeave) CArrayFixFlat<
       
   653                     TPtrC> (5);
       
   654             CleanupStack::PushL(textLines);
       
   655 
       
   656             // After WrapTextL call, visualText contains wrapped text in
       
   657             // memory buffer, textLines contain text pointers
       
   658             // (into visualText memory buffer) of beginning of each line of text.
       
   659             HBufC* visualText = WrapTextL(entry, *textLines);
       
   660             CleanupStack::PushL(visualText);
       
   661 
       
   662             // Put first line of text to current list line
       
   663             if (textLines->Count())
       
   664                 {
       
   665                 ptr.Append(textLines->At(0));
       
   666                 }
       
   667 
       
   668             TBool isEndDisplayed = ETrue;
       
   669             // For subsequent text lines, we create separate list lines.
       
   670             if ((end != start) && (!isAllDayEvent))
       
   671                 {
       
   672                 isEndDisplayed = EFalse;
       
   673                 }
       
   674             TInt textLinesCount = textLines->Count();
       
   675             for (TInt i(1); i <= textLinesCount || !isEndDisplayed; i++)
       
   676                 {
       
   677                 if(i == textLinesCount)
       
   678                     {
       
   679                     itemInfo.iBottomLine = iItemTextArray->Count();
       
   680                     break;
       
   681                     }
       
   682                 if (itemInfo.iTopLine == KIndexError)
       
   683                     {
       
   684                     itemInfo.iTopLine = iItemTextArray->Count();
       
   685                     }
       
   686                 iItemTextArray->AppendL(*listItemData);
       
   687                 ptr.Zero();
       
   688                 ptr.Append(KDesSeparator);
       
   689                 // Sets an end time in second line
       
   690                 if (!isEndDisplayed)
       
   691                     {
       
   692                     __ASSERT_ALWAYS( i == 1, User::Invariant() );
       
   693 
       
   694 #ifdef RD_CALEN_MIDNIGHT_VISUALIZATION
       
   695                     InsertEndTimeL(ptr, end, aCurrentDay);
       
   696 #else
       
   697                     InsertTimeL(ptr, end);
       
   698 #endif // RD_CALEN_MIDNIGHT_VISUALIZATION
       
   699                     isEndDisplayed = ETrue;
       
   700                     }
       
   701                 else
       
   702                     {
       
   703                     ptr.Append(KDesTimeSpace);
       
   704                     }
       
   705                 ptr.Append(KDesSeparator);
       
   706                 ptr.Append(KDesSeparator);
       
   707                 if (i < textLines->Count())
       
   708                     {
       
   709                     ptr.Append(textLines->At(i));
       
   710                     }
       
   711                 }
       
   712 
       
   713             // end of last line (also for non-timed notes)
       
   714             ptr.Append(KDesSeparator);
       
   715 
       
   716             CleanupStack::PopAndDestroy(visualText);
       
   717             CleanupStack::PopAndDestroy(textLines);
       
   718 
       
   719             // Alarm, repeat and priority icons
       
   720             iDayContainer->InsertAdditionalIconsL(entry,
       
   721                     KIconSeperatorFormat(), ptr);
       
   722 
       
   723             // append created list item data to array of list items
       
   724             aCellArray.AppendL(iItemTextArray->Count());
       
   725 
       
   726             if (itemInfo.iTopLine == KIndexError)
       
   727                 {
       
   728                 itemInfo.iTopLine = iItemTextArray->Count();
       
   729                 }
       
   730             iItemTextArray->AppendL(*listItemData);
       
   731             }
       
   732         }
       
   733     CleanupStack::PopAndDestroy(listItemData);
       
   734     CleanupStack::PopAndDestroy(&calendarInfoList);
       
   735 
       
   736     TRACE_EXIT_POINT;
       
   737     }
       
   738 
       
   739 #ifdef RD_CALEN_MIDNIGHT_VISUALIZATION
       
   740 void CCalenDayListBoxModel::InsertStartTimeL(TDes& aBuf,
       
   741                              const TTime& aStartTime,
       
   742                              const TTime& aCurrentDay)
       
   743     {
       
   744     TRACE_ENTRY_POINT;
       
   745 
       
   746     TBuf<6> arrow;
       
   747     TBuf<50> formattedStartTime;
       
   748     TBool mirrored( AknLayoutUtils::LayoutMirrored() );
       
   749 
       
   750     if(StartsBeforeFocusedDay(aStartTime, aCurrentDay))
       
   751         {
       
   752         arrow = GetArrowIndicator(mirrored);
       
   753 
       
   754         // need to format end time acc.to 12hr or 24hr format
       
   755         if(TimeFormat() == ETime24)
       
   756             {
       
   757             // 24 hour. show 00 only
       
   758             InsertTimeL(formattedStartTime, aStartTime, EInsert00);
       
   759             }
       
   760         else
       
   761             {
       
   762             // 12 hour. show hh:mm am/pm
       
   763             formattedStartTime = GetFormattedStartTimeL(aCurrentDay);
       
   764             }
       
   765         }
       
   766     else
       
   767         {
       
   768         // meeting starts after 12:00 am on current day
       
   769         // add start time as it is
       
   770         InsertTimeL( formattedStartTime, aStartTime );
       
   771         }
       
   772 
       
   773     if(mirrored)
       
   774         {
       
   775         // For mirrored UI layouts:
       
   776         aBuf.Append(formattedStartTime);
       
   777         aBuf.Append(arrow);
       
   778         }
       
   779     else
       
   780         {
       
   781         // For western UI layouts:
       
   782         aBuf.Append(arrow);
       
   783         aBuf.Append(formattedStartTime);
       
   784         }
       
   785 
       
   786     TRACE_EXIT_POINT;
       
   787     }
       
   788 
       
   789 TBool CCalenDayListBoxModel::StartsBeforeFocusedDay(const TTime& aStartTime,
       
   790 const TTime& aFocusedTime)
       
   791     {
       
   792     TRACE_ENTRY_POINT;
       
   793 
       
   794     const TTime focusedDay12am = CalenDateUtils::BeginningOfDay(aFocusedTime);
       
   795     if(aStartTime < focusedDay12am)
       
   796         {
       
   797         TRACE_EXIT_POINT;
       
   798         return ETrue;
       
   799         }
       
   800 
       
   801     TRACE_EXIT_POINT;
       
   802     return EFalse;
       
   803     }
       
   804 
       
   805 TBool CCalenDayListBoxModel::EndsAfterFocusedDay(const TTime& aEndTime,
       
   806 const TTime& aFocusedTime)
       
   807     {
       
   808     TRACE_ENTRY_POINT;
       
   809 
       
   810     const TTime nextDay12am = CalenDateUtils::BeginningOfDay(aFocusedTime)
       
   811     + TTimeIntervalDays(1);
       
   812 
       
   813     if(aEndTime >= nextDay12am)
       
   814         {
       
   815         TRACE_EXIT_POINT;
       
   816         return ETrue;
       
   817         }
       
   818 
       
   819     TRACE_EXIT_POINT;
       
   820     return EFalse;
       
   821     }
       
   822 
       
   823 const TDesC& CCalenDayListBoxModel::GetArrowIndicator(const TBool aMirroredLayout)
       
   824     {
       
   825     TRACE_ENTRY_POINT;
       
   826 
       
   827     if(aMirroredLayout)
       
   828         {
       
   829         // unicode leftwards arrow for right to left layouts
       
   830         TRACE_EXIT_POINT;
       
   831         return KUnicodeLeftwardsArrow;
       
   832         }
       
   833 
       
   834     // unicode rightwards arrow for left to right layouts
       
   835     TRACE_EXIT_POINT;
       
   836     return KUnicodeRightwardsArrow;
       
   837     }
       
   838 
       
   839 const TDesC& CCalenDayListBoxModel::GetFormattedStartTimeL(const TTime& aFocusedTime)
       
   840     {
       
   841     TRACE_ENTRY_POINT;
       
   842 
       
   843     iFormattedStartTime.Zero();
       
   844     const TTime focusedDay12am = CalenDateUtils::BeginningOfDay(aFocusedTime);
       
   845     InsertTimeL(iFormattedStartTime, focusedDay12am);
       
   846 
       
   847     TRACE_EXIT_POINT;
       
   848     return iFormattedStartTime;
       
   849     }
       
   850 
       
   851 const TDesC& CCalenDayListBoxModel::GetFormattedEndTimeL(const TTime& aFocusedTime)
       
   852     {
       
   853     TRACE_ENTRY_POINT;
       
   854 
       
   855     iFormattedEndTime.Zero();
       
   856     const TTime focusedDay24hrs = CalenDateUtils::BeginningOfDay(aFocusedTime)
       
   857         + TTimeIntervalDays(1);
       
   858 
       
   859     InsertTimeL(iFormattedEndTime, focusedDay24hrs);
       
   860 
       
   861     TRACE_EXIT_POINT;
       
   862     return iFormattedEndTime;
       
   863     }
       
   864 
       
   865 void CCalenDayListBoxModel::InsertEndTimeL(TDes& aBuf,
       
   866                                            const TTime& aEndTime,
       
   867                                            const TTime& aCurrentDay)
       
   868     {
       
   869     TRACE_ENTRY_POINT;
       
   870 
       
   871     TBuf<6> arrow;
       
   872     TBuf<50> formattedEndTime;
       
   873     TBool mirrored( AknLayoutUtils::LayoutMirrored() );
       
   874 
       
   875     if(EndsAfterFocusedDay(aEndTime, aCurrentDay))
       
   876         {
       
   877         arrow = GetArrowIndicator(mirrored);
       
   878 
       
   879         // need to format end time acc.to 12hr or 24hr format
       
   880         if(TimeFormat() == ETime24)
       
   881             {
       
   882             // 24 hour. show 24 only
       
   883             InsertTimeL(formattedEndTime, aEndTime, EInsert24);
       
   884             }
       
   885         else
       
   886             {
       
   887             // 12 hour. show hh:mm am/pm
       
   888             formattedEndTime = GetFormattedEndTimeL(aCurrentDay);
       
   889             }
       
   890         }
       
   891     else
       
   892         {
       
   893         // meeting does not continue after 24:00 on current day
       
   894         // add start time as it is
       
   895         InsertTimeL( formattedEndTime, aEndTime );
       
   896         }
       
   897 
       
   898     if(mirrored)
       
   899         {
       
   900         // For Mirrored Layouts:
       
   901         aBuf.Append(arrow);
       
   902         aBuf.Append(formattedEndTime);
       
   903         }
       
   904     else
       
   905         {
       
   906         // For Western Layouts:
       
   907         aBuf.Append(formattedEndTime);
       
   908         aBuf.Append(arrow);
       
   909         }
       
   910 
       
   911     TRACE_EXIT_POINT;
       
   912     }
       
   913 
       
   914 TTimeFormat CCalenDayListBoxModel::TimeFormat() const
       
   915     {
       
   916     TLocale locale;
       
   917     return locale.TimeFormat();
       
   918     }
       
   919 #endif // RD_CALEN_MIDNIGHT_VISUALIZATION
       
   920 
       
   921 
       
   922 // -----------------------------------------------------------------------------
       
   923 // CCalenDayListBoxModel::CalendarInfoIdentifierL
       
   924 // Searches for the index in calendar info list based on calendar file name
       
   925 // -----------------------------------------------------------------------------
       
   926 //
       
   927 TBool CCalenDayListBoxModel::CalendarInfoIdentifierL(
       
   928         const HBufC* aName, const CCalCalendarInfo& aCalendarInfo)
       
   929     {
       
   930     TRACE_ENTRY_POINT;
       
   931     TBool retVal = EFalse;
       
   932     HBufC* calendarFileName = aCalendarInfo.FileNameL().AllocLC();
       
   933     retVal = calendarFileName->CompareF(*aName);
       
   934     CleanupStack::PopAndDestroy(calendarFileName);        
       
   935     TRACE_EXIT_POINT;
       
   936     return (!retVal);
       
   937     }
       
   938 
       
   939 //  End of File
       
   940