imstutils/imconversationview/imcvuiapp/src/cimcvappsmileiconutility.cpp
author Pat Downey <patd@symbian.org>
Wed, 01 Sep 2010 12:33:36 +0100
branchRCL_3
changeset 23 9a48e301e94b
permissions -rw-r--r--
Revert incorrect RCL_3 drop: Revision: 201033 Kit: 201035

/*
* 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:  Utility for selecting smile icon and converting
*                between smile id and smile string.
*
*/


// INCLUDE FILES
#include "cimcvappsmileiconutility.h"
#include "cimcvappsmileicondialog.h"
#include "cimcvappsmilestring.h"
#include "cimcvappsmileyinformation.h"
#include "mimcvuiappskinvariant.h"
#include "cimcvengine.h"
#include    "cimcvappbitmapmapping.h"     // defines the skinned bitmap ids

#include 	"mimcvappui.h"
#include 	<uniutils.rsg>
#include 	<msgeditorappui.rsg>
#include 	<imcvuiapp.rsg>
#include 	<bautils.h>
#include 	<PUAcodes.hrh>
#include 	<barsread.h> // RResourceReader
#include 	<coemain.h>
#include 	<eikenv.h>
#include 	<gulicon.h>

#include	<aknappui.h>
#include	<AknsSkinInstance.h>	// skins 
#include	<AknsUtils.h>
#include	<AknsDrawUtils.h>
#include	<AknsBasicBackgroundControlContext.h>
#include    <AknIconUtils.h>
#include 	"imcvlogger.h"
#include    <mbsaccess.h>
#include    "cimcvuiappiconfileprovider.h"
#include    "conversations.h"
#include    "imcvuiapp.h"
#include 	<utf.h>


// ================= MEMBER FUNCTIONS =======================

// Two-phased constructor.
CIMCVAppSmileIconUtility* CIMCVAppSmileIconUtility::NewL(MIMCVUiAppSkinVariant& aSkinVariant,
                             MIMCVAppUi& aAppUi,
                             CIMCVEngine& aServiceEngine  )
    {
    IM_CV_LOGS(TXT("CIMCVAppSmileIconUtility::NewL() start") );
    CIMCVAppSmileIconUtility* self = new (ELeave) CIMCVAppSmileIconUtility(aSkinVariant, aAppUi);
    CleanupStack::PushL( self );
    self->ConstructL(aServiceEngine);
    CleanupStack::Pop( self );
    IM_CV_LOGS(TXT("CIMCVAppSmileIconUtility::NewL() end") );
    return self;
    }

// Destructor
CIMCVAppSmileIconUtility::~CIMCVAppSmileIconUtility()
    {
    iAppUi.RemoveResourceChangeObserver( this );  
	iStringArray.ResetAndDestroy();
	iSmileArray.ResetAndDestroy();
    iIconToSmileyPointers.Close();   
    iSmileDlgIconArray.ResetAndDestroy();
    iFile.Close();
    }

// C++ constructor can NOT contain any code, that
// might leave.
//
CIMCVAppSmileIconUtility::CIMCVAppSmileIconUtility(MIMCVUiAppSkinVariant& aSkinVariant, 
                             MIMCVAppUi& aAppUi )
    :iSkinVariant( aSkinVariant),                       
    iAppUi( aAppUi )
    {
    }

// ConstructL
//
void CIMCVAppSmileIconUtility::ConstructL(CIMCVEngine& aServiceEngine )
    {
    IM_CV_LOGS(TXT("CIMCVAppSmileIconUtility::ConstructL() start") );
	// we need to be resource aware
	iAppUi.AddResourceChangeObserver( this );
	ConstructSmileDialogIconArrayL( aServiceEngine );
    IM_CV_LOGS(TXT("CIMCVAppSmileIconUtility::ConstructL() end") );
    }

// ---------------------------------------------------------
// CIMCVAppSmileIconUtility::ParseAllSmileyStringL
// (other items were commented in a header).
// ---------------------------------------------------------
// 
void CIMCVAppSmileIconUtility::ParseAllSmileyStringL(RPointerArray<HBufC> aAllSmileyString)
    {       
    TInt iconCount  = aAllSmileyString.Count();
    //make sure everything is fresh
    iStringArray.ResetAndDestroy();
    for(TInt i=0; i<iconCount; i++)
        {
        CIMCVAppSmileString* smileArray = CIMCVAppSmileString::NewL();
        CleanupStack::PushL( smileArray );
     
        HBufC* smileString = aAllSmileyString[i];
        //set longest smiley lenth
        if( smileString->Length() > iLongestSmileyLength )
            {
            iLongestSmileyLength = smileString->Length();
            }
        // ownership is transferred
        smileArray->Set( smileString, i );
        User::LeaveIfError( iStringArray.Append( smileArray ) );            
        CleanupStack::Pop( smileArray );
        }    
    }
