emailuis/emailui/src/ncsaifeditor.cpp
branchRCL_3
changeset 73 c8382f7b54ef
parent 64 3533d4323edc
child 80 726fba06891a
--- a/emailuis/emailui/src/ncsaifeditor.cpp	Tue Sep 14 20:48:24 2010 +0300
+++ b/emailuis/emailui/src/ncsaifeditor.cpp	Wed Sep 15 11:52:37 2010 +0300
@@ -216,16 +216,17 @@
     }
 
 // ---------------------------------------------------------------------------
-// constructor/destructor
+// Constructor
 // ---------------------------------------------------------------------------
 //
 CNcsAifEditor::CNcsAifEditor(
     MNcsFieldSizeObserver* aSizeObserver, const TDesC& aCaptionText ) 
-    : CNcsEditor( aSizeObserver, ETrue, ENcsEditorAddress, aCaptionText ), iAddressPopupList( NULL ),
+    : CNcsEditor( aSizeObserver, ETrue, ENcsEditorAddress, aCaptionText ),
+    iAddressPopupList( NULL ),
     iAddLeftover( ETrue )
     {
     FUNC_LOG;
-	SetEdwinObserver( this );
+    SetEdwinObserver( this );
     }
 
 // ---------------------------------------------------------------------------
@@ -248,16 +249,15 @@
 CNcsAifEditor::~CNcsAifEditor()
     {
     FUNC_LOG;
-	iArray.ResetAndDestroy();
-	iAddressArray.Reset();
-	if ( iAsyncCallBack )
-	    {
-	    iAsyncCallBack->Cancel();
-	    delete iAsyncCallBack;
-	    }
+    iArray.ResetAndDestroy();
+    iAddressArray.Reset();
+    if ( iAsyncCallBack )
+        {
+        iAsyncCallBack->Cancel();
+        delete iAsyncCallBack;
+        }
     }
 
-
 // -----------------------------------------------------------------------------
 // CNcsAifEditor::CursorLineNumber() const
 // -----------------------------------------------------------------------------
@@ -311,22 +311,61 @@
         {
         ret = SetEditorSelectionL( aKeyEvent, aType );
         }
-    
+
     //when press a key down, record the coursor position
     if ( aType == EEventKeyDown )
-    	{
-    	iLastTimeCursorPos = CursorPos();
-    	}
+        {
+        iLastTimeCursorPos = CursorPos();
+        }
 
     if ( ret == EKeyWasNotConsumed )
         {
         // enter completes the address entry
-        if( aType == EEventKey && (aKeyEvent.iCode == EKeyEnter || 
-        	aKeyEvent.iScanCode == EStdKeyEnter) )
-        	{
-        	// make sure there is really some text inputted 
+        if ( aType == EEventKey && ( aKeyEvent.iCode == EKeyEnter || 
+             aKeyEvent.iScanCode == EStdKeyEnter ) )
+            {
+            // make sure there is really some text inputted 
+            const TInt cursorPos = CursorPos();
+            TCursorSelection selection = NonEntryTextAtPos( cursorPos );
+
+            const TInt length = selection.Length();
+            if ( length > 0 )
+                {
+                HBufC* text = HBufC::NewLC( length );
+                TPtr ptr = text->Des();
+                Text()->Extract( ptr, selection.LowerPos(), length );
+                ptr.Trim();
+
+                // complete the entry by adding a semicolon, 
+                // address will be added in HandleTextUpdateL
+                if ( ptr.Length() > 0 )
+                    {
+                    Text()->InsertL( cursorPos, KCharAddressDelimeterSemiColon );
+                    HandleTextChangedL();
+                    SetCursorPosL( cursorPos + 1, EFalse );
+                    iLastTimeCursorPos = CursorPos();
+                    HandleTextUpdateL();
+                    }
+
+                CleanupStack::PopAndDestroy( text );
+                }
+            }
+        else if ( IsCharacterKey( aKeyEvent ) )
+            {
+            PrepareForTextInputL( CursorPos() );
+            }
+        iTextSelection = Selection();
+        ret = CNcsEditor::OfferKeyEventL( aKeyEvent, aType );
+        }
+
+    // for Korean we need to simulate event 'text update' as FEP
+    // doesn't send it and the MRU is not shown
+    if ( User::Language() == ELangKorean )
+        {
+        if ( ret == EKeyWasNotConsumed && aType == EEventKeyUp )
+            {
             TInt cursorPos( CursorPos() );
-        	
+
             TCursorSelection selection = NonEntryTextAtPos( cursorPos );
             
             TInt length( selection.Length() );
@@ -335,20 +374,14 @@
             TPtr ptr = text->Des();
             Text()->Extract( ptr, selection.LowerPos(), length );
             ptr.Trim();
-            
-            // complete the entry by adding a semicolon, 
-            // address will be added in HandleTextUpdateL
-            if( ptr.Length() > 0 )
-            	{            
-				Text()->InsertL( cursorPos, KCharAddressDelimeterSemiColon );
-				HandleTextChangedL();
-				SetCursorPosL( cursorPos + 1, EFalse );
-            	}
-            
-            CleanupStack::PopAndDestroy( text );            
-        	}
-        iTextSelection = Selection();        
-        ret = CNcsEditor::OfferKeyEventL( aKeyEvent, aType );
+        
+            if ( TFsEmailUiUtility::IsKoreanWord( ptr ) )
+                {
+                HandleTextUpdateDeferred();
+                }
+        
+            CleanupStack::PopAndDestroy( text );
+            }
         }
     
     return ret;
