diff -r 3104fc151679 -r 9a48e301e94b imstutils/imconversationview/imcvuiengine/src/cimcvenginemessagecontainer.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/imstutils/imconversationview/imcvuiengine/src/cimcvenginemessagecontainer.cpp Wed Sep 01 12:33:36 2010 +0100 @@ -0,0 +1,738 @@ +/* +* Copyright (c) 2007-2008 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: message container class implementation +* +*/ + +#include "cimcvenginemessagecontainer.h" +#include "mimcvenginemessageobserver.h" +#include "mimcvenginechatinterface.h" // KSendBufferId +#include "cimcvenginemessagebase.h" +#include +#include "imcvuiliterals.h" +#include "imcvlogger.h" +#include +#include "mimcvenginebuffermemoryhandler.h" +#include "mimcvenginenewmsgobserver.h" + +// needed to skip domains in domain-neutral comparison (TUint version) +const TUint KAtUInt( '@' ); + +// general colon needed in various places +_LIT( KColon, ":" ); + +// general slash needed in various places +_LIT( KSlash, "/" ); + +// needed to skip domains in domain-neutral comparison +_LIT( KAt, "@" ); + +//----------------------------------------------------------------------------- +// CIMCVEngineMessageContainer::CIMCVEngineMessageContainer +// ( Other items commented in header ) +//----------------------------------------------------------------------------- +CIMCVEngineMessageContainer::CIMCVEngineMessageContainer( + MIMCVEngineBufferMemoryHandler& aMemoryHandler ) +: iMemoryHandler( aMemoryHandler ) + { + } + +//----------------------------------------------------------------------------- +// CIMCVEngineMessageContainer::~CIMCVEngineMessageContainer +// ( Other items commented in header ) +//----------------------------------------------------------------------------- +CIMCVEngineMessageContainer::~CIMCVEngineMessageContainer() + { + + + for( TInt a( 0 ); a < iMessageContainer.Count(); ++a ) + { + if( iMessageContainer[ a ]->DecreaseOwnerCount() ) + { + delete iMessageContainer[ a ]; + } + } + iMessageContainer.Reset(); + + + delete iTargetId; + delete iBuddyDisplayName; + delete iDecodedTargetId; + delete iEditerMessge; + delete iContactLink; + } + +//----------------------------------------------------------------------------- +// CIMCVEngineMessageContainer::NewL +// ( Other items commented in header ) +//----------------------------------------------------------------------------- +CIMCVEngineMessageContainer* CIMCVEngineMessageContainer::NewL( + TInt aServiceId, + const TDesC& aTargetId, + const TDesC& aDisplayName, + const TDesC8& aContactLink, + MIMCVEngineBufferMemoryHandler& aMemoryHandler, + TContainerType aType ) + { + CIMCVEngineMessageContainer* self = CIMCVEngineMessageContainer::NewLC( + aServiceId, + aTargetId, + aDisplayName, + aContactLink, + aMemoryHandler, + aType ); + CleanupStack::Pop( self ); + return self; + } + +//----------------------------------------------------------------------------- +// CIMCVEngineMessageContainer::NewLC +// ( Other items commented in header ) +//----------------------------------------------------------------------------- +CIMCVEngineMessageContainer* CIMCVEngineMessageContainer::NewLC( + TInt aServiceId, + const TDesC& aTargetId, + const TDesC& aDisplayName, + const TDesC8& aContactLink, + MIMCVEngineBufferMemoryHandler& aMemoryHandler, + TContainerType aType ) + { + CIMCVEngineMessageContainer* self = + new ( ELeave ) CIMCVEngineMessageContainer( aMemoryHandler ); + CleanupStack::PushL( self ); + self->ConstructL( aServiceId, aTargetId,aDisplayName,aContactLink, aType ); + return self; + } + +//----------------------------------------------------------------------------- +// CIMCVEngineMessageContainer::ConstructL +// ( Other items commented in header ) +//----------------------------------------------------------------------------- +void CIMCVEngineMessageContainer::ConstructL( + TInt /*aServiceId*/, + const TDesC& aTargetId, + const TDesC& aDisplayName, + const TDesC8& aContactLink, + TContainerType aType ) + { + iTargetId = aTargetId.AllocL(); + iBuddyDisplayName = aDisplayName.AllocL(); + iContactLink = aContactLink.Alloc(); + iDecodedTargetId = EscapeUtils::EscapeDecodeL( *iTargetId ); + ResolveType( aType ); + + } + +//----------------------------------------------------------------------------- +// CIMCVEngineMessageContainer::UnreadCount +// ( Other items commented in header ) +//----------------------------------------------------------------------------- +TInt CIMCVEngineMessageContainer::UnreadCount( + MIMCVEngineMessageReadInterface::TUnreadFilter aUnreadFilter ) const + { + TInt countOfAll = iMessageContainer.Count(); + TInt unreadCount = countOfAll - iUnreadOffset; + if( aUnreadFilter != EUnreadAll ) + { + for( TInt a = countOfAll - 1; a >= iUnreadOffset; --a ) + { + if( iMessageContainer[ a ]->MessagerType() == MIMCVEngineMessage::EMessageSent ) + { + unreadCount--; + } + } + } + return unreadCount; + } + +//----------------------------------------------------------------------------- +// CIMCVEngineMessageContainer::StoreEditerMessageL +// ( Other items commented in header ) +//----------------------------------------------------------------------------- +void CIMCVEngineMessageContainer::StoreEditerMessageL(const TDesC& aEditorMessage ) + { + if( iEditerMessge) + { + delete iEditerMessge; + iEditerMessge = NULL; + } + iEditerMessge = aEditorMessage.AllocL(); + } + +//----------------------------------------------------------------------------- +// CIMCVEngineMessageContainer::GetEditerMessage +// ( Other items commented in header ) +//----------------------------------------------------------------------------- + +const TDesC& CIMCVEngineMessageContainer::GetEditerMessage() + { + if( iEditerMessge) + { + return *iEditerMessge; + } + return KNullDesC; + } + +//----------------------------------------------------------------------------- +// CIMCVEngineMessageContainer::MessageCount +// ( Other items commented in header ) +//----------------------------------------------------------------------------- +TInt CIMCVEngineMessageContainer::MessageCount() const + { + // Offset is index to first unread message. It is exatly same as count of + // read messages. + return iUnreadOffset; + } +//----------------------------------------------------------------------------- +// CIMCVEngineMessageContainer::Read +// ( Other items commented in header ) +//----------------------------------------------------------------------------- +void CIMCVEngineMessageContainer::Read( TReadType aReadType, TInt aAmount /* = 0 */ ) + { + TInt messageCount( iMessageContainer.Count() ); + TInt originalUnreadCount = UnreadCount( ); + + switch( aReadType ) + { + case EReadAll: + iUnreadOffset = messageCount; + break; + case EReadAmount: + iUnreadOffset+= aAmount; + break; + case EReadOne: + ++iUnreadOffset; + break; + default: + return; + } + + // Cannot be more than messageCount + if( iUnreadOffset > messageCount ) + { + iUnreadOffset = messageCount; + } + + // Inform observers only if unreadcount is changed. + if( originalUnreadCount != UnreadCount() ) + { + if (( iChatObserver ) && (!iActiveChat)) + { + TRAP_IGNORE( iChatObserver->HandleChatEventL( + MIMCVEngineNewMsgObserver::EUnreadCountChanged ) ); + } + } + + } + +//----------------------------------------------------------------------------- +// CIMCVEngineMessageContainer::Message +// ( Other items commented in header ) +//----------------------------------------------------------------------------- +MIMCVEngineMessage& CIMCVEngineMessageContainer::Message( TInt aIndex ) const + { + //__CHAT_ASSERT_DEBUG( aIndex >= 0 && aIndex < MessageCount() ); + return *iMessageContainer[ aIndex ]; + } + +//----------------------------------------------------------------------------- +// CIMCVEngineMessageContainer::ReadNextUnread +// ( Other items commented in header ) +//----------------------------------------------------------------------------- +MIMCVEngineMessage& CIMCVEngineMessageContainer::ReadNextUnread() + { + //__CHAT_ASSERT_DEBUG( UnreadCount() != 0 ); + Read( EReadOne ); + return *iMessageContainer[ MessageCount() - 1 ]; + } + +//----------------------------------------------------------------------------- +// CIMCVEngineMessageContainer::ReadUnreadFromIndex +// ( Other items commented in header ) +//----------------------------------------------------------------------------- +MIMCVEngineMessage& CIMCVEngineMessageContainer::ReadUnreadFromIndex( TInt aIndex ) + { + //__CHAT_ASSERT_DEBUG( UnreadCount() != 0 ); + //__CHAT_ASSERT_DEBUG( aIndex >= 0 && aIndex < iMessageContainer.Count() ); + Read( EReadOne ); + return *iMessageContainer[aIndex]; + } + +//----------------------------------------------------------------------------- +// CIMCVEngineMessageContainer::SetObserver +// ( Other items commented in header ) +//----------------------------------------------------------------------------- +void CIMCVEngineMessageContainer::SetObserver( MIMCVEngineMessageObserver* aObserver ) + { + iObserver = aObserver; + } + +//----------------------------------------------------------------------------- +// CIMCVEngineMessageContainer::SetObserver +// ( Other items commented in header ) +//----------------------------------------------------------------------------- +TPtrC CIMCVEngineMessageContainer::Name() const + { + IM_CV_LOGS(TXT("CIMCVEngineMessageContainer::Name Start")); + if( iBuddyDisplayName && iBuddyDisplayName->Length()) + { + IM_CV_LOGS(TXT("to_del CIMCVEngineMessageContainer::Name iBuddyDisplayName= %S"),&(*iBuddyDisplayName) ); + //IM_CV_LOGS(TXT("to_del CIMCVEngineMessageContainer::Name iBuddyDisplayName length = %d"),iBuddyDisplayName->Length() ); + return *iBuddyDisplayName; + } + if( iTargetId ) + { + IM_CV_LOGS(TXT("to_del CIMCVEngineMessageContainer::target iTargetId= %S"), &(*iTargetId)); + return DisplayId( *iTargetId ); + } + return KNullDesC(); + } +//----------------------------------------------------------------------------- +// CIMCVEngineMessageContainer::DisplayName +// ( Other items commented in header ) +//----------------------------------------------------------------------------- +TDesC CIMCVEngineMessageContainer::DisplayName() const + { + IM_CV_LOGS(TXT("CIMCVEngineMessageContainer::DisplayName Start" )); + if( iBuddyDisplayName && iBuddyDisplayName->Length()) + { + IM_CV_LOGS(TXT("CIMCVEngineMessageContainer::DisplayName EChatContainer: %s"), &(*iBuddyDisplayName)); + return *iBuddyDisplayName; + } + return KNullDesC(); + } +//----------------------------------------------------------------------------- +// CIMCVEngineMessageContainer::SetName +// ( Other items commented in header ) +//----------------------------------------------------------------------------- +void CIMCVEngineMessageContainer::SetNameL(const TDesC& aDisplayName) + { + IM_CV_LOGS(TXT("CIMCVEngineMessageContainer::SetNameL Start")); + //if the iBuddydisplayName is same as aDisplayName + // then no need to set it again. + if(iBuddyDisplayName && (aDisplayName.Compare(*iBuddyDisplayName)!=0)) + { + delete iBuddyDisplayName; + iBuddyDisplayName = NULL; + IM_CV_LOGS(TXT("CIMCVEngineMessageContainer::SetName=%S"),&aDisplayName); + iBuddyDisplayName = aDisplayName.AllocL(); + } + } +//----------------------------------------------------------------------------- +// CIMCVEngineMessageContainer::SetName +// ( Other items commented in header ) +//----------------------------------------------------------------------------- +void CIMCVEngineMessageContainer::SetLinkL(const TDesC8& aContactLink) + { + IM_CV_LOGS(TXT(" CIMCVEngineMessageContainer::SetLinkL Start")); + //if the iContactLink is same as aContactLink + // then no need to set it again. + if(iContactLink && (aContactLink.Compare(*iContactLink)!=0)) + { + delete iContactLink; + iContactLink = NULL; + IM_CV_LOGS(TXT(" CIMCVEngineMessageContainer::SetLinkL=%S"),&aContactLink); + iContactLink = aContactLink.AllocL(); + } + + } +//----------------------------------------------------------------------------- +// CIMCVEngineMessageContainer::ContactLink +// ( Other items commented in header ) +//----------------------------------------------------------------------------- + +TPtrC8 CIMCVEngineMessageContainer::ContactLink() const + { + return *iContactLink; + } + +//----------------------------------------------------------------------------- +// CIMCVEngineMessageContainer::DeleteMessage +// ( Other items commented in header ) +//----------------------------------------------------------------------------- +void CIMCVEngineMessageContainer::DeleteMessage( TInt aIndex ) + { + MIMCVEngineMessage* target = &Message( aIndex ); + iMessageContainer.Remove( aIndex ); + iContainerSizeInBytes -= target->SizeInBytes(); + --iUnreadOffset; + + if( iObserver ) + { + iObserver->HandleMessageEvent( MIMCVEngineMessageObserver::EMessageDeleted, + aIndex ); + } + + if( target->DecreaseOwnerCount() ) + { + delete target; + } + } + +//----------------------------------------------------------------------------- +// CIMCVEngineMessageContainer::AppendL +// ( Other items commented in header ) +//----------------------------------------------------------------------------- +void CIMCVEngineMessageContainer::AppendL( MIMCVEngineMessage* aMessage, TBool aSharedOwnership ) + { + if( !aMessage ) + { + User::Leave( KErrArgument ); + } + + if( !aSharedOwnership ) + { + CleanupDeletePushL( aMessage ); + } + + // Check memory status + // if failes, leave with KErrNoMemory + if( !iMemoryHandler.FreeMemoryIfNeededL( aMessage->SizeInBytes() ) ) + { + User::Leave( KErrNoMemory ); + } + + iMessageContainer.AppendL( aMessage ); + iContainerSizeInBytes += aMessage->SizeInBytes(); + + if( !aSharedOwnership ) + { + CleanupStack::Pop( aMessage ); + } + + aMessage->IncreaseOwnerCount(); + + aMessage->SetContainerInfo( this ); + + IM_CV_LOGS(TXT( "Sender %s, Recipient %s" ), + &aMessage->Sender(), + &aMessage->Recipient() ); + + + if( iObserver ) + { + iObserver->HandleMessageEvent( MIMCVEngineMessageObserver::ENewMessage ); + } + + if ( ( iChatObserver ) && (!iActiveChat) ) + { + iChatObserver->HandleChatEventL( MIMCVEngineNewMsgObserver::EUnreadCountChanged, + aMessage ); + } + } + +//----------------------------------------------------------------------------- +// CIMCVEngineMessageContainer::ServerAddress +// ( Other items commented in header ) +//----------------------------------------------------------------------------- +// +TTime CIMCVEngineMessageContainer::Time() + { + TTime time = Time::NullTTime(); + TInt count = iMessageContainer.Count(); + if( count == 0 ) + { + // no messages, return null + return time; + } + return iMessageContainer[count - 1]->TimeStamp(); + } + + + +//----------------------------------------------------------------------------- +// CIMCVEngineMessageContainer::Target +// ( Other items commented in header ) +//----------------------------------------------------------------------------- +const TDesC& CIMCVEngineMessageContainer::Target() const + { + if( !iTargetId ) + { + return KNullDesC; + } + return *iTargetId; + } + + +//----------------------------------------------------------------------------- +// CIMCVEngineMessageContainer::OrderUid +// ( Other items commented in header ) +//----------------------------------------------------------------------------- +TInt CIMCVEngineMessageContainer::OrderUid( const CIMCVEngineMessageContainer& aSourceA, + const CIMCVEngineMessageContainer& aSourceB ) + { + + // points to user part of id + TPtrC ptrId1( aSourceA.ComparableTarget() ); + TPtrC ptrId2( aSourceB.ComparableTarget() ); + + // find out if we have domains in the ids + TInt domainPos1( ptrId1.Locate( KAtUInt ) ); + TInt domainPos2( ptrId2.Locate( KAtUInt ) ); + + TBool domainIn1( KErrNotFound != domainPos1 ); + TBool domainIn2( KErrNotFound != domainPos2 ); + + // points to domains in the neutral id + TPtrC ptrDom1( KNullDesC ); + TPtrC ptrDom2( KNullDesC ); + + // points to user parts in the neutral id + TPtrC ptrUid1( ptrId1 ); + TPtrC ptrUid2( ptrId2 ); + + // separate user id parts and domain parts + if ( domainIn1 ) + { + ptrDom1.Set( ptrId1.Mid( domainPos1 + 1) ); + ptrUid1.Set( ptrId1.Mid( 0, domainPos1 ) ); + } + + if ( domainIn2 ) + { + ptrDom2.Set( ptrId2.Mid( domainPos2 + 1) ); + ptrUid2.Set( ptrId2.Mid( 0, domainPos2 ) ); + } + + // Create custom collation method to ignore punctuations + // index 0 gets the default method + TCollationMethod collation = + *Mem::CollationMethodByIndex( 0 ); + collation.iFlags |= TCollationMethod::EIgnoreNone; + + // domains are compared only when it is really needed + // check if userid part is the same in both ids + TInt idResult = ptrUid1.CompareC( ptrUid2, KCollationLevel, &collation ); + + if( idResult != 0 ) + { + return idResult; + } + + // id part is same, we have to compare domain + + // If domain comparison is neutral and one id is without domain + // -> Domains are same. Other situation domainResult stays valid. + if ( domainIn1 ^ domainIn2 ) + { + return 0; + } + else + { + return ptrDom1.CompareC( ptrDom2, KCollationLevel, &collation ); + } + } + + + +//----------------------------------------------------------------------------- +// CIMCVEngineMessageContainer::ContainerType +// ( Other items commented in header ) +//----------------------------------------------------------------------------- +MIMCVEngineMessageReadInterface::TContainerType CIMCVEngineMessageContainer::ContainerType() const + { + return iContainerType; + } + +//----------------------------------------------------------------------------- +// CIMCVEngineMessageContainer::ResolveType +// ( Other items commented in header ) +//----------------------------------------------------------------------------- +void CIMCVEngineMessageContainer::SetChatObserver( MIMCVEngineNewMsgObserver* aObserver ) + { + iChatObserver = aObserver; + } + +//----------------------------------------------------------------------------- +// CIMCVEngineMessageContainer::ResolveType +// ( Other items commented in header ) +//----------------------------------------------------------------------------- +void CIMCVEngineMessageContainer::ResolveType( TContainerType aType ) + { + if( aType != ENoneContainer ) + { + iContainerType = aType; + } + else if( iTargetId->Compare( KSendBufferId ) == 0 ) + { + iContainerType = ESendContainer; + } + else + { + iContainerType = EChatContainer; + } + } + + + +// ----------------------------------------------------------------------------- +// CIMCVEngineMessageContainer::TargetId +// ( Other items commented in header ) +// ----------------------------------------------------------------------------- +// +MIMCVEngineMessageContainerInfo& CIMCVEngineMessageContainer::TargetId() + { + return *this; + } + +// ----------------------------------------------------------------------------- +// CIMCVEngineMessageContainer::Lock +// locks messagecontainer if needed. +// ----------------------------------------------------------------------------- +// +void CIMCVEngineMessageContainer::Lock( TBool aLocked ) + { + iLocked = aLocked; + } + +// ----------------------------------------------------------------------------- +// CIMCVEngineMessageContainer::ComparableTarget +// ( Other items commented in header ) +// ----------------------------------------------------------------------------- +// +const TDesC& CIMCVEngineMessageContainer::ComparableTarget() const + { + if ( !iDecodedTargetId ) + { + return KNullDesC; + } + return *iDecodedTargetId; + } + +// ----------------------------------------------------------------------------- +// CIMCVEngineMessageContainer::AllMessagesCount +// ( Other items commented in header ) +// ----------------------------------------------------------------------------- +// +TInt CIMCVEngineMessageContainer::AllMessagesCount() const + { + return iMessageContainer.Count(); + } + +// ----------------------------------------------------------------------------- +// CCABufferManager::NotifyContactForPending +// ( Other items commented in header ) +// ----------------------------------------------------------------------------- +// +MIMCVEngineMessage& CIMCVEngineMessageContainer::MessageFromAll( TInt aIndex ) const + { + //__CHAT_ASSERT_DEBUG( aIndex >= 0 && aIndex < AllMessagesCount() ); + return *iMessageContainer[ aIndex ]; + } + +//----------------------------------------------------------------------------- +// CIMCVEngineMessageContainer::DeleteMessageFromAll +// ( Other items commented in header ) +//----------------------------------------------------------------------------- +// +void CIMCVEngineMessageContainer::DeleteMessageFromAll( TInt aIndex ) + { + MIMCVEngineMessage* target = &MessageFromAll( aIndex ); + iMessageContainer.Remove( aIndex ); + iContainerSizeInBytes -= target->SizeInBytes(); + if( iUnreadOffset > aIndex ) + { + --iUnreadOffset; + } + + if( iObserver ) + { + iObserver->HandleMessageEvent( MIMCVEngineMessageObserver::EMessageDeleted, + aIndex ); + } + + if( target->DecreaseOwnerCount() ) + { + delete target; + } + } + +//----------------------------------------------------------------------------- +// CIMCVEngineMessageContainer::IsLocked +// ( Other items commented in header ) +//----------------------------------------------------------------------------- +// +TBool CIMCVEngineMessageContainer::IsLocked() const + { + return iLocked ; + } + +//----------------------------------------------------------------------------- +// CIMCVEngineMessageContainer::ContainerSizeInBytes +// ( Other items commented in header ) +//----------------------------------------------------------------------------- +// +TInt CIMCVEngineMessageContainer::ContainerSizeInBytes() const + { + return iContainerSizeInBytes; + } + + +//----------------------------------------------------------------------------- +// CIMCVEngineMessageContainer::SetActive +// ( Other items commented in header ) +//----------------------------------------------------------------------------- +// +void CIMCVEngineMessageContainer::SetActive( TBool aActiveChat ) + { + iActiveChat = aActiveChat; + } + + +//----------------------------------------------------------------------------- +// CIMCVEngineMessageContainer::IsActive +// ( Other items commented in header ) +//----------------------------------------------------------------------------- +// +TBool CIMCVEngineMessageContainer::IsActive() + { + return iActiveChat; + } + + + +// ----------------------------------------------------------------------------- +// CIMCVEngineMessageContainer::DisplayId +// ----------------------------------------------------------------------------- +// +TPtrC CIMCVEngineMessageContainer::DisplayId( const TDesC& aId, TBool aDomainHiding ) + { + TPtrC ret( aId ); + + // locate ":" for userid, groupid. + // locate "/" for list id. + TInt pos = aId.FindC( aDomainHiding ? KSlash : KColon ); + + if ( ( pos != KErrNotFound) && ( pos != aId.Length()-1) ) + { + // contains the special character, and it is not the last char + // remove everything before the special char (including the char) + ret.Set( aId.Mid( pos + 1 ) ); + } + if( aDomainHiding) + { + // remove also the domain part + TInt domainPos = ret.FindC( KAt ); + if ( ( domainPos != KErrNotFound ) && ( domainPos != 0 ) ) + { + ret.Set( ret.Mid( 0, domainPos ) ); + } + + } + + return ret; + } + + +// end of file