// ---------------------------------------------------------
// CIMCVAppSmileIconUtility::ConstructSmileDialogIconArrayL
// (other items were commented in a header).
// ---------------------------------------------------------
//
void CIMCVAppSmileIconUtility::ConstructSmileDialogIconArrayL(CIMCVEngine& aServiceEngine )
    {   
    RPointerArray<HBufC> smileyString = aServiceEngine.GetSmileStringArray(); 
    CleanupClosePushL( smileyString );
    ParseAllSmileyStringL(smileyString); // all object ownership transfered
    smileyString.Reset();
    CleanupStack::Pop( &smileyString ); // no objects alive
    
    iSmileDlgIconArray = aServiceEngine.GetSmileyIconArray();
 
    // Sort smileys according to their string length, so that searching
    // for smileys is done from the longest smiley to the shortest. This
    // prevents the chat from detecting smaller smileys inside the big ones.
    TLinearOrder< CIMCVAppSmileString > 
    order( CIMCVAppSmileIconUtility::CompareSmileyLengthReversed );
    iStringArray.Sort( order );
    // Precalculate an ref table from icon to smiley.        
    iIconToSmileyPointers.Reset();   
    TInt count = iSmileDlgIconArray.Count();
    for( TInt i = 0; i < count; ++i )
        {
        User::LeaveIfError( 
                iIconToSmileyPointers.Append( GetFirstSmileyIndex( i ) ) );        
        }  
    }    

// ---------------------------------------------------------
// CIMCVAppSmileIconUtility::LaunchSmileIconDialogL
// (other items were commented in a header).
// ---------------------------------------------------------
//code scaner warning can be ignored since ExecuteLD is leaving and we need to return dialogVal.
TInt CIMCVAppSmileIconUtility::LaunchSmileIconDialogL( TInt& aSelectedIconId )
    {
    if( iSmileDlgIconArray.Count() <= 0 )
        {
        User::Leave(KErrArgument);
        }
	CIMCVAppSmileIconDialog* dialog = CIMCVAppSmileIconDialog::NewL( iSmileDlgIconArray,
														   aSelectedIconId );
	TInt dialogVal = dialog->ExecuteLD( R_SELECT_SMILE_DIALOG );
	IM_CV_LOGS(TXT("CIMCVAppSmileIconUtility::LaunchSmileIconDialogL() end") );
	return dialogVal;
    }

// ---------------------------------------------------------
// CIMCVAppSmileIconUtility::SmileIconCount
// (other items were commented in a header).
// ---------------------------------------------------------
//
TInt CIMCVAppSmileIconUtility::SmileIconCount() const
	{
	return iSmileDlgIconArray.Count();
	}

// ---------------------------------------------------------
// CIMCVAppSmileIconUtility::GetSmileIcon
// (other items were commented in a header).
// ---------------------------------------------------------
//
const CGulIcon* CIMCVAppSmileIconUtility::GetSmileIcon( TInt aIconId ) const
	{
	return iSmileDlgIconArray[ aIconId ];
	}

// ---------------------------------------------------------
// CIMCVAppSmileIconUtility::GetSmileString
// (other items were commented in a header).
// ---------------------------------------------------------
//
const TDesC& CIMCVAppSmileIconUtility::GetSmileString( TInt aIconId ) const
	{
	return iStringArray[ iIconToSmileyPointers[ aIconId ] ]->SmileString();
	}

// ---------------------------------------------------------
// CIMCVAppSmileIconUtility::SearchSmilesL
// (other items were commented in a header).
// ---------------------------------------------------------
//
void CIMCVAppSmileIconUtility::SearchSmilesL( const TDesC& aStr, TDes& aFixedStr,
										 RArray<TInt>* aArray )
	{
	CleanupClosePushL(*aArray);
	
	IM_CV_LOGS(TXT("CIMCVAppSmileIconUtility::SearchSmilesL() start") );
	TInt i;
    iSmileArray.ResetAndDestroy();
    SearchSmilesL( aStr, iSmileArray, &aFixedStr );

	aArray->Reset();
    TInt arrayCount( iSmileArray.Count() );

    for ( i = 0; i < arrayCount; ++i )
		{
		User::LeaveIfError( aArray->Append( iSmileArray[ i ]->Index() ) );
		}
    
	iSmileArray.ResetAndDestroy();
	
	CleanupStack::Pop(aArray);
	
	IM_CV_LOGS(TXT("CIMCVAppSmileIconUtility::SearchSmilesL() end") );
	}