@@ -400,7 +433,7 @@
     if ( aKeyEvent.iCode == EKeyUpArrow || aKeyEvent.iCode == EKeyDownArrow )
         {
         CompleteEntryL();
-		
+
         response = CNcsEditor::OfferKeyEventL( aKeyEvent,aType );
         if ( response == EKeyWasConsumed ) 
             {
@@ -413,10 +446,11 @@
             }
         }
     // Check if the cursor is in any of the addresses
-    else if( aKeyEvent.iCode == EKeyLeftArrow || aKeyEvent.iCode == EKeyBackspace ) 
+    else if ( aKeyEvent.iCode == EKeyLeftArrow || aKeyEvent.iCode == EKeyBackspace ) 
         {
         // We're moving left, but haven't yet.
-        entry = GetEntryAt( CursorPos(), EDirectionLeft );
+        const TInt cursorPos = CursorPos();
+        entry = GetEntryAt( cursorPos, EDirectionLeft );
         if ( entry )
             {
             if ( selection.Length() && aKeyEvent.iCode == EKeyLeftArrow)
@@ -431,11 +465,25 @@
                 response = EKeyWasConsumed;
                 }
             }
+        else
+            {
+            // Complete entry, if cursor is being moved to the previous row.
+            TCursorSelection selection = NonEntryTextAndSpaceAtPos( cursorPos );
+            if ( cursorPos > 0 && selection.LowerPos() + 1 == cursorPos )
+                {
+                if ( IsDelimiter( CharAtPos( selection.LowerPos() ) ) )
+                    {
+                    CompleteEntryL();
+                    SetCursorPosL( cursorPos, EFalse );
+                    }
+                }
+            }
         }
-    else if( aKeyEvent.iCode == EKeyRightArrow || aKeyEvent.iCode == EKeyDelete )
+    else if ( aKeyEvent.iCode == EKeyRightArrow || aKeyEvent.iCode == EKeyDelete )
         {
         // We're moving right, but haven't yet.
-        entry = GetEntryAt( CursorPos(), EDirectionRight );
+        const TInt cursorPos = CursorPos();
+        entry = GetEntryAt( cursorPos, EDirectionRight );
         if ( entry )
             {
             if ( selection.Length() && aKeyEvent.iCode == EKeyRightArrow  )
@@ -450,6 +498,18 @@
                 response = EKeyWasConsumed;
                 }
             }
+        else
+            {
+            // Complete entry, if cursor is being moved to the next row.
+            TCursorSelection selection = NonEntryTextAndSpaceAtPos( cursorPos );
+            if ( cursorPos > 0 && selection.HigherPos() - 1 == cursorPos )
+                {
+                if ( IsDelimiter( CharAtPos( selection.HigherPos() - 1 ) ) )
+                    {
+                    CompleteEntryL();
+                    }
+                }
+            }
         }
     // to fix problems with updating CBA when hash key is pressed and hold
     else if ( aKeyEvent.iScanCode == EStdKeyHash ) 
@@ -507,10 +567,11 @@
                     break;
                     }
                 }
-            
+
+            SetCursorVisible( EFalse );
             ClearSelectionL();
-            
-            RepositionEntriesL( entry );
+            RepositionEntries( entry );
+            SetCursorVisible( ETrue );
 
             // The key event is set consumed only on delete and backpace
             // events, other events need to be forwarded to the editor.
@@ -529,26 +590,26 @@
 // ---------------------------------------------------------------------------
 //
 void CNcsAifEditor::DoCharChangeL()
