messagingappbase/msgeditor/viewsrc/MsgAddressControl.cpp
changeset 0 72b543305e3a
child 28 fbb813aef148
equal deleted inserted replaced
-1:000000000000 0:72b543305e3a
       
     1 /*
       
     2 * Copyright (c) 2002-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:  MsgAddressControl implementation
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 
       
    20 // ========== INCLUDE FILES ================================
       
    21 
       
    22 #include <eikenv.h>                        // for CEikonEnv
       
    23 #include <eikappui.h>                      // for CEikAppUi
       
    24 #include <barsread.h>                      // for TResourceReader
       
    25 #include <eikedwin.h>                      // for TClipboardFunc
       
    26 #include <txtrich.h>                       // for CRichText
       
    27 #include <AknUtils.h>                      // for AknUtils
       
    28 #include <aknbutton.h>                     // for CAknButton
       
    29 #include <eiklabel.h>                      // for CEikLabel
       
    30 
       
    31 #include "MsgAddressControl.h"             // for CMsgAddressControl
       
    32 #include "MsgAddressControlEditor.h"       // for CMsgAddressControlEditor
       
    33 #include "MsgAddressControlEditorField.h"  // for CMsgAddressControlEditorField
       
    34 #include "MsgBaseControlObserver.h"        // for MMsgBaseControlObserver
       
    35 #include "MsgRecipientItem.h"              // for CMsgRecipientItem
       
    36 #include "MsgEditorPanic.h"                // for CMsgEditor panics
       
    37 #include "MsgEditorCommon.h"               // for KArabicSemicolon
       
    38 
       
    39 // ========== EXTERNAL DATA STRUCTURES =====================
       
    40 
       
    41 // ========== EXTERNAL FUNCTION PROTOTYPES =================
       
    42 
       
    43 // ========== CONSTANTS ====================================
       
    44 
       
    45 // ========== MACROS =======================================
       
    46 
       
    47 // ========== LOCAL CONSTANTS AND MACROS ===================
       
    48 
       
    49 const TInt KRecipientArrayGranularity = 10;
       
    50 const TInt KMaxEntryLength = 256;
       
    51 const TUint KMsgListSeparator = ';';             // List separator
       
    52 
       
    53 // Unicode sign for S60 "enter" symbol
       
    54 const TInt KDownwardsArrowWithTipLeftwards  = 0x21B2;
       
    55 const TInt KDownwardsArrowWithTipRightwards = 0x21B3;
       
    56 
       
    57 
       
    58 // ========== MODULE DATA STRUCTURES =======================
       
    59 
       
    60 // ========== LOCAL FUNCTION PROTOTYPES ====================
       
    61 
       
    62 // ========== LOCAL FUNCTIONS ==============================
       
    63 
       
    64 // ========== MEMBER FUNCTIONS =============================
       
    65 
       
    66 
       
    67 // ---------------------------------------------------------
       
    68 // CMsgAddressControl::CMsgAddressControl
       
    69 //
       
    70 // Constructor.
       
    71 // ---------------------------------------------------------
       
    72 //
       
    73 CMsgAddressControl::CMsgAddressControl( MMsgBaseControlObserver& aBaseControlObserver ) : 
       
    74     CMsgExpandableControl( aBaseControlObserver )
       
    75     {
       
    76     }
       
    77 
       
    78 // ---------------------------------------------------------
       
    79 // CMsgAddressControl::~CMsgAddressControl
       
    80 //
       
    81 // Destructor.
       
    82 // ---------------------------------------------------------
       
    83 //
       
    84 CMsgAddressControl::~CMsgAddressControl()
       
    85     {
       
    86     if ( iRecipientArray )
       
    87         {
       
    88         iRecipientArray->ResetAndDestroy();
       
    89         }
       
    90 
       
    91     delete iRecipientArray;
       
    92     }
       
    93 
       
    94 // ---------------------------------------------------------
       
    95 // CMsgAddressControl::AddRecipientL
       
    96 //
       
    97 //
       
    98 // ---------------------------------------------------------
       
    99 //
       
   100 EXPORT_C void CMsgAddressControl::AddRecipientL( const TDesC& aName,
       
   101                                                  const TDesC& aAddress,
       
   102                                                  TBool aVerified,
       
   103                                                  MVPbkContactLink* aContactLink )
       
   104     {
       
   105     TInt count   = 0;
       
   106     TInt size    = 0;
       
   107     TInt entries = iAddressControlEditor->EntryCount();
       
   108 
       
   109     GetSizeOfAddresses( count, size );
       
   110 
       
   111     // when field is empty, count == 0 but entries == 1.
       
   112     // when count > 0, this inserts at the end of the field.
       
   113     if ( entries > 1 )
       
   114         {
       
   115         count = entries;
       
   116         }
       
   117 
       
   118     iAddressControlEditor->SetCursorPosAndCancelSelectionL(
       
   119         iAddressControlEditor->TextLength() );
       
   120     iAddressControlEditor->CheckHighlightingL();
       
   121     iAddressControlEditor->InsertEntryL(
       
   122         count,
       
   123         aName,
       
   124         aAddress,
       
   125         aVerified,
       
   126         ETrue,
       
   127         aContactLink
       
   128          );
       
   129 
       
   130     FormatAndSetCursorPosL( iAddressControlEditor->TextLength() );
       
   131     DrawDeferred();
       
   132     iControlModeFlags |= EMsgControlModeModified;
       
   133     }
       
   134 
       
   135 // ---------------------------------------------------------
       
   136 // CMsgAddressControl::AddRecipientsL
       
   137 //
       
   138 //
       
   139 // ---------------------------------------------------------
       
   140 //
       
   141 EXPORT_C void CMsgAddressControl::AddRecipientsL(
       
   142     const CMsgRecipientList& aRecipients )
       
   143     {
       
   144     CMsgRecipientArray* recipients = GetRecipientsL();
       
   145     RefreshL( *recipients );
       
   146 
       
   147     TInt count = 0;
       
   148     TInt size = 0;
       
   149     TInt entries = iAddressControlEditor->EntryCount();
       
   150 
       
   151     GetSizeOfAddresses( count, size );
       
   152 
       
   153     // when field is empty, count == 0 but entries == 1.
       
   154     // when count > 0, this inserts at the end of the field.
       
   155     if ( entries > 1 )
       
   156         {
       
   157         count = entries;
       
   158         }
       
   159 
       
   160     TInt cc = aRecipients.Count();
       
   161     CMsgRecipientItem* item = NULL;
       
   162 
       
   163     iAddressControlEditor->SetCursorPosAndCancelSelectionL(
       
   164         iAddressControlEditor->TextLength() );
       
   165     iAddressControlEditor->CheckHighlightingL();
       
   166 
       
   167     TBool bandFormatting( EFalse );
       
   168     if ( iAddressControlEditor->TextLayout()->IsFormattingBand() )
       
   169         {
       
   170         bandFormatting = ETrue;
       
   171         }
       
   172         
       
   173     for ( TInt i = 0; i < cc; i++ )
       
   174         {
       
   175         item = aRecipients.At( i );
       
   176         iAddressControlEditor->InsertEntryL(
       
   177             count,
       
   178             *item->Name(),
       
   179             *item->Address(),
       
   180             item->IsVerified(),
       
   181             item->IsValidated(),
       
   182             item->ContactLink() );
       
   183         count++;
       
   184         }    
       
   185     
       
   186     TInt pos = iAddressControlEditor->TextLength();
       
   187 
       
   188     iAddressControlEditor->TextView()->SetDocPosL( pos, EFalse );
       
   189     
       
   190     FormatAndSetCursorPosL( pos );
       
   191     
       
   192     // Editor changed to band formatting due to address addition.
       
   193     // Set the editor height to maximum as text was added directly to
       
   194     // richtext and height is not updated correctly because of partial format.
       
   195     if ( !bandFormatting &&
       
   196          iAddressControlEditor->TextLayout()->IsFormattingBand() )
       
   197         {
       
   198         // Set newSize to current width and maximum body height and
       
   199         // force CMsgExpandableControl::HandleEdwinSizeChangeEventL to
       
   200         // update the control size.
       
   201         iControlModeFlags |= EMsgControlModeForceSizeUpdate;
       
   202             
       
   203         TSize newSize( iAddressControlEditor->Size().iWidth,
       
   204                        iMaxBodyHeight - 1 );
       
   205         
       
   206         iAddressControlEditor->SetSize( newSize );
       
   207         
       
   208         iControlModeFlags &= ~EMsgControlModeForceSizeUpdate;
       
   209         }
       
   210         
       
   211     DrawDeferred();
       
   212     iControlModeFlags |= EMsgControlModeModified;
       
   213     }
       
   214 
       
   215 
       
   216 // ---------------------------------------------------------
       
   217 // CMsgAddressControl::GetRecipientsL
       
   218 //
       
   219 //
       
   220 // ---------------------------------------------------------
       
   221 //
       
   222 EXPORT_C CMsgRecipientArray* CMsgAddressControl::GetRecipientsL()
       
   223     {
       
   224     TInt entryNumber( iAddressControlEditor->EntryCount() );
       
   225     const CMsgAddressControlEditorField* field = NULL;
       
   226     TBuf<KMaxEntryLength> entryBuf;
       
   227     TInt ret( KErrNotFound );
       
   228 
       
   229     if ( iRecipientArray == NULL )
       
   230         {
       
   231         iRecipientArray = new ( ELeave )
       
   232             CMsgRecipientArray( KRecipientArrayGranularity );
       
   233         }
       
   234     else
       
   235         {
       
   236         iRecipientArray->ResetAndDestroy();
       
   237         }
       
   238 
       
   239     for ( TInt ii = 0; ii < entryNumber; ii++ )
       
   240         {
       
   241         field = iAddressControlEditor->Field( ii );
       
   242 
       
   243         if ( field && field->IsVerified() )
       
   244             {
       
   245             HBufC* addressCopy = field->Address()->AllocLC();
       
   246             TPtr addrTPtr = addressCopy->Des();
       
   247             AknTextUtils::ConvertDigitsTo( addrTPtr, EDigitTypeWestern );
       
   248             
       
   249             CMsgRecipientItem* item =
       
   250                 CMsgRecipientItem::NewLC( *field->Name(), *addressCopy );
       
   251 
       
   252             const MVPbkContactLink* contactLink = field->ContactLink();
       
   253             if ( contactLink )                  
       
   254                 {
       
   255                 item->SetContactLink( contactLink );
       
   256                 }
       
   257                 
       
   258             item->SetVerified( field->IsVerified() );
       
   259             item->SetValidated( field->IsValidated() );
       
   260             iRecipientArray->AppendL( item );
       
   261 
       
   262             CleanupStack::Pop(); // item
       
   263             CleanupStack::PopAndDestroy(); // addressCopy
       
   264             }
       
   265         else
       
   266             {
       
   267             SetParsingInfo( ii, 0, 0 );
       
   268             ret = KErrNone;
       
   269             while ( ret == KErrNone )
       
   270                 {
       
   271                 ret = GetNextItemOnEntry( entryBuf );
       
   272                 if ( ( ret == KErrNone ) && ( entryBuf.Length() > 0 ) )
       
   273                     {
       
   274                     AknTextUtils::ConvertDigitsTo( entryBuf, EDigitTypeWestern );
       
   275                     // unverified entries are treated as addresses.
       
   276                     CMsgRecipientItem* item =
       
   277                         CMsgRecipientItem::NewLC( KNullDesC, entryBuf );
       
   278 
       
   279                     iRecipientArray->AppendL( item );
       
   280 
       
   281                     CleanupStack::Pop(); // item
       
   282                     entryBuf.Zero();
       
   283                     }
       
   284                 }
       
   285             }
       
   286         }
       
   287 
       
   288     ResetParsingInfo();
       
   289     return iRecipientArray;
       
   290     }
       
   291 
       
   292 // ---------------------------------------------------------
       
   293 // CMsgAddressControl::ResetL
       
   294 //
       
   295 // Clears content of the address control.
       
   296 // ---------------------------------------------------------
       
   297 //
       
   298 EXPORT_C TInt CMsgAddressControl::ResetL()
       
   299     {
       
   300     ResetParsingInfo();
       
   301     TInt entryCount( iAddressControlEditor->EntryCount() );
       
   302 
       
   303     iAddressControlEditor->TurnHighlightingOffL();
       
   304     iAddressControlEditor->DeleteAllL();
       
   305     iControlModeFlags |= EMsgControlModeModified;
       
   306 
       
   307     return entryCount;
       
   308     }
       
   309 
       
   310 // ---------------------------------------------------------
       
   311 // CMsgAddressControl::Reset
       
   312 //
       
   313 // from CMsgBaseControl.
       
   314 // Same as above but non-leaving version.
       
   315 // ---------------------------------------------------------
       
   316 //
       
   317 EXPORT_C void CMsgAddressControl::Reset()
       
   318     {
       
   319     TRAP_IGNORE( ResetL() );
       
   320     }
       
   321 
       
   322 // ---------------------------------------------------------
       
   323 // CMsgAddressControl::GetFirstUnverifiedStringL
       
   324 //
       
   325 // Finds the first unverified string and updates also the iParserInfo
       
   326 // correspondingly.
       
   327 // ---------------------------------------------------------
       
   328 //
       
   329 EXPORT_C TInt CMsgAddressControl::GetFirstUnverifiedStringL( HBufC*& aString )
       
   330     {
       
   331     __ASSERT_DEBUG( IsFocused(), Panic( EMsgControlNotFocused ) );
       
   332 
       
   333     ResetParsingInfo();
       
   334     return GetNextUnverifiedStringL( aString );
       
   335     }
       
   336 
       
   337 // ---------------------------------------------------------
       
   338 // CMsgAddressControl::GetNextUnverifiedStringL
       
   339 //
       
   340 // Finds the next unverified string.
       
   341 // ---------------------------------------------------------
       
   342 //
       
   343 EXPORT_C TInt CMsgAddressControl::GetNextUnverifiedStringL( HBufC*& aString )
       
   344     {
       
   345     __ASSERT_DEBUG( IsFocused(), Panic( EMsgControlNotFocused ) );
       
   346 
       
   347     if ( aString != NULL )
       
   348         {
       
   349         delete aString;
       
   350         aString = NULL;
       
   351         }
       
   352 
       
   353     iAddressControlEditor->TurnHighlightingOffL();
       
   354 
       
   355     TInt entryCount = iAddressControlEditor->EntryCount();
       
   356     TInt entryNumber( iParsingInfo.iEntryNum );
       
   357     TBuf<KMaxEntryLength> entryBuf;
       
   358     TInt ret( KErrNotFound );
       
   359     HBufC* string = NULL;
       
   360 
       
   361     while ( entryNumber < entryCount )
       
   362         {
       
   363         entryBuf.Zero();
       
   364         if ( iAddressControlEditor->IsEntryVerified( entryNumber ) )
       
   365             {
       
   366             entryNumber++;
       
   367             SetParsingInfo( entryNumber, 0, 0 );
       
   368             }
       
   369         else
       
   370             {
       
   371             ret = GetNextItemOnEntry( entryBuf );
       
   372             if ( ( ret == KErrNone ) && ( entryBuf.Length() > 0 ) )
       
   373                 {
       
   374                 string = entryBuf.AllocLC();
       
   375                 TInt firstPos = iAddressControlEditor->EntryStartPos(
       
   376                     iParsingInfo.iEntryNum );
       
   377                 FormatAndSetCursorPosL( firstPos + iParsingInfo.iEndPos );
       
   378                 break;
       
   379                 }
       
   380             else if ( iParsingInfo.iEndPos > iParsingInfo.iStartPos )
       
   381                 {
       
   382                 // a string could not be found but there seems to be white
       
   383                 // spaces on an entry which may be also followed by the list
       
   384                 // separator, hence clean them up
       
   385                 iAddressControlEditor->DeleteEntryCharsL(
       
   386                     iParsingInfo.iEntryNum,
       
   387                     iParsingInfo.iStartPos,
       
   388                     iParsingInfo.iEndPos );
       
   389 
       
   390                 SetParsingInfo(
       
   391                     entryNumber,
       
   392                     iParsingInfo.iStartPos,
       
   393                     iParsingInfo.iStartPos );
       
   394                 }
       
   395             else if ( ( iParsingInfo.iEndPos == 0 ) &&
       
   396                      ( iParsingInfo.iEntryNum < entryCount - 1 ) )
       
   397                 {
       
   398                 // there is just an EParagraphDelimiter on the entry
       
   399                 iAddressControlEditor->DeleteEntryL( iParsingInfo.iEntryNum );
       
   400                 SetParsingInfo( entryNumber, 0, 0 );
       
   401                 entryCount--;
       
   402                 }
       
   403             else
       
   404                 {
       
   405                 // there are no strings left on the current entry
       
   406                 entryNumber++;
       
   407                 SetParsingInfo( entryNumber, 0, 0 );
       
   408                 }
       
   409             }
       
   410         }
       
   411 
       
   412     if ( entryNumber >= entryCount )
       
   413         {
       
   414         FormatAndSetCursorPosL( iAddressControlEditor->TextLength() );
       
   415         }
       
   416 
       
   417     aString = string;
       
   418 
       
   419     if ( string )
       
   420         {
       
   421         CleanupStack::Pop();  // string
       
   422         }
       
   423 
       
   424     return ret;
       
   425     }
       
   426 
       
   427 
       
   428 // ---------------------------------------------------------
       
   429 // CMsgAddressControl::ReplaceUnverifiedStringL
       
   430 //
       
   431 // Replaces a string with contents of the recipient array aArray. 
       
   432 // The string is replaced according to the iParsingInfo.
       
   433 //
       
   434 // This function cannot undelete a string if it leaves after/while removing it.
       
   435 // ---------------------------------------------------------
       
   436 //
       
   437 EXPORT_C TInt CMsgAddressControl::ReplaceUnverifiedStringL(
       
   438     CMsgRecipientArray& aArray )
       
   439     {
       
   440     __ASSERT_DEBUG( IsFocused(), Panic( EMsgControlNotFocused ) );
       
   441 
       
   442     if ( ( iParsingInfo.iEndPos <= iParsingInfo.iStartPos ) || 
       
   443         ( iParsingInfo.iEntryNum >= iAddressControlEditor->EntryCount() ) )
       
   444         {
       
   445         return KErrNotFound;
       
   446         }
       
   447 
       
   448     iAddressControlEditor->TurnHighlightingOffL();
       
   449 
       
   450     TInt entryLength = iAddressControlEditor->EntryLength( iParsingInfo.iEntryNum );
       
   451     iAddressControlEditor->DeleteEntryCharsL(
       
   452         iParsingInfo.iEntryNum,
       
   453         iParsingInfo.iStartPos,
       
   454         iParsingInfo.iEndPos );
       
   455    
       
   456     if ( ( iParsingInfo.iStartPos > 0 ) && ( iParsingInfo.iEndPos < entryLength ) )
       
   457         {
       
   458         iAddressControlEditor->InsertEntryBreakL(
       
   459             iParsingInfo.iEntryNum,
       
   460             iParsingInfo.iStartPos );
       
   461         iParsingInfo.iEntryNum++;
       
   462         }
       
   463 
       
   464     TInt entryNumber( iParsingInfo.iEntryNum );
       
   465     TInt contactCount = aArray.Count();
       
   466     CMsgRecipientItem* recipientItem = NULL;
       
   467 
       
   468     for ( TInt i = 0; i < contactCount; i++ )
       
   469         {
       
   470         recipientItem = aArray.At( i );
       
   471         iAddressControlEditor->InsertEntryL(
       
   472             entryNumber,
       
   473             *recipientItem->Name(),
       
   474             *recipientItem->Address(),
       
   475             recipientItem->IsVerified(),
       
   476             recipientItem->IsValidated(),
       
   477             recipientItem->ContactLink() );
       
   478             
       
   479         entryNumber++;
       
   480         }
       
   481 
       
   482     SetParsingInfo( iParsingInfo.iEntryNum, 0, 0 );
       
   483     TInt firstPos = iAddressControlEditor->EntryStartPos( iParsingInfo.iEntryNum );
       
   484     entryLength = iAddressControlEditor->EntryLength( iParsingInfo.iEntryNum );
       
   485     TInt endPos = firstPos + entryLength - 1;
       
   486     SetParsingInfo( iParsingInfo.iEntryNum, endPos, endPos );
       
   487     FormatAndSetCursorPosL( endPos );
       
   488     iControlModeFlags |= EMsgControlModeModified;
       
   489     return KErrNone;
       
   490     }
       
   491 
       
   492 // ---------------------------------------------------------
       
   493 // CMsgAddressControl::RefreshL
       
   494 //
       
   495 // Refreshes the contents of address control.
       
   496 // ---------------------------------------------------------
       
   497 //
       
   498 EXPORT_C TInt CMsgAddressControl::RefreshL( const CMsgRecipientArray& aArray )
       
   499     {
       
   500     iEditor->SetEdwinSizeObserver( NULL );
       
   501     
       
   502     TRAPD( error, ResetL() );  // Clears the control and turns highlighting off
       
   503     
       
   504     iEditor->SetEdwinSizeObserver( this );
       
   505     
       
   506     if ( error != KErrNone )
       
   507         {
       
   508         User::Leave( error );
       
   509         }
       
   510 
       
   511     TInt entryNumber = 0;
       
   512     TInt contactCount = aArray.Count();
       
   513     CMsgRecipientItem* item = NULL;
       
   514 
       
   515     for ( TInt i = 0; i < contactCount; i++ )
       
   516         {
       
   517         item = aArray.At( i );
       
   518         iAddressControlEditor->InsertEntryL(
       
   519             entryNumber,
       
   520             *item->Name(),
       
   521             *item->Address(),
       
   522             item->IsVerified(),
       
   523             item->IsValidated(),
       
   524             item->ContactLink() );
       
   525         entryNumber++;
       
   526         }
       
   527 
       
   528     ResetParsingInfo();
       
   529     FormatAndSetCursorPosL( iAddressControlEditor->TextLength() );
       
   530     iControlModeFlags |= EMsgControlModeModified;
       
   531 
       
   532     return KErrNone;
       
   533     }
       
   534 
       
   535 // ---------------------------------------------------------
       
   536 // CMsgAddressControl::HighlightUnverifiedStringL
       
   537 //
       
   538 // Highlights the found unverified entry.
       
   539 // ---------------------------------------------------------
       
   540 //
       
   541 EXPORT_C TInt CMsgAddressControl::HighlightUnverifiedStringL()
       
   542     {
       
   543     __ASSERT_DEBUG( IsFocused(), Panic( EMsgControlNotFocused ) );
       
   544 
       
   545     TInt ret = iParsingInfo.iEndPos - iParsingInfo.iStartPos > 0
       
   546         ? KErrNone
       
   547         : KErrNotFound;
       
   548 
       
   549     if ( IsActivated() && ( ret == KErrNone ) && IsFocused() )
       
   550         {
       
   551         TInt entryLength( 0 );  // not really needed
       
   552         TInt entryStart( iAddressControlEditor->RichText()->CharPosOfParagraph(
       
   553             entryLength, iParsingInfo.iEntryNum ) );
       
   554         FormatAndSetCursorPosL( entryStart + iParsingInfo.iEndPos );
       
   555         iAddressControlEditor->SetSelectionL(
       
   556             entryStart + iParsingInfo.iEndPos,
       
   557             entryStart + iParsingInfo.iStartPos );
       
   558         }
       
   559 
       
   560     return ret;
       
   561     }
       
   562 
       
   563 // ---------------------------------------------------------
       
   564 // CMsgAddressControl::SizeOfAddresses
       
   565 //
       
   566 // Returns size of addresses.
       
   567 // ---------------------------------------------------------
       
   568 //
       
   569 EXPORT_C void CMsgAddressControl::GetSizeOfAddresses(
       
   570     TInt& aEntryCount, TInt& aSizeOfAddresses )
       
   571     {
       
   572     const CMsgAddressControlEditorField* field = NULL;
       
   573     TBuf<KMaxEntryLength> entryBuf;
       
   574     TInt ret( KErrNotFound );
       
   575 
       
   576     aEntryCount = 0;
       
   577     aSizeOfAddresses = 0;
       
   578 
       
   579     for ( TInt entryNumber = iAddressControlEditor->EntryCount() - 1;
       
   580          entryNumber >= 0;
       
   581          entryNumber-- )
       
   582         {
       
   583         if ( iAddressControlEditor->IsEntryVerified( entryNumber ) )
       
   584             {
       
   585             field = iAddressControlEditor->Field( entryNumber );
       
   586 
       
   587             aSizeOfAddresses += field->Address()->Length();
       
   588             aEntryCount++;
       
   589             }
       
   590         else
       
   591             {
       
   592             SetParsingInfo( entryNumber, 0, 0 );
       
   593             ret = KErrNone;
       
   594             while ( ret == KErrNone )
       
   595                 {
       
   596                 ret = GetNextItemOnEntry( entryBuf );
       
   597                 if ( ( ret == KErrNone ) && ( entryBuf.Length() > 0 ) )
       
   598                     {
       
   599                     aSizeOfAddresses += entryBuf.Length();
       
   600                     aEntryCount++;
       
   601                     entryBuf.Zero();
       
   602                     }
       
   603                 }
       
   604             }
       
   605         }
       
   606 
       
   607     ResetParsingInfo();
       
   608     }
       
   609 
       
   610 // ---------------------------------------------------------
       
   611 // CMsgAddressControl::HighlightUnvalidatedStringL
       
   612 //
       
   613 // Highlights the found unvvalidated entry.
       
   614 // ---------------------------------------------------------
       
   615 //
       
   616 EXPORT_C TInt CMsgAddressControl::HighlightUnvalidatedStringL()
       
   617     {
       
   618     ResetParsingInfo();
       
   619 
       
   620     iAddressControlEditor->TurnHighlightingOffL();
       
   621 
       
   622     TInt entryCount = iAddressControlEditor->EntryCount();
       
   623     TInt entryNumber( iParsingInfo.iEntryNum );
       
   624     TBuf<KMaxEntryLength> entryBuf;
       
   625     TInt ret( KErrNotFound );
       
   626 
       
   627     while ( entryNumber < entryCount )
       
   628         {
       
   629         entryBuf.Zero();
       
   630         if ( iAddressControlEditor->IsEntryValidated( entryNumber ) )
       
   631             {
       
   632             entryNumber++;
       
   633             SetParsingInfo( entryNumber, 0, 0 );
       
   634             }
       
   635         else
       
   636             {
       
   637             ret = GetNextItemOnEntry( entryBuf );
       
   638             if ( ( ret == KErrNone ) && ( entryBuf.Length() > 0 ) )
       
   639                 {
       
   640                 TInt firstPos = iAddressControlEditor->EntryStartPos(
       
   641                     iParsingInfo.iEntryNum );
       
   642                 FormatAndSetCursorPosL( firstPos + iParsingInfo.iEndPos );
       
   643                 break;
       
   644                 }
       
   645             else if ( iParsingInfo.iEndPos > iParsingInfo.iStartPos )
       
   646                 {
       
   647                 // a string could not be found but there seems to be white
       
   648                 // spaces on an entry which may be also followed by the list
       
   649                 // separator, hence clean them up
       
   650                 iAddressControlEditor->DeleteEntryCharsL(
       
   651                     iParsingInfo.iEntryNum,
       
   652                     iParsingInfo.iStartPos,
       
   653                     iParsingInfo.iEndPos );
       
   654 
       
   655                 SetParsingInfo(
       
   656                     entryNumber,
       
   657                     iParsingInfo.iStartPos,
       
   658                     iParsingInfo.iStartPos );
       
   659                 }
       
   660             else if ( ( iParsingInfo.iEndPos == 0 ) &&
       
   661                 ( iParsingInfo.iEntryNum < entryCount - 1 ) )
       
   662                 {
       
   663                 // there is just an EParagraphDelimiter on the entry
       
   664                 iAddressControlEditor->DeleteEntryL( iParsingInfo.iEntryNum );
       
   665                 SetParsingInfo( entryNumber, 0, 0 );
       
   666                 entryCount--;
       
   667                 }
       
   668             else
       
   669                 {
       
   670                 // there are no strings left on the current entry
       
   671                 entryNumber++;
       
   672                 SetParsingInfo( entryNumber, 0, 0 );
       
   673                 }
       
   674             }
       
   675         }
       
   676 
       
   677     if ( entryNumber >= entryCount )
       
   678         {
       
   679         FormatAndSetCursorPosL( iAddressControlEditor->TextLength() );
       
   680         }
       
   681 
       
   682     ret = iParsingInfo.iEndPos - iParsingInfo.iStartPos > 0
       
   683         ? KErrNone
       
   684         : KErrNotFound;
       
   685 
       
   686     if ( IsActivated() && ( ret == KErrNone ) && IsFocused() )
       
   687         {
       
   688         TInt entryLength( 0 );  // not really needed
       
   689         TInt entryStart( iAddressControlEditor->RichText()->CharPosOfParagraph(
       
   690             entryLength, iParsingInfo.iEntryNum ) );
       
   691         FormatAndSetCursorPosL( entryStart + iParsingInfo.iEndPos );
       
   692         iAddressControlEditor->SetSelectionL(
       
   693             entryStart + iParsingInfo.iEndPos,
       
   694             entryStart + iParsingInfo.iStartPos );
       
   695         }
       
   696     return ret;
       
   697     }
       
   698 
       
   699 // ---------------------------------------------------------
       
   700 // CMsgAddressControl::IsPriorCharSemicolonL()
       
   701 //
       
   702 // Checks whether prior character is semicolon. Needed to variable
       
   703 // selection key functionality in editors.
       
   704 // ---------------------------------------------------------
       
   705 //
       
   706 EXPORT_C TBool CMsgAddressControl::IsPriorCharSemicolonL() const
       
   707     {
       
   708     TInt cursorPos = Editor().CursorPos();
       
   709     HBufC* buf = Editor().GetTextInHBufL();
       
   710     CleanupStack::PushL( buf );
       
   711 
       
   712     TBool semicolonFound = EFalse;
       
   713     TUint character;
       
   714     while ( cursorPos > 1 && !semicolonFound )
       
   715         {
       
   716         cursorPos--;
       
   717         character = TUint( (*buf)[cursorPos] );
       
   718 
       
   719         if ( character == KMsgListSeparator || character == KArabicSemicolon )
       
   720             {
       
   721             semicolonFound = ETrue;
       
   722             }
       
   723         else if ( character != CEditableText::ESpace &&
       
   724             character != CEditableText::EParagraphDelimiter )
       
   725             {
       
   726             break;
       
   727             }
       
   728         }
       
   729     
       
   730     CleanupStack::PopAndDestroy(); // buf
       
   731     return semicolonFound;
       
   732     }
       
   733 
       
   734 // ---------------------------------------------------------
       
   735 // CMsgAddressControl::SetAddressFieldAutoHighlight()
       
   736 //
       
   737 // Turns on or off automatic recipient highlight on this address
       
   738 // field. Focus must stop to this control if highlight is enabled.
       
   739 // Updates also the highlight accordingly.
       
   740 // ---------------------------------------------------------
       
   741 //
       
   742 EXPORT_C void CMsgAddressControl::SetAddressFieldAutoHighlight( TBool aValidHighlightable )
       
   743     {
       
   744     iAddressControlEditor->SetAddressFieldAutoHighlight( aValidHighlightable );    
       
   745     TRAP_IGNORE( iAddressControlEditor->CheckHighlightingL() );
       
   746     DrawDeferred();
       
   747     }
       
   748 
       
   749 // ---------------------------------------------------------
       
   750 // CMsgAddressControl::AddressFieldAutoHighlight()
       
   751 //
       
   752 // ---------------------------------------------------------
       
   753 //
       
   754 EXPORT_C TBool CMsgAddressControl::AddressFieldAutoHighlight()
       
   755     {
       
   756     return iAddressControlEditor->AddressFieldAutoHighlight();
       
   757     }
       
   758 
       
   759 // ---------------------------------------------------------
       
   760 // CMsgAddressControl::ConstructFromResourceL
       
   761 //
       
   762 // Creates this control from resource.
       
   763 // ---------------------------------------------------------
       
   764 //
       
   765 void CMsgAddressControl::ConstructFromResourceL( TInt aResourceId )
       
   766     {
       
   767     BaseConstructL();  // Sets margins only.
       
   768 
       
   769     TResourceReader reader;
       
   770     iCoeEnv->CreateResourceReaderLC( reader, aResourceId );
       
   771 
       
   772     // Create caption.
       
   773     iCaption = CreateCaptionFromResourceL( reader );
       
   774     
       
   775     // Read some information about control from resource.
       
   776     ReadControlPropertiesFromResourceL( reader );
       
   777 
       
   778     // Create editor.
       
   779     iEditor = CreateEditorFromResourceL( reader );
       
   780     
       
   781     iEditor->SetControlType(EMsgAddressControl);
       
   782     iEditor->SetObserver( this );
       
   783     iEditor->SetEdwinSizeObserver( this );
       
   784     iEditor->AddEdwinObserverL( this );
       
   785     
       
   786     SetPlainTextMode( ETrue );
       
   787 
       
   788 #ifdef RD_SCALABLE_UI_V2
       
   789     if ( AknLayoutUtils::PenEnabled() )
       
   790         {
       
   791         CreateButtonL();
       
   792         }
       
   793 #endif // RD_SCALABLE_UI_V2
       
   794 
       
   795     ResolveLayoutsL();
       
   796     
       
   797     iControlModeFlags |= EMsgControlModeForceFocusStop;
       
   798     
       
   799     CleanupStack::PopAndDestroy();  // reader
       
   800     }
       
   801 
       
   802 // ---------------------------------------------------------
       
   803 // CMsgAddressControl::NotifyViewEvent
       
   804 //
       
   805 // Builds up text fields for the control i.e. reads verified recipients and
       
   806 // creates corresponding text fields for them.
       
   807 // ---------------------------------------------------------
       
   808 //
       
   809 void CMsgAddressControl::NotifyViewEvent( TMsgViewEvent aEvent, TInt aParam )
       
   810     {
       
   811     if ( iAddressControlEditor->AddressFieldAutoHighlight() )
       
   812         {
       
   813         aParam |= EMsgViewEventAutoHighlight;
       
   814         }
       
   815 
       
   816     CMsgExpandableControl::NotifyViewEvent( aEvent, aParam );
       
   817 
       
   818     if ( aEvent == EMsgViewEventPrepareForViewing )
       
   819         {
       
   820         if ( iAddressControlEditor->TextLength() && IsFocused() )
       
   821             {
       
   822             iAddressControlEditor->PrepareForViewing();
       
   823             
       
   824             // TODO: Implement better error handling?
       
   825             TRAP_IGNORE( iAddressControlEditor->CheckHighlightingL() );
       
   826             }
       
   827         }
       
   828     }
       
   829 
       
   830 // ---------------------------------------------------------
       
   831 // ReadControlPropertiesFromResourceL
       
   832 //
       
   833 // Reads control properties from resource.
       
   834 // ---------------------------------------------------------
       
   835 //
       
   836 void CMsgAddressControl::ReadControlPropertiesFromResourceL(
       
   837     TResourceReader& aReader )
       
   838     {
       
   839     CMsgExpandableControl::ReadControlPropertiesFromResourceL( aReader );
       
   840     }
       
   841 
       
   842 // ---------------------------------------------------------
       
   843 // CMsgAddressControl::CreateEditorFromResourceL
       
   844 //
       
   845 // Creates editor (CEikRichTextEditor) for the control from resource and
       
   846 // returns pointer to it.
       
   847 // ---------------------------------------------------------
       
   848 //
       
   849 CMsgExpandableControlEditor* CMsgAddressControl::CreateEditorFromResourceL(
       
   850     TResourceReader& aReader )
       
   851     {
       
   852     // Create an editor.
       
   853     CMsgExpandableControlEditor* editor =
       
   854         new ( ELeave ) CMsgAddressControlEditor(
       
   855             this, iControlModeFlags, iBaseControlObserver );
       
   856 
       
   857     CleanupStack::PushL( editor );
       
   858     editor->ConstructFromResourceL( aReader );
       
   859     CleanupStack::Pop();  // editor
       
   860 
       
   861     return editor;
       
   862     }
       
   863 
       
   864 // ---------------------------------------------------------
       
   865 // CMsgAddressControl::EditPermission
       
   866 //
       
   867 // Checks and returns control's edit permissions. Edit permissions are needed
       
   868 // to check in order to know whether some key press is allowed to pass
       
   869 // to the control or not.
       
   870 // ---------------------------------------------------------
       
   871 //
       
   872 TUint32 CMsgAddressControl::EditPermission() const
       
   873     {
       
   874     return iAddressControlEditor->CheckEditPermission();
       
   875     }
       
   876 
       
   877 
       
   878 // ---------------------------------------------------------
       
   879 // CMsgAddressControl::OfferKeyEventL
       
   880 //
       
   881 // Handles key events. The most of the keys are passed to the control editor.
       
   882 // ---------------------------------------------------------
       
   883 //
       
   884 TKeyResponse CMsgAddressControl::OfferKeyEventL(
       
   885     const TKeyEvent& aKeyEvent, TEventCode aType )
       
   886     {
       
   887     // reset "trap" for extraneous multi-tap TextUpdate edwin events as we are
       
   888     // now working on another input
       
   889     iDuplicateEvent = EFalse;
       
   890     
       
   891     TKeyResponse keyResp = EKeyWasNotConsumed;
       
   892     ResetParsingInfo();
       
   893     TInt  cursorPos = iAddressControlEditor->CursorPos();
       
   894 
       
   895     if ( aKeyEvent.iModifiers & EModifierShift )
       
   896         {
       
   897         iControlModeFlags |= EMsgControlModeShiftPressed;
       
   898         }
       
   899     else
       
   900         {
       
   901         iControlModeFlags &= ~EMsgControlModeShiftPressed;
       
   902         }
       
   903 
       
   904     switch ( aKeyEvent.iCode )
       
   905         {
       
   906         case EKeyHome:
       
   907         case EKeyEnd:
       
   908         case EKeyPageUp:
       
   909         case EKeyPageDown:
       
   910             {
       
   911             break;
       
   912             }
       
   913         case EKeyUpArrow:
       
   914         case EKeyDownArrow:
       
   915             {
       
   916             /*TInt fldpos = iAddressControlEditor->FirstFieldPos( cursorPos );
       
   917             TInt entryNumber = iAddressControlEditor->EntryNumber( cursorPos );
       
   918 
       
   919             if ( cursorPos != fldpos )
       
   920                 {
       
   921                     iAddressControlEditor->MoveCursorToEntryPosL( entryNumber, 0 );
       
   922                 }*/
       
   923             break;
       
   924             }
       
   925         case EKeyLeftArrow:
       
   926             {
       
   927             if ( iAddressControlEditor->IsPosAtEntryBeginning( cursorPos ) )
       
   928                 {
       
   929                 TInt entryNumber = iAddressControlEditor->EntryNumber( cursorPos );
       
   930                 if ( iAddressControlEditor->IsEntryVerified( entryNumber ) )
       
   931                     {
       
   932                     if ( iAddressControlEditor->IsEntryRightToLeft( entryNumber ) )
       
   933                         {
       
   934                         iAddressControlEditor->MoveCursorToEntryPosL(
       
   935                             entryNumber,
       
   936                             iAddressControlEditor->EntryLength( entryNumber ) );
       
   937                         iAddressControlEditor->CheckHighlightingL();
       
   938                         return EKeyWasConsumed;
       
   939                         }
       
   940                     }
       
   941                 }
       
   942                 
       
   943             if ( !iAddressControlEditor->IsPosAtEntryBeginning( cursorPos ) )
       
   944                 {
       
   945                 TInt entryNumber = iAddressControlEditor->EntryNumber( cursorPos );
       
   946                 if (iAddressControlEditor->IsEntryVerified( entryNumber ) )
       
   947                     {
       
   948                     if ( !iAddressControlEditor->IsEntryRightToLeft( entryNumber ) )
       
   949                         {
       
   950                         iAddressControlEditor->MoveCursorToEntryPosL( entryNumber, 0 );
       
   951                         iAddressControlEditor->CheckHighlightingL();
       
   952                         return EKeyWasConsumed;
       
   953                         }
       
   954                     }
       
   955                 }
       
   956                 
       
   957             break;
       
   958             }
       
   959         case EKeyRightArrow:
       
   960             {
       
   961             if ( iAddressControlEditor->IsPosAtEntryBeginning( cursorPos ) )
       
   962                 {
       
   963                 TInt entryNumber = iAddressControlEditor->EntryNumber( cursorPos );
       
   964                 if (iAddressControlEditor->IsEntryVerified( entryNumber ) )
       
   965                     {
       
   966                     if( !iAddressControlEditor->IsEntryRightToLeft( entryNumber ) )
       
   967                         {
       
   968                         iAddressControlEditor->MoveCursorToEntryPosL(
       
   969                             entryNumber,
       
   970                             iAddressControlEditor->EntryLength( entryNumber ) );
       
   971                         iAddressControlEditor->CheckHighlightingL();
       
   972                         return EKeyWasConsumed;
       
   973                         }
       
   974                     }
       
   975                 }
       
   976             if ( !iAddressControlEditor->IsPosAtEntryBeginning( cursorPos ) )
       
   977                 {
       
   978                 TInt entryNumber = iAddressControlEditor->EntryNumber( cursorPos );
       
   979                 if (iAddressControlEditor->IsEntryVerified( entryNumber ) )
       
   980                     {
       
   981                     if( iAddressControlEditor->IsEntryRightToLeft( entryNumber ) )
       
   982                         {
       
   983                         iAddressControlEditor->MoveCursorToEntryPosL( entryNumber, 0 );
       
   984                         iAddressControlEditor->CheckHighlightingL();
       
   985                         return EKeyWasConsumed;
       
   986                         }
       
   987                     }
       
   988                 }
       
   989             break;
       
   990             }
       
   991         case EKeyTab:
       
   992         case EKeyInsert:
       
   993             {
       
   994             return EKeyWasConsumed;
       
   995             }
       
   996         case EKeyEnter:
       
   997             {
       
   998             TUint32 editPermission = iAddressControlEditor->CheckEditPermission();
       
   999             if ( !( editPermission & EMsgEditParagraphDelimiter ) ||
       
  1000                 ( aKeyEvent.iModifiers & EModifierShift ) )
       
  1001                 {
       
  1002                 return EKeyWasConsumed;
       
  1003                 }
       
  1004                 
       
  1005             iAddressControlEditor->TurnHighlightingOffL( iAddressControlEditor->Selection() );
       
  1006                 
       
  1007             break;
       
  1008             }
       
  1009         case EKeyDelete:
       
  1010             {
       
  1011             TUint32 editPermission = iAddressControlEditor->CheckEditPermission();
       
  1012             if ( editPermission & EMsgEditRemoveEntry &&
       
  1013                  iAddressControlEditor->IsPosAtEntryBeginning( cursorPos ) )
       
  1014                 {
       
  1015                 RemoveHighlightedEntryL();
       
  1016                 return EKeyWasConsumed;
       
  1017                 }
       
  1018             else if ( !( editPermission & EMsgEditDelete ) )
       
  1019                 {
       
  1020                 return EKeyWasConsumed;
       
  1021                 }
       
  1022                 
       
  1023             iAddressControlEditor->TurnHighlightingOffL( iAddressControlEditor->Selection() );
       
  1024             break;
       
  1025             }
       
  1026         case EKeyBackspace:
       
  1027             {
       
  1028             TUint32 editPermission = iAddressControlEditor->CheckEditPermission();
       
  1029             
       
  1030             if ( editPermission & EMsgEditRemoveEntry )
       
  1031                 {
       
  1032                 RemoveHighlightedEntryL();
       
  1033                 return EKeyWasConsumed;
       
  1034                 }
       
  1035             else if ( editPermission & EMsgEditBackspaceMove )
       
  1036                 {
       
  1037                 TInt entryNumber = iAddressControlEditor->EntryNumber( cursorPos ) - 1;
       
  1038                 iAddressControlEditor->MoveCursorToEntryPosL(
       
  1039                     entryNumber,
       
  1040                     iAddressControlEditor->EntryLength( entryNumber ) );
       
  1041                 return EKeyWasConsumed;
       
  1042                 }
       
  1043             else if ( !( editPermission & EMsgEditBackspace ) )
       
  1044                 {
       
  1045                 return EKeyWasConsumed;
       
  1046                 }
       
  1047                 
       
  1048             iAddressControlEditor->TurnHighlightingOffL( iAddressControlEditor->Selection() );
       
  1049             
       
  1050             // This is for disabling paragraph adding when removing line feed after 
       
  1051             // semicolon. OfferKeyEventL below will trigger EEventTextUpdate event.
       
  1052             iDuplicateEvent = ETrue;
       
  1053             
       
  1054             break;
       
  1055             }
       
  1056         default:
       
  1057             {
       
  1058             if ( !iAddressControlEditor->IsHandleEditEvent() )
       
  1059                 {
       
  1060                 TUint32 editPermission = iAddressControlEditor->CheckEditPermission();
       
  1061                 if ( !( editPermission & EMsgEditCharInsert ) )
       
  1062                     {
       
  1063                     return EKeyWasConsumed;
       
  1064                     }
       
  1065                 }
       
  1066             iAddressControlEditor->TurnHighlightingOffL( iAddressControlEditor->Selection() );
       
  1067             break;
       
  1068             }
       
  1069         }
       
  1070 
       
  1071     keyResp = iAddressControlEditor->OfferKeyEventL( aKeyEvent, aType );
       
  1072 
       
  1073     return keyResp;
       
  1074     }
       
  1075 
       
  1076 // ---------------------------------------------------------
       
  1077 // CMsgAddressControl::HandleEdwinEventL
       
  1078 //
       
  1079 //
       
  1080 // ---------------------------------------------------------
       
  1081 //
       
  1082 void CMsgAddressControl::HandleEdwinEventL(
       
  1083     CEikEdwin* aEdwin, TEdwinEvent aEventType )
       
  1084     {
       
  1085     CMsgExpandableControl::HandleEdwinEventL( aEdwin, aEventType );
       
  1086 
       
  1087     if ( aEventType == MEikEdwinObserver::EEventNavigation )
       
  1088         {
       
  1089         if ( iAddressControlEditor->CursorPos() ==
       
  1090             iAddressControlEditor->TextLength() )
       
  1091             {
       
  1092             iAddressControlEditor->TurnHighlightingOffFromPosL( 0 );
       
  1093             }
       
  1094         iAddressControlEditor->CheckHighlightingL();
       
  1095         }
       
  1096     if ( aEventType == MEikEdwinObserver::EEventTextUpdate )
       
  1097         {
       
  1098         iAddressControlEditor->PostInsertEditorFormattingL( iDuplicateEvent );
       
  1099         
       
  1100         // Reset duplicate event flag.
       
  1101         iDuplicateEvent = EFalse;
       
  1102         }
       
  1103     }
       
  1104 
       
  1105 // ---------------------------------------------------------
       
  1106 // CMsgAddressControl::PrepareForReadOnly
       
  1107 //
       
  1108 // Prepares read only or non read only state.
       
  1109 // ---------------------------------------------------------
       
  1110 //
       
  1111 void CMsgAddressControl::PrepareForReadOnly( TBool aReadOnly )
       
  1112     {
       
  1113     CMsgExpandableControl::PrepareForReadOnly( aReadOnly );
       
  1114     
       
  1115 #ifdef RD_SCALABLE_UI_V2
       
  1116     if ( !aReadOnly && 
       
  1117          AknLayoutUtils::PenEnabled() )
       
  1118         {
       
  1119         if ( !iButton )
       
  1120             {
       
  1121             TRAPD( error, CreateButtonL() );
       
  1122             if ( error == KErrNone )
       
  1123                 {
       
  1124                 LayoutButton();
       
  1125                 }
       
  1126             else
       
  1127                 {
       
  1128                 delete iButton;
       
  1129                 iButton = NULL;
       
  1130                 }
       
  1131             }
       
  1132         }
       
  1133     else 
       
  1134         {
       
  1135         // No button is created at the read only state or when pen is disabled
       
  1136         delete iButton;
       
  1137         iButton = NULL;
       
  1138         }
       
  1139 #endif
       
  1140     }
       
  1141 
       
  1142 // ---------------------------------------------------------
       
  1143 // CMsgAddressControl::FocusChanged
       
  1144 //
       
  1145 // This is called when the focus of the control is changed.
       
  1146 // ---------------------------------------------------------
       
  1147 //
       
  1148 void CMsgAddressControl::FocusChanged( TDrawNow aDrawNow )
       
  1149     {
       
  1150     CMsgExpandableControl::FocusChanged( aDrawNow );
       
  1151 
       
  1152     // TODO: Implement better error handling?
       
  1153     if ( !IsFocused() )
       
  1154         {
       
  1155         TRAP_IGNORE( iAddressControlEditor->TurnHighlightingOffL() );
       
  1156         }
       
  1157     else
       
  1158         {
       
  1159         TRAP_IGNORE( iAddressControlEditor->CheckHighlightingL() );
       
  1160         }
       
  1161     }
       
  1162 
       
  1163 // ---------------------------------------------------------
       
  1164 // CMsgAddressControl::HandleResourceChange
       
  1165 //
       
  1166 // This is called when the focus of the control is changed.
       
  1167 // ---------------------------------------------------------
       
  1168 //
       
  1169 void CMsgAddressControl::HandleResourceChange( TInt aType )
       
  1170     {
       
  1171 
       
  1172     CMsgExpandableControl::HandleResourceChange( aType );
       
  1173     }
       
  1174 
       
  1175 // ---------------------------------------------------------
       
  1176 // CMsgAddressControl::GetNextItemOnEntry
       
  1177 //
       
  1178 // Finds the next unverified string on entry and updates parsing info
       
  1179 // correspondingly. Returns ETrue if found.
       
  1180 // ---------------------------------------------------------
       
  1181 //
       
  1182 TInt CMsgAddressControl::GetNextItemOnEntry( TDes& aEntryBuf )
       
  1183     {
       
  1184     TInt entryNumber = iParsingInfo.iEntryNum;
       
  1185     TInt startPos = iParsingInfo.iEndPos;
       
  1186     TInt endPos = iParsingInfo.iEndPos;
       
  1187 
       
  1188     TPtrC entryString( iAddressControlEditor->ReadEntry( entryNumber ) );
       
  1189     TInt ret = ParseString( aEntryBuf, entryString, startPos, endPos );
       
  1190     SetParsingInfo( entryNumber, startPos, endPos );
       
  1191 
       
  1192     return ret;
       
  1193     }
       
  1194 
       
  1195 // ---------------------------------------------------------
       
  1196 // CMsgAddressControl::ParseString
       
  1197 //
       
  1198 // Finds and returns an unverified string aEntryItem from aString starting at
       
  1199 // position aStartPos. Returns a start position aStartPos and an end position
       
  1200 // aEndPos of the searched range. Returns KErrNotFound if the string cannot be
       
  1201 // found or KErrOverflow if a sting was too long.
       
  1202 // ---------------------------------------------------------
       
  1203 //
       
  1204 TInt CMsgAddressControl::ParseString(
       
  1205     TDes& aEntryItem, const TPtrC& aString, TInt& aStartPos, TInt& aEndPos )
       
  1206     {
       
  1207     __ASSERT_DEBUG( aStartPos >= 0, Panic( EMsgInvalidStartPos ) );
       
  1208 
       
  1209     aEntryItem.Zero();
       
  1210     aEndPos = aStartPos;
       
  1211     TInt stringLength = aString.Length();
       
  1212     TInt ret( KErrNone );
       
  1213 
       
  1214     while ( aEndPos < stringLength )
       
  1215         {
       
  1216         // finds suitable strings e.g. kalle;^   kalle^   ______;^
       
  1217         if ( ( ( aString[aEndPos] == KMsgListSeparator ) ||
       
  1218             ( aString[aEndPos] == KArabicSemicolon ) ||
       
  1219             ( aString[aEndPos] == CEditableText::ELineBreak ) ||
       
  1220             ( aString[aEndPos] == KDownwardsArrowWithTipLeftwards ) ||
       
  1221             ( aString[aEndPos] == KDownwardsArrowWithTipRightwards ) )
       
  1222             // SJK 25.04.2005: Fixing "HNUN-6BPAVU":
       
  1223             /*&& ( aStartPos != aEndPos )*/ )
       
  1224             {
       
  1225             aEndPos++;
       
  1226             break;
       
  1227             }
       
  1228         else if ( ( ( aString[aEndPos] != KMsgListSeparator ) ||
       
  1229             ( aString[aEndPos] != KArabicSemicolon ) ) &&
       
  1230             ( aEntryItem.Length() < aEntryItem.MaxLength() ) )
       
  1231             {
       
  1232             aEntryItem.Append( aString[aEndPos] );
       
  1233             }
       
  1234         else if ( aString[aEndPos] != CEditableText::ESpace )
       
  1235             {
       
  1236             // Do we ever get here? Even in theory!?
       
  1237             // What is this branch for?!
       
  1238             aEndPos++;
       
  1239             break;
       
  1240             }
       
  1241         aEndPos++;
       
  1242         }
       
  1243 
       
  1244     aEntryItem.TrimAll();
       
  1245 
       
  1246     if ( ( aEntryItem.Length() == 0 ) && ( aStartPos == aEndPos ) )
       
  1247         {
       
  1248         ret = KErrNotFound;
       
  1249         }
       
  1250 
       
  1251     return ret;
       
  1252     }
       
  1253 
       
  1254 // ---------------------------------------------------------
       
  1255 // CMsgAddressControl::FormatAndSetCursorPosL
       
  1256 //
       
  1257 // Formats and sets the cursor to the beginning of the formatted band.
       
  1258 // ---------------------------------------------------------
       
  1259 //
       
  1260 void CMsgAddressControl::FormatAndSetCursorPosL( TInt aPos )
       
  1261     {
       
  1262     if ( iControlModeFlags & EMsgControlModeInitialized )
       
  1263         {
       
  1264         iAddressControlEditor->SetAmountToFormatL( ETrue );
       
  1265         iAddressControlEditor->CheckHighlightingL();
       
  1266         }
       
  1267 
       
  1268     // Formats and draws the content
       
  1269     iAddressControlEditor->SetCursorPosAndCancelSelectionL( aPos );
       
  1270     if ( iControlModeFlags & EMsgControlModeInitialized )
       
  1271         {
       
  1272         iAddressControlEditor->CheckHighlightingL();
       
  1273         iBaseControlObserver->HandleBaseControlEventRequestL(
       
  1274             this, EMsgEnsureCorrectFormPosition );
       
  1275         }
       
  1276     }
       
  1277 
       
  1278 // ---------------------------------------------------------
       
  1279 // CMsgAddressControl::RemoveHightlightedEntryL
       
  1280 // ---------------------------------------------------------
       
  1281 //
       
  1282 void CMsgAddressControl::RemoveHighlightedEntryL( )
       
  1283     {
       
  1284     iAddressControlEditor->TurnHighlightingOffL();
       
  1285     TInt cursorPos( iAddressControlEditor->CursorPos() );
       
  1286     TInt entryNumber = iAddressControlEditor->EntryNumber( iAddressControlEditor->CursorPos() );
       
  1287     //Count the paragraph delimiter while capturing length
       
  1288     TInt entryLength = iAddressControlEditor->EntryLength( entryNumber )+1;
       
  1289     //Clear the entry
       
  1290     iAddressControlEditor->DeleteEntryCharsL( entryNumber, 0, entryLength );
       
  1291     iAddressControlEditor->DeleteEntryL( entryNumber );
       
  1292     FormatAndSetCursorPosL(iAddressControlEditor->CursorPos()); 
       
  1293 
       
  1294     iControlModeFlags |= EMsgControlModeModified;
       
  1295     }
       
  1296 
       
  1297 // ---------------------------------------------------------
       
  1298 // CMsgAddressControl::CreateButtonL
       
  1299 // ---------------------------------------------------------
       
  1300 //
       
  1301 void CMsgAddressControl::CreateButtonL()
       
  1302     {
       
  1303 #ifdef RD_SCALABLE_UI_V2
       
  1304     delete iButton;
       
  1305     iButton = NULL;
       
  1306     
       
  1307     iButton = CAknButton::NewL( NULL,
       
  1308                                 NULL,
       
  1309                                 NULL,
       
  1310                                 NULL,
       
  1311                                 *iCaption->Text(),
       
  1312                                 KNullDesC,
       
  1313                                 KAknButtonSizeFitText | KAknButtonTextLeft,
       
  1314                                 0 );
       
  1315     
       
  1316     iButton->SetTextColorIds( KAknsIIDQsnTextColors, EAknsCIQsnTextColorsCG63 );
       
  1317     iButton->SetObserver( this );
       
  1318     
       
  1319     if ( Parent() )
       
  1320         {
       
  1321         iButton->SetContainerWindowL( *Parent() );
       
  1322         iButton->ActivateL();
       
  1323         }
       
  1324 #endif // RD_SCALABLE_UI_V2
       
  1325     }
       
  1326 
       
  1327 // ---------------------------------------------------------
       
  1328 // CMsgAddressControl::LayoutButton
       
  1329 // ---------------------------------------------------------
       
  1330 //    
       
  1331 void CMsgAddressControl::LayoutButton()
       
  1332     {
       
  1333 #ifdef RD_SCALABLE_UI_V2
       
  1334     CMsgExpandableControl::LayoutButton();
       
  1335     
       
  1336     if ( iButton )
       
  1337         {
       
  1338         TMargins8 margins;
       
  1339         TRect buttonRect = iButtonLayout.Rect();
       
  1340         TRect textRect = iCaptionLayout.TextRect();
       
  1341         margins.iTop = textRect.iTl.iY - buttonRect.iTl.iY;
       
  1342         margins.iBottom = buttonRect.iBr.iY - textRect.iBr.iY;
       
  1343         margins.iLeft = textRect.iTl.iX - buttonRect.iTl.iX;
       
  1344         margins.iRight = buttonRect.iBr.iX - textRect.iBr.iX;
       
  1345         
       
  1346         iButton->SetMargins( margins );
       
  1347         }
       
  1348 #endif // RD_SCALABLE_UI_V2
       
  1349     }
       
  1350 
       
  1351 //  End of File