wvuing/wvuieng/EngSrc/CCAChatContainer.cpp
changeset 0 094583676ce7
equal deleted inserted replaced
-1:000000000000 0:094583676ce7
       
     1 /*
       
     2 * Copyright (c) 2004-2005 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:  Container for message containers
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 #include "CCAChatContainer.h"
       
    20 #include "CCAMessageContainer.h"
       
    21 #include "PublicEngineDefinitions.h"
       
    22 #include "MCAChatObserver.h"
       
    23 #include "MCASettings.h"
       
    24 #include "mcamessage.h"
       
    25 
       
    26 #include "ChatDebugAssert.h"
       
    27 #include "ChatDebugPrint.h"
       
    28 #include <hal.h>
       
    29 
       
    30 const TInt KMinAvailableMemory = 0x32000; // 200kb
       
    31 
       
    32 //-----------------------------------------------------------------------------
       
    33 // CCAChatContainer::CCAChatContainer
       
    34 // ( Other items commented in header )
       
    35 //-----------------------------------------------------------------------------
       
    36 CCAChatContainer::CCAChatContainer( MCASettings& aSettingsInterface )
       
    37         : iSettingsInterface( aSettingsInterface )
       
    38     {
       
    39     }
       
    40 
       
    41 //-----------------------------------------------------------------------------
       
    42 // CCAChatContainer::CCAChatContainer
       
    43 // ( Other items commented in header )
       
    44 //-----------------------------------------------------------------------------
       
    45 CCAChatContainer::~CCAChatContainer()
       
    46     {
       
    47     iChatContainer.ResetAndDestroy();
       
    48     iGroupContainer.ResetAndDestroy();
       
    49     iSendContainer.ResetAndDestroy();
       
    50     iObservers.Reset();
       
    51     }
       
    52 
       
    53 //-----------------------------------------------------------------------------
       
    54 // CCAChatContainer::NewL
       
    55 // ( Other items commented in header )
       
    56 //-----------------------------------------------------------------------------
       
    57 CCAChatContainer* CCAChatContainer::NewL( MCASettings& aSettingsInterface )
       
    58     {
       
    59     CCAChatContainer* self =
       
    60         new ( ELeave ) CCAChatContainer( aSettingsInterface );
       
    61 
       
    62     return self;
       
    63     }
       
    64 
       
    65 //-----------------------------------------------------------------------------
       
    66 // CCAChatContainer::MessageReadInterfaceL
       
    67 // ( Other items commented in header )
       
    68 //-----------------------------------------------------------------------------
       
    69 MCAMessagesReadInterface& CCAChatContainer::MessageReadInterfaceL(
       
    70     const TDesC& aServerAddress,
       
    71     const TDesC& aUserId,
       
    72     const TDesC& aTargetId,
       
    73     MCAMessagesReadInterface::TContainerType aType )
       
    74     {
       
    75     return *ChatL( ChatL( aServerAddress, aUserId, aTargetId, aType ) );
       
    76     }
       
    77 
       
    78 //-----------------------------------------------------------------------------
       
    79 // CCAChatContainer::MessageWriteInterfaceL
       
    80 // ( Other items commented in header )
       
    81 //-----------------------------------------------------------------------------
       
    82 MCAMessagesWriteInterface& CCAChatContainer::MessageWriteInterfaceL(
       
    83     const TDesC& aServerAddress,
       
    84     const TDesC& aUserId,
       
    85     const TDesC& aTargetId,
       
    86     MCAMessagesReadInterface::TContainerType aType )
       
    87     {
       
    88     return *ChatL( ChatL( aServerAddress, aUserId, aTargetId, aType ) );
       
    89     }
       
    90 
       
    91 //-----------------------------------------------------------------------------
       
    92 // CCAChatContainer::DeleteChatL
       
    93 // ( Other items commented in header )
       
    94 //-----------------------------------------------------------------------------
       
    95 void CCAChatContainer::DeleteChatL( const TDesC& aServerAddress,
       
    96                                     const TDesC& aUserId,
       
    97                                     const TDesC& aTargetId )
       
    98     {
       
    99     // Find out if chat exist or not. ChatExists() not used,
       
   100     // because we need index.
       
   101     CCAMessageContainer* tempChat = CreateContainerLC(
       
   102                                         aServerAddress,
       
   103                                         aUserId,
       
   104                                         aTargetId,
       
   105                                         *this,
       
   106                                         MCAMessagesReadInterface::ENoneContainer );
       
   107     TInt index( FindChat( *tempChat ) );
       
   108     CleanupStack::PopAndDestroy( tempChat );
       
   109 
       
   110     // If index is positive  value, Chat exists and we can remove it.
       
   111     if ( index >= 0 )
       
   112         {
       
   113         CCAMessageContainer* target = ChatL( index, EFalse );
       
   114 
       
   115         // Get count of pending messages before removing chat
       
   116         TInt ignore;
       
   117         TInt pendignMsgs = MessagesPendingCount( ignore );
       
   118 
       
   119         RemoveChat( index );
       
   120 
       
   121         // Check if removed chat had unread messages
       
   122         if ( pendignMsgs != MessagesPendingCount( ignore ) )
       
   123             {
       
   124             // Notify about changed unread count
       
   125             HandleChatEvent( EUnreadCountChanged );
       
   126             }
       
   127 
       
   128         // Observers are notified, delete target.
       
   129         delete target;
       
   130         }
       
   131     else if ( index != KErrNotFound )
       
   132         {
       
   133         // some other error than not found occurred. Inform caller.
       
   134         User::Leave( index );
       
   135         }
       
   136     }
       
   137 
       
   138 //-----------------------------------------------------------------------------
       
   139 // CCAChatContainer::CloseAllContainers
       
   140 // ( Other items commented in header )
       
   141 //-----------------------------------------------------------------------------
       
   142 void CCAChatContainer::CloseAllContainers()
       
   143     {
       
   144     iChatContainer.ResetAndDestroy();
       
   145     HandleChatEvent( EChatListChanged );
       
   146     iGroupContainer.ResetAndDestroy();
       
   147     HandleChatEvent( EGroupListChanged );
       
   148     }
       
   149 
       
   150 //-----------------------------------------------------------------------------
       
   151 // CCAChatContainer::ChatExistsL
       
   152 // ( Other items commented in header )
       
   153 //-----------------------------------------------------------------------------
       
   154 MCAMessagesReadInterface* CCAChatContainer::ChatExistsL(
       
   155     const TDesC& aServerAddress,
       
   156     const TDesC& aUserId,
       
   157     const TDesC& aTargetId )
       
   158     {
       
   159     CCAMessageContainer* tempChat = CreateContainerLC(
       
   160                                         aServerAddress,
       
   161                                         aUserId,
       
   162                                         aTargetId,
       
   163                                         *this,
       
   164                                         MCAMessagesReadInterface::ENoneContainer );
       
   165 
       
   166     TInt index( FindChat( *tempChat ) );
       
   167     CleanupStack::PopAndDestroy( tempChat );
       
   168     if ( index < 0 )
       
   169         {
       
   170         return NULL;
       
   171         }
       
   172     return ChatL( index );
       
   173     }
       
   174 
       
   175 //-----------------------------------------------------------------------------
       
   176 // CCAChatContainer::ChangeChatIdL
       
   177 // ( Other items commented in header )
       
   178 //-----------------------------------------------------------------------------
       
   179 MCAMessagesReadInterface& CCAChatContainer::ChangeChatIdL(
       
   180     const TDesC& aOldServerAddress,
       
   181     const TDesC& aOldUserId,
       
   182     const TDesC& aOldTargetId,
       
   183     const TDesC& aNewServerAddress,
       
   184     const TDesC& aNewUserId,
       
   185     const TDesC& aNewTargetId,
       
   186     MCAMessagesReadInterface::TContainerType aType )
       
   187     {
       
   188     // If old does not exists. ChatL creates it.
       
   189     TInt index = ChatL(  aOldServerAddress, aOldUserId, aOldTargetId  );
       
   190     CCAMessageContainer* target = ChatL( index, EFalse );
       
   191 
       
   192     MCAMessagesReadInterface::TContainerType oldType = target->ContainerType();
       
   193 
       
   194     // Update chat to new type.
       
   195     target->ChangeIdL(  aNewServerAddress, aNewUserId, aNewTargetId, aType  );
       
   196 
       
   197     MCAMessagesReadInterface::TContainerType newType = target->ContainerType();
       
   198 
       
   199     // If type is changed, container must be changed.
       
   200     if ( oldType != newType )
       
   201         {
       
   202         // Remove chat from current container.
       
   203         RemoveChat( index );
       
   204         CleanupStack::PushL( target );
       
   205 
       
   206         // Append to right container.
       
   207         TLinearOrder< CCAMessageContainer > order(
       
   208             CCAMessageContainer::OrderUid );
       
   209         switch ( newType )
       
   210             {
       
   211             case MCAMessagesReadInterface::EGroupContainer:
       
   212                 {
       
   213                 // User::LeaveIfError returns value if value is positive.
       
   214                 index = User::LeaveIfError( iGroupContainer.InsertInOrder(
       
   215                                                 target, order ) );
       
   216                 HandleChatEvent( EGroupListChanged );
       
   217                 break;
       
   218                 }
       
   219             case MCAMessagesReadInterface::EChatContainer:
       
   220                 {
       
   221                 index = User::LeaveIfError( iChatContainer.InsertInOrder(
       
   222                                                 target, order ) );
       
   223                 HandleChatEvent( EChatListChanged );
       
   224                 break;
       
   225                 }
       
   226             case MCAMessagesReadInterface::ESendContainer:
       
   227                 {
       
   228                 index = User::LeaveIfError(
       
   229                             iSendContainer.InsertInOrder( target, order ) );
       
   230                 break;
       
   231                 }
       
   232             default:
       
   233                 {
       
   234                 User::Leave( KErrArgument );
       
   235                 break;
       
   236                 }
       
   237             }
       
   238         CleanupStack::Pop( target );
       
   239         }
       
   240     else
       
   241         {
       
   242         switch ( newType )
       
   243             {
       
   244             case MCAMessagesReadInterface::EGroupContainer:
       
   245                 {
       
   246                 HandleChatEvent( EGroupListChanged );
       
   247                 break;
       
   248                 }
       
   249             case MCAMessagesReadInterface::EChatContainer:
       
   250                 {
       
   251                 HandleChatEvent( EChatListChanged );
       
   252                 break;
       
   253                 }
       
   254             default:
       
   255                 {
       
   256                 User::Leave( KErrArgument );
       
   257                 break;
       
   258                 }
       
   259             }
       
   260         }
       
   261     iLatestType = newType;
       
   262     return *target;
       
   263     }
       
   264 
       
   265 //-----------------------------------------------------------------------------
       
   266 // CCAChatContainer::GroupCount
       
   267 // ( Other items commented in header )
       
   268 //-----------------------------------------------------------------------------
       
   269 TInt CCAChatContainer::GroupCount() const
       
   270     {
       
   271     return iGroupContainer.Count();
       
   272     }
       
   273 
       
   274 //-----------------------------------------------------------------------------
       
   275 // CCAChatContainer::ChatCount
       
   276 // ( Other items commented in header )
       
   277 //-----------------------------------------------------------------------------
       
   278 TInt CCAChatContainer::ChatCount() const
       
   279     {
       
   280     return iChatContainer.Count();
       
   281     }
       
   282 
       
   283 //-----------------------------------------------------------------------------
       
   284 // CCAChatContainer::GroupAt
       
   285 // ( Other items commented in header )
       
   286 //-----------------------------------------------------------------------------
       
   287 MCAMessagesReadInterface& CCAChatContainer::GroupAt( TInt aIndex ) const
       
   288     {
       
   289     __CHAT_ASSERT_DEBUG( aIndex >= 0 && aIndex < GroupCount() );
       
   290     return *iGroupContainer[ aIndex ];
       
   291     }
       
   292 
       
   293 //-----------------------------------------------------------------------------
       
   294 // CCAChatContainer::ChatAt
       
   295 // ( Other items commented in header )
       
   296 //-----------------------------------------------------------------------------
       
   297 MCAMessagesReadInterface& CCAChatContainer::ChatAt( TInt aIndex ) const
       
   298     {
       
   299     __CHAT_ASSERT_DEBUG( aIndex >= 0 && aIndex < ChatCount() )
       
   300     return *iChatContainer[ aIndex ];
       
   301     }
       
   302 
       
   303 
       
   304 //-----------------------------------------------------------------------------
       
   305 // CCAChatContainer::RegisterChatObserver
       
   306 // ( Other items commented in header )
       
   307 //-----------------------------------------------------------------------------
       
   308 TInt CCAChatContainer::RegisterChatObserver( MCAChatObserver* aObserver )
       
   309     {
       
   310     TInt index = iObservers.Find( aObserver );
       
   311     if ( index == KErrNotFound )
       
   312         {
       
   313         return iObservers.Append( aObserver );
       
   314         }
       
   315     return KErrAlreadyExists;
       
   316     }
       
   317 
       
   318 //-----------------------------------------------------------------------------
       
   319 // CCAChatContainer::RegisterChatObserver
       
   320 // ( Other items commented in header )
       
   321 //-----------------------------------------------------------------------------
       
   322 TInt CCAChatContainer::UnregisterChatObserver( MCAChatObserver* aObserver )
       
   323     {
       
   324     TInt index = iObservers.Find( aObserver );
       
   325     if ( index >= 0 )
       
   326         {
       
   327         iObservers.Remove( index );
       
   328         return KErrNone;
       
   329         }
       
   330     return index;
       
   331     }
       
   332 
       
   333 //-----------------------------------------------------------------------------
       
   334 // CCAChatContainer::ResetPendingCount
       
   335 // ( Other items commented in header )
       
   336 //-----------------------------------------------------------------------------
       
   337 void CCAChatContainer::ResetPendingCount()
       
   338     {
       
   339     TInt count( ChatCount() );
       
   340     for ( TInt a( 0 ); a < count; ++a )
       
   341         {
       
   342         ChatAt( a ).Read( MCAMessagesReadInterface::EReadAll );
       
   343         }
       
   344     }
       
   345 
       
   346 //-----------------------------------------------------------------------------
       
   347 // CCAChatContainer::PendingMessagesCount
       
   348 // ( Other items commented in header )
       
   349 //-----------------------------------------------------------------------------
       
   350 TInt CCAChatContainer::MessagesPendingCount( TInt& aCountOfChats,
       
   351                                              MCAMessagesReadInterface::TUnreadFilter aUnreadFilter
       
   352                                              /*= MCAMessagesReadInterface::EUnreadAll*/ ) const
       
   353     {
       
   354     TInt count( ChatCount() );
       
   355     TInt pendingCount( 0 );
       
   356     aCountOfChats = 0;
       
   357     for ( TInt a( 0 ); a < count; ++a )
       
   358         {
       
   359         TInt unreadCount = ChatAt( a ).UnreadCount( aUnreadFilter );
       
   360         if ( unreadCount > 0 )
       
   361             {
       
   362             pendingCount += unreadCount;
       
   363             ++aCountOfChats;
       
   364             }
       
   365         }
       
   366     return pendingCount;
       
   367     }
       
   368 
       
   369 //-----------------------------------------------------------------------------
       
   370 // CCAChatContainer::PendingMessagesCount
       
   371 // ( Other items commented in header )
       
   372 //-----------------------------------------------------------------------------
       
   373 MCAMessageContainerInfo* CCAChatContainer::PendingMessageInfo() const
       
   374     {
       
   375     TInt count( ChatCount() );
       
   376     for ( TInt a( 0 ); a < count; ++a )
       
   377         {
       
   378         if ( ChatAt( a ).UnreadCount( MCAMessagesReadInterface::EUnreadReceived ) > 0 )
       
   379             {
       
   380             return iChatContainer[ a ];
       
   381             }
       
   382         }
       
   383     return NULL;
       
   384     }
       
   385 
       
   386 #ifdef RD_CHAT_GROUP_MESSAGE_INDICATION_NEW
       
   387 //-----------------------------------------------------------------------------
       
   388 // CCAChatContainer::ChatGroupMessagesPendingCount
       
   389 // ( Other items commented in header )
       
   390 //-----------------------------------------------------------------------------
       
   391 TInt CCAChatContainer::ChatGroupMessagesPendingCount( TInt& aCountOfChats ) const
       
   392     {
       
   393     TInt count = GroupCount();
       
   394     TInt pendingCount = 0;
       
   395     aCountOfChats = 0;
       
   396 
       
   397     for ( TInt i = 0; i < count; ++i )
       
   398         {
       
   399         TInt unreadCount = GroupAt( i ).UnreadCount(
       
   400                                MCAMessagesReadInterface::EUnreadReceived );
       
   401         if ( unreadCount > 0 )
       
   402             {
       
   403             pendingCount += unreadCount;
       
   404             ++aCountOfChats;
       
   405             }
       
   406         }
       
   407 
       
   408     return pendingCount;
       
   409     }
       
   410 
       
   411 
       
   412 //-----------------------------------------------------------------------------
       
   413 // CCAChatContainer::ChatGroupPendingMessageInfo
       
   414 // ( Other items commented in header )
       
   415 //-----------------------------------------------------------------------------
       
   416 MCAMessageContainerInfo* CCAChatContainer::ChatGroupPendingMessageInfo() const
       
   417     {
       
   418     TInt count( GroupCount() );
       
   419     for ( TInt a( 0 ); a < count; ++a )
       
   420         {
       
   421         if ( GroupAt( a ).UnreadCount( MCAMessagesReadInterface::EUnreadReceived ) > 0 )
       
   422             {
       
   423             return iGroupContainer[ a ];
       
   424             }
       
   425         }
       
   426     return NULL;
       
   427     }
       
   428 
       
   429 #endif  // RD_CHAT_GROUP_MESSAGE_INDICATION_NEW
       
   430 
       
   431 //-----------------------------------------------------------------------------
       
   432 // CCAChatContainer::MessageInterface
       
   433 // ( Other items commented in header )
       
   434 //-----------------------------------------------------------------------------
       
   435 TBool CCAChatContainer::FreeMemoryIfNeededL( TInt aSize )
       
   436     {
       
   437     CHAT_DP_FUNC_ENTER( "CCAChatContainer::FreeMemoryIfNeededL" );
       
   438 
       
   439     TInt halSize;
       
   440     TInt biggestBlock;
       
   441 
       
   442     HAL::Get( HALData::EMemoryRAMFree, halSize );
       
   443     TInt maxHeap = Min( User::Heap().MaxLength(), halSize );
       
   444     TInt available = maxHeap - ( User::Heap().Size() - User::Heap().Available( biggestBlock ) );
       
   445     TInt memoryNeed = KMinAvailableMemory + aSize;
       
   446 
       
   447     TTime oldestUnread;
       
   448     TInt unreadIndex;
       
   449 
       
   450     CHAT_DP( D_CHAT_LIT( "CCAChatContainer::FreeMemoryIfNeededL, heapSize = %d" ), maxHeap );
       
   451     CHAT_DP( D_CHAT_LIT( "****heapSize, available, need = %d, %d, %d" ),
       
   452              maxHeap, available, memoryNeed );
       
   453 
       
   454     TBool ready = EFalse;
       
   455     TBool memLowNotified = EFalse;
       
   456     while ( !ready )
       
   457         {
       
   458         TBool freeMemoryNeeded( EFalse );
       
   459         if ( iExternalMemoryHandler )
       
   460             {
       
   461             freeMemoryNeeded = !iExternalMemoryHandler->FreeMemoryIfNeededL( aSize );
       
   462             }
       
   463         if ( freeMemoryNeeded || memoryNeed > available )
       
   464             {
       
   465             // we have to react.
       
   466             TInt count = GroupCount();
       
   467 
       
   468             // Check how much memory can be made free
       
   469             TInt freeableBytes = 0;
       
   470             for ( TInt i = 0; i < count; ++i )
       
   471                 {
       
   472                 TBool locked = iGroupContainer[i]->IsLocked();
       
   473                 if ( iGroupContainer[i]->AllMessagesCount() && !locked )
       
   474                     {
       
   475                     freeableBytes += iGroupContainer[i]->ContainerSizeInBytes();
       
   476                     }
       
   477                 }
       
   478 
       
   479             if ( ( ( available + freeableBytes ) < memoryNeed )
       
   480                  && !memLowNotified )
       
   481                 {
       
   482                 // Can't free enough memory
       
   483                 return EFalse;
       
   484                 }
       
   485 
       
   486             oldestUnread.HomeTime();
       
   487             unreadIndex = KErrNotFound;
       
   488 
       
   489             for ( TInt a( 0 ); a < count; ++a )
       
   490                 {
       
   491                 MCAMessagesReadInterface& chat = GroupAt( a );
       
   492                 TBool locked = iGroupContainer[ a ]->IsLocked();
       
   493                 if ( iGroupContainer[ a ]->AllMessagesCount() && !locked )
       
   494                     {
       
   495                     MCAMessage& message = iGroupContainer[ a ]->MessageFromAll( 0 );
       
   496                     if ( oldestUnread > message.TimeStamp() )
       
   497                         {
       
   498                         oldestUnread = message.TimeStamp();
       
   499                         unreadIndex = a;
       
   500                         }
       
   501                     }
       
   502                 }
       
   503 
       
   504             if ( unreadIndex == KErrNotFound )
       
   505                 {
       
   506                 return EFalse;
       
   507                 }
       
   508             else
       
   509                 {
       
   510                 // Inform observers about memory handling
       
   511                 if ( !memLowNotified )
       
   512                     {
       
   513                     HandleChatEvent( EMemoryLow );
       
   514                     memLowNotified = ETrue;
       
   515                     }
       
   516                 iGroupContainer[ unreadIndex ]->DeleteMessageFromAll( 0 );
       
   517                 }
       
   518             available = maxHeap - ( User::Heap().Size() - User::Heap().Available( biggestBlock ) );
       
   519             CHAT_DP( D_CHAT_LIT( "****heapSize, available, need = %d, %d, %d" ),
       
   520                      maxHeap, available, memoryNeed );
       
   521             }
       
   522         else
       
   523             {
       
   524             ready = ETrue;
       
   525             }
       
   526         }
       
   527     CHAT_DP_FUNC_DONE( "CCAChatContainer::FreeMemoryIfNeededL" );
       
   528     return ETrue;
       
   529     }
       
   530 
       
   531 //-----------------------------------------------------------------------------
       
   532 // CCAChatContainer::SetAccessInterface
       
   533 // ( Other items commented in header )
       
   534 //-----------------------------------------------------------------------------
       
   535 void CCAChatContainer::SetAccessInterface( MCAChatInterface* /*aAccess*/ )
       
   536     {
       
   537     // Not need to use in here. We have access already.
       
   538     }
       
   539 
       
   540 //-----------------------------------------------------------------------------
       
   541 // CCAChatContainer::HandleChatEvent
       
   542 // ( Other items commented in header )
       
   543 //-----------------------------------------------------------------------------
       
   544 void CCAChatContainer::HandleChatEvent( TChatEventType aEvent,
       
   545                                         MCAMessage* aMessage )
       
   546     {
       
   547     // Inform all observer about chat event.
       
   548     TInt count( iObservers.Count() );
       
   549     for ( TInt a( 0 ); a < count; ++a )
       
   550         {
       
   551         iObservers[ a ]->HandleChatEvent( aEvent, aMessage );
       
   552         }
       
   553     }
       
   554 
       
   555 //-----------------------------------------------------------------------------
       
   556 // CCAChatContainer::MessageRecipient
       
   557 // ( Other items commented in header )
       
   558 //-----------------------------------------------------------------------------
       
   559 const TDesC& CCAChatContainer::MessageRecipient( TInt aOperationCode,
       
   560                                                  TInt& aStatus ) const
       
   561     {
       
   562     TInt count( ChatCount() );
       
   563     for ( TInt a( 0 ); a < count; ++a )
       
   564         {
       
   565         const TDesC& res = iChatContainer[ a ]->MessageRecipient(
       
   566                                aOperationCode, aStatus );
       
   567         if ( aStatus == KErrNone )
       
   568             {
       
   569             return res;
       
   570             }
       
   571         }
       
   572 
       
   573     count = GroupCount();
       
   574     for ( TInt a( 0 ); a < count; ++a )
       
   575         {
       
   576         const TDesC& res = iGroupContainer[ a ]->MessageRecipient(
       
   577                                aOperationCode, aStatus );
       
   578         if ( aStatus == KErrNone )
       
   579             {
       
   580             return res;
       
   581             }
       
   582         }
       
   583 
       
   584     count = iSendContainer.Count();
       
   585     for ( TInt a( 0 ); a < count; ++a )
       
   586         {
       
   587         const TDesC& res = iSendContainer[ a ]->MessageRecipient(
       
   588                                aOperationCode, aStatus );
       
   589         if ( aStatus == KErrNone )
       
   590             {
       
   591             return res;
       
   592             }
       
   593         }
       
   594 
       
   595     aStatus = KErrNotFound;
       
   596     return KNullDesC;
       
   597     }
       
   598 
       
   599 // -----------------------------------------------------------------------------
       
   600 // CCAChatContainer::SetExternalMemoryHandler
       
   601 // ( Other items commented in header )
       
   602 // -----------------------------------------------------------------------------
       
   603 void CCAChatContainer::SetExternalMemoryHandler(
       
   604     MCABufferMemoryHandler* aMemoryHandler )
       
   605     {
       
   606     iExternalMemoryHandler = aMemoryHandler;
       
   607     }
       
   608 
       
   609 //-----------------------------------------------------------------------------
       
   610 // CCAChatContainer::ChatL
       
   611 // ( Other items commented in header )
       
   612 //-----------------------------------------------------------------------------
       
   613 TInt CCAChatContainer::ChatL(
       
   614     const TDesC& aServerAddress,
       
   615     const TDesC& aUserId,
       
   616     const TDesC& aTargetId,
       
   617     MCAMessagesReadInterface::TContainerType aType
       
   618     /*= MCAMessagesReadInterface::ENoneContainer*/ )
       
   619     {
       
   620     CCAMessageContainer* tempChat =
       
   621         CreateContainerLC( aServerAddress, aUserId, aTargetId, *this, aType );
       
   622 
       
   623     TInt index( FindChat( *tempChat ) );
       
   624     if ( index == KErrNotFound )
       
   625         {
       
   626         TLinearOrder< CCAMessageContainer > order(
       
   627             CCAMessageContainer::OrderUid );
       
   628         // User::LeaveIfError returns value if value is positive.
       
   629         iLatestType = tempChat->ContainerType();
       
   630         switch ( iLatestType )
       
   631             {
       
   632             case MCAMessagesReadInterface::EGroupContainer:
       
   633                 {
       
   634                 User::LeaveIfError( iGroupContainer.InsertInOrder( tempChat,
       
   635                                                                    order ) );
       
   636                 index = FindChat( *tempChat );
       
   637                 iGroupContainer[ index ]->SetChatObserver( this );
       
   638                 HandleChatEvent( EGroupListChanged );
       
   639                 break;
       
   640                 }
       
   641             case MCAMessagesReadInterface::EChatContainer:
       
   642                 {
       
   643                 User::LeaveIfError( iChatContainer.InsertInOrder( tempChat,
       
   644                                                                   order ) );
       
   645                 index = FindChat( *tempChat );
       
   646                 iChatContainer[ index ]->SetChatObserver( this );
       
   647                 HandleChatEvent( EChatListChanged );
       
   648                 break;
       
   649                 }
       
   650             case MCAMessagesReadInterface::ESendContainer:
       
   651                 {
       
   652                 User::LeaveIfError( iSendContainer.InsertInOrder( tempChat,
       
   653                                                                   order ) );
       
   654                 index = FindChat( *tempChat );
       
   655                 break;
       
   656                 }
       
   657             default:
       
   658                 {
       
   659                 User::Leave( KErrArgument );
       
   660                 break;
       
   661                 }
       
   662             }
       
   663         CleanupStack::Pop( tempChat );
       
   664         }
       
   665     else
       
   666         {
       
   667         CleanupStack::PopAndDestroy( tempChat );
       
   668         }
       
   669 
       
   670     return User::LeaveIfError( index );
       
   671     }
       
   672 
       
   673 //-----------------------------------------------------------------------------
       
   674 // CCAChatContainer::ChatL
       
   675 // ( Other items commented in header )
       
   676 //-----------------------------------------------------------------------------
       
   677 CCAMessageContainer* CCAChatContainer::ChatL( TInt aIndex,
       
   678                                               TBool aResetLatest /* = ETrue*/ )
       
   679     {
       
   680     MCAMessagesReadInterface::TContainerType type = iLatestType;
       
   681 
       
   682     if ( aResetLatest )
       
   683         {
       
   684         iLatestType = MCAMessagesReadInterface::ENoneContainer;
       
   685         }
       
   686 
       
   687     switch ( type )
       
   688         {
       
   689         case MCAMessagesReadInterface::EGroupContainer:
       
   690             {
       
   691             return iGroupContainer[ aIndex ];
       
   692             }
       
   693         case MCAMessagesReadInterface::EChatContainer:
       
   694             {
       
   695             return iChatContainer[ aIndex ];
       
   696             }
       
   697         case MCAMessagesReadInterface::ESendContainer:
       
   698             {
       
   699             return iSendContainer[ aIndex ];
       
   700             }
       
   701         default:
       
   702             {
       
   703             User::Leave( KErrArgument );
       
   704             break;
       
   705             }
       
   706         }
       
   707     // Can never get this far
       
   708     __CHAT_ASSERT_DEBUG( EFalse );
       
   709     return NULL;
       
   710     }
       
   711 
       
   712 //-----------------------------------------------------------------------------
       
   713 // CCAChatContainer::RemoveChatL
       
   714 // ( Other items commented in header )
       
   715 //-----------------------------------------------------------------------------
       
   716 void CCAChatContainer::RemoveChat( TInt aIndex,
       
   717                                    TBool aResetLatest /* = ETrue */ )
       
   718     {
       
   719     MCAMessagesReadInterface::TContainerType type = iLatestType;
       
   720 
       
   721     if ( aResetLatest )
       
   722         {
       
   723         iLatestType = MCAMessagesReadInterface::ENoneContainer;
       
   724         }
       
   725 
       
   726     switch ( type )
       
   727         {
       
   728         case MCAMessagesReadInterface::EGroupContainer:
       
   729             {
       
   730             iGroupContainer.Remove( aIndex );
       
   731             HandleChatEvent( EGroupListChanged );
       
   732             break;
       
   733             }
       
   734         case MCAMessagesReadInterface::EChatContainer:
       
   735             {
       
   736             iChatContainer.Remove( aIndex );
       
   737             HandleChatEvent( EChatListChanged );
       
   738             break;
       
   739             }
       
   740         case MCAMessagesReadInterface::ESendContainer:
       
   741             {
       
   742             iSendContainer.Remove( aIndex );
       
   743             break;
       
   744             }
       
   745         default:
       
   746             {
       
   747             break;
       
   748             }
       
   749         }
       
   750     }
       
   751 
       
   752 //-----------------------------------------------------------------------------
       
   753 // CCAChatContainer::FindChat
       
   754 // ( Other items commented in header )
       
   755 //-----------------------------------------------------------------------------
       
   756 TInt CCAChatContainer::FindChat( const CCAMessageContainer& aChat )
       
   757     {
       
   758     TInt index( 0 );
       
   759     TLinearOrder< CCAMessageContainer > order( CCAMessageContainer::OrderUid );
       
   760     TInt status = iChatContainer.FindInOrder( &aChat, index, order );
       
   761     if ( status == KErrNone )
       
   762         {
       
   763         iLatestType = MCAMessagesReadInterface::EChatContainer;
       
   764         return index;
       
   765         }
       
   766     status = iGroupContainer.FindInOrder( &aChat, index, order );
       
   767     if ( status == KErrNone )
       
   768         {
       
   769         iLatestType = MCAMessagesReadInterface::EGroupContainer;
       
   770         return index;
       
   771         }
       
   772     iLatestType = MCAMessagesReadInterface::ESendContainer;
       
   773     status = iSendContainer.FindInOrder( &aChat, index, order );
       
   774     return ( status == KErrNone ? index : status );
       
   775     }
       
   776 
       
   777 //-----------------------------------------------------------------------------
       
   778 // CCAChatContainer::CreateContainerLC
       
   779 // ( Other items commented in header )
       
   780 //-----------------------------------------------------------------------------
       
   781 CCAMessageContainer* CCAChatContainer::CreateContainerLC(
       
   782     const TDesC& aServerAddress,
       
   783     const TDesC& aUserId,
       
   784     const TDesC& aTargetId,
       
   785     MCABufferMemoryHandler& aMemoryHandler,
       
   786     MCAMessagesReadInterface::TContainerType aType )
       
   787     {
       
   788     HBufC* accesspoint = NULL;
       
   789     HBufC* userid = NULL;
       
   790 
       
   791     if ( aServerAddress == KNullDesC )
       
   792         {
       
   793         accesspoint = iSettingsInterface.ValueL( MCASettings::EServiceAddress );
       
   794         CleanupStack::PushL( accesspoint );
       
   795         }
       
   796     if ( aUserId == KNullDesC )
       
   797         {
       
   798         userid = iSettingsInterface.ValueL( MCASettings::EOwnWVUserID );
       
   799         CleanupStack::PushL( userid );
       
   800         }
       
   801 
       
   802     const TDesC& accessDes = ( accesspoint ? *accesspoint : aServerAddress );
       
   803     const TDesC& userDes = ( userid ? *userid : aUserId );
       
   804 
       
   805     CCAMessageContainer* messageContainer = CCAMessageContainer::NewL(
       
   806                                                 accessDes,
       
   807                                                 userDes,
       
   808                                                 aTargetId,
       
   809                                                 aMemoryHandler,
       
   810                                                 aType );
       
   811     if ( userid )
       
   812         {
       
   813         CleanupStack::PopAndDestroy( userid );
       
   814         }
       
   815     if ( accesspoint )
       
   816         {
       
   817         CleanupStack::PopAndDestroy( accesspoint );
       
   818         }
       
   819     CleanupStack::PushL( messageContainer );
       
   820     return messageContainer;
       
   821     }
       
   822 
       
   823 // end of file