-	{
+    {
     FUNC_LOG;
-	RecalculateEntryPositions();
+    RecalculateEntryPositions();
 
-	TChar previousChar = CharAtPos( CursorPos() - 1 );
-	TBool sentinel = ( previousChar == KCharAddressDelimeterSemiColon || 
-	    previousChar == KCharAddressDelimeterComma );
-	if ( sentinel )
+    TChar previousChar = CharAtPos( CursorPos() - 1 );
+    TBool sentinel = ( previousChar == KCharAddressDelimeterSemiColon || 
+        previousChar == KCharAddressDelimeterComma );
+    if ( sentinel )
         {
         // if comma was pressed we replace it with semicolon
-		if ( previousChar == KCharAddressDelimeterComma )
+        if ( previousChar == KCharAddressDelimeterComma )
             {
-			CPlainText* text = Text();
-			text->DeleteL( CursorPos() - 1, 1 );
-			text->InsertL( CursorPos() - 1, KCharAddressDelimeterSemiColon );
+            CPlainText* text = Text();
+            text->DeleteL( CursorPos() - 1, 1 );
+            text->InsertL( CursorPos() - 1, KCharAddressDelimeterSemiColon );
             }
-		ParseNewAddressL();
+        ParseNewAddressL();
         }
-	UpdateAddressAutoCompletionL();
-	}
+    UpdateAddressAutoCompletionL();
+    }
 
 // ---------------------------------------------------------------------------
 // CNcsAddressInputField::CharAtPos
@@ -557,15 +618,15 @@
 TChar CNcsAifEditor::CharAtPos( TInt aPos ) const
     {
     FUNC_LOG;
-	if ( aPos >= 0 && aPos < TextLength() )
+    if ( aPos >= 0 && aPos < TextLength() )
         {
-		TBuf<1> buf;
-		Text()->Extract( buf, aPos, 1 );
-		return buf[0];
+        TBuf<1> buf;
+        Text()->Extract( buf, aPos, 1 );
+        return buf[0];
         }
-	else
+    else
         {
-		return 0;
+        return 0;
         }
     }
 
@@ -584,7 +645,8 @@
 // CNcsAifEditor::AppendAddressesL()
 // -----------------------------------------------------------------------------
 //
-void CNcsAifEditor::AppendAddressesL( const RPointerArray<CNcsEmailAddressObject>& aAddresses )
+void CNcsAifEditor::AppendAddressesL( 
+    const RPointerArray<CNcsEmailAddressObject>& aAddresses )
     {
     FUNC_LOG;
     // First, add all the addresses without updating the editor text contents 
@@ -592,8 +654,13 @@
         {
         AddAddressL( *aAddresses[i], EFalse );
         }
-    // Update editor text content after all the items have been added
-    RepositionEntriesL( NULL );
+
+    // Update editor text content after all the items have been added.
+    SetCursorVisible( EFalse );
+    const TInt count = iArray.Count();
+    CNcsAifEntry* lastEntry = count ? iArray[count-1] : NULL;
+    RepositionEntries( lastEntry );
+    SetCursorVisible( ETrue );
     }
 
 // -----------------------------------------------------------------------------
@@ -602,17 +669,17 @@
 //   
 const RPointerArray<CNcsEmailAddressObject>& CNcsAifEditor::GetAddressesL()
     {
-	// Clear the existing array since it may be out of sync
-	iAddressArray.Reset();
+    // Clear the existing array since it may be out of sync
+    iAddressArray.Reset();
 
-	for ( TInt i=0 ; i<iArray.Count() ; i++ ) 
+    for ( TInt i=0; i<iArray.Count(); i++ ) 
         {
-		iAddressArray.AppendL(&iArray[i]->Address());
+        iAddressArray.AppendL( &iArray[i]->Address() );
         }
 
-	return iAddressArray;
+    return iAddressArray;
     }
-    
+
 // -----------------------------------------------------------------------------
 // CNcsAifEditor::GetEntryAt()
 // -----------------------------------------------------------------------------
@@ -710,29 +777,29 @@
 void CNcsAifEditor::ParseNewAddressL()
 	{
     FUNC_LOG;
-	HBufC* text = GetNonEntryTextLC();
-	__ASSERT_ALWAYS( text, Panic(EFSEmailUiNullPointerException) );
+    HBufC* text = GetNonEntryTextLC();
+    __ASSERT_ALWAYS( text, Panic(EFSEmailUiNullPointerException) );
 
-	if ( text->Length() )
-		{
+    if ( text->Length() )
+        {
         // if changing focus leftover text is parsed to email
         // object - we don't need to add it anymore
         iAddLeftover = EFalse;
         // check if there is a name for the email address
         HBufC* name = CFsDelayedLoader::InstanceL()->GetContactHandlerL()->GetLastSearchNameL( *text );
-	if ( name )
-		{
+        if ( name )
+            {
             CleanupStack::PushL( name );
-		AddAddressL( *name, *text, ETrue );
-		CleanupStack::PopAndDestroy( name );
-		}
-	else
-		{
-		AddAddressL( KNullDesC, *text );
-		}
-	    }
-	
-	CleanupStack::PopAndDestroy(text);
+            AddAddressL( *name, *text, ETrue );
+            CleanupStack::PopAndDestroy( name );
+            }
+        else
+            {
+            AddAddressL( KNullDesC, *text );
+            }
+        }
+
+    CleanupStack::PopAndDestroy(text);
 	}
 
 // -----------------------------------------------------------------------------
