diff -r 968773a0b6ef -r c8382f7b54ef emailuis/emailui/src/ncsaifeditor.cpp --- 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& aAddresses ) +void CNcsAifEditor::AppendAddressesL( + const RPointerArray& 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& 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 ; iAddress()); + 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 ; idxIsSameDN(*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 ; iSetPos( pos ); - pos++; // for whitespace - } + TInt pos = 0; + CNcsAifEntry* entry; + for ( TInt i=0 ; iSetPos( 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& 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