diff -r 000000000000 -r 5e5d6b214f4f imstutils/imconversationview/imcvuiapp/src/cimcvappsmileyutil.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/imstutils/imconversationview/imcvuiapp/src/cimcvappsmileyutil.cpp Tue Feb 02 10:12:18 2010 +0200 @@ -0,0 +1,627 @@ +/* +* 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 "cimcvappsmileyutil.h" +#include "cimcvapppicture.h" +#include "cimcvappsmileyinformation.h" + +#include + +#include +#include +#include +#include +#include +#include "imcvlogger.h" +#include "imcvuiliterals.h" +#include "cimcvengine.h" +//CONSTANT +const TInt KChatSmileyLength( 3 ); +_LIT(KSpace, " "); + +// ================= MEMBER FUNCTIONS ======================= + +// ----------------------------------------------------------------------------- +// CIMCVAppSmileyUtil::NewL +// Two-phased constructor. +// ----------------------------------------------------------------------------- +// +CIMCVAppSmileyUtil* CIMCVAppSmileyUtil::NewL( + MIMCVUiAppSkinVariant& aSkinVariant, + MIMCVAppUi& aAppUi, TMessageExtensionTypes aType, + CIMCVEngine& aServiceEngine) + { + CIMCVAppSmileyUtil* self = new (ELeave) CIMCVAppSmileyUtil( aType ); + CleanupStack::PushL( self ); + self->ConstructL( aSkinVariant, aAppUi,aServiceEngine ); + CleanupStack::Pop(); + return self; + } + +// ----------------------------------------------------------------------------- +// CIMCVAppSmileyUtil::~CIMCVAppSmileyUtil +// Destructor +// ----------------------------------------------------------------------------- +// +CIMCVAppSmileyUtil::~CIMCVAppSmileyUtil() + { + iConvertArray.ResetAndDestroy(); + delete iSmileUtil; + } + +// ----------------------------------------------------------------------------- +// CIMCVAppSmileyUtil::CIMCVAppSmileyUtil +// C++ constructor can NOT contain any code, that +// might leave. +// ----------------------------------------------------------------------------- +// +CIMCVAppSmileyUtil::CIMCVAppSmileyUtil( TMessageExtensionTypes aType ) +: MIMCVAppMessageExtension( aType) + { + } + +// ----------------------------------------------------------------------------- +// CIMCVAppSmileyUtil::ConstructL +// ConstructL +// ----------------------------------------------------------------------------- +// +void CIMCVAppSmileyUtil::ConstructL( + MIMCVUiAppSkinVariant& aSkinVariant, + MIMCVAppUi& aAppUi, + CIMCVEngine& aServiceEngine ) + { + iServiceId = aServiceEngine.GetServiceId(); + iSmileUtil = CIMCVAppSmileIconUtility::NewL(aSkinVariant, aAppUi, aServiceEngine ); + } + + +// --------------------------------------------------------- +// CIMCVAppSmileyUtil::InsertExtensionL +// (other items were commented in a header). +// --------------------------------------------------------- +// +void CIMCVAppSmileyUtil::InsertExtensionL( CEikRichTextEditor& aEditor, + TBool& aCancelled, TSize asize ) + { + IM_CV_LOGS(TXT("CIMCVAppSmileyUtil::InsertExtensionL() start") ); + TInt bitmapId( KErrNone ); + TInt retVal = iSmileUtil->LaunchSmileIconDialogL( bitmapId ); + iSmileUtil->ResizeIcons(asize); + if( retVal ) + { + // check if there is room for icon, if not return + if( ( aEditor.MaxLength() - aEditor.TextLength() ) < KChatSmileyLength ) + { + return; + } + //we don't own this + const TDesC& iconString = iSmileUtil->GetSmileString(bitmapId); + TInt cursorPos = aEditor.CursorPos(); + HBufC* msgBuf = aEditor.GetTextInHBufL(); + CleanupStack::PushL( msgBuf ); + if(msgBuf) + { + TPtr msgPtr( msgBuf->Des() ); + aEditor.RichText()->InsertL(cursorPos,iconString); + cursorPos = aEditor.TextLength(); + aEditor.SetCursorPosL( cursorPos, EFalse); + } + else + { + aEditor.RichText()->InsertL(cursorPos,iconString); + cursorPos = aEditor.TextLength(); + aEditor.SetCursorPosL( cursorPos, EFalse); + } + CleanupStack::PopAndDestroy( msgBuf ); // msgBuf + if( &aEditor != iEditor ) + { + iEditor = &aEditor; + iCurrentCount = 1; + } + else + { + ++iCurrentCount; + } + + aCancelled = EFalse; + } + else + { + // apply formatting even in case of cancel, as the sizes of icons would have changed and when + // shifted from portrait to landscape and vice versa, alignment differs. + TCharFormat charFormat; + TCharFormatMask charFormatMask; + + IM_CV_LOGS(TXT("CIMCVAppSmileyUtil::InsertExtensionL() before applying format") ); + charFormat.iFontPresentation.iPictureAlignment = TFontPresentation::EAlignCentered; + charFormatMask.SetAttrib( EAttFontPictureAlignment ); + aEditor.RichText()->ApplyCharFormatL( charFormat, charFormatMask, 0, + aEditor.TextLength() ); + IM_CV_LOGS(TXT("CIMCVAppSmileyUtil::InsertExtensionL() after applying format") ); + aEditor.HandleTextChangedL (); + aCancelled = ETrue; + } + IM_CV_LOGS(TXT("CIMCVAppSmileyUtil::InsertExtensionL() end") ); + } + +// --------------------------------------------------------- +// CIMCVAppSmileyUtil::ExtensionToStringL +// (other items were commented in a header). +// --------------------------------------------------------- +// +void CIMCVAppSmileyUtil::ExtensionToStringL( CEikRichTextEditor& anEditor, TDes& aDes ) + { + IM_CV_LOGS(TXT("CIMCVAppSmileyUtil::ExtensionToStringL() start") ); + RArray iconIndArray; + CleanupClosePushL( iconIndArray ); + + CPicture* editorPic; + TInt i; + TInt limit( 0 ); + + // for loop gets icon positions to array + TInt length = aDes.Length(); + for( i = 0; i < length; ++i ) + { + if( aDes[ i ] == CEditableText::EPictureCharacter ) + { + User::LeaveIfError( iconIndArray.Append( i ) ); + } + } + + // real count of pictures + TInt count = anEditor.RichText()->PictureCount(); + TInt indCount = iconIndArray.Count(); + + if( &anEditor != iEditor ) + { + Reset(); + } + + // whisper message + if( indCount > iCurrentCount ) + { + limit = indCount - iCurrentCount; + } + + if( indCount > 0 ) + { + for( i = count; i > limit; --i ) + { + editorPic = anEditor.RichText()->PictureHandleL( + iconIndArray[ i - 1 ], MLayDoc::EForceLoadTrue ); + if ( !editorPic ) + { + User::Leave( KErrBadHandle ); + } + + CIMCVAppPicture* icon = static_cast ( editorPic ); + + TInt oldLen = aDes.Length(); + //delete padding char + aDes.Delete( iconIndArray[ i - 1 ], 1 ); // 1 = one char + //insert string smiley + aDes.Insert( iconIndArray[ i - 1 ], + iSmileUtil->GetSmileString( icon->Index() ) ); + } + } + CleanupStack::PopAndDestroy(); // iconIndArray.Close() + IM_CV_LOGS(TXT("CIMCVAppSmileyUtil::ExtensionToStringL() end") ); + } + +// ----------------------------------------------------------------------------- +// CIMCVAppSmileyUtil::ConvertSelectionToExtensionL +// Convert selection smileys to icons. +// ----------------------------------------------------------------------------- +// +void CIMCVAppSmileyUtil::ConvertSelectionToExtensionL( CEikRichTextEditor& aEditor ) + { + IM_CV_LOGS(TXT("CIMCVAppSmileyUtil::ConvertSelectionToExtensionL() start") ); + TInt selectAdd( 0 ); + + // for loop gets icon positions to array + TInt start = aEditor.Selection().LowerPos(); + TInt end = aEditor.Selection().HigherPos(); + + // Clear convert array, it has something, but its not correct + iConvertArray.ResetAndDestroy(); + + const TInt KMaxLength( KDefaultMsgLength ); + HBufC* des = HBufC::NewLC( KMaxLength ); + TPtr desText( des->Des() ); + + aEditor.GetText( desText ); + TInt txtLen = desText.Length(); + if ( txtLen < end ) + { + end = txtLen; + } + desText.Delete( end, txtLen - end ); + desText.Delete( 0, start ); + + iSmileUtil->SearchSmilesL( desText, iConvertArray, NULL, start ); + + #ifdef _DEBUG + TPtrC myDebug( aEditor.Text()->Read( 0 ) ); + #endif + + for( TInt a( iConvertArray.Count() - 1 ); a >= 0; --a ) + { + if( iConvertArray[ a ]->Position() >= start && iConvertArray[ a ]->Position() < end ) // do we convert or not + { + TPictureHeader picHeader; + // Insert icon in place + + //we don't own this + CGulIcon* icon = const_cast( + iSmileUtil->GetSmileIcon( iConvertArray[ a ]->Index() ) ); + + //create CIMCVAppPicture from selected icon + CIMCVAppPicture* smileIcon = new ( ELeave ) CIMCVAppPicture( + *CCoeEnv::Static()->SystemGc().Device(), + icon, + iConvertArray[ a ]->Index() ); + + picHeader.iPicture = TSwizzle( smileIcon ); + aEditor.Text()->DeleteL( iConvertArray[ a ]->Position(), + iConvertArray[ a ]->SmileyString().Length() ); + + #ifdef _DEBUG + myDebug.Set( aEditor.Text()->Read( 0 ) ); + + #endif + + aEditor.RichText()->InsertL( iConvertArray[ a ]->Position(), picHeader ); + + #ifdef _DEBUG + myDebug.Set( aEditor.Text()->Read( 0 ) ); + + #endif + + selectAdd -= iConvertArray[ a ]->SmileyString().Length() - 1; + + // icon is inserted, and it should be converted to text + // before sending, so it needs extra chars according to smiley string length + TInt textLimit = + aEditor.MaxLength() - iConvertArray[ a ]->SmileyString().Length(); + TInt currentlength = aEditor.Text()->DocumentLength(); + aEditor.SetTextLimit( Max( textLimit, currentlength ) ); + + if( &aEditor != iEditor ) + { + iEditor = &aEditor; + iCurrentCount = 1; + } + else + { + ++iCurrentCount; + } + } + } + + // Apply formatting + TInt selectionLen = end + selectAdd - start; + TCharFormat charFormat; + TCharFormatMask charFormatMask; + charFormat.iFontPresentation.iPictureAlignment = + TFontPresentation::EAlignCentered; + charFormatMask.SetAttrib( EAttFontPictureAlignment ); + aEditor.RichText()->ApplyCharFormatL( charFormat, charFormatMask, + start, selectionLen ); + + // Handle changes in editor + aEditor.TextView()->HandleGlobalChangeL(); + + // Set selection to correct after adding images + aEditor.SetSelectionL( start, end + selectAdd ); + + // Clear convert array + iConvertArray.ResetAndDestroy(); + + CleanupStack::PopAndDestroy( des ); + IM_CV_LOGS(TXT("CIMCVAppSmileyUtil::ConvertSelectionToExtensionL() end") ); + } + +// ----------------------------------------------------------------------------- +// CIMCVAppSmileyUtil::ConvertSelectionToExtensionL +// Convert selection smileys to icons. +// ----------------------------------------------------------------------------- +// +void CIMCVAppSmileyUtil::ConvertSelectionToExtensionL( CRichText& aRichText, + TCursorSelection& aSelection ) + { + IM_CV_LOGS(TXT("CIMCVAppSmileyUtil::ConvertSelectionToExtensionL() start") ); + TInt start( aSelection.LowerPos() ); + TInt length( aSelection.Length() ); + + // Clear convert array and fetch the text + iConvertArray.ResetAndDestroy(); + HBufC* text = HBufC::NewMaxLC( aRichText.DocumentLength() ); + TPtr desText( text->Des() ); + aRichText.Extract( desText, start, length ); + + iSmileUtil->SearchSmilesL( desText, iConvertArray ); + + for( TInt a( iConvertArray.Count() - 1 ); a >= 0; --a ) + { + TPictureHeader picHeader; + // Insert icon in place + //we don't own this + CGulIcon* icon = const_cast( + iSmileUtil->GetSmileIcon( iConvertArray[ a ]->Index()) ); + + //create CIMCVAppPicture from selected icon + CIMCVAppPicture* smileIcon = new ( ELeave ) CIMCVAppPicture( + *CCoeEnv::Static()->SystemGc().Device(), + icon, + iConvertArray[ a ]->Index()); + + picHeader.iPicture = TSwizzle( smileIcon ); + aRichText.DeleteL( iConvertArray[ a ]->Position() + start, + iConvertArray[ a ]->SmileyString().Length() ); + + aRichText.InsertL( iConvertArray[ a ]->Position() + start, picHeader ); + } + + // clean up + iConvertArray.ResetAndDestroy(); + CleanupStack::PopAndDestroy( text ); + IM_CV_LOGS(TXT("CIMCVAppSmileyUtil::ConvertSelectionToExtensionL() end") ); + } + +// ----------------------------------------------------------------------------- +// CIMCVAppSmileyUtil::ConvertSelectionToStringL +// Convert selection smileys to strings +// ----------------------------------------------------------------------------- +// +void CIMCVAppSmileyUtil::ConvertSelectionToStringL( CEikRichTextEditor& aEditor, TBool aPreserve ) + { + IM_CV_LOGS(TXT("CIMCVAppSmileyUtil::ConvertSelectionToStringL() start") ); + // Clear convert array + iConvertArray.ResetAndDestroy(); + + HBufC* text = HBufC::NewMaxLC( KDefaultMsgLength ); + TPtr textCopy( text->Des() ); + aEditor.GetText( textCopy ); + + // for loop gets icon positions to array + TInt start = 0; + TInt end = aEditor.Text()->DocumentLength(); + //aEditor.Selection().HigherPos(); + + TInt i; + for( i = start; i < end; ++i ) + { + if( textCopy[ i ] == CEditableText::EPictureCharacter ) + { + CIMCVAppSmileyInformation* smileInfo = CIMCVAppSmileyInformation::NewL(); + CleanupStack::PushL( smileInfo ); + smileInfo->SetPosition( i ); + smileInfo->SetIcon( ETrue ); + User::LeaveIfError( iConvertArray.Append( smileInfo ) ); + CleanupStack::Pop( smileInfo ); + } + } + + TInt count = iConvertArray.Count(); + for( i = count - 1; i >= 0; --i ) + { + CPicture* editorPic = aEditor.RichText()->PictureHandleL( + iConvertArray[ i ]->Position(), MLayDoc::EForceLoadTrue ); + + if ( !editorPic ) + { + User::Leave( KErrBadHandle ); + } + + CIMCVAppPicture* icon = static_cast ( editorPic ); + + const TDesC& iconString = iSmileUtil->GetSmileString( icon->Index() ); + iConvertArray[ i ]->SetSmileyStringL( iconString ); + iConvertArray[ i ]->SetIndex( icon->Index() ); + } + + textCopy.Delete( end, textCopy.Length() - end ); + textCopy.Delete( 0, start ); + iSmileUtil->SearchSmilesL( textCopy, iConvertArray, NULL, start ); + + // Change icons to strings + TPtrC myDebug( aEditor.Text()->Read( 0 ) ); + + TInt selectAdd( 0 ); + count = iConvertArray.Count(); + for( i = count - 1; i >= 0; --i ) + { + if( iConvertArray[ i ]->IsIcon() ) // Icon + { + TCursorSelection deleteSel( iConvertArray[ i ]->Position(), + iConvertArray[ i ]->Position() + 1 ); + + aEditor.InsertDeleteCharsL( iConvertArray[ i ]->Position(), + iConvertArray[ i ]->SmileyString(), + deleteSel ); + selectAdd += iConvertArray[ i ]->SmileyString().Length() - 1; + //aEditor.SetMaxLength( aEditor.MaxLength() + selectAdd ); + } + } + myDebug.Set( aEditor.Text()->Read( 0 ) ); + + + aEditor.SetSelectionL( start, end + selectAdd ); + aEditor.TextView()->HandleGlobalChangeL(); + + if( !aPreserve ) + { + iConvertArray.ResetAndDestroy(); + } + + CleanupStack::PopAndDestroy( text ); + IM_CV_LOGS(TXT("CIMCVAppSmileyUtil::ConvertSelectionToStringL() end") ); + } + +// --------------------------------------------------------- +// CIMCVAppSmileyUtil::DeleteExtensionL +// (other items were commented in a header). +// --------------------------------------------------------- +// +void CIMCVAppSmileyUtil::DeleteExtensionL( CEikRichTextEditor& aEditor, TInt aPos ) + { + IM_CV_LOGS(TXT("CIMCVAppSmileyUtil::DeleteExtensionL() start") ); + // Set cursor position before deletion. + // Deletion may cause editor size to change and if + // cursor pos is not updated before that ETEXT 12 panic + // is raised. + aEditor.SetCursorPosL( aPos, EFalse ); + aEditor.RichText()->DeleteL( aPos, 1 ); + aEditor.HandleTextChangedL(); + // Ugly hack. Needed to keep alignment of + // cursor correct. + aEditor.SetCursorPosL( aPos, EFalse ); + + // update editors length, it grows by 2 when icon is deleted + TInt textLimit = aEditor.MaxLength() + 2; + aEditor.SetTextLimit( textLimit ); + + --iCurrentCount; + IM_CV_LOGS(TXT("CIMCVAppSmileyUtil::DeleteExtensionL() end") ); + } + +// ----------------------------------------------------------------------------- +// CIMCVAppSmileyUtil::Reset +// Reset extension +// ----------------------------------------------------------------------------- +// +void CIMCVAppSmileyUtil::Reset() + { + iCurrentCount = 0; + } + +// ----------------------------------------------------------------------------- +// CIMCVAppSmileyUtil::SizeChanged +// Reset extension +// ----------------------------------------------------------------------------- +// +void CIMCVAppSmileyUtil::SizeChanged( TSize& aSize ) + { + IM_CV_LOGS(TXT("CIMCVAppSmileyUtil::SizeChanged() start") ); + iSmileUtil->ResizeIcons( aSize ); + IM_CV_LOGS(TXT("CIMCVAppSmileyUtil::SizeChanged() end") ); + } + +// ----------------------------------------------------------------------------- +// CIMCVAppSmileyUtil::ConvertSelectionToStringL +// Convert selection smileys to strings +// ----------------------------------------------------------------------------- +// +void CIMCVAppSmileyUtil::ConvertSelectionToStringL( + CEikRichTextEditor& aEditor, + TDes& aResultString, + TCursorSelection& aSelectionAfterConversion, + TBool aPreserve ) + { + IM_CV_LOGS(TXT("CIMCVAppSmileyUtil::ConvertSelectionToStringL() start") ); + // Clear convert array + iConvertArray.ResetAndDestroy(); + + // Get text from editor + HBufC* text = HBufC::NewMaxLC( KDefaultMsgLength ); + TPtr textCopy( text->Des() ); + aEditor.GetText( textCopy ); + + // For loop gets icon positions to array + TInt start = aEditor.Selection().LowerPos(); + TInt end = aEditor.Selection().HigherPos(); + + // Copy text to result string + aResultString.Append( textCopy ); + + TInt i = 0; + for( i = start; i < end; ++i ) + { + if ( textCopy[i] == CEditableText::EPictureCharacter ) + { + CIMCVAppSmileyInformation* smileInfo = CIMCVAppSmileyInformation::NewL(); + CleanupStack::PushL( smileInfo ); + smileInfo->SetPosition( i ); + smileInfo->SetIcon( ETrue ); + User::LeaveIfError( iConvertArray.Append( smileInfo ) ); + CleanupStack::Pop( smileInfo ); + } + } + + TInt count = iConvertArray.Count(); + for( i = count - 1; i >= 0; --i ) + { + CPicture* editorPic = NULL; + + editorPic = aEditor.RichText()->PictureHandleL( + iConvertArray[i]->Position(), MLayDoc::EForceLoadTrue ); + + if ( !editorPic ) + { + User::Leave( KErrBadHandle ); + } + + CIMCVAppPicture* icon = static_cast ( editorPic ); + + const TDesC& iconString = iSmileUtil->GetSmileString( icon->Index() ); + iConvertArray[i]->SetSmileyStringL( iconString ); + iConvertArray[i]->SetIndex( icon->Index() ); + } + + textCopy.Delete( end, textCopy.Length() - end ); + textCopy.Delete( 0, start ); + iSmileUtil->SearchSmilesL( textCopy, iConvertArray, NULL, start ); + + // Change icons to strings + TInt selectAdd = 0; + count = iConvertArray.Count(); + for( i = count - 1; i >= 0; --i ) + { + if( iConvertArray[ i ]->IsIcon() ) // Icon + { + // Append smiley string to result + aResultString.Delete( iConvertArray[i]->Position(), 1 ); + aResultString.Insert( iConvertArray[i]->Position(), iConvertArray[i]->SmileyString() ); + selectAdd += iConvertArray[ i ]->SmileyString().Length() - 1; + } + } + + if( !aPreserve ) + { + iConvertArray.ResetAndDestroy(); + } + + // Set correct selection + aSelectionAfterConversion.SetSelection( end + selectAdd, start ); + + CleanupStack::PopAndDestroy( text ); + IM_CV_LOGS(TXT("CIMCVAppSmileyUtil::ConvertSelectionToStringL() end") ); + } +// ----------------------------------------------------------------------------- +// CIMCVAppSmileyUtil::ServiceId +// Convert selection smileys to strings +// ----------------------------------------------------------------------------- +// +TInt CIMCVAppSmileyUtil::ServiceId() const + { + return iServiceId; + } + +// End of File