@@ -848,7 +915,8 @@
 // CNcsAifEditor::AddAddressL()
 // -----------------------------------------------------------------------------
 //
-void CNcsAifEditor::AddAddressL( const CNcsEmailAddressObject& aAddress, TBool aUpdateEditorText /*= ETrue*/ )
+void CNcsAifEditor::AddAddressL( const CNcsEmailAddressObject& aAddress,
+    TBool aUpdateEditorText /*= ETrue*/ )
     {
     FUNC_LOG;
     CNcsAifEntry* entry = CNcsAifEntry::NewL( aAddress );
@@ -866,57 +934,59 @@
     FUNC_LOG;
     CNcsAifEntry* entry = CNcsAifEntry::NewL( aDisplayName, aEmail, aDisplayFull );
     CleanupStack::PushL( entry );
-	AddAddressL( entry, aUpdateEditorText );
-	CleanupStack::Pop( entry );
+    AddAddressL( entry, aUpdateEditorText );
+    CleanupStack::Pop( entry );
     }
 
 void CNcsAifEditor::AddAddressL( CNcsAifEntry* aNewEntry, TBool aUpdateEditorText )
     {
     FUNC_LOG;
-	TInt idx;
-	
-	// Check for duplicate display names
-	for ( idx=0 ; idx<iArray.Count() ; idx++ ) 
+    TInt idx;
+
+    // Check for duplicate display names
+    for ( idx=0 ; idx<iArray.Count() ; idx++ ) 
         {
-		if ( iArray[idx]->IsSameDN(*aNewEntry) ) 
+        if ( iArray[idx]->IsSameDN(*aNewEntry) ) 
             {
-			iArray[idx]->SetDupL();
-			aNewEntry->SetDupL();
+            iArray[idx]->SetDupL();
+            aNewEntry->SetDupL();
             }
         }
 
-	// Find the location where we need to insert the address.
-	// Browse from back to forth to make last index as default index. 
-	// This ensures items remain in correct order when populating field from
-	// existing message.
-	TInt cursorPos = CursorPos();
+    // Find the location where we need to insert the address.
+    // Browse from back to forth to make last index as default index. 
+    // This ensures items remain in correct order when populating field from
+    // existing message.
+    TInt cursorPos = CursorPos();
     // if we are at the end of editor the address was
     // added from MRU list or separator was typed in
     if ( cursorPos == Text()->DocumentLength() )
         {
         iAddLeftover = EFalse;
         }
-	
-	for ( idx = iArray.Count() ; idx > 0 ; idx-- ) 
+
+    for ( idx = iArray.Count() ; idx > 0 ; idx-- ) 
         {
-		if ( cursorPos >= iArray[idx-1]->End() ) break;
+        if ( cursorPos >= iArray[idx-1]->End() ) break;
         }
-	if ( idx == iArray.Count() ) 
+    if ( idx == iArray.Count() ) 
         {
-		// Tack the address onto the end of the array
-		iArray.AppendL( aNewEntry );
+        // Tack the address onto the end of the array
+        iArray.AppendL( aNewEntry );
         }
-	else
+    else
         {
-		iArray.InsertL( aNewEntry, idx );
+        iArray.InsertL( aNewEntry, idx );
         }
-	
-	if ( aUpdateEditorText )
-	    {
-	    // Trap because we must not leave after we have taken the ownership of aNewEntry.
-	    // Otherwise douple deletion might happen.
-	    TRAP_IGNORE( RepositionEntriesL( aNewEntry ) );
-	    }
+
+    if ( aUpdateEditorText )
+        {
+        // Trap because we must not leave after we have taken the ownership of
+        // aNewEntry. Otherwise douple deletion might happen.
+        SetCursorVisible( EFalse );
+        RepositionEntries( aNewEntry );
+        SetCursorVisible( ETrue );
+        }
     }
 
 // ---------------------------------------------------------------------------
@@ -966,27 +1036,37 @@
 	}
 
 // ---------------------------------------------------------------------------
+// CNcsAifEditor::RepositionEntries()
+// ---------------------------------------------------------------------------
+//
+TInt CNcsAifEditor::RepositionEntries( const CNcsAifEntry* aPosEntry )
+    {
+    FUNC_LOG;
+    TRAPD( err, RepositionEntriesL( aPosEntry ) );
+    return err;
+    }
+
+// ---------------------------------------------------------------------------
 // CNcsAifEditor::RepositionEntriesL()
 // ---------------------------------------------------------------------------
 //
 void CNcsAifEditor::RepositionEntriesL( const CNcsAifEntry* aPosEntry )
