wvuing/wvuiave/AppSrc/CCASmileIconUtility.cpp
changeset 0 094583676ce7
equal deleted inserted replaced
-1:000000000000 0:094583676ce7
       
     1 /*
       
     2 * Copyright (c) 2006 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:  Utility for selecting smile icon and converting
       
    15 *                between smile id and smile string.
       
    16 *
       
    17 */
       
    18 
       
    19 
       
    20 // INCLUDE FILES
       
    21 #include "CCASmileIconUtility.h"
       
    22 #include "CCASmileIconDialog.h"
       
    23 #include "ccasmilestring.h"
       
    24 #include "ccasmileyinformation.h"
       
    25 #include "IMUtils.h"
       
    26 
       
    27 #include "CCAAppUi.h"
       
    28 #include "MCASkinVariant.h"
       
    29 #include "CCAApp.h"
       
    30 #include "CCAVariantFactory.h"
       
    31 #include "ChatDebugPrint.h"
       
    32 #include "chatdebugassert.h"
       
    33 
       
    34 #include <chatNG.rsg>
       
    35 #include <bautils.h>
       
    36 #include <PUAcodes.hrh>
       
    37 #include <barsread.h> // RResourceReader
       
    38 #include <coemain.h>
       
    39 #include <eikenv.h>
       
    40 #include <gulicon.h>
       
    41 #include <akniconutils.h>
       
    42 
       
    43 // The Settings have been moved to Cenrep (also retained in the Resource file),
       
    44 // so the enums for keys and central repository header is added here
       
    45 #include 	"VariantKeys.h"
       
    46 // ================= MEMBER FUNCTIONS =======================
       
    47 
       
    48 // Two-phased constructor.
       
    49 CCASmileIconUtility* CCASmileIconUtility::NewL(
       
    50     MCASkinVariant& aSkinVariant,
       
    51     MCAAppUi& aAppUi )
       
    52     {
       
    53     CCASmileIconUtility* self = new ( ELeave ) CCASmileIconUtility( aSkinVariant, aAppUi );
       
    54     CleanupStack::PushL( self );
       
    55     self->ConstructL( R_SMILE_ARRAY_RESOURCE );
       
    56     CleanupStack::Pop( self );
       
    57     return self;
       
    58     }
       
    59 
       
    60 // Two-phased constructor.
       
    61 CCASmileIconUtility* CCASmileIconUtility::NewL(
       
    62     MCASkinVariant& aSkinVariant,
       
    63     MCAAppUi& aAppUi,
       
    64     TInt aResourceId )
       
    65     {
       
    66     CCASmileIconUtility* self = new ( ELeave ) CCASmileIconUtility( aSkinVariant, aAppUi );
       
    67     CleanupStack::PushL( self );
       
    68     self->ConstructL( aResourceId );
       
    69     CleanupStack::Pop( self );
       
    70     return self;
       
    71     }
       
    72 
       
    73 // Destructor
       
    74 CCASmileIconUtility::~CCASmileIconUtility()
       
    75     {
       
    76     iAppUi.RemoveResourceChangeObserver( this );
       
    77     iIconArray.ResetAndDestroy();
       
    78     iStringArray.ResetAndDestroy();
       
    79     iSmileArray.ResetAndDestroy();
       
    80     iIconToSmileyPointers.Close();
       
    81 
       
    82     iSmileDlgIconArray.ResetAndDestroy();
       
    83     }
       
    84 
       
    85 // C++ constructor can NOT contain any code, that
       
    86 // might leave.
       
    87 //
       
    88 CCASmileIconUtility::CCASmileIconUtility( MCASkinVariant& aSkinVariant,
       
    89                                           MCAAppUi& aAppUi )
       
    90         : iSkinVariant( aSkinVariant ), iAppUi( aAppUi )
       
    91     {
       
    92     }
       
    93 
       
    94 // ConstructL
       
    95 //
       
    96 void CCASmileIconUtility::ConstructL( TInt aResourceId )
       
    97     {
       
    98     // we need to be resource aware
       
    99     iAppUi.AddResourceChangeObserver( this );
       
   100 
       
   101     ConstructFromResourceL( aResourceId );
       
   102     }
       
   103 
       
   104 // ---------------------------------------------------------
       
   105 // CCASmileIconUtility::ConstructSmileDialogIconArrayL
       
   106 // (other items were commented in a header).
       
   107 // ---------------------------------------------------------
       
   108 //
       
   109 void CCASmileIconUtility::ConstructSmileDialogIconArrayL( TInt aResourceId )
       
   110     {
       
   111     TResourceReader reader;
       
   112     CCoeEnv::Static()->CreateResourceReaderLC( reader, aResourceId );
       
   113 
       
   114     TInt iconId;
       
   115     TInt maskId;
       
   116     TInt err( KErrNone );
       
   117 
       
   118     TInt iconCount( reader.ReadInt16() );
       
   119     for ( TInt i( 0 ); i < iconCount; ++i )
       
   120         {
       
   121         iconId = reader.ReadInt16();
       
   122         maskId = reader.ReadInt16();
       
   123 
       
   124         CGulIcon* icon = iSkinVariant.LoadBitmapL( iconId, maskId,
       
   125                                                    iAppUi.MbmFullPath() );
       
   126 
       
   127         err = iSmileDlgIconArray.Append( icon );
       
   128         if ( err )
       
   129             {
       
   130             delete icon;
       
   131             User::Leave( err );
       
   132             }
       
   133 
       
   134         TInt stringCount( reader.ReadInt16() );
       
   135         if ( !stringCount )
       
   136             {
       
   137             User::Leave( KErrGeneral );
       
   138             }
       
   139 
       
   140         HBufC* shortertString = NULL;
       
   141         for ( TInt j( 0 ); j < stringCount; ++j )
       
   142             {
       
   143             HBufC* smileString = reader.ReadHBufCL();
       
   144             delete smileString;
       
   145             }
       
   146         }
       
   147     CleanupStack::PopAndDestroy( ); // reader
       
   148     }
       
   149 
       
   150 // ---------------------------------------------------------
       
   151 // CCASmileIconUtility::LaunchSmileIconDialogL
       
   152 // (other items were commented in a header).
       
   153 // ---------------------------------------------------------
       
   154 //
       
   155 TInt CCASmileIconUtility::LaunchSmileIconDialogL( TInt& aSelectedIconId )
       
   156     {
       
   157     if ( iSmileDlgIconArray.Count() <= 0 )
       
   158         {
       
   159         ConstructSmileDialogIconArrayL( R_SMILE_ARRAY_RESOURCE );
       
   160         }
       
   161 
       
   162     CCASmileIconDialog* dialog = CCASmileIconDialog::NewL( iSmileDlgIconArray,
       
   163                                                            aSelectedIconId );
       
   164     TInt dialogVal = dialog->ExecuteLD( R_SELECT_SMILE_DIALOG );
       
   165 
       
   166     return dialogVal;
       
   167     }
       
   168 
       
   169 // ---------------------------------------------------------
       
   170 // CCASmileIconUtility::SmileIconCount
       
   171 // (other items were commented in a header).
       
   172 // ---------------------------------------------------------
       
   173 //
       
   174 TInt CCASmileIconUtility::SmileIconCount() const
       
   175     {
       
   176     return iIconArray.Count();
       
   177     }
       
   178 
       
   179 // ---------------------------------------------------------
       
   180 // CCASmileIconUtility::GetSmileIcon
       
   181 // (other items were commented in a header).
       
   182 // ---------------------------------------------------------
       
   183 //
       
   184 const CGulIcon* CCASmileIconUtility::GetSmileIcon( TInt aIconId ) const
       
   185     {
       
   186     return iIconArray[ aIconId ];
       
   187     }
       
   188 
       
   189 // ---------------------------------------------------------
       
   190 // CCASmileIconUtility::GetSmileString
       
   191 // (other items were commented in a header).
       
   192 // ---------------------------------------------------------
       
   193 //
       
   194 const TDesC& CCASmileIconUtility::GetSmileString( TInt aIconId ) const
       
   195     {
       
   196     return iStringArray[ iIconToSmileyPointers[ aIconId ] ]->HasShortestString() ?
       
   197            iStringArray[ iIconToSmileyPointers[ aIconId ] ]->ShortestSmileString() :
       
   198            iStringArray[ iIconToSmileyPointers[ aIconId ] ]->SmileString();
       
   199     }
       
   200 
       
   201 // ---------------------------------------------------------
       
   202 // CCASmileIconUtility::SearchSmilesL
       
   203 // (other items were commented in a header).
       
   204 // ---------------------------------------------------------
       
   205 //
       
   206 void CCASmileIconUtility::SearchSmilesL( const TDesC& aStr, TDes& aFixedStr,
       
   207                                          RArray<TInt>* aArray )
       
   208     {
       
   209 
       
   210     CHAT_DP( D_CHAT_LIT( "CCASmileIconUtility::SearchSmilesL: begin %S" ),
       
   211              &aStr );
       
   212     TInt i;
       
   213     iSmileArray.ResetAndDestroy();
       
   214     SearchSmilesL( aStr, iSmileArray, &aFixedStr );
       
   215 
       
   216     aArray->Reset();
       
   217     TInt arrayCount( iSmileArray.Count() );
       
   218 
       
   219     for ( i = 0; i < arrayCount; ++i )
       
   220         {
       
   221         User::LeaveIfError( aArray->Append( iSmileArray[ i ]->Index() ) );
       
   222         }
       
   223 
       
   224     iSmileArray.ResetAndDestroy();
       
   225     CHAT_DP( D_CHAT_LIT( "CCASmileIconUtility::SearchSmilesL: done %S" ),
       
   226              &aFixedStr );
       
   227     }
       
   228 
       
   229 // -----------------------------------------------------------------------------
       
   230 // CCASmileIconUtility::SearchSmilesL
       
   231 // Search smileys from string and sort them in linear order.
       
   232 // -----------------------------------------------------------------------------
       
   233 //
       
   234 void CCASmileIconUtility::SearchSmilesL( const TDesC& aStr,
       
   235                                          RPointerArray< CCASmileyInformation >& aSmileyInfoArray,
       
   236                                          TDes* aFixedStr /*= NULL */,
       
   237                                          TInt aStartPos /* = 0 */ ) const
       
   238     {
       
   239     CHAT_DP( D_CHAT_LIT( "CCASmileIconUtility::SearchSmilesL2: %S %d" ),
       
   240              &aStr, aStartPos );
       
   241 
       
   242     HBufC* text = HBufC::NewMaxLC( aStr.Length() );
       
   243     TPtr fixedText( text->Des() );
       
   244     fixedText.Copy( aStr.Left( fixedText.MaxLength() ) );
       
   245 
       
   246     HBufC* replaceString = HBufC::NewMaxLC( iLongestSmileyLength );
       
   247     TPtr replace( replaceString->Des() );
       
   248     if ( aFixedStr )
       
   249         {
       
   250         replace.Fill( KPuaCodeSmileyIconPadding, 1 );
       
   251         }
       
   252     else
       
   253         {
       
   254         //we dont need fixed, but we do need correct positions
       
   255         replace.Fill( KPuaCodeSmileyIconPadding, iLongestSmileyLength );
       
   256         }
       
   257 
       
   258     // order to sort array by the position
       
   259     TLinearOrder< CCASmileyInformation > order( CCASmileIconUtility::Compare );
       
   260 
       
   261     // for i-loop goes throug every smile string
       
   262     // while-loop searches smiles from given string
       
   263     TInt arrayCount = iStringArray.Count();
       
   264     TInt index = 0;
       
   265     for ( TInt i = 0; i < arrayCount; ++i )
       
   266         {
       
   267         const TDesC& smileString( iStringArray[ i ]->SmileString() );
       
   268         index = fixedText.Find( smileString );
       
   269         while ( index != KErrNotFound )
       
   270             {
       
   271             CCASmileyInformation* smileInfo = CCASmileyInformation::NewL();
       
   272             CleanupStack::PushL( smileInfo );
       
   273 
       
   274             smileInfo->SetPosition( index + aStartPos );
       
   275             smileInfo->SetIndex( iStringArray[ i ]->SmileIconIndex() );
       
   276             smileInfo->SetSmileyStringL( smileString );
       
   277             smileInfo->SetIcon( EFalse );
       
   278 
       
   279             User::LeaveIfError( aSmileyInfoArray.Append( smileInfo ) );
       
   280             CleanupStack::Pop( smileInfo );
       
   281 
       
   282             TInt smilyLength = smileString.Length();
       
   283             // Only replace the same amount of chars than in smiley, so we
       
   284             // don't mess up the length or index table.
       
   285             fixedText.Replace( index,
       
   286                                smilyLength,
       
   287                                replace.Left( smilyLength ) );
       
   288             index = fixedText.Find( smileString );
       
   289             } // while
       
   290         } // for i
       
   291 
       
   292     aSmileyInfoArray.Sort( order );
       
   293     if ( aFixedStr )
       
   294         {
       
   295         *aFixedStr = fixedText;
       
   296         }
       
   297 
       
   298     CleanupStack::PopAndDestroy( 2, text ); // replaceString, text
       
   299     CHAT_DP_TXT( "CCASmileIconUtility::SearchSmilesL2: done" );
       
   300     }
       
   301 
       
   302 // ---------------------------------------------------------
       
   303 // CCASmileIconUtility::Compare
       
   304 // (other items were commented in a header).
       
   305 // ---------------------------------------------------------
       
   306 //
       
   307 TInt CCASmileIconUtility::Compare( const CCASmileyInformation& aFirst,
       
   308                                    const CCASmileyInformation& aSecond )
       
   309     {
       
   310     return ( aFirst.Position() - aSecond.Position() );
       
   311     }
       
   312 
       
   313 // -----------------------------------------------------------------------------
       
   314 // CCASmileIconUtility::CompareSmileyLengthReversed
       
   315 // (other items were commented in a header).
       
   316 // -----------------------------------------------------------------------------
       
   317 //
       
   318 TInt CCASmileIconUtility::CompareSmileyLengthReversed(
       
   319     const CCASmileString& aFirst,
       
   320     const CCASmileString& aSecond )
       
   321     {
       
   322     return ( aSecond.SmileString().Length() - aFirst.SmileString().Length() );
       
   323     }
       
   324 
       
   325 // ---------------------------------------------------------
       
   326 // CCASmileIconUtility::ResizeIcons
       
   327 // (other items were commented in a header).
       
   328 // ---------------------------------------------------------
       
   329 //
       
   330 void CCASmileIconUtility::ResizeIcons( const TSize& aSize )
       
   331     {
       
   332     TInt count( SmileIconCount() );
       
   333     for ( TInt i( 0 ); i < count; i++ )
       
   334         {
       
   335         AknIconUtils::SetSize( iIconArray[ i ]->Bitmap(), aSize );
       
   336         }
       
   337     }
       
   338 
       
   339 // ---------------------------------------------------------
       
   340 // CCASmileIconUtility::ConstructFromResourceL
       
   341 // (other items were commented in a header).
       
   342 // ---------------------------------------------------------
       
   343 //
       
   344 void CCASmileIconUtility::ConstructFromResourceL( TInt aResourceId )
       
   345     {
       
   346     TResourceReader reader;
       
   347     CCoeEnv::Static()->CreateResourceReaderLC( reader, aResourceId );
       
   348 
       
   349     iLongestSmileyLength = 1;
       
   350     TInt iconId;
       
   351     TInt maskId;
       
   352     TInt err( KErrNone );
       
   353     TInt iconCount( reader.ReadInt16() );
       
   354     for ( TInt i( 0 ); i < iconCount; ++i )
       
   355         {
       
   356         iconId = reader.ReadInt16();
       
   357         maskId = reader.ReadInt16();
       
   358 
       
   359         CGulIcon* icon = iSkinVariant.LoadBitmapL( iconId, maskId,
       
   360                                                    iAppUi.MbmFullPath() );
       
   361 
       
   362         err = iIconArray.Append( icon );
       
   363         if ( err )
       
   364             {
       
   365             delete icon;
       
   366             User::Leave( err );
       
   367             }
       
   368 
       
   369         TInt stringCount( reader.ReadInt16() );
       
   370         if ( !stringCount )
       
   371             {
       
   372             User::Leave( KErrGeneral );
       
   373             }
       
   374 
       
   375         HBufC* shortertString = NULL;
       
   376 
       
   377         for ( TInt j( 0 ); j < stringCount; ++j )
       
   378             {
       
   379             CCASmileString* smileArray = CCASmileString::NewL();
       
   380             CleanupStack::PushL( smileArray );
       
   381 
       
   382             HBufC* smileString = reader.ReadHBufCL();
       
   383             // ownership is transferred
       
   384             smileArray->Set( smileString, i );
       
   385 
       
   386             // Update the smiley length
       
   387             if ( smileString->Length() > iLongestSmileyLength )
       
   388                 {
       
   389                 iLongestSmileyLength = smileString->Length();
       
   390                 }
       
   391 
       
   392             // Check for shorter smiley strings,
       
   393             // needed when converting smileys from images to
       
   394             // strings before sending to avoid descriptor overflow
       
   395             if ( shortertString )
       
   396                 {
       
   397                 if ( shortertString->Length() < shortertString->Length() )
       
   398                     {
       
   399                     // Set shotestString to current smiley
       
   400                     smileArray->SetShortestSmileStringL( *shortertString );
       
   401                     }
       
   402                 else
       
   403                     {
       
   404                     // Found a new shortest string
       
   405                     // Set it to previous similar smileys
       
   406                     for ( TInt ii = 0; ii < j; ii++ )
       
   407                         {
       
   408                         iStringArray[iStringArray.Count() - ii - 1]->
       
   409                         SetShortestSmileStringL( *smileString );
       
   410                         }
       
   411                     // Store new shortest string
       
   412                     shortertString = smileString;
       
   413                     }
       
   414                 }
       
   415             else
       
   416                 {
       
   417                 // First string, store to shortestString
       
   418                 shortertString = smileString;
       
   419                 }
       
   420 
       
   421             User::LeaveIfError( iStringArray.Append( smileArray ) );
       
   422             CleanupStack::Pop( smileArray );
       
   423             }
       
   424         }
       
   425 
       
   426     CleanupStack::PopAndDestroy(); // reader
       
   427 
       
   428     // Sort smileys according to their string length, so that searching
       
   429     // for smileys is done from the longest smiley to the shortest. This
       
   430     // prevents the chat from detecting smaller smileys inside the big ones.
       
   431     TLinearOrder< CCASmileString >
       
   432     order( CCASmileIconUtility::CompareSmileyLengthReversed );
       
   433     iStringArray.Sort( order );
       
   434 
       
   435     // Precalculate an ref table from icon to smiley.
       
   436     iIconToSmileyPointers.Reset();
       
   437     TInt count = iIconArray.Count();
       
   438     for ( TInt i = 0; i < count; ++i )
       
   439         {
       
   440         User::LeaveIfError(
       
   441             iIconToSmileyPointers.Append( GetFirstSmileyIndex( i ) ) );
       
   442         }
       
   443     }
       
   444 
       
   445 // -----------------------------------------------------------------------------
       
   446 // CCASmileIconUtility::GetFirstSmileyIndex
       
   447 // -----------------------------------------------------------------------------
       
   448 //
       
   449 TInt CCASmileIconUtility::GetFirstSmileyIndex( TInt aIconIndex ) const
       
   450     {
       
   451     TInt count = iStringArray.Count();
       
   452 
       
   453     for ( TInt i = 0; i < count; ++i )
       
   454         {
       
   455         if ( iStringArray[ i ]->SmileIconIndex() == aIconIndex )
       
   456             {
       
   457             return i;
       
   458             }
       
   459         }
       
   460 
       
   461     // Icon was not found.
       
   462     __CHAT_ASSERT_DEBUG( EFalse );
       
   463     return KErrNotFound;
       
   464     }
       
   465 
       
   466 // -----------------------------------------------------------------------------
       
   467 // CCASmileIconUtility::HandleResourceChange
       
   468 // -----------------------------------------------------------------------------
       
   469 //
       
   470 void CCASmileIconUtility::ResourceChangedL()
       
   471     {
       
   472     iIconArray.ResetAndDestroy();
       
   473     iStringArray.ResetAndDestroy();
       
   474     ConstructFromResourceL( R_SMILE_ARRAY_RESOURCE );
       
   475     }
       
   476 
       
   477 // End of File
       
   478