messagingappbase/mce/src/MceMessageListItemArray.cpp
changeset 0 72b543305e3a
child 17 caea42e26caa
equal deleted inserted replaced
-1:000000000000 0:72b543305e3a
       
     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:  
       
    15 *     Item array for the message items to be displayed by mce.
       
    16 *     Main view items are kept in memory (CArrayFixFlat<TMceListItem>) when created but
       
    17 *     Message view list items are fetched from the msgs when needed in MdcaPoint function
       
    18 *
       
    19 */
       
    20 
       
    21 
       
    22 
       
    23 // INCLUDE FILES
       
    24 
       
    25 #include <AknUtils.h>       // AknTextUtils
       
    26 #include <mtudcbas.h>
       
    27 #include <msvids.h>
       
    28 #include <NpdApi.h>         // CNotepadApi
       
    29 #include "MtmRegistryObserver.h" // MMtmUiDataRegistryObserver
       
    30 #include <StringLoader.h>   // StringLoader
       
    31 #include <mce.rsg>
       
    32 #include <SenduiMtmUids.h>  // mtm uids
       
    33 #include <eikenv.h>
       
    34 
       
    35 #include "MceMessageListItemArray.h"
       
    36 #include "MceBitmapResolver.h"
       
    37 #include "MceIds.h" // KMceDocumentsEntryIdValue
       
    38 #include "McePanic.h"
       
    39 #include "MceCommands.hrh"
       
    40 #include "MceLogText.h"
       
    41 
       
    42 #include <MTMStore.h>
       
    43 #include <commonphoneparser.h>
       
    44 
       
    45 #include <aknappui.h>
       
    46 #include <akncontext.h>
       
    47 #include <aknconsts.h>
       
    48 #include <e32math.h>
       
    49 
       
    50 #include <bldvariant.hrh>
       
    51 #include <featmgr.h>
       
    52 #include <NumberGrouping.h>
       
    53 #include <mmsconst.h>
       
    54 #include <mmsgenutils.h>
       
    55 #include <mmsclient.h>
       
    56 #include <mtclreg.h>
       
    57 #include <muiu.mbg>
       
    58 #include <mtudreg.h>        // CMtmUiDataRegistry
       
    59 
       
    60 // security data caging
       
    61 #include <data_caging_path_literals.hrh>
       
    62 #include <miutset.h>
       
    63 #include <msvapi.h>
       
    64 #include <ImumInternalApi.h>            // CImumInternalApi
       
    65 #include <ImumInSettingsData.h>         // CImumInSettingsData
       
    66 
       
    67 #include <muiuflags.h>
       
    68 
       
    69 //FS email stuff
       
    70 #include <centralrepository.h>
       
    71 #include <MessagingDomainCRKeys.h>
       
    72 const TInt KMceListArrayGranuality = 4;
       
    73 
       
    74 // CONSTANTS
       
    75 
       
    76 const TInt KMceArabicSemiColon                = {0x061B};
       
    77 const TInt KMceSemiColon                      = {0x003B};
       
    78 const TInt KMceMaxFormatFactor                = 2;
       
    79 const TText KMceRLM = 0x200F;
       
    80 const TText KMcePDF = 0x202C;
       
    81 
       
    82 const TUid KUidMsvMessageListSortOrder={0x10005359};
       
    83 
       
    84 _LIT( KSortSubjectSkipString, "*:*" );
       
    85 const TChar KWhiteSpaceCharacter(' ');
       
    86 const TInt KSortSubjectStringLength = 100;
       
    87 
       
    88 // LOCAL CONSTANTS AND MACROS
       
    89 enum
       
    90     {
       
    91     KMceListArrayDocAmount = 0x0,
       
    92     KMceListArrayDocAmountMany,
       
    93     KMceListArrayDocAmountTemp,
       
    94     KMceListArrayDocAmountTemps,
       
    95     KMceListArrayTimeFormatBuffer,
       
    96     KMceListArrayDateFormatBuffer
       
    97     };
       
    98 
       
    99 //cmail update
       
   100 #define KUidMsgTypeFsMtmVal               0x2001F406
       
   101 
       
   102 // ================= MEMBER FUNCTIONS =======================
       
   103 
       
   104 // C++ default constructor can NOT contain any code that
       
   105 // might leave.
       
   106 //
       
   107 CMceMessageListItemArray::CMceMessageListItemArray(
       
   108     CMsvSessionPtr aSession,
       
   109     TMsvId aFolderId,
       
   110     TMceListType aListType,
       
   111     CMceBitmapResolver& aBitmapResolver ) :
       
   112 //    CArrayFixFlat<TMceListItem>( KMceListGranuality ),
       
   113     iSession( aSession ),
       
   114     iFolderId( aFolderId ),
       
   115     iListType( aListType ),
       
   116     iBitmapResolver( aBitmapResolver ),
       
   117     iEmailClientIntegration(EFalse),
       
   118     iEmailFramework(EFalse),
       
   119     iIntegratedEmailAppExcist(EFalse)
       
   120     {
       
   121     iDescriptionLength = iBitmapResolver.DescriptionLength();
       
   122     }
       
   123 
       
   124 // ----------------------------------------------------
       
   125 // CMceMessageListItemArray::ConstructL
       
   126 // Symbian OS default constructor can leave.
       
   127 // ----------------------------------------------------
       
   128 void CMceMessageListItemArray::ConstructL()
       
   129     {
       
   130     CRepository* repository = NULL;
       
   131     // read phone number grouping feature flag
       
   132     iNumberGroupingEnabledFlag = MceUtils::NumberGroupingEnabled();
       
   133         
       
   134     iPreviousSelectionOrdering = TMsvSelectionOrdering(
       
   135             KMsvGroupByStandardFolders, EMsvSortByDateReverse);
       
   136     // Added for FS Email stuff
       
   137     FeatureManager::InitializeLibL();
       
   138     if ( FeatureManager::FeatureSupported( KFeatureIdFfEmailFramework ) )
       
   139         {
       
   140         iEmailFramework = ETrue;
       
   141         }
       
   142     if ( FeatureManager::FeatureSupported( KFeatureIdEmailMceIntegration) )
       
   143         {
       
   144         iEmailClientIntegration = ETrue;
       
   145 
       
   146         // Check if there is other than platform email application registered to handle S60 mailboxes   
       
   147         repository = NULL;
       
   148         TInt mtmPluginID = 0;
       
   149         TRAPD( ret, repository = CRepository::NewL(
       
   150                KCRUidSelectableDefaultEmailSettings ) );
       
   151 
       
   152         if ( ret == KErrNone )
       
   153             {
       
   154             TInt err = repository->Get( KIntegratedEmailAppMtmPluginId ,
       
   155                                         mtmPluginID );
       
   156             if ( err != KErrNone )
       
   157                 {
       
   158                 mtmPluginID = 0;
       
   159                 }
       
   160             }
       
   161         delete repository;
       
   162 
       
   163         if ( mtmPluginID != 0 )
       
   164             {
       
   165             iIntegratedEmailAppExcist = ETrue;
       
   166             }
       
   167         }
       
   168 
       
   169     
       
   170     FeatureManager::UnInitializeLib();
       
   171     iFolderEntry = CMsvEntry::NewL(
       
   172         *iSession,
       
   173         iFolderId,
       
   174         iPreviousSelectionOrdering );
       
   175 
       
   176     iNumberOfMessagesStrings = new(ELeave)CDesCArrayFlat( KMceListGranuality );
       
   177     TBuf<KMcePrintableTextLength> tempString;
       
   178     CCoeEnv* eikonEnv = CEikonEnv::Static();
       
   179     StringLoader::Load( tempString, R_MCE_DOC_AMOUNT, eikonEnv );
       
   180     iNumberOfMessagesStrings->AppendL( tempString );
       
   181     StringLoader::Load( tempString, R_MCE_DOC_AMOUNT_MANY, eikonEnv );
       
   182     iNumberOfMessagesStrings->AppendL( tempString );
       
   183     StringLoader::Load( tempString, R_MCE_DOC_AMOUNT_TEMP, eikonEnv );
       
   184     iNumberOfMessagesStrings->AppendL( tempString );
       
   185     StringLoader::Load( tempString, R_MCE_DOC_AMOUNT_TEMPS, eikonEnv );
       
   186     iNumberOfMessagesStrings->AppendL( tempString );
       
   187 
       
   188 
       
   189     HBufC* timeFormat = eikonEnv->
       
   190         AllocReadResourceLC( R_QTN_TIME_USUAL_WITH_ZERO );
       
   191     iNumberOfMessagesStrings->AppendL( *timeFormat );
       
   192     CleanupStack::PopAndDestroy();
       
   193     
       
   194     HBufC* dateFormat = eikonEnv->
       
   195         AllocReadResourceLC( R_QTN_DATE_WITHOUT_YEAR_WITH_ZERO );
       
   196     iNumberOfMessagesStrings->AppendL( *dateFormat );
       
   197     CleanupStack::PopAndDestroy();
       
   198     
       
   199     // TODO
       
   200     iListBoxText = HBufC::NewL( iDescriptionLength*3 ); 
       
   201     iUiRegistry = CMtmUiDataRegistry::NewL(*iSession); 
       
   202     //FS Email stuff
       
   203     iMsgIndex = new ( ELeave )CArrayFixFlat<TInt>( KMceListArrayGranuality );
       
   204     }
       
   205 
       
   206 // Two-phased constructor.
       
   207 CMceMessageListItemArray* CMceMessageListItemArray::NewL(
       
   208     CMsvSessionPtr aSession,
       
   209     TMsvId aFolderId,
       
   210     TMceListType aListType,
       
   211     CMceBitmapResolver& aBitmapResolver )
       
   212     {
       
   213     CMceMessageListItemArray* self = new (ELeave) CMceMessageListItemArray(
       
   214         aSession, aFolderId, aListType, aBitmapResolver );
       
   215     CleanupStack::PushL(self);
       
   216     self->ConstructL();
       
   217     CleanupStack::Pop(); // self
       
   218     return self;
       
   219     }
       
   220 
       
   221 
       
   222 // Destructor
       
   223 CMceMessageListItemArray::~CMceMessageListItemArray( )
       
   224     {
       
   225     delete iFolderEntry;
       
   226     delete iListBoxText;
       
   227     delete iNumberOfMessagesStrings;
       
   228     delete iUiRegistry;
       
   229     }
       
   230 
       
   231 
       
   232 // ----------------------------------------------------
       
   233 // CMceMessageListItemArray::ItemIndex
       
   234 // ----------------------------------------------------
       
   235 TInt CMceMessageListItemArray::ItemIndex(TMsvId aItemId) const
       
   236     {
       
   237     TInt foundItem = KErrNotFound;
       
   238     TInt count = iFolderEntry->Count();
       
   239     if ( (iEmailClientIntegration && iIntegratedEmailAppExcist) || iEmailFramework ) 
       
   240         {
       
   241         TRAPD( err, count = CreateEntryIndexL() );
       
   242         }
       
   243     for( TInt loop = 0; loop < count && foundItem == KErrNotFound ; loop++)
       
   244         {
       
   245         if ( (*iFolderEntry)[ GetEntryIndex( loop ) ].Id() == aItemId )
       
   246             {
       
   247             foundItem = loop;
       
   248             }
       
   249         }
       
   250     return foundItem;
       
   251     }
       
   252 
       
   253 // ----------------------------------------------------
       
   254 // CMceMessageListItemArray::ItemId
       
   255 // ----------------------------------------------------
       
   256 TMsvId CMceMessageListItemArray::ItemId( TInt aIndex ) const
       
   257     {
       
   258     TMsvId id = KErrNotFound;
       
   259     if ( aIndex >= 0 && iFolderEntry->Count() > aIndex )
       
   260         {
       
   261         id = (*iFolderEntry)[ GetEntryIndex( aIndex ) ].Id();
       
   262         }
       
   263     return id;
       
   264     }
       
   265 
       
   266 // ----------------------------------------------------
       
   267 // CMceMessageListItemArray::Item
       
   268 // ----------------------------------------------------
       
   269 const TMceListItem CMceMessageListItemArray::Item( TInt aIndex ) const
       
   270     {
       
   271     TMceListItem tempItem;
       
   272     tempItem.iMsvId = (*iFolderEntry)[ aIndex ].Id();
       
   273     tempItem.iExtraItem = EFalse;
       
   274     return tempItem;
       
   275     }
       
   276 
       
   277 
       
   278 // ----------------------------------------------------
       
   279 // CMceMessageListItemArray::GetEntry
       
   280 // ----------------------------------------------------
       
   281 TInt CMceMessageListItemArray::GetEntry( TMsvId aEntryId, TMsvEntry& aEntry )
       
   282     {
       
   283     TMsvId serviceId;
       
   284     return iSession->GetEntry( aEntryId, serviceId, aEntry );
       
   285     }
       
   286 
       
   287 
       
   288 // ----------------------------------------------------
       
   289 // CMceMessageListItemArray::SetFolderL
       
   290 // ----------------------------------------------------
       
   291 void CMceMessageListItemArray::SetFolderL( TMsvId aFolderId )
       
   292     {
       
   293     // this can only happen when iListType == EMceListTypeMessage
       
   294     iFolderEntry->SetEntryL( aFolderId );
       
   295     iFolderId = aFolderId;
       
   296     }
       
   297 
       
   298 // ----------------------------------------------------
       
   299 // CMceMessageListItemArray::IsItemFolder
       
   300 // ----------------------------------------------------
       
   301 TBool CMceMessageListItemArray::IsItemFolder( TMsvId aItemId ) const
       
   302     {
       
   303     TBool isFolder = EFalse;
       
   304     TMsvId serviceId;
       
   305     TMsvEntry entry;
       
   306     if ( iSession->GetEntry( aItemId, serviceId, entry ) == KErrNone &&
       
   307          entry.iType == KUidMsvFolderEntry )
       
   308         {
       
   309         isFolder = ETrue;
       
   310         }
       
   311     return isFolder;
       
   312     }
       
   313 
       
   314 // ----------------------------------------------------
       
   315 // CMceMessageListItemArray::MdcaCount
       
   316 // ----------------------------------------------------
       
   317 TInt CMceMessageListItemArray::MdcaCount() const
       
   318     {
       
   319     TInt retval=iFolderEntry->Count();
       
   320     if (( iEmailClientIntegration && iIntegratedEmailAppExcist )||(iEmailFramework))
       
   321         {
       
   322         if( iFolderId == KMsvDraftEntryId || 
       
   323                 iFolderId == KMsvSentEntryId || 
       
   324                 iFolderId == KMsvDeletedEntryFolderEntryId || 
       
   325                 iFolderId == KMsvGlobalInBoxIndexEntryId || iFolderId == KMsvGlobalOutBoxIndexEntryId)
       
   326             {
       
   327 
       
   328             TRAPD( err, retval = CreateEntryIndexL() );
       
   329             }
       
   330         }   
       
   331     return ( retval );
       
   332     }
       
   333 
       
   334 // ----------------------------------------------------
       
   335 // CMceMessageListItemArray::MdcaPoint
       
   336 // ----------------------------------------------------
       
   337 TPtrC CMceMessageListItemArray::MdcaPoint( TInt aIndex ) const
       
   338     {
       
   339     return MakeStringForMessageView( aIndex );
       
   340     }
       
   341 
       
   342 // ----------------------------------------------------
       
   343 // CMceMessageListItemArray::MakeStringForMessageView
       
   344 // ----------------------------------------------------
       
   345 TPtrC CMceMessageListItemArray::MakeStringForMessageView( TInt aIndex ) const
       
   346     {
       
   347     __ASSERT_DEBUG( iListType == EMceListTypeMessage, Panic(EMceListItemArrayNotMessageViewList ) );
       
   348     const TMsvEntry* child;
       
   349     child = &(*iFolderEntry)[ GetEntryIndex( aIndex ) ];
       
   350     TPtr tempText = iListBoxText->Des();
       
   351 
       
   352     tempText.Zero();
       
   353     const TInt index = iBitmapResolver.BitmapIndex( *child );
       
   354     tempText.AppendNum( index );
       
   355     tempText.Append( KColumnListSeparator );
       
   356 
       
   357     if ( child->iType == KUidMsvFolderEntry )
       
   358         {
       
   359         AppendFolderString( tempText, *child );
       
   360         }
       
   361     else // should be KUidMsvMessageEntryValue
       
   362         {
       
   363         AppendMessageString( tempText, *child );
       
   364         }
       
   365     return tempText;
       
   366 
       
   367     }
       
   368 
       
   369 // ----------------------------------------------------
       
   370 // CMceMessageListItemArray::AppendMessageString
       
   371 // ----------------------------------------------------
       
   372 void CMceMessageListItemArray::AppendMessageString( TDes& aBuffer, const TMsvEntry& aEntry ) const
       
   373     {
       
   374     __ASSERT_DEBUG( aEntry.iType == KUidMsvMessageEntry, Panic(EMceListItemArrayEntryNotMessage ) );
       
   375 
       
   376     if ( aEntry.iMtm == KSenduiMtmImap4Uid || aEntry.iMtm == KSenduiMtmPop3Uid
       
   377         || aEntry.iMtm == KSenduiMtmSmtpUid )
       
   378         {
       
   379         StripAndAppendString( aBuffer, aEntry.iDetails );
       
   380         }
       
   381     else
       
   382         {
       
   383         TRAPD( error, AppendRecipientStringL( aBuffer, aEntry ) );
       
   384         if ( error != KErrNone )
       
   385             {
       
   386             // leave is not needed to handle; if leaves, nothing is shown
       
   387             }        
       
   388         }   
       
   389     
       
   390     aBuffer.Append( KColumnListSeparator );
       
   391 
       
   392     if ( ( iFolderEntry->Entry().Id() == KMsvGlobalInBoxIndexEntryId ) &&
       
   393         ( aEntry.iMtm == KUidMsgMMSNotification ) ) 
       
   394         {
       
   395         TRAP_IGNORE( MakeInboxStatusStringL( aBuffer, aEntry ) );
       
   396         }
       
   397 
       
   398     else if ( iFolderEntry->Entry().Id() == KMsvGlobalOutBoxIndexEntryId )
       
   399         {
       
   400         // in outbox show status of the message
       
   401         TRAP_IGNORE(MakeSendStatusStringL(aBuffer, aEntry));
       
   402         }
       
   403     else
       
   404         {
       
   405         TRAP_IGNORE( AppendTimeStringL( aBuffer, aEntry ) );
       
   406 
       
   407         if ( aEntry.iMtm==KSenduiMtmIrUid || aEntry.iMtm==KSenduiMtmBtUid )
       
   408             {
       
   409             TRAP_IGNORE( AppendBtIrMessageStringL( aBuffer, aEntry ) );
       
   410             }
       
   411          else
       
   412             {
       
   413             StripAndAppendString( aBuffer, aEntry.iDescription );
       
   414             }
       
   415         }
       
   416 
       
   417     aBuffer.Append( KColumnListSeparator );
       
   418 
       
   419     if ( aEntry.iMtm != KSenduiMtmMmsUid &&
       
   420          aEntry.Attachment() )
       
   421         {
       
   422         aBuffer.AppendNum( (TInt) EMceBitmapIndexAttachment );
       
   423 	    aBuffer.Append( KColumnListSeparator );
       
   424         }
       
   425         
       
   426     TMsvPriority priority = aEntry.Priority();
       
   427     if ( priority == EMsvHighPriority )
       
   428         {
       
   429         aBuffer.AppendNum( EMceBitmapIndexPriorityHigh );
       
   430         aBuffer.Append( KColumnListSeparator );
       
   431         }
       
   432     else if ( priority == EMsvLowPriority )
       
   433         {
       
   434         aBuffer.AppendNum( EMceBitmapIndexPriorityLow );
       
   435         aBuffer.Append( KColumnListSeparator );
       
   436         }
       
   437        
       
   438     }
       
   439 
       
   440 // ----------------------------------------------------
       
   441 // CMceMessageListItemArray::AppendFolderString
       
   442 // ----------------------------------------------------
       
   443 void CMceMessageListItemArray::AppendFolderString( TDes& aBuffer, const TMsvEntry& aEntry ) const
       
   444     {
       
   445     __ASSERT_DEBUG( aEntry.iType == KUidMsvFolderEntry, Panic(EMceListItemArrayEntryNotFolder ) );
       
   446 
       
   447     StripAndAppendString( aBuffer, aEntry.iDetails );
       
   448     aBuffer.Append( KColumnListSeparator );
       
   449     if ( aEntry.Id() == KMceTemplatesEntryId )
       
   450         {        
       
   451         TInt templatesCount = CNotepadApi::NumberOfTemplates();
       
   452         templatesCount = templatesCount < 0 ? 0 : templatesCount;
       
   453         if ( templatesCount == 1 )
       
   454             {
       
   455             TBuf<KMcePrintableTextLength> tempString;
       
   456             tempString.Append( (*iNumberOfMessagesStrings)[
       
   457                 KMceListArrayDocAmountTemp] );
       
   458             AknTextUtils::LanguageSpecificNumberConversion( tempString );         
       
   459             aBuffer.Append( tempString );
       
   460             }
       
   461         else
       
   462             {
       
   463             TBuf<KMcePrintableTextLength> tempString;
       
   464             StringLoader::Format( tempString,
       
   465                 (*iNumberOfMessagesStrings)[KMceListArrayDocAmountTemps],
       
   466                 -1, // no index in the key string
       
   467                 templatesCount );
       
   468             AknTextUtils::LanguageSpecificNumberConversion( tempString );
       
   469             aBuffer.Append( tempString );
       
   470             }
       
   471         }
       
   472     else
       
   473         {
       
   474         TRAP_IGNORE( HandleFolderMessagesStringL( aBuffer, aEntry ) );        
       
   475         }
       
   476     aBuffer.Append( KColumnListSeparator );
       
   477     }
       
   478 
       
   479 
       
   480 // ----------------------------------------------------
       
   481 // CMceMessageListItemArray::HandleSessionEventL
       
   482 // ----------------------------------------------------
       
   483 void CMceMessageListItemArray::HandleSessionEventL(
       
   484     TMsvSessionEvent aEvent, TAny* /*aArg1*/, TAny* /*aArg2*/, TAny* /*aArg3*/)
       
   485     {
       
   486     // TODO: why?
       
   487     switch (aEvent)
       
   488         {
       
   489     case EMsvEntriesCreated:
       
   490     case EMsvEntriesChanged:
       
   491     case EMsvEntriesDeleted:
       
   492     case EMsvMediaChanged:
       
   493     case EMsvMediaUnavailable:
       
   494     case EMsvMediaAvailable:
       
   495     case EMsvCloseSession:        
       
   496         break;
       
   497 
       
   498     default:
       
   499         break;
       
   500         }
       
   501     }
       
   502 
       
   503 // ----------------------------------------------------
       
   504 // CMceMessageListItemArray::SetRegistryObserver
       
   505 // ----------------------------------------------------
       
   506 void CMceMessageListItemArray::SetRegistryObserver( MMtmUiDataRegistryObserver* aRegistryObserver )
       
   507     {
       
   508     iRegistryObserver = aRegistryObserver;
       
   509     }
       
   510 
       
   511 // ----------------------------------------------------
       
   512 // CMceMessageListItemArray::MakeSendStatusStringL
       
   513 // ----------------------------------------------------
       
   514 void CMceMessageListItemArray::MakeSendStatusStringL(TDes& aText, const TMsvEntry& aEntry) const
       
   515     {
       
   516     if ( iRegistryObserver )
       
   517         {
       
   518         CBaseMtmUiData* data=iRegistryObserver->GetMtmUiDataL(aEntry.iMtm);
       
   519         if ( data )
       
   520             {
       
   521             HBufC* statusText=data->StatusTextL(aEntry);
       
   522             if ( statusText->Length() )
       
   523                 {
       
   524                 aText.Append( statusText->Des() );
       
   525                 }
       
   526             else
       
   527                 {
       
   528                 aText.Append( CEditableText::ESpace );
       
   529                 }
       
   530             delete statusText;
       
   531             }
       
   532         }
       
   533     }
       
   534 
       
   535 
       
   536 // ----------------------------------------------------
       
   537 // CMceMessageListItemArray::StripAndAppendString
       
   538 // ----------------------------------------------------
       
   539 void CMceMessageListItemArray::StripAndAppendString(TDes& aTargetString, const TDesC& aSourceString) const
       
   540     {
       
   541     TRAP_IGNORE( MceUtils::StripAndAppendStringL(
       
   542         aTargetString,
       
   543         aSourceString,
       
   544         iDescriptionLength ) );
       
   545     }
       
   546 
       
   547 // ----------------------------------------------------
       
   548 // CMceMessageListItemArray::IsFolderRemote
       
   549 // return ETrue, if remote folder
       
   550 //
       
   551 // ----------------------------------------------------
       
   552 TBool CMceMessageListItemArray::IsFolderRemote() const
       
   553     {
       
   554     return IsItemRemote( iFolderId );
       
   555     }
       
   556     
       
   557 // ----------------------------------------------------
       
   558 // CMceMessageListItemArray::
       
   559 // ----------------------------------------------------
       
   560 TBool CMceMessageListItemArray::IsItemRemote( TMsvId aItemId ) const
       
   561     {
       
   562     TMsvId service = KMsvLocalServiceIndexEntryId;
       
   563     TMsvEntry entry;
       
   564     if ( iSession->GetEntry(aItemId,service,entry) == KErrNone )
       
   565     	{
       
   566     	return KMsvLocalServiceIndexEntryId != service;
       
   567     	}
       
   568     else
       
   569     	{
       
   570     	return EFalse;
       
   571     	}
       
   572     }
       
   573 
       
   574 // ----------------------------------------------------
       
   575 // CMceMessageListItemArray::FolderId
       
   576 // return folder id
       
   577 //
       
   578 // ----------------------------------------------------
       
   579 TMsvId CMceMessageListItemArray::FolderId() const
       
   580     {
       
   581     return iFolderId;
       
   582     }
       
   583     
       
   584 // ----------------------------------------------------
       
   585 // CMceMessageListItemArray::
       
   586 // ----------------------------------------------------
       
   587 const TMsvEntry& CMceMessageListItemArray::FolderEntry() const
       
   588     {
       
   589     return iFolderEntry->Entry();
       
   590     }
       
   591     
       
   592 
       
   593 
       
   594 // ----------------------------------------------------
       
   595 // CMceMessageListItemArray::IsConnected
       
   596 // return ETrue, if account is connected
       
   597 //
       
   598 // ----------------------------------------------------
       
   599 TBool CMceMessageListItemArray::IsConnected() const
       
   600     {
       
   601     TMsvEntry entry;
       
   602     entry = iFolderEntry->Entry();
       
   603 
       
   604     TMsvEntry serviceEntry;
       
   605     TMsvId serviceId;
       
   606     if ( iSession->GetEntry(entry.iServiceId,serviceId,serviceEntry) == KErrNone )
       
   607     	{
       
   608     	return serviceEntry.Connected();
       
   609     	}
       
   610     else
       
   611     	{
       
   612     	return EFalse;
       
   613     	}
       
   614     }
       
   615 
       
   616 
       
   617 // ----------------------------------------------------
       
   618 // CMceMessageListItemArray::FindEntryIndex
       
   619 // Finds entry index in message list
       
   620 //
       
   621 // ----------------------------------------------------
       
   622 TInt CMceMessageListItemArray::FindEntryIndex( const TDesC& aMatchString ) const
       
   623     {
       
   624     TInt foundIndex = KErrNotFound;
       
   625     TMsvSelectionOrdering ordering( KMsvNoGrouping, EMsvSortByDateReverse, EFalse );
       
   626     ordering = iFolderEntry->SortType();
       
   627 
       
   628     const TInt count = iFolderEntry->Count();
       
   629     const TInt length = aMatchString.Length();
       
   630 
       
   631     if ( (ordering.Sorting()==EMsvSortByDetails) ||
       
   632     	 (ordering.Sorting()==EMsvSortByDetailsReverse) )
       
   633         { 
       
   634         for( TInt loop = 0; loop < count && foundIndex == KErrNotFound ; loop++ )
       
   635             {
       
   636             if ( aMatchString.CompareF((*iFolderEntry)[loop].iDetails.Left( length ) ) == 0 )
       
   637                 {
       
   638                 foundIndex = loop;
       
   639                 }
       
   640             }
       
   641         }
       
   642   
       
   643     else if ( (ordering.Sorting()==EMsvSortByDescription) ||
       
   644     		  (ordering.Sorting()==EMsvSortByDescriptionReverse) )
       
   645         {
       
   646         for( TInt loop = 0; loop < count && foundIndex == KErrNotFound ; loop++)
       
   647             {
       
   648             TBufC<100> tmpString( (*iFolderEntry)[loop].iDescription.Left(KSortSubjectStringLength) );
       
   649             TInt start = SkipPrefix( tmpString.Des() );
       
   650             if ( start < tmpString.Length() && tmpString.Length() >= (start + length) )
       
   651                 {
       
   652                 TPtrC mid = (*iFolderEntry)[loop].iDescription.Mid( start, length );
       
   653                 if ( aMatchString.CompareF( mid ) == 0 )
       
   654                     {
       
   655                     foundIndex = loop;
       
   656                     }
       
   657                 }
       
   658             }
       
   659         }
       
   660     else
       
   661         {
       
   662         //EMsvSortByReverse, nothing cannot be searched          
       
   663         }
       
   664 
       
   665     return foundIndex;
       
   666     }
       
   667 
       
   668 // ----------------------------------------------------
       
   669 // CMceMessageListItemArray::SetOrderingL
       
   670 // Sets sort order in folder entry
       
   671 //
       
   672 // ----------------------------------------------------
       
   673 void CMceMessageListItemArray::SetOrderingL( TInt aOrdering )
       
   674     { 
       
   675     TMsvSorting sorting = EMsvSortByDateReverse;
       
   676     TInt grouping = KMsvGroupByStandardFolders; 
       
   677     switch ( aOrdering )
       
   678         {	
       
   679         case EMceCmdSortByRecipient:
       
   680         case EMceCmdSortBySender:
       
   681             sorting=EMsvSortByDetails;		    		
       
   682             break;
       
   683         case EMceCmdSortBySubject:
       
   684             sorting=EMsvSortByDescription;            
       
   685             break;        
       
   686         case EMceCmdSortByDate:
       
   687         default:
       
   688             sorting=EMsvSortByDateReverse;           
       
   689             break;        
       
   690               
       
   691         }
       
   692 
       
   693     const TMsvSelectionOrdering newOrdering( grouping, sorting, EFalse );
       
   694     iFolderEntry->SetSortTypeL( newOrdering );   
       
   695     }
       
   696 
       
   697 
       
   698 
       
   699 // ----------------------------------------------------
       
   700 // CMceMessageListItemArray::DeleteDiscard
       
   701 // return ETrue, if delete command should be discarded
       
   702 //
       
   703 // ----------------------------------------------------
       
   704 TBool CMceMessageListItemArray::DeleteDiscard( TMsvId aItemId ) const
       
   705     {
       
   706     TMsvEntry entry;        
       
   707     TMsvId serviceId;
       
   708     if ( iSession->GetEntry(aItemId,serviceId,entry) != KErrNone )
       
   709     	{
       
   710     	return ETrue;
       
   711     	}
       
   712     
       
   713     //mail or syncml folder cannot be deleted
       
   714     if ( ( entry.iType == KUidMsvFolderEntry ) &&
       
   715         ( entry.iMtm == KSenduiMtmImap4Uid ||
       
   716         entry.iMtm == KSenduiMtmSyncMLEmailUid ) )
       
   717         {
       
   718         return ETrue;
       
   719         }
       
   720 
       
   721     if ( iFolderEntry->Entry().Id() == KMsvGlobalOutBoxIndexEntryId )
       
   722         {
       
   723         if ( entry.SendingState() == KMsvSendStateSending )
       
   724             {
       
   725             return ETrue;
       
   726             }
       
   727 
       
   728         // Message in waiting state cannot be deleted except e-mail.
       
   729         // For e-mail, waiting, resend and scheduled states are presented
       
   730         // to user as queued state (by CSmtpMtmUiData). Delete is allowed
       
   731         // from the queued state.
       
   732         if ( ( entry.SendingState() == KMsvSendStateWaiting ) &&
       
   733             ( entry.iMtm != KSenduiMtmSmtpUid ) )
       
   734             {
       
   735             return ETrue;
       
   736             }
       
   737 
       
   738         if ( entry.iMtm == KSenduiMtmSmsUid ||
       
   739             entry.iMtm == KSenduiMtmMmsUid )
       
   740             {
       
   741             if ( entry.Connected() || ( entry.SendingState() == KMsvSendStateUnknown )
       
   742                 || ( entry.SendingState() == KMsvSendStateNotApplicable ) )
       
   743                 {
       
   744                 return ETrue;
       
   745                 }
       
   746             }
       
   747         }
       
   748     return EFalse;
       
   749     }
       
   750 
       
   751 // ----------------------------------------------------
       
   752 // CMceMessageListItemArray::AppendRecipientStringL
       
   753 // handles recipient string
       
   754 //
       
   755 // ----------------------------------------------------
       
   756 void CMceMessageListItemArray::AppendRecipientStringL( TDes& aBuffer, const TMsvEntry& aEntry ) const
       
   757     {
       
   758 
       
   759     //
       
   760     // The following processes the recipient(s) for languages which require number
       
   761     // conversion and/or number grouping
       
   762     //
       
   763     if ( AknLayoutUtils::LayoutMirrored() || iNumberGroupingEnabledFlag || 
       
   764            EDigitTypeWestern != AknTextUtils::NumericEditorDigitType() )
       
   765         {
       
   766 
       
   767         //
       
   768         // semicolon separator
       
   769         //
       
   770         TBuf<1> semiColon;              
       
   771         semiColon.Append( KMceSemiColon );
       
   772         TInt posForSemiColon = KErrNotFound;
       
   773 
       
   774         //
       
   775         // arabic semicolon separator
       
   776         //
       
   777         TBuf<1> arabicSemiColon;              
       
   778         arabicSemiColon.Append( KMceArabicSemiColon );
       
   779         TInt posForArabicSemiColon = KErrNotFound;
       
   780 
       
   781         //
       
   782         // The following are used for keeping track of which type of separator we're
       
   783         // currently processing
       
   784         //
       
   785         TBuf<1> separator;
       
   786         TInt posForSeparator = KErrNotFound;
       
   787 
       
   788         TInt len = aEntry.iDetails.Length();
       
   789 
       
   790         //
       
   791         // recipient buffer is made to be larger than the length of the entry details
       
   792         // to allow additional room needed for number grouping
       
   793         //
       
   794         HBufC* recipientBuf = HBufC::NewLC(	KMceMaxFormatFactor*len );
       
   795         TPtr recipientPtr = recipientBuf->Des();
       
   796 
       
   797         //
       
   798         // remaining details buffer is initialized to the same as the entry details
       
   799         // and we will remove processed info until this buffer becomes empty
       
   800         //
       
   801         HBufC* remainingDetailsBuf = HBufC::NewLC( len );
       
   802         TPtr remainingDetailsPtr = remainingDetailsBuf->Des();
       
   803         remainingDetailsPtr.Copy( aEntry.iDetails );
       
   804 
       
   805         //
       
   806         // result buffer is made to be larger than the length of the entry details
       
   807         // to allow additional room needed for number grouping
       
   808         //
       
   809         HBufC* resultBuf = HBufC::NewLC( KMceMaxFormatFactor*len );        
       
   810         TPtr resultPtr = resultBuf->Des();
       
   811 
       
   812         //
       
   813         // Construct the result buffer from the entry details. Each recipient is
       
   814         // extracted from the entry details and valid phone numbers are number
       
   815         // grouped and converted as needed before they are concatenated into a
       
   816         // string separated by semicolon/arabic semicolon
       
   817         //
       
   818         do
       
   819             {
       
   820 
       
   821             // find the first occurrence of semi colon in the remaining details buffer 
       
   822             posForSemiColon = remainingDetailsPtr.Find( semiColon );
       
   823 
       
   824             // find the first occurrence of arabic semicolon in the remaining details
       
   825             // buffer
       
   826             posForArabicSemiColon = remainingDetailsPtr.Find( arabicSemiColon );
       
   827 
       
   828             //
       
   829             // 5 possible cases:
       
   830             //
       
   831             // 1) Neither semicolon nor arabic semicolon is found in the remaining
       
   832             //    details buffer:
       
   833             //
       
   834             //    we will take the first KPhCltNameBufferLength to the recipient buffer
       
   835             //    to proceed with our number grouping and/or conversion. At the end of
       
   836             //    this iteration, there will not be any in the remaining details buffer
       
   837             //    to be processed. This is either the single recipient case or we are
       
   838             //    processing the last of the recipients
       
   839             //
       
   840             if ( posForSemiColon == KErrNotFound && posForArabicSemiColon == KErrNotFound )
       
   841                 {
       
   842                 posForSeparator = KErrNotFound;
       
   843                 }
       
   844 
       
   845             // 2) found arabic semicolon in the remaining details buffer:
       
   846             //
       
   847             //    we will take everything upto where we find the arabic semicolon to the
       
   848             //    recipient buffer and we strip this recipient from our remaining details
       
   849             //    buffer for the next round of processing. (this is the multiple
       
   850             //    recipients case where each recipient is separated by arabic semicolon)
       
   851             //
       
   852             else if ( posForSemiColon == KErrNotFound )
       
   853                 {
       
   854                 posForSeparator = posForArabicSemiColon;
       
   855                 separator.Copy( arabicSemiColon );
       
   856                 }
       
   857 
       
   858             // 3) found semicolon in the remaining details buffer:
       
   859             //
       
   860             //    similar to the above. We will take everything upto where we find the
       
   861             //    semicolon to the recipient buffer and we strip this recipient from our
       
   862             //    remaining details buffer. (this is also the multiple recipients case
       
   863             //    where each recipient is separated by semicolon)
       
   864             //
       
   865             else if ( posForArabicSemiColon == KErrNotFound )
       
   866                 {
       
   867                 posForSeparator = posForSemiColon;
       
   868                 separator.Copy( semiColon );
       
   869                 }
       
   870 
       
   871             // The following 2 blocks are categorized under case 4).
       
   872             //
       
   873             // 4) found both semicolon and arabic semicolon: (This is the multiple
       
   874             //    recipients case where each recipient is separated by mix of semicolon
       
   875             //    and arabic semicolon).
       
   876             //    This is further broken down into 2 cases:
       
   877             //
       
   878             //    a) semicolon found is before arabic semicolon: treat it the same way
       
   879             //       as 3)
       
   880             //
       
   881             else if ( posForSemiColon < posForArabicSemiColon )
       
   882                 {
       
   883                 posForSeparator = posForSemiColon;
       
   884                 separator.Copy( semiColon );
       
   885                 }
       
   886         
       
   887             //    b) semicolon found is after arabic semicolon: treat it the same way
       
   888             //       as 2)
       
   889             //
       
   890             else
       
   891                 {
       
   892                 posForSeparator = posForArabicSemiColon;
       
   893                 separator.Copy( arabicSemiColon );
       
   894                 }
       
   895 
       
   896             //
       
   897             // take the first KPhCltNameBufferLength to the recipient buffer or take
       
   898             // everything upto where we find the separator
       
   899             //
       
   900             recipientPtr.Copy(
       
   901                 remainingDetailsPtr.Left(
       
   902                     ( posForSeparator == KErrNotFound ) ? KPhCltNameBufferLength : posForSeparator ) );
       
   903 
       
   904             //
       
   905             // remove the recipient we're processing from the remaining details buffer.
       
   906             // remove the separator as well (this is accomplished by advancing the position
       
   907             // by 1)
       
   908             //
       
   909             remainingDetailsPtr.Copy(
       
   910                 remainingDetailsPtr.Mid(
       
   911                     ( posForSeparator == KErrNotFound ) ? remainingDetailsPtr.Length() : posForSeparator + 1 ) );
       
   912 
       
   913             //
       
   914             // process the recipient buffer
       
   915             //
       
   916             if ( recipientPtr.Length() > 0 )
       
   917                 {
       
   918 
       
   919                 TBool validNumber = CommonPhoneParser::IsValidPhoneNumber( 
       
   920                     recipientPtr, CommonPhoneParser::ESMSNumber );
       
   921 
       
   922                 //
       
   923                 // if the recipient is specified as a valid number, we will
       
   924                 // perform number grouping and/or conversion as needed
       
   925                 //
       
   926                 if ( validNumber )
       
   927                     {
       
   928 
       
   929                     // perform number grouping as needed
       
   930                     DoNumberGroupingL( recipientPtr );
       
   931 
       
   932                     // perform Arabic & Hebrew conversion as needed
       
   933                     AknTextUtils::LanguageSpecificNumberConversion( recipientPtr );
       
   934 
       
   935                     }
       
   936 
       
   937                 //
       
   938                 // for Arabic/Hebrew, if the recipient isn't the last in the list, we need to
       
   939                 // put KMceRLM marker before the recipient name and McePDF marker before the
       
   940                 // arabic semicolon, e.g.
       
   941                 //
       
   942                 // <KMceRLM><recipient name><KMcePDF><arabic semicolon>
       
   943                 //
       
   944                 if ( !validNumber &&
       
   945                      ( posForSeparator != KErrNotFound ) &&
       
   946                      ( separator.Compare( arabicSemiColon ) == 0 ) )
       
   947                    {
       
   948                    resultPtr.Append( KMceRLM );
       
   949                    }
       
   950 
       
   951                 //
       
   952                 // we've finished processing this recipient, append it to the result buffer
       
   953                 //
       
   954                 resultPtr.Append( recipientPtr );
       
   955 
       
   956                 //
       
   957                 // append separator if there are subsequent recipients
       
   958                 //
       
   959                 if ( posForSeparator != KErrNotFound )
       
   960                     {
       
   961 
       
   962                     //
       
   963                     // for Arabic/Hebrew, if the recipient isn't the last in the list, we need to
       
   964                     // put KMceRLM marker before the recipient name and McePDF marker before the
       
   965                     // arabic semicolon, e.g.
       
   966                     //
       
   967                     // <KMceRLM><recipient name><KMcePDF><arabic semicolon>
       
   968                     //
       
   969                     if ( !validNumber &&
       
   970                          ( separator.Compare( arabicSemiColon ) == 0 ) )
       
   971                         {
       
   972                         resultPtr.Append( KMcePDF );
       
   973                         }
       
   974 
       
   975                     resultPtr.Append( separator );
       
   976                     }
       
   977 
       
   978                 }
       
   979 
       
   980             } while ( remainingDetailsPtr.Length() > 0 );
       
   981 
       
   982         //
       
   983         // we've processed the entire entry details, append our result to aBuffer
       
   984         //
       
   985         if ( len )
       
   986             {
       
   987             StripAndAppendString( aBuffer, resultPtr );
       
   988             }
       
   989         else
       
   990             {
       
   991             HBufC* text = StringLoader::LoadLC( R_MCE_PUSH_INBOX_SENDER_UNKW );
       
   992             aBuffer.Append( *text );
       
   993             CleanupStack::PopAndDestroy(); // text
       
   994             }
       
   995 
       
   996         CleanupStack::PopAndDestroy( 3 ); // recipientBuf, remainingDetailsBuf, resultBuf
       
   997 
       
   998         }
       
   999 
       
  1000     //
       
  1001     // The following processes the recipient(s) for languages which do not require number
       
  1002     // conversion or number grouping for performance consideration
       
  1003     //
       
  1004     else
       
  1005         {
       
  1006         if ( aEntry.iDetails.Length() )
       
  1007             {
       
  1008         StripAndAppendString( aBuffer, aEntry.iDetails );
       
  1009             }
       
  1010         else
       
  1011             {
       
  1012             HBufC* text = StringLoader::LoadLC( R_MCE_PUSH_INBOX_SENDER_UNKW );
       
  1013             aBuffer.Append( *text );
       
  1014             CleanupStack::PopAndDestroy(); // text
       
  1015             }
       
  1016         }
       
  1017 
       
  1018     }
       
  1019 
       
  1020 // ----------------------------------------------------
       
  1021 // CMceMessageListItemArray::DoNumberGroupingL
       
  1022 //
       
  1023 // This method uses CPNGNumberGrouping to reformat the given
       
  1024 // valid phone number if all of the following are true:
       
  1025 //
       
  1026 // 1) number grouping feature is turned on
       
  1027 //
       
  1028 // 2) the given number does not already exceed the maximum
       
  1029 //    displayable length for number grouping
       
  1030 //
       
  1031 // If not all of the above are true, the given phone number
       
  1032 // remains unchanged.
       
  1033 //
       
  1034 // This method leaves if unable to instantiate a CPNGNumberGrouping
       
  1035 // object.
       
  1036 // ----------------------------------------------------
       
  1037 void CMceMessageListItemArray::DoNumberGroupingL( TDes& aPhoneNumber ) const
       
  1038     {
       
  1039 
       
  1040     if ( iNumberGroupingEnabledFlag )
       
  1041         {
       
  1042 
       
  1043         CPNGNumberGrouping* numberGrouping =
       
  1044             CPNGNumberGrouping::NewL( KPhCltTelephoneNumberLength );
       
  1045         CleanupStack::PushL( numberGrouping );
       
  1046 
       
  1047         if ( aPhoneNumber.Length() <= numberGrouping->MaxDisplayLength() )
       
  1048             {
       
  1049 
       
  1050             //
       
  1051             // Remove extra space for multiple recipients
       
  1052             //
       
  1053             TInt lengthBeforeTrimming = aPhoneNumber.Length();
       
  1054             aPhoneNumber.Trim();
       
  1055             TInt lengthAfterTrimming = aPhoneNumber.Length();
       
  1056 
       
  1057             numberGrouping->Set( aPhoneNumber );
       
  1058 
       
  1059             // reset aPhoneNumber
       
  1060             aPhoneNumber.Zero();
       
  1061 
       
  1062             //
       
  1063             // put the space prefix back if one was stripped before
       
  1064             //
       
  1065             if ( lengthBeforeTrimming != lengthAfterTrimming )
       
  1066                 {
       
  1067                 aPhoneNumber.Append( CEditableText::ESpace );
       
  1068                 }
       
  1069 
       
  1070             aPhoneNumber.Append( numberGrouping->FormattedNumber() );
       
  1071 
       
  1072             } // end if aPhoneNumber
       
  1073 
       
  1074         CleanupStack::PopAndDestroy(); // numberGrouping
       
  1075 
       
  1076         } // end if iNumberGroupingEnabledFlag
       
  1077 
       
  1078     }
       
  1079 
       
  1080 // ----------------------------------------------------
       
  1081 // CMceMessageListItemArray::MakeInboxStatusStringL
       
  1082 // ----------------------------------------------------
       
  1083 void CMceMessageListItemArray::MakeInboxStatusStringL( TDes& aText, const TMsvEntry& aEntry ) const
       
  1084     {
       
  1085     AppendTimeStringL( aText, aEntry );
       
  1086     if ( iRegistryObserver )
       
  1087         {
       
  1088         CBaseMtmUiData* data=iRegistryObserver->GetMtmUiDataL( aEntry.iMtm );
       
  1089         if ( data )
       
  1090             {
       
  1091             HBufC* statusText=data->StatusTextL( aEntry );
       
  1092             StripAndAppendString( aText, statusText->Des() );            
       
  1093             delete statusText;
       
  1094             }
       
  1095         }
       
  1096     }
       
  1097 
       
  1098 // ----------------------------------------------------
       
  1099 // CMceMessageListItemArray::HandleFolderMessagesStringL
       
  1100 // ----------------------------------------------------
       
  1101 void CMceMessageListItemArray::HandleFolderMessagesStringL( TDes& aBuffer, const TMsvEntry& aEntry ) const
       
  1102     {
       
  1103     CMsvEntry* folderCEntry = NULL;
       
  1104     folderCEntry = iFolderEntry->ChildEntryL( aEntry.Id() );
       
  1105    
       
  1106 	TUid technologyType = KNullUid;
       
  1107 
       
  1108     if ( aEntry.iMtm.iUid != 0 && aEntry.iMtm != KUidMsvLocalServiceMtm &&
       
  1109          iUiRegistry->IsPresent( aEntry.iMtm ) )
       
  1110         {
       
  1111         technologyType = iUiRegistry->TechnologyTypeUid( aEntry.iMtm );
       
  1112         }
       
  1113 
       
  1114     // Is Mail MTM
       
  1115     if ( KSenduiTechnologyMailUid == technologyType )
       
  1116         {
       
  1117         // Count subfolders
       
  1118         CMsvEntrySelection* sel=folderCEntry->ChildrenWithTypeL( KUidMsvFolderEntry );
       
  1119         CleanupStack::PushL(sel);
       
  1120         TInt folderCount = sel->Count();               
       
  1121 
       
  1122         // Count mail messages
       
  1123         CMsvEntrySelection* mesSel=folderCEntry->ChildrenWithTypeL( KUidMsvMessageEntry );
       
  1124         CleanupStack::PushL( mesSel );
       
  1125         TInt messagesCount = mesSel->Count();
       
  1126         CleanupStack::PopAndDestroy(); // mesSel
       
  1127 
       
  1128         CArrayFix<TInt>* indexArray =
       
  1129             new( ELeave ) CArrayFixFlat<TInt>( KMceListArrayGranuality );             
       
  1130                     
       
  1131         CleanupStack::PushL( indexArray );
       
  1132            
       
  1133        if (folderCount >  0)
       
  1134            {
       
  1135            TInt cnt;
       
  1136            for(cnt=0;cnt<folderCount;cnt++)
       
  1137                {
       
  1138                CMsvEntry* folderSubEntry = iSession->GetEntryL( sel->At( cnt ) );
       
  1139                CleanupStack::PushL( folderSubEntry );
       
  1140                CMsvEntrySelection* mesSel = folderSubEntry->ChildrenWithTypeL( KUidMsvMessageEntry );
       
  1141                CleanupStack::PushL( mesSel );        
       
  1142                messagesCount+=mesSel->Count();              
       
  1143                CleanupStack::PopAndDestroy( mesSel );
       
  1144                CleanupStack::PopAndDestroy( folderSubEntry );
       
  1145                }
       
  1146            }
       
  1147         indexArray->AppendL( folderCount );
       
  1148         indexArray->AppendL( messagesCount );           
       
  1149 
       
  1150         HBufC* tempString = NULL;               
       
  1151 
       
  1152         if ( folderCount == 1 )
       
  1153             {
       
  1154             if ( messagesCount == 1 )
       
  1155                 {
       
  1156                 tempString = StringLoader::LoadLC(
       
  1157                     R_MCE_MAILBOX_AMOUNT_FOLDER_MAIL, *indexArray );
       
  1158                 }
       
  1159             else
       
  1160                 {
       
  1161                 tempString = StringLoader::LoadLC(
       
  1162                     R_MCE_MAILBOX_AMOUNT_FOLDER_MAILS, *indexArray );
       
  1163                 }
       
  1164             }
       
  1165         else
       
  1166             {
       
  1167             if ( messagesCount == 1 )
       
  1168                 {
       
  1169                 tempString = StringLoader::LoadLC(
       
  1170 	                R_MCE_MAILBOX_AMOUNT_FOLDERS_MAIL, *indexArray );
       
  1171                 }
       
  1172             else
       
  1173                 {
       
  1174                 tempString = StringLoader::LoadLC(
       
  1175                     R_MCE_MAILBOX_AMOUNT_FOLDERS_MAILS, *indexArray );
       
  1176                 }
       
  1177             }
       
  1178            
       
  1179         aBuffer.Append( tempString->Des() );
       
  1180         CleanupStack::PopAndDestroy( 2 ); // indexArray, tempString
       
  1181        CleanupStack::PopAndDestroy(); //sel 
       
  1182         }
       
  1183     else
       
  1184         {
       
  1185         CMsvEntrySelection* mesSel=folderCEntry->ChildrenWithTypeL( KUidMsvMessageEntry );
       
  1186         CleanupStack::PushL( mesSel );
       
  1187         TInt messagesCount = mesSel->Count();
       
  1188         CleanupStack::PopAndDestroy(); // mesSel
       
  1189         
       
  1190         // Append Message count
       
  1191         if ( messagesCount == 1 )
       
  1192             {
       
  1193             TBuf<KMcePrintableTextLength> tempString;
       
  1194             tempString.Append( (*iNumberOfMessagesStrings)[
       
  1195                 KMceListArrayDocAmount] );
       
  1196             AknTextUtils::LanguageSpecificNumberConversion( tempString );
       
  1197             aBuffer.Append( tempString );
       
  1198             }
       
  1199         else
       
  1200             {
       
  1201             TBuf<KMcePrintableTextLength> tempString;
       
  1202             StringLoader::Format( tempString,
       
  1203                 (*iNumberOfMessagesStrings)[KMceListArrayDocAmountMany],
       
  1204                 -1, // no index in the key string
       
  1205                 messagesCount );
       
  1206             AknTextUtils::LanguageSpecificNumberConversion( tempString );
       
  1207             aBuffer.Append( tempString );
       
  1208             }
       
  1209         }
       
  1210     delete folderCEntry;
       
  1211     }
       
  1212 
       
  1213 // ----------------------------------------------------
       
  1214 // CMceMessageListItemArray::SetOrderingL
       
  1215 // Sets sort order in folder entry, overloaded version
       
  1216 // ----------------------------------------------------
       
  1217 void CMceMessageListItemArray::SetOrderingL( TInt aSortType, TBool aOrdering )
       
  1218     { 
       
  1219     TMsvSorting sorting = EMsvSortByDateReverse;
       
  1220     TInt grouping = KMsvGroupByStandardFolders; 
       
  1221     switch ( aSortType )
       
  1222         {
       
  1223         case EMceCmdSortByType:            
       
  1224             grouping=KMsvGroupByStandardFolders|KMsvGroupByMtm; 
       
  1225             sorting = aOrdering ? EMsvSortByIdReverse: EMsvSortById;
       
  1226             break;  
       
  1227         case EMceCmdSortByRecipient:           
       
  1228         case EMceCmdSortBySender:
       
  1229             sorting= aOrdering ? EMsvSortByDetailsReverse: EMsvSortByDetails;
       
  1230             break;
       
  1231         case EMceCmdSortBySubject:
       
  1232             sorting= aOrdering ? EMsvSortByDescriptionReverse: EMsvSortByDescription;
       
  1233             break;        
       
  1234         case EMceCmdSortByDate:
       
  1235         default:            
       
  1236             sorting= aOrdering ? EMsvSortByDate: EMsvSortByDateReverse;
       
  1237             break;
       
  1238         }
       
  1239 
       
  1240     const TMsvSelectionOrdering newOrdering( grouping, sorting, EFalse );
       
  1241     iFolderEntry->SetSortTypeL( newOrdering );
       
  1242     // Ignore possible error. If this leaves worst thing is that ordering is not saved to root for message iterator.
       
  1243     TRAP_IGNORE( SaveOrderingL( newOrdering ) );
       
  1244     iPreviousSelectionOrdering = newOrdering;
       
  1245     }
       
  1246     
       
  1247 // ----------------------------------------------------
       
  1248 // CMceMessageListItemArray::SaveOrderingL
       
  1249 // Write the sorting order into the message store, MUIU accesses and
       
  1250 // uses this for CMessageIterator
       
  1251 // ----------------------------------------------------
       
  1252 void CMceMessageListItemArray::SaveOrderingL( const TMsvSelectionOrdering& aNewOrdering ) const
       
  1253     {
       
  1254     // TMsvSelectionOrdering class does not have != operator
       
  1255     if ( !(iPreviousSelectionOrdering == aNewOrdering ) )
       
  1256         {
       
  1257         CMsvEntry* entry=iSession->GetEntryL( KMsvRootIndexEntryId ); // Access the entry
       
  1258         CleanupStack::PushL( entry );
       
  1259         CMsvStore* store = entry->EditStoreL();
       
  1260         CleanupStack::PushL( store );
       
  1261         RMsvWriteStream writeStream;
       
  1262         writeStream.AssignLC( *store, KUidMsvMessageListSortOrder );
       
  1263         aNewOrdering.ExternalizeL( writeStream );
       
  1264         writeStream.CommitL();
       
  1265         store->CommitL();
       
  1266         CleanupStack::PopAndDestroy( 3 );
       
  1267         }
       
  1268     }
       
  1269 
       
  1270 // ----------------------------------------------------
       
  1271 // CMceMessageListItemArray::SortType
       
  1272 // returns folder's sort type
       
  1273 //
       
  1274 // ----------------------------------------------------
       
  1275 TMsvSelectionOrdering CMceMessageListItemArray::SortType(  )
       
  1276     {
       
  1277     return iFolderEntry->SortType();
       
  1278     }
       
  1279         
       
  1280 // ----------------------------------------------------
       
  1281 // CMceMessageListItemArray::StripPrefix
       
  1282 // Removes the "Re:" or "Fw:" prefixes from the given 
       
  1283 // text string
       
  1284 // ----------------------------------------------------
       
  1285 TInt CMceMessageListItemArray::SkipPrefix( TPtrC aTextString ) const
       
  1286     {
       
  1287     TPtrC searchString( aTextString );
       
  1288     TPtrC searchStringOrig( aTextString );
       
  1289     TInt matchInd = searchString.Match( KSortSubjectSkipString );
       
  1290     TInt matchStart = 0;
       
  1291     TInt lenRight = searchString.Length() - matchInd - 1;
       
  1292     
       
  1293     // Find the last prefix character
       
  1294     while ( matchInd != KErrNotFound  && lenRight > 0 )
       
  1295         {
       
  1296         TPtrC searchString2 = searchString.Right( lenRight );
       
  1297         matchStart += matchInd + 1;
       
  1298         matchInd = searchString2.Match( KSortSubjectSkipString );
       
  1299         lenRight = searchString2.Length() - matchInd - 1;
       
  1300         searchString.Set( searchString2 );
       
  1301         }
       
  1302         
       
  1303     // Skip the white space after the prefix character
       
  1304     matchInd = searchStringOrig.Locate(KWhiteSpaceCharacter);
       
  1305     if ( matchInd!=KErrNotFound && matchStart==matchInd )
       
  1306         {
       
  1307         ++matchStart;
       
  1308         }    
       
  1309     
       
  1310     return matchStart;
       
  1311     }
       
  1312 
       
  1313 // ----------------------------------------------------
       
  1314 // CMceMessageListItemArray::AppendBtIrMessageStringL
       
  1315 // ----------------------------------------------------
       
  1316 void CMceMessageListItemArray::AppendBtIrMessageStringL( TDes& aBuffer, const TMsvEntry& aEntry ) const
       
  1317     {
       
  1318     HBufC *fileName = AknTextUtils::ConvertFileNameL( aEntry.iDescription );
       
  1319     StripAndAppendString( aBuffer, *fileName ); // does not leave
       
  1320 	delete fileName;
       
  1321     }
       
  1322     
       
  1323 #ifdef RD_READ_MESSAGE_DELETION      
       
  1324 // ----------------------------------------------------
       
  1325 // CMceMessageListItemArray::GetParentFolder
       
  1326 // ----------------------------------------------------
       
  1327 TMsvId CMceMessageListItemArray::GetParentFolderId() const
       
  1328     {
       
  1329     return iFolderEntry->Entry().Parent();
       
  1330     }
       
  1331 #endif // RD_READ_MESSAGE_DELETION  
       
  1332 
       
  1333 
       
  1334 // ----------------------------------------------------
       
  1335 // CMceMessageListItemArray::
       
  1336 // ----------------------------------------------------
       
  1337 void CMceMessageListItemArray::AppendMessageCountString( TDes& aBuffer, TInt aMessageCount ) const
       
  1338     {
       
  1339     aBuffer.Append( KColumnListSeparator );
       
  1340     if ( aMessageCount == 1 )
       
  1341         {
       
  1342         aBuffer.Append( (*iNumberOfMessagesStrings)[
       
  1343             KMceListArrayDocAmount] );
       
  1344         }
       
  1345     else
       
  1346         {
       
  1347         TBuf<KMcePrintableTextLength> tempString;
       
  1348         StringLoader::Format( tempString,
       
  1349             (*iNumberOfMessagesStrings)[KMceListArrayDocAmountMany],
       
  1350             -1, // no index in the key string
       
  1351             aMessageCount );
       
  1352         aBuffer.Append( tempString );
       
  1353         }
       
  1354 
       
  1355     }
       
  1356 
       
  1357 // ----------------------------------------------------
       
  1358 // CMceMessageListItemArray::
       
  1359 // ----------------------------------------------------
       
  1360 void CMceMessageListItemArray::AppendTimeStringL( TDes& aText, const TMsvEntry& aEntry ) const
       
  1361     {
       
  1362 //        TBuf<KMceMaxDateString> timeBuffer;
       
  1363     TBuf<30> dateBuffer;
       
  1364     TTime timeNow;
       
  1365     timeNow.UniversalTime();
       
  1366     
       
  1367     TTime home;
       
  1368     home.HomeTime();
       
  1369     TTimeIntervalMinutes timeZoneDifference;
       
  1370     TInt err = home.MinutesFrom( timeNow, timeZoneDifference );
       
  1371     if ( err )
       
  1372         {
       
  1373         timeZoneDifference = 0;
       
  1374         }
       
  1375     
       
  1376     timeNow = timeNow + timeZoneDifference;
       
  1377     TDateTime dateTime = timeNow.DateTime();
       
  1378     dateTime.SetHour( 0 );
       
  1379     dateTime.SetMinute( 0 );
       
  1380     dateTime.SetSecond( 0 );
       
  1381     dateTime.SetMicroSecond( 0 );
       
  1382     timeNow = dateTime;
       
  1383     
       
  1384     TTime entryTime = aEntry.iDate + timeZoneDifference;
       
  1385 
       
  1386     TTimeIntervalMinutes oneDay( 1440 );
       
  1387     TInt bufferInt = KMceListArrayDateFormatBuffer; 
       
  1388     TTimeIntervalMinutes minutesfrom;
       
  1389     err = entryTime.MinutesFrom( timeNow, minutesfrom );
       
  1390     if ( err == KErrNone && minutesfrom <= oneDay && minutesfrom.Int() >= 0 )
       
  1391         {
       
  1392         // show time
       
  1393         bufferInt = KMceListArrayTimeFormatBuffer; 
       
  1394         }
       
  1395     entryTime.FormatL( dateBuffer, (*iNumberOfMessagesStrings)[bufferInt] ); 
       
  1396     AknTextUtils::LanguageSpecificNumberConversion( dateBuffer );
       
  1397     aText.Append( dateBuffer );
       
  1398     aText.Append( CEditableText::ESpace );
       
  1399     aText.Append( CEditableText::ESpace );
       
  1400     }
       
  1401 
       
  1402 // ----------------------------------------------------
       
  1403 // CMceMessageListItemArray::
       
  1404 // ----------------------------------------------------
       
  1405 TBool CMceMessageListItemArray::FindFirstUnreadMessageL( TMsvId& aEntryId ) const
       
  1406     {
       
  1407     aEntryId = KErrNotFound;
       
  1408     TInt numberOfUnreadMessages = 0;          
       
  1409     const TInt itemCount = iFolderEntry->Count();    
       
  1410     for ( TInt loop = 0; loop < itemCount; loop++ )
       
  1411         {
       
  1412         if ( (*iFolderEntry)[loop].iType == KUidMsvMessageEntry &&
       
  1413              (*iFolderEntry)[loop].Unread() )
       
  1414             {
       
  1415             if ( aEntryId == KErrNotFound )
       
  1416                 {
       
  1417                 aEntryId = (*iFolderEntry)[loop].Id();
       
  1418                 }
       
  1419             numberOfUnreadMessages++;
       
  1420             if ( numberOfUnreadMessages > 1 )
       
  1421                 {
       
  1422                 // we are only interested of first unread message and info that if
       
  1423                 // there are more than one unread messages.
       
  1424                 // So we can stop if there are more than one.
       
  1425                 break;
       
  1426                 }
       
  1427             }
       
  1428         }
       
  1429     return (numberOfUnreadMessages == 1);
       
  1430     }
       
  1431 
       
  1432 // ----------------------------------------------------
       
  1433 // CMceMessageListItemArray::
       
  1434 // ----------------------------------------------------
       
  1435 TInt CMceMessageListItemArray::MessageCount()
       
  1436     {
       
  1437     TInt numberOfMessages = 0;          
       
  1438     const TInt itemCount = iFolderEntry->Count();    
       
  1439     for ( TInt loop = 0; loop < itemCount; loop++ )
       
  1440         {
       
  1441         if ( (*iFolderEntry)[loop].iType == KUidMsvMessageEntry )
       
  1442             {
       
  1443             numberOfMessages++;
       
  1444             }
       
  1445         }
       
  1446     return numberOfMessages;
       
  1447     }
       
  1448     
       
  1449 // ----------------------------------------------------
       
  1450 // CMceMessageListItemArray::
       
  1451 // ----------------------------------------------------
       
  1452 TInt CMceMessageListItemArray::FolderCount()
       
  1453     {
       
  1454     TInt numberOfFolders = 0;          
       
  1455     const TInt itemCount = iFolderEntry->Count();    
       
  1456     for ( TInt loop = 0; loop < itemCount; loop++ )
       
  1457         {
       
  1458         if ( (*iFolderEntry)[loop].iType == KUidMsvFolderEntry )
       
  1459             {
       
  1460             numberOfFolders++;
       
  1461             }
       
  1462         else if ( (*iFolderEntry)[loop].iType == KUidMsvMessageEntry )
       
  1463             {
       
  1464             // folders are grouped first, so we can stop when first message is reached.
       
  1465             break; //loop = itemCount;
       
  1466             }
       
  1467         }
       
  1468     return numberOfFolders;
       
  1469     }
       
  1470 
       
  1471 
       
  1472 // ----------------------------------------------------
       
  1473 // CMceMessageListItemArray::CreateEntryIndex()
       
  1474 // ----------------------------------------------------
       
  1475 TInt CMceMessageListItemArray::CreateEntryIndexL() const
       
  1476     {
       
  1477     TInt visiblecount;
       
  1478     TInt itemcount = iFolderEntry->Count();
       
  1479 
       
  1480     CMsvEntrySelection *sel = new(ELeave) CMsvEntrySelection;
       
  1481     CleanupStack::PushL( sel );
       
  1482      
       
  1483     //Find email messages 
       
  1484     CMsvEntrySelection *smtpselection = iFolderEntry->ChildrenWithMtmL( KUidMsgTypeSMTP );
       
  1485     CleanupStack::PushL( smtpselection );
       
  1486     
       
  1487     CMsvEntrySelection *pop3selection = NULL;
       
  1488     CMsvEntrySelection *imapselection = NULL ;
       
  1489     CMsvEntrySelection *cmailselection = NULL ;
       
  1490     
       
  1491     if(!iEmailFramework)
       
  1492         {
       
  1493         pop3selection = iFolderEntry->ChildrenWithMtmL( KUidMsgTypePOP3 );
       
  1494         CleanupStack::PushL( pop3selection );
       
  1495         imapselection = iFolderEntry->ChildrenWithMtmL( KUidMsgTypeIMAP4 );
       
  1496         CleanupStack::PushL( imapselection );
       
  1497         }
       
  1498     else
       
  1499         {
       
  1500         cmailselection = iFolderEntry->ChildrenWithMtmL( 
       
  1501                 TUid::Uid(KUidMsgTypeFsMtmVal));
       
  1502         CleanupStack::PushL( cmailselection );
       
  1503         }
       
  1504     
       
  1505     sel->Reset();
       
  1506     iMsgIndex->Reset();
       
  1507 
       
  1508     //store all email id's to sel array
       
  1509     if ( smtpselection!=0 && smtpselection->Count()>0 )
       
  1510         {
       
  1511         for( TInt i=0 ; i < smtpselection->Count() ; i++ )
       
  1512             {
       
  1513             sel->AppendL( smtpselection->At(i) );
       
  1514             }
       
  1515         }
       
  1516     if(!iEmailFramework)
       
  1517         {
       
  1518         if ( pop3selection!=0 && pop3selection->Count()>0 )
       
  1519             {
       
  1520             for( TInt i=0 ; i < pop3selection->Count() ; i++ )
       
  1521                 {
       
  1522                 sel->AppendL( pop3selection->At(i) );
       
  1523                 }
       
  1524             }
       
  1525         if ( imapselection!=0 && imapselection->Count()>0 )
       
  1526             {
       
  1527             for( TInt i=0 ; i < imapselection->Count() ; i++ )
       
  1528                 {
       
  1529                 sel->AppendL( imapselection->At(i) );
       
  1530                 }
       
  1531             }
       
  1532         }
       
  1533     else
       
  1534         {
       
  1535         if ( cmailselection!=0 && cmailselection->Count()>0 )
       
  1536             {
       
  1537             for( TInt i=0 ; i < cmailselection->Count() ; i++ )
       
  1538                 {
       
  1539                 sel->AppendL( cmailselection->At(i) );
       
  1540                 }
       
  1541             }
       
  1542         }
       
  1543     visiblecount = itemcount - sel->Count();
       
  1544 
       
  1545     TInt i = 0;
       
  1546     TInt j = visiblecount;
       
  1547 
       
  1548     if ( visiblecount < itemcount )
       
  1549         {
       
  1550         do
       
  1551             {
       
  1552             if ( sel->Find( (*iFolderEntry)[i].Id() ) == KErrNotFound )
       
  1553                 {
       
  1554                 //add everything else but emails to msg index
       
  1555                 iMsgIndex->AppendL( i );
       
  1556                 j--;
       
  1557                 }
       
  1558             i++;
       
  1559 
       
  1560             } while ( j > 0 && i < itemcount);    
       
  1561         }
       
  1562     
       
  1563     if(iEmailFramework)
       
  1564         {
       
  1565         CleanupStack::PopAndDestroy( cmailselection );       
       
  1566         }
       
  1567     else
       
  1568         {
       
  1569         CleanupStack::PopAndDestroy(imapselection);
       
  1570         CleanupStack::PopAndDestroy( pop3selection );
       
  1571         }
       
  1572     CleanupStack::PopAndDestroy( smtpselection );
       
  1573     CleanupStack::PopAndDestroy( sel );
       
  1574 
       
  1575     return visiblecount; 
       
  1576     }
       
  1577 
       
  1578 // ----------------------------------------------------
       
  1579 // CMceListItemArray::GetEntryIndex()
       
  1580 // ----------------------------------------------------
       
  1581 TInt CMceMessageListItemArray::GetEntryIndex( TInt aIndex ) const
       
  1582     {
       
  1583     TInt tmpindex = aIndex;
       
  1584 
       
  1585     if ( (iEmailClientIntegration && iIntegratedEmailAppExcist) || iEmailFramework ) 
       
  1586         {
       
  1587         if( ( iFolderId == KMsvDraftEntryId || 
       
  1588                 iFolderId == KMsvSentEntryId || 
       
  1589                 iFolderId == KMsvDeletedEntryFolderEntryId || 
       
  1590                 iFolderId == KMsvGlobalInBoxIndexEntryId || iFolderId == KMsvGlobalOutBoxIndexEntryId ) &&
       
  1591                 iMsgIndex->Count() > 0 )
       
  1592             {
       
  1593             tmpindex = iMsgIndex->At( aIndex );
       
  1594             }
       
  1595         }
       
  1596 
       
  1597     return tmpindex;
       
  1598     }
       
  1599 
       
  1600 //  End of File