-	{
+    {
     FUNC_LOG;
-	TInt pos = 0;
-	CNcsAifEntry* entry;
-	for ( TInt i=0 ; i<iArray.Count() ; i++ ) 
-		{
-		entry = iArray[i];
-		pos = entry->SetPos( pos );
-		pos++; // for whitespace
-		}
+    TInt pos = 0;
+    CNcsAifEntry* entry;
+    for ( TInt i=0 ; i<iArray.Count() ; i++ ) 
+        {
+        entry = iArray[i];
+        pos = entry->SetPos( pos );
+        pos++; // for whitespace
+        }
 
-  // Reset the text
-	HBufC* text = NULL;
-	text = GetFormattedAddressListLC( iArray );
-	// fix for dissapearing text PWAN-82DNEJ	
-	SetCursorPosL( 0, EFalse ); //In case the cursor pos is invalid
-	
+    // Reset the text
+    HBufC* text = GetFormattedAddressListLC( iArray );
+    // fix for dissapearing text PWAN-82DNEJ
+    //SetCursorPosL( 0, EFalse ); //In case the cursor pos is invalid
+
     if ( iAddLeftover )
         {
         TInt lengthBefore = Text()->DocumentLength();
@@ -1001,10 +1081,10 @@
         HBufC* newText = HBufC::NewLC( text->Length() + leftover.Length() );
         TPtr newTextPtr = newText->Des();
         // add all email addresses
-        newTextPtr.Append( text->Des() );
+        newTextPtr.Append( *text );
         // add the text that was after last email object
         newTextPtr.Append( leftover );
-    
+
         SetTextL( newText );
         CleanupStack::PopAndDestroy( newText );
         CleanupStack::PopAndDestroy( textBefore );
@@ -1013,19 +1093,21 @@
         {
         SetTextL( text );
         }
+
+    if ( !aPosEntry )
+        {
+        // Set cursor at the beginning of the document.
+        SetCursorPosL( 0, EFalse );
+        }
+    else
+        {
+        // Set the cursor at the end of the given entry 
+        SetCursorPosL( aPosEntry->End(), EFalse );
+        }
+
     CleanupStack::PopAndDestroy( text );
     HandleTextChangedL();
-    
-    // Set the cursor at the end of the given entry 
-    if ( !aPosEntry )
-    	{
-	    SetCursorPosL( 0, EFalse );
-    	}
-    else
-    	{
-    	SetCursorPosL( aPosEntry->End(), EFalse );
-    	}
-	}
+    }
 
 // ---------------------------------------------------------------------------
 // CNcsAifEditor::CheckAndRemoveInvalidEntriesL()
@@ -1083,19 +1165,19 @@
 HBufC* CNcsAifEditor::GetLookupTextLC() const
     {
     FUNC_LOG;
-	HBufC* text = GetTextInHBufL();
-	
-	if (text == NULL) return NULL;
-
-	CleanupStack::PushL( text );
-	TPtr ptr( text->Des() );
-	TInt location = ptr.LocateReverse( KCharAddressDelimeterSemiColon );
-	if( location != KErrNotFound )
+    HBufC* text = GetTextInHBufL();
+    CleanupStack::PushL( text );
+    if ( text )
         {
-		ptr = ptr.RightTPtr( ptr.Length() - location -1 );
-		ptr.TrimLeft();
+        TPtr ptr( text->Des() );
+        TInt location = ptr.LocateReverse( KCharAddressDelimeterSemiColon );
+        if ( location != KErrNotFound )
+            {
+            ptr = ptr.RightTPtr( ptr.Length() - location -1 );
+            ptr.TrimLeft();
+            }
         }
-	return text;
+    return text;
     }
 
 // ---------------------------------------------------------------------------
@@ -1107,17 +1189,17 @@
     TBool aDisplayList ) const
     {
     FUNC_LOG;
-	TInt length = CalculateAddressListLength( aEntries, aDisplayList );
-	if ( length <= 0 )
+    TInt length = CalculateAddressListLength( aEntries, aDisplayList );
+    if ( length <= 0 )
         {
-		return HBufC::NewLC(0);
+        return HBufC::NewLC(0);
         }
-    
-	HBufC* buf = HBufC::NewLC( length );
-	TPtr ptr = buf->Des();
-    
-	TInt count = aEntries.Count();
-	for ( TInt i = 0; i < count; i++ )
+
+    HBufC* buf = HBufC::NewLC( length );
+    TPtr ptr = buf->Des();
+
+    TInt count = aEntries.Count();
+    for ( TInt i = 0; i < count; i++ )
         {
         if ( aDisplayList )
             {
@@ -1146,12 +1228,12 @@
 HBufC* CNcsAifEditor::GetFormattedAddressListL(
     RPointerArray<CNcsAifEntry>& aEntries,
     TBool aDisplayList ) const
-	{
+    {
     FUNC_LOG;
     HBufC* buf = GetFormattedAddressListLC( aEntries, aDisplayList );
     CleanupStack::Pop( buf );
     return buf;
-	}
+    }
 
 // ---------------------------------------------------------------------------
 // CNcsAifEditor::CalculateAddressListLength()
@@ -1202,12 +1284,12 @@
 void CNcsAifEditor::UpdateAddressAutoCompletionL()
     {
     FUNC_LOG;
-	HBufC* text = GetNonEntryTextLC();
-	__ASSERT_ALWAYS( text, Panic(EFSEmailUiNullPointerException) );
+    HBufC* text = GetNonEntryTextLC();
+    __ASSERT_ALWAYS( text, Panic(EFSEmailUiNullPointerException) );
 
-		iAddressPopupList->UpdatePopupContactListL( *text, EFalse );
-		CleanupStack::PopAndDestroy( text );
-        }
+    iAddressPopupList->UpdatePopupContactListL( *text, EFalse );
+    CleanupStack::PopAndDestroy( text );
+    }
 
 // ---------------------------------------------------------------------------
 // CNcsAifEditor::UpdateAddressAutoCompletionL()
@@ -1240,10 +1322,9 @@
 void CNcsAifEditor::UpdateAddressListAllL()
     {
     FUNC_LOG;
-	iAddressPopupList->UpdatePopupContactListL( KNullDesC, ETrue );
+    iAddressPopupList->UpdatePopupContactListL( KNullDesC, ETrue );
     }
 
-
 // ---------------------------------------------------------------------------
 // Updates the duplicate markings in the entry array.
 // ---------------------------------------------------------------------------
@@ -1306,38 +1387,23 @@
     FUNC_LOG;
     RecalculateEntryPositions();
     TCursorSelection textSelection = NonEntryTextAtPos( CursorPos() );
-    TBool newEntryCreated = EFalse;
     if ( textSelection.Length() )
         {
         // Check non-entry text for complete entries.
-        newEntryCreated = HandleTextUpdateL( textSelection );
+        const TBool newEntriesAdded = HandleTextUpdateL( textSelection );
+        if ( newEntriesAdded )
+            {
+            iAddressPopupList->ClosePopupContactListL();
+            iSizeObserver->UpdateFieldSizeL( ETrue );
+            iPartialRemove = EFalse;
+            }
+        else
+            {
+            MoveNonEntryTextToDedicatedRowsL( CursorPos() );
+            }
+        textSelection = NonEntryTextAtPos( CursorPos() );
         }
-    
-    if ( newEntryCreated )
-        {
-        iAddressPopupList->ClosePopupContactListL();
-        
-        // add line feed after new entry
-        TInt cursorPos( CursorPos() );
-        // related to PWAN-82DNEJ cursorPos shouldn't be 0 here
-        if (cursorPos == 0)
-          {
-          cursorPos = TextLength();
-          }
-          
-        if ( !iPartialRemove )
-            {
-            Text()->InsertL( cursorPos, TChar(CEditableText::ELineBreak) );
-            }
-        HandleTextChangedL();
-        SetCursorPosL( cursorPos + 1, EFalse );
-        iSizeObserver->UpdateFieldSizeL( ETrue );
-        iPartialRemove = EFalse;
-        }
-    else
-        {
-        UpdateAddressAutoCompletionL( textSelection );
-        }
+    UpdateAddressAutoCompletionL( textSelection );
     }
 
 // ---------------------------------------------------------------------------
@@ -1350,10 +1416,10 @@
     iAddLeftover = ETrue;
     TInt firstCharacter = aSelection.LowerPos();
     TInt lastCharacter = aSelection.HigherPos();
-    
+
     // get the inputted text
-    TInt length = lastCharacter - firstCharacter;
-    
+    const TInt length = lastCharacter - firstCharacter;
+
     HBufC* text = HBufC::NewLC( length );
     TPtr ptr = text->Des();
     Text()->Extract( ptr, firstCharacter, length );
@@ -1411,30 +1477,114 @@
                 }
             }
         }
