mobilemessaging/unieditor/utils/src/UniAddressHandler.cpp
changeset 0 72b543305e3a
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mobilemessaging/unieditor/utils/src/UniAddressHandler.cpp	Thu Dec 17 08:44:11 2009 +0200
@@ -0,0 +1,832 @@
+/*
+* Copyright (c) 2002-2007 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:  
+*       Defines implementation of CUniAddressHandler class methods.
+*
+*/
+
+
+
+// ========== INCLUDE FILES ================================
+
+#include "UniAddressHandler.h"
+
+// MSV
+#include <cmsvrecipientlist.h>  
+#include <mtclbase.h>
+
+// MMS Engine
+#include <mmsgenutils.h>
+
+// Base Editor
+#include <MsgAddressControl.h>      // for CMsgAddressControl
+#include <MsgRecipientItem.h>       // for CMsgRecipientItem
+#include <MsgCheckNames.h>          // for CMsgCheckNames
+#include <contactmatcher.h>
+#include <MVPbkStoreContact.h>
+
+// MUIU
+#include <MuiuMsvUiServiceUtilities.h>
+#include <muiumsvuiserviceutilitiesinternal.h>
+
+#include <centralrepository.h>    // link against centralrepository.lib
+#include <telconfigcrkeys.h> // for Central Repository keys
+
+// AVKON
+#include <AknUtils.h>
+#include <aknnotewrappers.h>
+#include <akninputblock.h>
+
+// Common Components
+#include <StringLoader.h>           // for StringLoader (load and foramt strings from resources)
+#include <commonphoneparser.h>      // Common phone number validity checker
+#include <data_caging_path_literals.hrh> 
+
+#include <bautils.h>                        // NearestLanguageFile
+
+#include <UniUtils.rsg>           // resources
+
+#include "UniUtils.h"
+
+// ========== EXTERNAL DATA STRUCTURES =====================
+
+// ========== EXTERNAL FUNCTION PROTOTYPES =================
+
+// ========== CONSTANTS ====================================
+
+const TInt KMaxDetailsLength = 64;   // Copy max this many chars to TMsvEntry iDetails
+const TInt KDefaultCompareLength = 7;
+
+_LIT( KAddressSeparator, ";" );
+
+// ========== MACROS =======================================
+
+// ========== LOCAL CONSTANTS AND MACROS ===================
+
+// ========== MODULE DATA STRUCTURES =======================
+
+// ========== LOCAL FUNCTION PROTOTYPES ====================
+
+// ========== LOCAL FUNCTIONS ==============================
+
+// ========== MEMBER FUNCTIONS =============================
+
+// ---------------------------------------------------------
+// CUniAddressHandler::CUniAddressHandler
+//
+// C++ constructor.
+// ---------------------------------------------------------
+//
+CUniAddressHandler::CUniAddressHandler( CBaseMtm& aMtm,
+                                        CMsgAddressControl& aControl,
+                                        CCoeEnv& aCoeEnv ) :
+    iMtm( aMtm ),
+    iControl( aControl ),
+    iCoeEnv( aCoeEnv ),
+    iValidAddressType( CMsgCheckNames::EMsgTypeMms ),
+    iResourceLoader( iCoeEnv )
+    {
+    }
+
+// ---------------------------------------------------------
+// CUniAddressHandler::ConstructL
+// ---------------------------------------------------------
+//
+void CUniAddressHandler::ConstructL()
+    {
+    if ( !iCoeEnv.IsResourceAvailableL( R_UNUT_INFO_FAIL_RECIPIENT_NO_ALIAS ) )
+        {
+        TParse parse;
+        User::LeaveIfError( parse.Set( KUniUtilsResourceFileName, &KDC_RESOURCE_FILES_DIR, NULL ) );
+        TFileName fileName( parse.FullName() );
+        iResourceLoader.OpenL( fileName );                 
+        }
+        iCheckNames = CMsgCheckNames::NewL();
+    }
+
+// ---------------------------------------------------------
+// CUniAddressHandler::NewL
+//
+// Factory method.
+// ---------------------------------------------------------
+//
+EXPORT_C CUniAddressHandler* CUniAddressHandler::NewL( CBaseMtm& aMtm,
+                                                       CMsgAddressControl& aControl,
+                                                       CCoeEnv& aCoeEnv )
+    {
+    CUniAddressHandler* self = new ( ELeave ) CUniAddressHandler( aMtm, aControl, aCoeEnv );
+
+    CleanupStack::PushL( self );
+    self->ConstructL();
+    CleanupStack::Pop( self );
+
+    return self;
+    }
+
+// ---------------------------------------------------------
+// CUniAddressHandler::~CUniAddressHandler
+// ---------------------------------------------------------
+//
+CUniAddressHandler::~CUniAddressHandler()
+    {
+    iResourceLoader.Close();
+    
+    delete iCheckNames;
+    delete iInvalidRecipients;
+    }
+
+// ---------------------------------------------------------
+// CUniAddressHandler::RemoveAddressesFromMtmL
+//
+// Resets address list in MTM
+// ---------------------------------------------------------
+//
+EXPORT_C void CUniAddressHandler::RemoveAddressesFromMtmL( TMsvRecipientTypeValues aRecipientType)
+    {
+    const CMsvRecipientList& addresses = iMtm.AddresseeList();
+
+    for ( TInt i = iMtm.AddresseeList().Count(); --i >=  0; )
+        {
+        if ( addresses.Type( i ) == aRecipientType )
+            {
+            iMtm.RemoveAddressee( i );
+            }
+        }
+    }
+
+// ---------------------------------------------------------
+// CUniAddressHandler::CopyAddressesToMtmL
+//
+// Resets address list in MTM and insert addresses from 
+// address control to MTM
+// ---------------------------------------------------------
+//
+EXPORT_C void CUniAddressHandler::CopyAddressesToMtmL( TMsvRecipientTypeValues aRecipientType )
+    {
+    RemoveAddressesFromMtmL( aRecipientType );
+    AppendAddressesToMtmL( aRecipientType );
+    }
+
+// ---------------------------------------------------------
+// CUniAddressHandler::AppendAddressesToMtmL
+//
+// Inserts addresses from control to MTM.
+// ---------------------------------------------------------
+//
+EXPORT_C void CUniAddressHandler::AppendAddressesToMtmL( TMsvRecipientTypeValues aRecipientType)
+
+    {
+    const TInt KMaxContactLength = 100;
+    const CMsgRecipientArray* recipients = iControl.GetRecipientsL(); // Not owned
+    
+    HBufC* contactname = HBufC::NewL( KMaxContactLength );
+    CleanupStack::PushL( contactname ); 
+    TPtr aliPtr ( contactname->Des() );
+    TInt addrCnt = recipients->Count();
+    
+    for ( TInt i = 0; i < addrCnt ; i++ )
+        {
+        CMsgRecipientItem* addrItem = recipients->At( i );
+
+        TPtr realAddress = addrItem->Address()->Des();
+        TPtr alias = addrItem->Name()->Des();
+
+        // Check that neither string contains illegal characters.
+        // If they does strip illegal chars away and save
+        RemoveIllegalChars( realAddress );
+        
+        if ( alias.Length() > 0 )
+            {
+            RemoveIllegalChars( alias );
+            iMtm.AddAddresseeL( aRecipientType, realAddress, alias );
+            }
+        else
+            {               
+            iCheckNames->GetAliasL(realAddress,aliPtr,KMaxContactLength);             
+            if(contactname->Des().Length() > 0 )
+                {
+                RemoveIllegalChars( aliPtr );
+                }            
+            iMtm.AddAddresseeL( aRecipientType, realAddress, aliPtr );
+            }                              
+        }
+        CleanupStack::PopAndDestroy( contactname );           
+    }
+
+// ---------------------------------------------------------
+// CUniAddressHandler::CopyAddressesFromMtmL
+//
+// Inserts addresses from MTM to address control. aAddInvalid
+// parameter is used to determine whether invalid addresses
+// should be added to the control or to special list that can
+// be used later on to show invalid address notes.
+// ---------------------------------------------------------
+//
+EXPORT_C void CUniAddressHandler::CopyAddressesFromMtmL( TMsvRecipientTypeValues aRecipientType,
+                                                         TBool aAddInvalid )
+    {
+    const CMsvRecipientList& addresses = iMtm.AddresseeList();
+
+    CMsgRecipientList* recipients = CMsgRecipientList::NewL();
+    CleanupStack::PushL( recipients );
+        
+    TInt addrCnt = addresses.Count();        
+    for ( TInt i = 0; i < addrCnt; i++ )
+        {          
+        if ( addresses.Type( i ) == aRecipientType )
+            {
+            TPtrC address = TMmsGenUtils::PureAddress( addresses[i] );
+            if ( address.Length() > 0 )
+                {
+                TPtrC alias   = TMmsGenUtils::Alias( addresses[i] );
+                if ( address.Compare( alias ) == 0 )
+                    {
+                    // Both alias and address are the same -> drop the alias as this is most likely reply to 
+                    // SMS and SMS client MTM sets both alias and address to be the same.
+                    alias.Set( KNullDesC );
+                    }
+                
+                CMsgRecipientItem* item = CMsgRecipientItem::NewLC( alias, address );
+                item->SetVerified( alias.Length() > 0 ? ETrue : EFalse );
+                
+                HBufC16* convertBuffer = NumberConversionLC( address, EFalse );
+                
+            	if ( aAddInvalid || CheckSingleAddressL( *convertBuffer ) )
+                    {    
+                    recipients->AppendL( item );
+                    }
+                else
+                    {
+                    if ( !iInvalidRecipients )
+                        {
+                        iInvalidRecipients = CMsgRecipientList::NewL();
+                        }
+                    iInvalidRecipients->AppendL( item );
+                    }
+                
+                CleanupStack::PopAndDestroy( convertBuffer );    
+                CleanupStack::Pop( item );
+                }
+            }
+        }
+
+    if ( recipients->Count() > 0 )
+        {
+        iControl.AddRecipientsL( *recipients );
+        iControl.SetModified( EFalse );
+        }
+        
+    CleanupStack::PopAndDestroy( recipients );
+    }
+
+// ---------------------------------------------------------
+// CUniAddressHandler::VerifyAddressesL
+//
+// Walks thru addresses in addresscontrol and counts errors. 
+// If unverified address is valid, marks it validated (verified now). 
+// Stops to first error.
+// ---------------------------------------------------------
+//
+EXPORT_C TBool CUniAddressHandler::VerifyAddressesL( TBool& aModified )
+    {
+    CAknInputBlock::NewLC();  
+
+    aModified = EFalse;
+
+    CMsgRecipientArray* recipients = iControl.GetRecipientsL(); // Not owned
+
+    TInt addrCnt = recipients->Count();
+    
+    // First verify unverified addresses in control.
+    for ( TInt i = 0; i < addrCnt; i++ )
+        {
+        CMsgRecipientItem* addrItem = recipients->At( i );
+
+        if ( !addrItem->IsVerified() || 
+             !addrItem->IsValidated() )
+            {
+            // Must check
+            // Just check the addresses here. Don't modify them yet.
+            if ( CheckSingleAddressL( *( addrItem->Address() ) ) )
+                {
+                addrItem->SetValidated( ETrue );
+                }
+            else 
+                {
+                // Address not OK, but maybe it's an alias from Phonebook...
+                TBool addressOK = EFalse;
+                
+                // Search for matches
+                if ( !iCheckNames )
+                    {
+                    iCheckNames = CMsgCheckNames::NewL();
+                    }
+                    
+                if ( iCheckNames->FindAndCheckByNameL( *addrItem->Address(), 
+                                                       iValidAddressType, 
+                                                       *recipients, 
+                                                       i ) ) 
+                    { 
+                    //  Determine how many new entries
+                    addressOK = ETrue;
+                    aModified = ETrue;
+
+                    TInt newEntries = recipients->Count() - addrCnt;
+                    TInt checkedEntry = i;
+                    i = i + newEntries;
+                    
+                    // Check that found entry's/entries number is valid
+                    while ( checkedEntry <= i )
+                        {
+                        addrItem = recipients->At( checkedEntry );
+                        if ( CheckSingleAddressL( *( addrItem->Address() ) ) )
+                            {
+                            addrItem->SetValidated( ETrue );
+                            addrItem->SetVerified( ETrue );
+                            }
+                        else 
+                            { 
+                            // Address not OK
+                            addressOK = EFalse;
+                            break;
+                            }
+                            
+                        checkedEntry++;
+                        }
+                    }
+                    
+                if ( !addressOK )
+                    {
+                    // Save the address & alias name. Those will be
+                    // lost if slide is changed.
+                    HBufC* address = addrItem->Address()->AllocLC();
+                    HBufC* name = addrItem->Name()->AllocLC();
+                    
+                    iControl.RefreshL( *recipients ); 
+                    
+                    // Address is not OK.
+                    ShowAddressInfoNoteL( *address, *name );
+                    
+                    CleanupStack::PopAndDestroy( 3 ); //address, name, CAknInputBlock
+                    
+                    iControl.HighlightUnvalidatedStringL(); 
+                    return EFalse;
+                    }
+                }
+            }
+        }
+
+
+    // Addresses are all ok. Now parse not allowed chars away before giving it to MTM.
+    addrCnt = recipients->Count();
+    for ( TInt ii = 0; ii < addrCnt; ii++ )
+        {
+        // Note: This is just to parse spaces etc away from phonenumbers.
+        //       Ignore EFalse returned for email addresses. 
+        TPtr tempPtr = recipients->At( ii )->Address()->Des();
+        CommonPhoneParser::ParsePhoneNumber( tempPtr, 
+                                             CommonPhoneParser::ESMSNumber );
+        }
+
+    iControl.RefreshL( *recipients ); // returns always KErrNone!
+    
+    CleanupStack::PopAndDestroy(); // CAknInputBlock
+    return ETrue;
+    }
+
+// ---------------------------------------------------------
+// CUniAddressHandler::RemoveDuplicateAddressesL
+//
+// Should be called when sending and after 
+// all addresses are validated i.e. no more error corrections
+// from user i.e. user is not going to edit addr control 
+// after this because Addresscontrol is not updated to show 
+// removed entries.
+// ---------------------------------------------------------
+//
+EXPORT_C TBool CUniAddressHandler::RemoveDuplicateAddressesL( 
+    CArrayPtrFlat<CMsgAddressControl>& aAddressControls )
+    {
+    TBool retVal = EFalse;
+    
+    TInt controlCount = aAddressControls.Count();
+    if ( controlCount == 0 )
+        {
+        return retVal;
+        }
+
+    // Initialize internal recipient info array.
+    // Needed for tracking modifications of the recipient lists.
+    // Possible modifications are "committed" back to address
+    // controls only once after all the checks have been performed.
+    CArrayFixFlat<TRecipientsInfo>* recipientInfos = 
+                                    new ( ELeave ) CArrayFixFlat<TRecipientsInfo>( controlCount );
+    CleanupStack::PushL( recipientInfos );
+    
+    for ( TInt init = 0; init < controlCount; init++ )
+        {
+        TRecipientsInfo info;
+        info.iRecipients = aAddressControls.At( init )->GetRecipientsL();
+        info.iOriginalCount = info.iRecipients->Count();
+        info.iModified = EFalse;
+        recipientInfos->AppendL( info );
+        }
+
+    TInt compareLength( KDefaultCompareLength );
+    
+    CRepository* repository = CRepository::NewL( KCRUidTelConfiguration );
+    
+    repository->Get( KTelMatchDigits, compareLength );
+    
+    delete repository;   
+   
+    CMsgRecipientItem* addrItem1 = NULL;
+    CMsgRecipientItem* addrItem2 = NULL;
+    CMsgRecipientArray* recipients1 = NULL;
+    CMsgRecipientArray* recipients2 = NULL;
+    
+    for ( TInt i = 0; i < controlCount; i++ )
+        {
+        recipients1 = recipientInfos->At( i ).iRecipients;
+        
+        for ( TInt j = 0; j < recipients1->Count(); j++ )
+            {
+            addrItem1 = recipients1->At( j );
+            
+            for ( TInt k = i; k < controlCount; k++ )
+                {
+                recipients2 = recipientInfos->At( k ).iRecipients;
+                TInt l( 0 );
+                if ( recipients2 == recipients1 )
+                    {
+                    // No need to check earlier items of "recipients1"
+                    l = j + 1;
+                    }
+                for ( ; l < recipients2->Count(); l++ )
+                    {
+                    addrItem2 = recipients2->At( l );
+
+                    if ( addrItem1->Address() && addrItem2->Address() )
+                        {
+                        // Check for equal phone numbers
+                        TBool equal = MsvUiServiceUtilitiesInternal::ComparePhoneNumberL( *( addrItem1->Address() ), 
+                                                                                          *( addrItem2->Address() ), 
+                                                                                          compareLength );
+                        if ( !equal )
+                            {
+                            // Check for equal mail addresses
+                            equal = addrItem1->Address()->CompareF( *(addrItem2->Address() ) ) == 0;
+                            }
+                        
+                        // If email address check or phone number check returns that addresses are 
+                        // equal then remove either one of them.
+                        if ( equal )
+                            {
+                            if( addrItem1->Name()->Length() && addrItem2->Name()->Length() )
+                                { // Both recipients have alias
+                                if ( addrItem1->Name()->Compare( *(addrItem2->Name()) ) != 0 )
+                                    {
+                                    // if aliases don't match clear alias.
+                                    addrItem1->SetNameL( KNullDesC() );
+                                    addrItem1->SetVerified( EFalse );
+                                    recipientInfos->At( i ).iModified = ETrue;
+                                    }
+                                // if they match -> leave it as it is
+                                }
+                            else if( addrItem1->Name()->Length() || addrItem2->Name()->Length() )
+                                { // only one of them has an alias
+                                if( addrItem2->Name()->Length() )
+                                    { // addrItem2 has it
+                                    addrItem1->SetNameL( *addrItem2->Name( ) );
+                                    addrItem1->SetVerified( ETrue );
+                                    recipientInfos->At( i ).iModified = ETrue;
+                                    }
+                                // else addrItem1 has it so it's already set in the Name field
+                                }
+                            recipients2->Delete( l );
+                            delete addrItem2;
+                            addrItem2 = NULL;
+                            l--;
+                            retVal = ETrue;
+                            }
+                        }
+                    }
+                }
+            }
+        }
+
+    // Check whether recipients have changed and refresh if needed.
+    for ( TInt final = 0; final < controlCount; final++ )
+        {
+        if ( recipientInfos->At( final ).iModified ||
+            ( recipientInfos->At( final ).iOriginalCount !=
+              recipientInfos->At( final ).iRecipients->Count() ) )
+            {
+            aAddressControls.At( final )->RefreshL( *recipientInfos->At( final ).iRecipients );
+            }
+        }
+    CleanupStack::PopAndDestroy( recipientInfos );
+    return retVal;
+    }
+
+// ----------------------------------------------------
+// CUniAddressHandler::AddRecipientL
+//
+// Performs address(es) fetch operation.
+// ----------------------------------------------------
+//
+EXPORT_C TBool CUniAddressHandler::AddRecipientL( TBool& aInvalid )
+    {
+    TBool addressesAdded( EFalse );
+    aInvalid = EFalse;
+    
+    CMsgRecipientList* recipientList = CMsgRecipientList::NewL();
+    CleanupStack::PushL( recipientList );
+
+    CMsgRecipientArray* recipients = new ( ELeave ) CMsgRecipientArray( 10 );
+    CleanupStack::PushL( TCleanupItem( CleanupRecipientArray, recipients ) );
+    
+    // Multiple entry fetch to get the contact    
+    if ( !iCheckNames )
+        {
+        iCheckNames = CMsgCheckNames::NewL();
+        }
+        
+    iCheckNames->FetchRecipientsL( *recipients, iValidAddressType );
+    
+    // Contacts now fetched, verify that valid address is given for every contact
+    while ( recipients->Count() > 0 )
+        {
+        CMsgRecipientItem* recipient = recipients->At( 0 );
+        
+        TPtrC namePtr = recipient->Name()->Des();
+        TPtrC addressPtr = recipient->Address()->Des();
+
+        // Don't parse away chars here so this is consistent with 
+        // addresses that user writes "-()" are saved to draft
+        // but removed when sending
+        if ( CheckSingleAddressL( addressPtr ) )
+            {
+            //  add it to the list of valid addresses
+            recipient->SetValidated( ETrue );
+            recipient->SetVerified( ( namePtr.Length() > 0 ? ETrue : EFalse ) );
+            recipientList->AppendL( recipient );
+            }
+        else
+            {
+            aInvalid = ETrue;
+            ShowAddressInfoNoteL( addressPtr, namePtr );
+            delete recipient;
+            }
+        
+        recipients->Delete( 0 );
+        }
+    
+    if ( recipientList->Count() > 0 )
+        {
+        iControl.AddRecipientsL( *recipientList );
+        addressesAdded = ETrue;
+        }
+ 
+    CleanupStack::PopAndDestroy( 2, recipientList );//recipients
+    
+    return addressesAdded;
+    }
+    
+// ---------------------------------------------------------
+// CUniAddressHandler::CheckSingleAddressL
+// ---------------------------------------------------------
+//
+EXPORT_C TBool CUniAddressHandler::CheckSingleAddressL( const TDesC& aAddress )
+    {
+    if ( iValidAddressType != CMsgCheckNames::EMsgTypeMail &&
+         CommonPhoneParser::IsValidPhoneNumber( aAddress, CommonPhoneParser::ESMSNumber ) )
+        {
+        return ETrue;
+        }
+        
+    if ( iValidAddressType != CMsgCheckNames::EMsgTypeSms && 
+         MsvUiServiceUtilities::IsValidEmailAddressL( aAddress ) )
+        {
+        return ETrue;
+        }
+        
+    return EFalse;
+    }
+
+// ---------------------------------------------------------
+// CUniAddressHandler::MakeDetailsL
+// ---------------------------------------------------------
+//
+EXPORT_C void CUniAddressHandler::MakeDetailsL( TDes& aDetails )
+    {
+    // This very same code can be found in MMSPlugin. 
+    // They should be put in common location some day...
+    const CMsvRecipientList& addresses = iMtm.AddresseeList();
+    TInt addrCnt = addresses.Count();
+
+    TPtrC stringToAdd;
+    for ( TInt i = 0; i < addrCnt; i++)
+        {
+        // Only address is converted to western. 
+        // There may numbers in contact name - they must not be converted 
+        TPtrC alias = TMmsGenUtils::Alias( addresses[i] );
+        HBufC* addressBuf = NULL;
+        
+        if ( alias.Length() != 0 )
+            {
+            stringToAdd.Set( alias );
+            }
+        else
+            {
+            TPtrC address = TMmsGenUtils::PureAddress( addresses[i] );
+            addressBuf = HBufC::NewLC( address.Length() );
+            TPtr addressPtr = addressBuf->Des();
+            addressPtr.Copy( address );
+            stringToAdd.Set( addressPtr );
+
+            // Internal data structures always holds the address data in western format.
+            // UI is responsible of doing language specific conversions.    
+            AknTextUtils::ConvertDigitsTo( addressPtr, EDigitTypeWestern );      
+            }
+        
+        if ( ( aDetails.Length() != 0 ) &&   // Not a first address
+             ( aDetails.Length() + KAddressSeparator().Length() < KMaxDetailsLength ) )
+            {
+            // Add separator
+            aDetails.Append( KAddressSeparator() );
+            }
+
+        if ( aDetails.Length() + stringToAdd.Length() < KMaxDetailsLength ) 
+            {
+            // whole string fits. Add it.
+            aDetails.Append( stringToAdd );
+            if ( addressBuf )
+                {
+                CleanupStack::PopAndDestroy( addressBuf );
+                }
+            }
+        else
+            {
+            // Only part of the string fits
+            TInt charsToAdd = KMaxDetailsLength - aDetails.Length();
+
+            if ( charsToAdd <= 0 )
+                {
+                // Cannot add any more chars 
+                break;
+                }
+
+            if ( charsToAdd >= stringToAdd.Length() )
+                {
+                // Guarantee that charsToAdd is not larger that stringToAdd lenght 
+                charsToAdd = stringToAdd.Length();
+                }
+
+            aDetails.Append( stringToAdd.Left( charsToAdd ) );
+            if ( addressBuf )
+                {
+                CleanupStack::PopAndDestroy( addressBuf );
+                }
+            break;
+            }
+        }
+    }
+
+// ----------------------------------------------------
+// CUniAddressHandler::ShowInvalidRecipientInfoNotesL
+// ----------------------------------------------------
+//
+EXPORT_C void CUniAddressHandler::ShowInvalidRecipientInfoNotesL()
+    {
+    if ( iInvalidRecipients )
+        {
+        for ( TInt current = 0; current < iInvalidRecipients->Count(); current++ )
+            {
+            ShowAddressInfoNoteL( *iInvalidRecipients->At( current )->Address(),
+                                  *iInvalidRecipients->At( current )->Name() );
+            }
+            
+        delete iInvalidRecipients;
+        iInvalidRecipients = NULL;
+        }
+    }
+
+// ---------------------------------------------------------
+// CUniAddressHandler::ShowAddressInfoNoteL
+// ---------------------------------------------------------
+//
+void CUniAddressHandler::ShowAddressInfoNoteL( const TDesC& aAddress, const TDesC& aAlias )
+    {
+    TInt cleanupCount = 0;
+    HBufC* string = NULL;
+
+    HBufC* convertedAddress = NumberConversionLC( aAddress, ETrue );
+    cleanupCount++;
+
+    if ( aAlias.Length() == 0 )
+        {
+        string = StringLoader::LoadLC( R_UNUT_INFO_FAIL_RECIPIENT_NO_ALIAS,
+                                       *convertedAddress,
+                                       &iCoeEnv );
+        cleanupCount++;
+        }
+    else
+        {
+        CDesCArrayFlat* stringArr = new ( ELeave ) CDesCArrayFlat( 2 );
+        CleanupStack::PushL( stringArr );
+        cleanupCount++;
+        
+        stringArr->AppendL( aAlias );    //First string
+        stringArr->AppendL( *convertedAddress );  //Second string
+        string = StringLoader::LoadLC( R_UNUT_INFO_FAIL_RECIPIENT,
+                                       *stringArr,
+                                       &iCoeEnv );
+        cleanupCount++;
+        }
+    
+    CAknInformationNote* note = new ( ELeave ) CAknInformationNote( ETrue );
+    note->ExecuteLD( *string );
+    
+    CleanupStack::PopAndDestroy( cleanupCount );  // string, (stringArr), convertedAddress
+    }
+
+// ---------------------------------------------------------
+// CUniAddressHandler::RemoveIllegalChars
+// ---------------------------------------------------------
+
+TBool CUniAddressHandler::RemoveIllegalChars( TDes& aString )
+    {
+    TBool ret( EFalse );
+    for ( TInt i = 0; i < aString.Length(); i++ )
+        {
+        if ( !IsValidChar( (TChar) aString[ i ] ) ) 
+            {
+            aString.Delete( i, 1 );
+            i--;
+            ret = ETrue;
+            }
+        }
+    return ret;
+    }
+
+// ---------------------------------------------------------
+// CUniAddressHandler::IsValidChar
+//
+// These characters are used by system on it's internal data structure
+// and cannot be because of that used on address or alias string
+// ---------------------------------------------------------
+//
+TBool CUniAddressHandler::IsValidChar( const TChar& aChar )
+    {
+    // Don't allow "<" (60), ">" (62)
+    return ( aChar != '<' && aChar != '>' );
+    }
+
+// ----------------------------------------------------
+// CUniAddressHandler::NumberConversionLC
+// ----------------------------------------------------
+//
+HBufC* CUniAddressHandler::NumberConversionLC( const TDesC& aOrigNumber, TBool aDirection )
+    {
+    HBufC* addressCopy = aOrigNumber.AllocLC();
+    TPtr tempTPtr = addressCopy->Des();
+    if ( aDirection )
+        {
+        AknTextUtils::DisplayTextLanguageSpecificNumberConversion( tempTPtr );
+        }
+    else
+        {
+        AknTextUtils::ConvertDigitsTo( tempTPtr, EDigitTypeWestern );
+        }
+
+    return addressCopy;
+    }
+
+// ----------------------------------------------------
+// CUniAddressHandler::NumberConversionLC
+// ----------------------------------------------------
+//
+void CUniAddressHandler::CleanupRecipientArray( TAny* aArray )
+    {
+    CMsgRecipientArray* recipientArray = static_cast<CMsgRecipientArray*>( aArray );
+    
+    recipientArray->ResetAndDestroy();
+    delete recipientArray;
+    }
+
+
+// ========== OTHER EXPORTED FUNCTIONS =====================
+
+//  End of File