// -----------------------------------------------------------------------------
// CIMCVAppSmileIconUtility::SearchSmilesL
// Search smileys from string and sort them in linear order.
// -----------------------------------------------------------------------------
//
void CIMCVAppSmileIconUtility::SearchSmilesL( const TDesC& aStr, 
                         RPointerArray< CIMCVAppSmileyInformation >& aSmileyInfoArray, 
                         TDes* aFixedStr /*= NULL */,
                         TInt aStartPos /* = 0 */) const
    {
	CleanupClosePushL(aSmileyInfoArray);
	
	IM_CV_LOGS(TXT("CIMCVAppSmileIconUtility::SearchSmilesL() start") );
	HBufC* text = HBufC::NewMaxLC( aStr.Length() );
	TPtr fixedText( text->Des() );
	fixedText.Copy( aStr.Left(fixedText.MaxLength()) );
    
    HBufC* replaceString = HBufC::NewMaxLC( iLongestSmileyLength );
	TPtr replace( replaceString->Des() );
	if ( aFixedStr )
		{
		replace.Fill( KPuaCodeSmileyIconPadding, 1 );
		}
	else
		{
		//we dont need fixed, but we do need correct positions
		replace.Fill( KPuaCodeSmileyIconPadding, iLongestSmileyLength );
		}

    // order to sort array by the position
	TLinearOrder< CIMCVAppSmileyInformation > order( CIMCVAppSmileIconUtility::Compare );

	// for i-loop goes throug every smile string
	// while-loop searches smiles from given string
    TInt arrayCount = iStringArray.Count(); 
	TInt index = 0;
	for ( TInt i = 0; i < arrayCount; ++i )
		{
		const TDesC& smileString( iStringArray[ i ]->SmileString() );
		index = fixedText.Find( smileString );
		while ( index != KErrNotFound )
			{
            CIMCVAppSmileyInformation* smileInfo = CIMCVAppSmileyInformation::NewL();
            CleanupStack::PushL( smileInfo );
            
			smileInfo->SetPosition( index + aStartPos );
			smileInfo->SetIndex( iStringArray[ i ]->SmileIconIndex() );
            smileInfo->SetSmileyStringL( smileString );
            smileInfo->SetIcon( EFalse );
            
			User::LeaveIfError( aSmileyInfoArray.Append( smileInfo ) );
            CleanupStack::Pop( smileInfo );
            
			TInt smilyLength = smileString.Length();
            // Only replace the same amount of chars than in smiley, so we 
            // don't mess up the length or index table.
            fixedText.Replace( index, 
                               smilyLength, 
                               replace.Left( smilyLength ) );
			index = fixedText.Find( smileString );
			} // while
		} // for i
    
	aSmileyInfoArray.Sort( order );
    if( aFixedStr )
        {
        *aFixedStr = fixedText;
        }
        
    CleanupStack::PopAndDestroy( 2, text ); // replaceString, text
    CleanupStack::Pop(&aSmileyInfoArray);
    
	IM_CV_LOGS(TXT("CIMCVAppSmileIconUtility::SearchSmilesL() end") );
    }

// ---------------------------------------------------------
// CIMCVAppSmileIconUtility::Compare
// (other items were commented in a header).
// ---------------------------------------------------------
//
TInt CIMCVAppSmileIconUtility::Compare( const CIMCVAppSmileyInformation& aFirst,
                                   const CIMCVAppSmileyInformation& aSecond )
    {
    return ( aFirst.Position() - aSecond.Position() );
    }

// -----------------------------------------------------------------------------
// CIMCVAppSmileIconUtility::CompareSmileyLengthReversed
// (other items were commented in a header).
// -----------------------------------------------------------------------------
//
TInt CIMCVAppSmileIconUtility::CompareSmileyLengthReversed( 
                                            const CIMCVAppSmileString& aFirst,
                                            const CIMCVAppSmileString& aSecond )
    {
    return ( aSecond.SmileString().Length() - aFirst.SmileString().Length() );
    }

// ---------------------------------------------------------
// CIMCVAppSmileIconUtility::ResizeIcons
// (other items were commented in a header).
// ---------------------------------------------------------
//
void CIMCVAppSmileIconUtility::ResizeIcons( const TSize& aSize )
	{
	IM_CV_LOGS(TXT("CIMCVAppSmileIconUtility::ResizeIcons() start") );
	TInt count( SmileIconCount() );
	for( TInt i(0); i < count; i++) 
		{
		AknIconUtils::SetSize( iSmileDlgIconArray[ i ]->Bitmap(), aSize );
		}
	IM_CV_LOGS(TXT("CIMCVAppSmileIconUtility::ResizeIcons() end") );
	}

// -----------------------------------------------------------------------------
// CIMCVAppSmileIconUtility::GetFirstSmileyIndex
// -----------------------------------------------------------------------------
//
TInt CIMCVAppSmileIconUtility::GetFirstSmileyIndex( TInt aIconIndex ) const
    {
    IM_CV_LOGS(TXT("CIMCVAppSmileIconUtility::GetFirstSmileyIndex() start") );
	TInt count = iStringArray.Count();
	
	for( TInt i = 0; i < count; ++i )
	    {
	    if( iStringArray[ i ]->SmileIconIndex() == aIconIndex )
	        {
	        return i;
	        }
	    }
	IM_CV_LOGS(TXT("CIMCVAppSmileIconUtility::GetFirstSmileyIndex() end") );
	// Icon was not found.	
	return KErrNotFound;
    }

// -----------------------------------------------------------------------------
// CIMCVAppSmileIconUtility::ResourceChangedL
// -----------------------------------------------------------------------------
//
void CIMCVAppSmileIconUtility::ResourceChangedL()
    {
    IM_CV_LOGS(TXT("CIMCVAppSmileIconUtility::ResourceChangedL() start") );		
	IM_CV_LOGS(TXT("CIMCVAppSmileIconUtility::ResourceChangedL() end") );
    }


// End of File