-    
+
     // add email that wasn't ended with semicolon
     if ( lastSentinel != KErrNotFound )
         {
         if ( lastSentinel < end && start < end )
             {
             AddAddressL( KNullDesC(), ptr.Mid(start, end-start) );
+            entriesFound = ETrue;
             }
         }
-    
+
     CleanupStack::PopAndDestroy( text );
-        
     return entriesFound;
     }
 
 // ---------------------------------------------------------------------------
+// Moves inputted non-entry text to separate row
+// ---------------------------------------------------------------------------
+//
+void CNcsAifEditor::MoveNonEntryTextToDedicatedRowsL( TUint aPosition )
+    {
+    // Get the non-entry text and whitespace at given location
+    TCursorSelection textSelection = NonEntryTextAndSpaceAtPos( aPosition );
+    const TInt start = textSelection.LowerPos();
+    const TInt end = textSelection.HigherPos();
+    const TInt length = end - start;
+
+    const TChar lineBreak = TChar( CEditableText::ELineBreak );
+    const TChar paragraphDelimiter =
+        TChar( CEditableText::EParagraphDelimiter );
+
+    // Make sure that the inputted non-entry text is not on the same lines
+    // with existing entries.
+    if ( length )
+        {
+        HBufC* text = HBufC::NewLC( length );
+        TPtr ptr = text->Des();
+        Text()->Extract( ptr, start, length );
+
+        const TChar firstCharacter = TChar( ptr[0] );
+        const TChar lastCharacter = TChar( ptr[length-1] );
+        const TInt documentLength = Text()->DocumentLength();
+
+        TBool textChanged = EFalse;
+
+        if ( end < documentLength &&
+             lastCharacter != paragraphDelimiter &&
+             lastCharacter != lineBreak )
+            {
+            Text()->InsertL( end, lineBreak );
+            HandleTextChangedL();
+            textChanged = ETrue;
+            }
+
+        if ( start > 0 && start < end &&
+             firstCharacter != paragraphDelimiter &&
+             firstCharacter != lineBreak )
+            {
+            Text()->InsertL( start, lineBreak );
+            SetCursorVisible( EFalse );
+            HandleTextChangedL();
+            SetCursorPosL( CursorPos() + 1, EFalse );
+            SetCursorVisible( ETrue );
+            textChanged = ETrue;
+            }
+
+        if ( textChanged )
+            {
+            RecalculateEntryPositions();
+            }
+
+        CleanupStack::PopAndDestroy( text );
+        }
+    }
+
+// ---------------------------------------------------------------------------
+// Prepares for text entry to given cursor position making sure that the
+// new text will not be entered on same row with existing 
+// ---------------------------------------------------------------------------
+//
+void CNcsAifEditor::PrepareForTextInputL( TUint aPosition )
+    {
+    FUNC_LOG;
+    // Get the non-entry text and whitespace at given position.
+    TCursorSelection textSelection = NonEntryTextAndSpaceAtPos( aPosition );
+    const TInt start = textSelection.LowerPos();
+    const TInt end = textSelection.HigherPos();
+    const TInt length = end - start;
+
+    const TChar lineBreak = TChar( CEditableText::ELineBreak );
+
+    if ( start > 0 && ( !length || aPosition == start ) )
+        {
+        Text()->InsertL( start, lineBreak );
+        HandleTextChangedL();
+        SetCursorPosL( start + 1, EFalse );
+        }
+    }
+
+// ---------------------------------------------------------------------------
 // Handles navigation event.
 // ---------------------------------------------------------------------------
 //
 void CNcsAifEditor::HandleNavigationEventL()
     {
     FUNC_LOG;
-    // Close the contact popup when cursor is moved withing the field to make it less distracting. 
-    // It's reopened when user types something.
+    // Close the contact popup when cursor is moved withing the field to make
+    // it less distracting. It's reopened when user types something.
     iAddressPopupList->ClosePopupContactListL();
     }
 
@@ -1445,6 +1595,51 @@
 TCursorSelection CNcsAifEditor::NonEntryTextAtPos( TUint aPosition ) const
     {
     FUNC_LOG;
+    // Get the range of non-entry text and whitespace at given position.
+    TCursorSelection text = NonEntryTextAndSpaceAtPos( aPosition );
+
+    // Get the selected text to remove whitespace
+    const TInt length = text.Length();
+
+    HBufC* selectedText = NULL;
+    TRAPD( err, selectedText = HBufC::NewL( length ) );
+
+    if( err == KErrNone )
+        {
+        TPtr ptr = selectedText->Des();
+        Text()->Extract( ptr, text.LowerPos(), length );
+
+        // trim from end
+        TInt index( length - 1 );
+
+        while( index >= 0 && IsWhitespace( ptr[index--] ) )
+            {
+            text.iCursorPos--;
+            }
+
+        // trim from begin
+        index = 0;
+
+        while( index < length && IsWhitespace( ptr[index++] ) )
+            {
+            text.iAnchorPos++;
+            }
+
+        delete selectedText;
+        selectedText = NULL;
+        }    
+
+    return text;
+    }
+
+// ---------------------------------------------------------------------------
+// Gets non-entry text including surrounding whitespace at given position.
+// ---------------------------------------------------------------------------
+//
+TCursorSelection CNcsAifEditor::NonEntryTextAndSpaceAtPos(
+    TUint aPosition ) const
+    {
+    FUNC_LOG;
     TCursorSelection text( TextLength(), 0 );
     for ( TInt ii = iArray.Count() - 1; ii >= 0; --ii )
         {
@@ -1467,37 +1662,6 @@
             }
         }
 
-    // get the selected text to remove whitespace
-    TInt length( text.Length() );    
-    
-    HBufC* selectedText = NULL;
-    TRAPD( err, selectedText = HBufC::NewL( length ) );
-    
-    if( err == KErrNone )
-    	{
-		TPtr ptr = selectedText->Des();
-		Text()->Extract( ptr, text.LowerPos(), length );
-		
-		// trim from end
-		TInt index( length - 1 );
-		
-		while( index >= 0 && IsWhitespace( ptr[index--] ) )
-			{
-			text.iCursorPos--;
-			}
-		
-		// trim from begin
-		index = 0;
-		
-		while( index < length && IsWhitespace( ptr[index++] ) )
-			{
-			text.iAnchorPos++;
-			}
-
-		delete selectedText;
-		selectedText = NULL;
-    	}    
-    	
     return text;
     }
 
@@ -1540,6 +1704,18 @@
     }
 
 // ---------------------------------------------------------------------------
+// Checks whether given character is considered as line delimiter.
+// ---------------------------------------------------------------------------
+//
+//
+TBool CNcsAifEditor::IsDelimiter( TChar aCharacter ) const
+    {
+    FUNC_LOG;
+    return ( aCharacter == TChar( CEditableText::ELineBreak) || 
+             aCharacter == TChar( CEditableText::EParagraphDelimiter) );
+    }
+
+// ---------------------------------------------------------------------------
 // Checks whether given character is considered as whitespace.
 // ---------------------------------------------------------------------------
 //
@@ -1547,8 +1723,8 @@
     {
     FUNC_LOG;
     return ( aCharacter == KCharSpace || 
-    		 aCharacter == TChar(CEditableText::ELineBreak) || 
-    		 aCharacter == TChar(CEditableText::EParagraphDelimiter) );
+             aCharacter == TChar(CEditableText::ELineBreak) || 
+             aCharacter == TChar(CEditableText::EParagraphDelimiter) );
     }
 
 // ---------------------------------------------------------------------------
@@ -1648,61 +1824,68 @@
 
         //adjust touch point to mach editor coordinates
         touchPoint.iX -= Position().iX;
-        
-        TInt pointerLineNbr = textLayout->GetLineNumber( textLayout->XyPosToDocPosL( touchPoint ));
+
+        TInt pointerLineNbr = textLayout->GetLineNumber( 
+            textLayout->XyPosToDocPosL( touchPoint ) );
         TInt cursorLineNbr = textLayout->GetLineNumber( cursorPos );
-        
-        
+
         if ( pointerLineNbr != cursorLineNbr )
             {
             CompleteEntryL();
             
             // We're moving to a new line.
-            CNcsAifEntry* entry = NULL;
-            entry = GetEntryAt( CursorPos() );
+            CNcsAifEntry* entry = GetEntryAt( CursorPos() );
             if ( entry )
                 {
                 SetSelectionL( entry->iCursorPos, entry->iAnchorPos );
                 }
-            }    
+            }
         }
-            
+
     CEikEdwin::HandlePointerEventL( aPointerEvent );
+
+    // Do not allow to insert cursor into the middle of some entry
+    CNcsAifEntry* entry = GetEntryAt( CursorPos() );
+    if ( entry )
+        {
+        SetSelectionL( entry->iCursorPos, entry->iAnchorPos );
+        }
     }
 
 
 // -----------------------------------------------------------------------------
 // CNcsAifEditor::CompleteEntryL()
-// Adds semicolol to the of the entry
+// Adds semicolon to the end of the entry.
 // -----------------------------------------------------------------------------
 //
 void CNcsAifEditor::CompleteEntryL()
     {
     // make sure there is really some text inputted 
-    TInt cursorPos( CursorPos() );
+    const TInt cursorPos = CursorPos();
 
     TCursorSelection selection = NonEntryTextAtPos( cursorPos );
-
-    TInt length( selection.Length() );
+    const TInt length =  selection.Length();
 
-    HBufC* text = HBufC::NewLC( length );
-    TPtr ptr = text->Des();
+    if ( length > 0 && selection.LowerPos() >= 0 )
+        {
+        HBufC* text = HBufC::NewLC( length );
+        TPtr ptr = text->Des();
 
-    if( selection.LowerPos() >= 0 )
-        {
         Text()->Extract( ptr, selection.LowerPos(), length );
         ptr.Trim();
-        
+
         // complete the entry
-        if( ptr.Length() > 0 )
+        if ( ptr.Length() > 0 )
             {
             Text()->InsertL( selection.HigherPos(), KCharAddressDelimeterSemiColon );
             HandleTextChangedL();
-            HandleTextUpdateL( TCursorSelection(selection.LowerPos(), selection.HigherPos() + 1) );
+            HandleTextUpdateL( TCursorSelection( selection.LowerPos(),
+                selection.HigherPos() + 1 ) );
             }
+
+        CleanupStack::PopAndDestroy( text );
         }
+    }
 
-    CleanupStack::PopAndDestroy( text );
-    }
 // End of File