Merge "Completely remove use of Adaptor class" into tizen
[platform/core/uifw/dali-toolkit.git] / base / dali-toolkit / internal / controls / text-input / text-input-impl.cpp
index fe54de2..69e02a8 100644 (file)
@@ -21,6 +21,7 @@
 #include <dali-toolkit/internal/controls/text-view/text-processor.h>
 #include <dali-toolkit/public-api/controls/buttons/push-button.h>
 #include <dali-toolkit/public-api/controls/alignment/alignment.h>
+#include <dali-toolkit/public-api/controls/default-controls/solid-color-actor.h>
 
 #include <dali/integration-api/debug.h>
 
@@ -51,9 +52,6 @@ const char* DEFAULT_SELECTION_HANDLE_ONE( DALI_IMAGE_DIR "text-input-selection-h
 const char* DEFAULT_SELECTION_HANDLE_TWO( DALI_IMAGE_DIR "text-input-selection-handle-right.png" );
 const char* DEFAULT_SELECTION_HANDLE_ONE_PRESSED( DALI_IMAGE_DIR "text-input-selection-handle-left-press.png" );
 const char* DEFAULT_SELECTION_HANDLE_TWO_PRESSED( DALI_IMAGE_DIR "text-input-selection-handle-right-press.png" );
-const char* DEFAULT_CURSOR( DALI_IMAGE_DIR "cursor.png" );
-
-const Vector4 DEFAULT_CURSOR_IMAGE_9_BORDER( 2.0f, 2.0f, 2.0f, 2.0f );
 
 const std::size_t CURSOR_BLINK_INTERVAL = 500;                              ///< Cursor blink interval
 const float CHARACTER_THRESHOLD( 2.5f );                                    ///< the threshold of a line.
@@ -66,8 +64,9 @@ const Vector3 DEFAULT_HANDLE_ONE_OFFSET(0.0f, -5.0f, 0.0f);                 ///<
 const Vector3 DEFAULT_HANDLE_TWO_OFFSET(0.0f, -5.0f, 0.0f);                 ///< Handle Two's Offset
 const float TOP_HANDLE_TOP_OFFSET( 34.0f);                                   ///< Offset between top handle and cutCopyPaste pop-up
 const float BOTTOM_HANDLE_BOTTOM_OFFSET(34.0f);                              ///< Offset between bottom handle and cutCopyPaste pop-up
-const float CURSOR_THICKNESS(6.0f);
+const float CURSOR_THICKNESS(4.0f);
 const Degree CURSOR_ANGLE_OFFSET(2.0f);                                     ///< Offset from the angle of italic angle.
+const Vector4 DEFAULT_CURSOR_COLOR(1.0f, 1.0f, 1.0f, 1.0f);
 
 const std::string NEWLINE( "\n" );
 
@@ -87,36 +86,6 @@ enum SelectionState
   SelectionFinished                         ///< Finished selected section
 };
 
-/**
- * Whether the given style is the default style or not.
- * @param[in] style The given style.
- * @return \e true if the given style is the default. Otherwise it returns \e false.
- */
-bool IsDefaultStyle( const TextStyle& style )
-{
-  return DEFAULT_TEXT_STYLE == style;
-}
-
-/**
- * Whether the given styled text is using the default style or not.
- * @param[in] textArray The given text.
- * @return \e true if the given styled text is using the default style. Otherwise it returns \e false.
- */
-bool IsTextDefaultStyle( const Toolkit::MarkupProcessor::StyledTextArray& textArray )
-{
-  for( Toolkit::MarkupProcessor::StyledTextArray::const_iterator it = textArray.begin(), endIt = textArray.end(); it != endIt; ++it )
-  {
-    const TextStyle& style( (*it).mStyle );
-
-    if( !IsDefaultStyle( style ) )
-    {
-      return false;
-    }
-  }
-
-  return true;
-}
-
 std::size_t FindVisibleCharacterLeft( std::size_t cursorPosition, const Toolkit::TextView::CharacterLayoutInfoContainer& characterLayoutInfoTable )
 {
   for( Toolkit::TextView::CharacterLayoutInfoContainer::const_reverse_iterator it = characterLayoutInfoTable.rbegin() + characterLayoutInfoTable.size() - cursorPosition, endIt = characterLayoutInfoTable.rend();
@@ -200,15 +169,20 @@ namespace Toolkit
 const Property::Index TextInput::HIGHLIGHT_COLOR_PROPERTY                     = Internal::TextInput::TEXTINPUT_PROPERTY_START_INDEX;
 const Property::Index TextInput::CUT_AND_PASTE_COLOR_PROPERTY                 = Internal::TextInput::TEXTINPUT_PROPERTY_START_INDEX+1;
 const Property::Index TextInput::CUT_AND_PASTE_PRESSED_COLOR_PROPERTY         = Internal::TextInput::TEXTINPUT_PROPERTY_START_INDEX+2;
+const Property::Index TextInput::CUT_AND_PASTE_BORDER_COLOR_PROPERTY          = Internal::TextInput::TEXTINPUT_PROPERTY_START_INDEX+3;
+const Property::Index TextInput::CUT_AND_PASTE_ICON_COLOR_PROPERTY            = Internal::TextInput::TEXTINPUT_PROPERTY_START_INDEX+4;
+const Property::Index TextInput::CUT_AND_PASTE_ICON_PRESSED_COLOR_PROPERTY    = Internal::TextInput::TEXTINPUT_PROPERTY_START_INDEX+5;
+const Property::Index TextInput::CUT_AND_PASTE_TEXT_COLOR_PROPERTY            = Internal::TextInput::TEXTINPUT_PROPERTY_START_INDEX+6;
+const Property::Index TextInput::CUT_AND_PASTE_TEXT_PRESSED_COLOR_PROPERTY    = Internal::TextInput::TEXTINPUT_PROPERTY_START_INDEX+7;
+const Property::Index TextInput::CUT_BUTTON_POSITION_PRIORITY_PROPERTY        = Internal::TextInput::TEXTINPUT_PROPERTY_START_INDEX+8;
+const Property::Index TextInput::COPY_BUTTON_POSITION_PRIORITY_PROPERTY       = Internal::TextInput::TEXTINPUT_PROPERTY_START_INDEX+9;
+const Property::Index TextInput::PASTE_BUTTON_POSITION_PRIORITY_PROPERTY      = Internal::TextInput::TEXTINPUT_PROPERTY_START_INDEX+10;
+const Property::Index TextInput::SELECT_BUTTON_POSITION_PRIORITY_PROPERTY     = Internal::TextInput::TEXTINPUT_PROPERTY_START_INDEX+11;
+const Property::Index TextInput::SELECT_ALL_BUTTON_POSITION_PRIORITY_PROPERTY = Internal::TextInput::TEXTINPUT_PROPERTY_START_INDEX+12;
+const Property::Index TextInput::CLIPBOARD_BUTTON_POSITION_PRIORITY_PROPERTY  = Internal::TextInput::TEXTINPUT_PROPERTY_START_INDEX+13;
+const Property::Index TextInput::POP_UP_OFFSET_FROM_TEXT_PROPERTY             = Internal::TextInput::TEXTINPUT_PROPERTY_START_INDEX+14;
+const Property::Index TextInput::CURSOR_COLOR_PROPERTY                        = Internal::TextInput::TEXTINPUT_PROPERTY_START_INDEX+15;
 
-const Property::Index TextInput::CUT_BUTTON_POSITION_PRIORITY_PROPERTY        = Internal::TextInput::TEXTINPUT_PROPERTY_START_INDEX+3;
-const Property::Index TextInput::COPY_BUTTON_POSITION_PRIORITY_PROPERTY       = Internal::TextInput::TEXTINPUT_PROPERTY_START_INDEX+4;
-const Property::Index TextInput::PASTE_BUTTON_POSITION_PRIORITY_PROPERTY      = Internal::TextInput::TEXTINPUT_PROPERTY_START_INDEX+5;
-const Property::Index TextInput::SELECT_BUTTON_POSITION_PRIORITY_PROPERTY     = Internal::TextInput::TEXTINPUT_PROPERTY_START_INDEX+6;
-const Property::Index TextInput::SELECT_ALL_BUTTON_POSITION_PRIORITY_PROPERTY = Internal::TextInput::TEXTINPUT_PROPERTY_START_INDEX+7;
-const Property::Index TextInput::CLIPBOARD_BUTTON_POSITION_PRIORITY_PROPERTY  = Internal::TextInput::TEXTINPUT_PROPERTY_START_INDEX+8;
-
-const Property::Index TextInput::POP_UP_OFFSET_FROM_TEXT_PROPERTY             = Internal::TextInput::TEXTINPUT_PROPERTY_START_INDEX+9;
 
 namespace Internal
 {
@@ -235,12 +209,19 @@ SignalConnectorType signalConnector6( typeRegistration, Toolkit::TextInput::SIGN
 PropertyRegistration property1( typeRegistration, "highlight-color",  Toolkit::TextInput::HIGHLIGHT_COLOR_PROPERTY, Property::VECTOR4, &TextInput::SetProperty, &TextInput::GetProperty );
 PropertyRegistration property2( typeRegistration, "cut-and-paste-bg-color",  Toolkit::TextInput::CUT_AND_PASTE_COLOR_PROPERTY, Property::VECTOR4, &TextInput::SetProperty, &TextInput::GetProperty );
 PropertyRegistration property3( typeRegistration, "cut-and-paste-pressed-color",  Toolkit::TextInput::CUT_AND_PASTE_PRESSED_COLOR_PROPERTY, Property::VECTOR4, &TextInput::SetProperty, &TextInput::GetProperty );
-PropertyRegistration property4( typeRegistration, "cut-button-position-priority",  Toolkit::TextInput::CUT_BUTTON_POSITION_PRIORITY_PROPERTY, Property::UNSIGNED_INTEGER, &TextInput::SetProperty, &TextInput::GetProperty );
-PropertyRegistration property5( typeRegistration, "copy-button-position-priority",  Toolkit::TextInput::COPY_BUTTON_POSITION_PRIORITY_PROPERTY, Property::UNSIGNED_INTEGER, &TextInput::SetProperty, &TextInput::GetProperty );
-PropertyRegistration property6( typeRegistration, "paste-button-position-priority",  Toolkit::TextInput::PASTE_BUTTON_POSITION_PRIORITY_PROPERTY, Property::UNSIGNED_INTEGER, &TextInput::SetProperty, &TextInput::GetProperty );
-PropertyRegistration property7( typeRegistration, "select-button-position-priority",  Toolkit::TextInput::SELECT_BUTTON_POSITION_PRIORITY_PROPERTY, Property::UNSIGNED_INTEGER, &TextInput::SetProperty, &TextInput::GetProperty );
-PropertyRegistration property8( typeRegistration, "select-all-button-position-priority",  Toolkit::TextInput::SELECT_ALL_BUTTON_POSITION_PRIORITY_PROPERTY, Property::UNSIGNED_INTEGER, &TextInput::SetProperty, &TextInput::GetProperty );
-PropertyRegistration property9( typeRegistration, "clipboard-button-position-priority",  Toolkit::TextInput::CLIPBOARD_BUTTON_POSITION_PRIORITY_PROPERTY, Property::UNSIGNED_INTEGER, &TextInput::SetProperty, &TextInput::GetProperty );
+PropertyRegistration property4( typeRegistration, "cut-and-paste-icon-color",  Toolkit::TextInput::CUT_AND_PASTE_ICON_COLOR_PROPERTY, Property::VECTOR4, &TextInput::SetProperty, &TextInput::GetProperty );
+PropertyRegistration property5( typeRegistration, "cut-and-paste-icon-pressed-color",  Toolkit::TextInput::CUT_AND_PASTE_ICON_PRESSED_COLOR_PROPERTY, Property::VECTOR4, &TextInput::SetProperty, &TextInput::GetProperty );
+PropertyRegistration property6( typeRegistration, "cut-and-paste-text-color",  Toolkit::TextInput::CUT_AND_PASTE_TEXT_COLOR_PROPERTY, Property::VECTOR4, &TextInput::SetProperty, &TextInput::GetProperty );
+PropertyRegistration property7( typeRegistration, "cut-and-paste-text-pressed-color",  Toolkit::TextInput::CUT_AND_PASTE_TEXT_PRESSED_COLOR_PROPERTY, Property::VECTOR4, &TextInput::SetProperty, &TextInput::GetProperty );
+PropertyRegistration property8( typeRegistration, "cut-and-paste-border-color",  Toolkit::TextInput::CUT_AND_PASTE_BORDER_COLOR_PROPERTY, Property::VECTOR4, &TextInput::SetProperty, &TextInput::GetProperty );
+PropertyRegistration property9( typeRegistration, "cut-button-position-priority",  Toolkit::TextInput::CUT_BUTTON_POSITION_PRIORITY_PROPERTY, Property::UNSIGNED_INTEGER, &TextInput::SetProperty, &TextInput::GetProperty );
+PropertyRegistration property10( typeRegistration, "copy-button-position-priority",  Toolkit::TextInput::COPY_BUTTON_POSITION_PRIORITY_PROPERTY, Property::UNSIGNED_INTEGER, &TextInput::SetProperty, &TextInput::GetProperty );
+PropertyRegistration property11( typeRegistration, "paste-button-position-priority",  Toolkit::TextInput::PASTE_BUTTON_POSITION_PRIORITY_PROPERTY, Property::UNSIGNED_INTEGER, &TextInput::SetProperty, &TextInput::GetProperty );
+PropertyRegistration property12( typeRegistration, "select-button-position-priority",  Toolkit::TextInput::SELECT_BUTTON_POSITION_PRIORITY_PROPERTY, Property::UNSIGNED_INTEGER, &TextInput::SetProperty, &TextInput::GetProperty );
+PropertyRegistration property13( typeRegistration, "select-all-button-position-priority",  Toolkit::TextInput::SELECT_ALL_BUTTON_POSITION_PRIORITY_PROPERTY, Property::UNSIGNED_INTEGER, &TextInput::SetProperty, &TextInput::GetProperty );
+PropertyRegistration property14( typeRegistration, "clipboard-button-position-priority",  Toolkit::TextInput::CLIPBOARD_BUTTON_POSITION_PRIORITY_PROPERTY, Property::UNSIGNED_INTEGER, &TextInput::SetProperty, &TextInput::GetProperty );
+PropertyRegistration property15( typeRegistration, "popup-offset-from-text", Toolkit::TextInput::POP_UP_OFFSET_FROM_TEXT_PROPERTY, Property::VECTOR4, &TextInput::SetProperty, &TextInput::GetProperty );
+PropertyRegistration property16( typeRegistration, "cursor-color", Toolkit::TextInput::CURSOR_COLOR_PROPERTY, Property::VECTOR4, &TextInput::SetProperty, &TextInput::GetProperty );
 
 
 // [TextInput::HighlightInfo] /////////////////////////////////////////////////
@@ -270,9 +251,9 @@ Dali::Toolkit::TextInput TextInput::New()
   TextInputPtr textInput(new TextInput());
   // Pass ownership to CustomActor via derived handle
   Dali::Toolkit::TextInput handle(*textInput);
+  handle.SetName( "TextInput");
 
   textInput->Initialize();
-
   return handle;
 }
 
@@ -303,7 +284,7 @@ TextInput::TextInput()
  mTouchStartTime( 0 ),
  mTextLayoutInfo(),
  mCurrentCopySelecton(),
- mPopUpPanel(),
+ mPopupPanel(),
  mScrollTimer(),
  mScrollDisplacement(),
  mCurrentHandlePosition(),
@@ -785,9 +766,6 @@ void TextInput::SetBoundingRectangle( const Rect<float>& boundingRectangle )
                           originY + boundingRectangle.height );
 
   mBoundingRectangleWorldCoordinates = boundary;
-
-  // Set Boundary for Popup so it keeps the Pop-up within the area also.
-  mPopUpPanel.SetPopupBoundary( boundingRectangle );
 }
 
 const Rect<float> TextInput::GetBoundingRectangle() const
@@ -1064,13 +1042,10 @@ void TextInput::OnKeyInputFocusGained()
   mClipboard = Clipboard::Get(); // Store handle to clipboard
 
   // Now in edit mode we can accept string to paste from clipboard
-  if( Adaptor::IsAvailable() )
+  ClipboardEventNotifier notifier( ClipboardEventNotifier::Get() );
+  if ( notifier )
   {
-    ClipboardEventNotifier notifier( ClipboardEventNotifier::Get() );
-    if ( notifier )
-    {
-      notifier.ContentSelectedSignal().Connect( this, &TextInput::OnClipboardTextSelected );
-    }
+    notifier.ContentSelectedSignal().Connect( this, &TextInput::OnClipboardTextSelected );
   }
 }
 
@@ -1114,19 +1089,16 @@ void TextInput::OnKeyInputFocusLost()
 
   mClipboard.Reset();
   // No longer in edit mode so do not want to receive string from clipboard
-  if( Adaptor::IsAvailable() )
+  ClipboardEventNotifier notifier( ClipboardEventNotifier::Get() );
+  if ( notifier )
   {
-    ClipboardEventNotifier notifier( ClipboardEventNotifier::Get() );
-    if ( notifier )
-    {
-      notifier.ContentSelectedSignal().Disconnect( this, &TextInput::OnClipboardTextSelected );
-    }
-    Clipboard clipboard = Clipboard::Get();
+    notifier.ContentSelectedSignal().Disconnect( this, &TextInput::OnClipboardTextSelected );
+  }
 
-    if ( clipboard )
-    {
-      clipboard.HideClipboard();
-    }
+  Clipboard clipboard = Clipboard::Get();
+  if ( clipboard )
+  {
+    clipboard.HideClipboard();
   }
 }
 
@@ -1144,6 +1116,7 @@ void TextInput::CreateActiveLayer()
 {
   Actor self = Self();
   mActiveLayer = Layer::New();
+  mActiveLayer.SetName ( "ActiveLayerActor" );
 
   mActiveLayer.SetAnchorPoint( AnchorPoint::CENTER);
   mActiveLayer.SetParentOrigin( ParentOrigin::CENTER);
@@ -1161,9 +1134,8 @@ void TextInput::OnInitialize()
 
   // Create 2 cursors (standard LTR and RTL cursor for when text can be added at
   // different positions depending on language)
-  Image mCursorImage = Image::New( DEFAULT_CURSOR );
-  mCursor = CreateCursor( mCursorImage, DEFAULT_CURSOR_IMAGE_9_BORDER );
-  mCursorRTL = CreateCursor( mCursorImage, DEFAULT_CURSOR_IMAGE_9_BORDER );
+  mCursor = CreateCursor(DEFAULT_CURSOR_COLOR);
+  mCursorRTL = CreateCursor(DEFAULT_CURSOR_COLOR);
 
   Actor self = Self();
   self.Add( mCursor );
@@ -1188,6 +1160,8 @@ void TextInput::OnControlSizeSet(const Vector3& targetSize)
 void TextInput::OnRelaidOut( Vector2 size, ActorSizeContainer& container )
 {
   Relayout( mDisplayedTextView, size, container );
+  Relayout( mPopupPanel.GetRootActor(), size, container );
+
   GetTextLayoutInfo();
 
   DrawCursor();
@@ -1270,7 +1244,7 @@ void TextInput::OnHandlePan(Actor actor, PanGesture gesture)
       {
         mActualGrabHandlePosition = MoveGrabHandle( gesture.displacement );
         SetCursorVisibility( true );
-        SetUpPopUpSelection();
+        SetUpPopupSelection();
         ShowPopup();
       }
       if (actor == mHandleOneGrabArea)
@@ -1378,6 +1352,12 @@ void TextInput::OnDoubleTap(Dali::Actor actor, Dali::TapGesture tap)
      mTextLayoutInfo.mScrollOffset = mDisplayedTextView.GetScrollPosition();
      ReturnClosestIndex( tap.localPoint, mCursorPosition );
 
+     std::size_t start = 0;
+     std::size_t end = 0;
+     Dali::Toolkit::Internal::TextProcessor::FindNearestWord( mStyledText, mCursorPosition, start, end );
+
+     mCursorPosition = end; // Ensure cursor is positioned at end of selected word
+
      ImfManager imfManager = ImfManager::Get();
      if ( imfManager )
      {
@@ -1385,14 +1365,20 @@ void TextInput::OnDoubleTap(Dali::Actor actor, Dali::TapGesture tap)
        imfManager.NotifyCursorPosition();
      }
 
-     std::size_t start = 0;
-     std::size_t end = 0;
-     Dali::Toolkit::Internal::TextProcessor::FindNearestWord( mStyledText, mCursorPosition, start, end );
-
-     SelectText( start, end );
+     if ( !mStyledText.at(end-1).mText[0].IsWhiteSpace() )
+     {
+       SelectText( start, end );
+       ShowPopupCutCopyPaste();
+     }
+     else
+     {
+       RemoveHighlight( false ); // Remove highlight but do not auto hide popup
+       HidePopup( false ); // Hide popup with setting to do auto show.
+       SetUpPopupSelection( false ); // Set to false so if nearest word is whitespace it will not show cut button.
+       ShowPopup();
+     }
    }
-   // if no text but clipboard has content then show paste option
-   if ( ( mClipboard && mClipboard.NumberOfItems() ) || !mStyledText.empty() )
+   else if ( mClipboard && mClipboard.NumberOfItems() )
    {
      ShowPopupCutCopyPaste();
    }
@@ -1414,9 +1400,9 @@ void TextInput::OnTextTap(Dali::Actor actor, Dali::TapGesture tap)
 
   if( mGrabArea == actor )
   {
-    if( mPopUpPanel.GetState() == TextInputPopup::StateHidden || mPopUpPanel.GetState() == TextInputPopup::StateHiding )
+    if( mPopupPanel.GetState() == TextInputPopup::StateHidden || mPopupPanel.GetState() == TextInputPopup::StateHiding )
     {
-      SetUpPopUpSelection();
+      SetUpPopupSelection();
       ShowPopup();
     }
 
@@ -1441,26 +1427,6 @@ void TextInput::OnTextTap(Dali::Actor actor, Dali::TapGesture tap)
     {
       // Set the initial cursor position in the tap point.
       ReturnClosestIndex(tap.localPoint, mCursorPosition );
-
-      // Create the grab handle.
-      // TODO Make this a re-usable function.
-      if ( IsGrabHandleEnabled() )
-      {
-        const Vector3 cursorPosition = GetActualPositionFromCharacterPosition(mCursorPosition);
-
-        CreateGrabHandle();
-
-        mActualGrabHandlePosition.x = cursorPosition.x; // Set grab handle to be at the cursor position
-        mActualGrabHandlePosition.y = cursorPosition.y; // Set grab handle to be at the cursor position
-        mGrabHandle.SetPosition( mActualGrabHandlePosition + UI_OFFSET );
-        ShowGrabHandleAndSetVisibility( mIsGrabHandleInScrollArea );
-
-      }
-
-      // Edit mode started after grab handle created to ensure the signal InputStarted is sent last.
-      // This is used to ensure if selecting text hides the grab handle then this code is run after grab handle is created,
-      // otherwise the Grab handle will be shown when selecting.
-
       StartEditMode();
     }
   }
@@ -1514,6 +1480,9 @@ void TextInput::OnTextTap(Dali::Actor actor, Dali::TapGesture tap)
     }
   }
 
+  // Edit mode started after grab handle created to ensure the signal InputStarted is sent last.
+  // This is used to ensure if selecting text hides the grab handle then this code is run after grab handle is created,
+  // otherwise the Grab handle will be shown when selecting.
   if ( createGrabHandle && IsGrabHandleEnabled() )
   {
     const Vector3 cursorPosition = GetActualPositionFromCharacterPosition(mCursorPosition);
@@ -1532,6 +1501,12 @@ void TextInput::OnLongPress(Dali::Actor actor, Dali::LongPressGesture longPress)
 {
   DALI_LOG_INFO( gLogFilter, Debug::General, "OnLongPress\n" );
 
+  // Ignore longpress if in selection mode already
+  if( mHighlightMeshActor )
+  {
+    return;
+  }
+
   if(longPress.state == Dali::Gesture::Started)
   {
     // Start edit mode on long press
@@ -1568,15 +1543,18 @@ void TextInput::OnLongPress(Dali::Actor actor, Dali::LongPressGesture longPress)
       mTextLayoutInfo.mScrollOffset = mDisplayedTextView.GetScrollPosition();
       ReturnClosestIndex( longPress.localPoint, mCursorPosition );
 
+      std::size_t start = 0;
+      std::size_t end = 0;
+      Dali::Toolkit::Internal::TextProcessor::FindNearestWord( mStyledText, mCursorPosition, start, end );
+
+      mCursorPosition  = end; // Ensure cursor is positioned at end of selected word
+
       ImfManager imfManager = ImfManager::Get();
       if ( imfManager )
       {
         imfManager.SetCursorPosition ( mCursorPosition );
         imfManager.NotifyCursorPosition();
       }
-      std::size_t start = 0;
-      std::size_t end = 0;
-      Dali::Toolkit::Internal::TextProcessor::FindNearestWord( mStyledText, mCursorPosition, start, end );
 
       SelectText( start, end );
     }
@@ -1605,7 +1583,7 @@ void TextInput::OnClipboardTextSelected( ClipboardEventNotifier& notifier )
 
 bool TextInput::OnPopupButtonPressed( Toolkit::Button button )
 {
-  mPopUpPanel.PressedSignal().Disconnect( this, &TextInput::OnPopupButtonPressed );
+  mPopupPanel.PressedSignal().Disconnect( this, &TextInput::OnPopupButtonPressed );
 
   const std::string& name = button.GetName();
 
@@ -1735,11 +1713,9 @@ bool TextInput::OnKeyDownEvent(const KeyEvent& event)
     {
       bool preEditFlagPreviouslySet( mPreEditFlag );
 
-      if (mHighlightMeshActor)
-      {
-        // replaces highlighted text with new line
-        DeleteHighlightedText( false );
-      }
+      // replaces highlighted text with new line
+      DeleteHighlightedText( false );
+
       mCursorPosition = mCursorPosition + InsertAt( Text( NEWLINE ), mCursorPosition, 0 );
 
       // If we are in pre-edit mode then pressing enter will cause a commit.  But the commit string does not include the
@@ -1816,15 +1792,11 @@ bool TextInput::OnKeyDownEvent(const KeyEvent& event)
     // Some text may be selected, hiding keyboard causes an empty keystring to be sent, we don't want to delete highlight in this case
     if ( !keyString.empty() )
     {
-      if ( mHighlightMeshActor )
-      {
-        // replaces highlighted text with new character
-        DeleteHighlightedText( false );
-      }
-
+      // replaces highlighted text with new character
+      DeleteHighlightedText( false );
 
       // Received key String
-      mCursorPosition = mCursorPosition + InsertAt( Text( keyString ), mCursorPosition, 0 );
+      mCursorPosition += InsertAt( Text( keyString ), mCursorPosition, 0 );
       update = true;
       EmitTextModified();
     }
@@ -1942,11 +1914,7 @@ void TextInput::ScrollTextViewToMakeCursorVisible( const Vector3& cursorPosition
     scrollOffset.x += cursorPosition.x;
   }
 
-  if( cursorPosition.y - cursorSize.height < 0.f )
-  {
-    scrollOffset.y += ( cursorPosition.y - cursorSize.height );
-  }
-  else if( cursorPosition.y > controlSize.height )
+  if( cursorPosition.y - cursorSize.height < 0.f || cursorPosition.y > controlSize.height )
   {
     scrollOffset.y += cursorPosition.y;
   }
@@ -2071,6 +2039,7 @@ void TextInput::SetUpTouchEvents()
 void TextInput::CreateTextViewActor()
 {
   mDisplayedTextView = Toolkit::TextView::New();
+  mDisplayedTextView.SetName( "DisplayedTextView ");
   mDisplayedTextView.SetMarkupProcessingEnabled( mMarkUpEnabled );
   mDisplayedTextView.SetParentOrigin(ParentOrigin::TOP_LEFT);
   mDisplayedTextView.SetAnchorPoint(AnchorPoint::TOP_LEFT);
@@ -2258,7 +2227,7 @@ ImfManager::ImfCallbackData TextInput::ImfEventReceived( Dali::ImfManager& imfMa
       }
       else
       {
-        if( std::abs( imfEvent.cursorOffset ) < mCursorPosition )
+        if( static_cast<std::size_t>(std::abs( imfEvent.cursorOffset )) < mCursorPosition )
         {
           toDelete = mCursorPosition + imfEvent.cursorOffset;
         }
@@ -2574,7 +2543,7 @@ void TextInput::DeleteHighlightedText( bool inheritStyle )
 {
   DALI_LOG_INFO( gLogFilter, Debug::General, "DeleteHighlightedText handlePosOne[%u] handlePosTwo[%u]\n", mSelectionHandleOnePosition, mSelectionHandleTwoPosition);
 
-  if(mHighlightMeshActor)
+  if( mHighlightMeshActor )
   {
     mCursorPosition = std::min( mSelectionHandleOnePosition, mSelectionHandleTwoPosition );
 
@@ -2630,6 +2599,8 @@ void TextInput::DeleteHighlightedText( bool inheritStyle )
 
     RemoveHighlight();
 
+    EmitTextModified();
+
     if( inheritStyle )
     {
       const TextStyle oldInputStyle( mInputStyle );
@@ -2815,24 +2786,14 @@ std::size_t TextInput::InsertAt( const Text& newText, const std::size_t insertio
   return insertedStringLength;
 }
 
-ImageActor TextInput::CreateCursor( Image cursorImage, const Vector4& border )
+ImageActor TextInput::CreateCursor( const Vector4& color)
 {
   ImageActor cursor;
-
-  if ( cursorImage )
-  {
-    cursor = ImageActor::New( cursorImage );
-  }
-  else
-  {
-    cursor = ImageActor::New( Image::New( DEFAULT_CURSOR ) );
-  }
-
-  cursor.SetStyle(ImageActor::STYLE_NINE_PATCH);
-  cursor.SetNinePatchBorder( border );
+  cursor = CreateSolidColorActor(color);
+  cursor.SetName( "Cursor" );
 
   cursor.SetParentOrigin(ParentOrigin::TOP_LEFT);
-  cursor.SetAnchorPoint(AnchorPoint::BOTTOM_CENTER);
+  cursor.SetAnchorPoint(AnchorPoint::BOTTOM_LEFT);
   cursor.SetVisible(false);
 
   return cursor;
@@ -2891,7 +2852,7 @@ void TextInput::DrawCursor(const std::size_t nthChar)
 {
   // Get height of cursor and set its size
   Size size( CURSOR_THICKNESS, 0.0f );
-  if (!mTextLayoutInfo.mCharacterLayoutInfoTable.empty())
+  if( !mTextLayoutInfo.mCharacterLayoutInfoTable.empty() )
   {
     size.height = GetRowRectFromCharacterPosition( GetVisualPosition( mCursorPosition ) ).height;
   }
@@ -2985,11 +2946,13 @@ void TextInput::CreateGrabHandle( Dali::Image image )
 void TextInput::CreateGrabArea( Actor& parent )
 {
   mGrabArea = Actor::New(); // Area that Grab handle responds to, larger than actual handle so easier to move
+  mGrabArea.SetName( "GrabArea" );
   mGrabArea.SetPositionInheritanceMode( Dali::USE_PARENT_POSITION );
   mGrabArea.ApplyConstraint( Constraint::New<Vector3>( Actor::SIZE, ParentSource( Actor::SIZE ), RelativeToConstraint( DEFAULT_GRAB_HANDLE_RELATIVE_SIZE ) ) );  // grab area to be larger than text actor
   mGrabArea.TouchedSignal().Connect(this,&TextInput::OnPressDown);
   mTapDetector.Attach( mGrabArea );
   mPanGestureDetector.Attach( mGrabArea );
+  mLongPressDetector.Attach( mGrabArea );
 
   parent.Add(mGrabArea);
 }
@@ -3499,7 +3462,7 @@ TextInput::HighlightInfo TextInput::CalculateHighlightInfo()
           // TODO: TextView should have a table of visual rows, and each character a reference to the row
           // that it resides on. That way this enumeration is not necessary.
           Vector2 min, max;
-          if(lastIt->mIsNewLineChar)
+          if(lastIt->mIsNewParagraphChar)
           {
             // If the last character is a new line, then to get the row rect, we need to scan from the character before the new line.
             lastIt = std::max( mTextLayoutInfo.mCharacterLayoutInfoTable.begin(), lastIt - 1 );
@@ -3546,7 +3509,7 @@ TextInput::HighlightInfo TextInput::CalculateHighlightInfo()
       {
         // finished selection.
         Vector2 min, max;
-        if(lastIt->mIsNewLineChar)
+        if(lastIt->mIsNewParagraphChar)
         {
           lastIt = std::max( mTextLayoutInfo.mCharacterLayoutInfoTable.begin(), lastIt - 1 );
         }
@@ -3695,65 +3658,102 @@ void TextInput::UpdateHighlight()
 
 void TextInput::ClearPopup()
 {
-  mPopUpPanel.Clear();
+  mPopupPanel.Clear();
 }
 
 void TextInput::AddPopupOptions()
 {
-  mPopUpPanel.AddPopupOptions();
+  mPopupPanel.AddPopupOptions();
 }
 
-void TextInput::SetPopupPosition(const Vector3& position)
+void TextInput::SetPopupPosition( const Vector3& position, const Vector2& alternativePosition )
 {
-  mPopUpPanel.Self().SetPosition( position );
-  mPopUpPanel.SetTailPosition( position );
+  const Vector3& visiblePopUpSize = mPopupPanel.GetVisibileSize();
+
+  Vector3 clampedPosition ( position );
+  Vector3 tailOffsetPosition ( position );
+
+  float xOffSet( 0.0f );
+
+  Actor self = Self();
+  const Vector3 textViewTopLeftWorldPosition = self.GetCurrentWorldPosition() - self.GetCurrentSize()*0.5f;
+
+  const float popUpLeft = textViewTopLeftWorldPosition.x + position.x - visiblePopUpSize.width*0.5f;
+  const float popUpTop = textViewTopLeftWorldPosition.y + position.y - visiblePopUpSize.height;
+
+  // Clamp to left or right or of boundary
+  if( popUpLeft < mBoundingRectangleWorldCoordinates.x )
+  {
+    xOffSet = mBoundingRectangleWorldCoordinates.x - popUpLeft ;
+  }
+  else if ( popUpLeft + visiblePopUpSize.width > mBoundingRectangleWorldCoordinates.z )
+  {
+    xOffSet = mBoundingRectangleWorldCoordinates.z - ( popUpLeft + visiblePopUpSize.width );
+  }
+
+  clampedPosition.x = position.x + xOffSet;
+  tailOffsetPosition.x = -xOffSet;
+
+  // Check if top left of PopUp outside of top bounding rectangle, if so then flip to lower position.
+  bool flipTail( false );
+
+  if ( popUpTop < mBoundingRectangleWorldCoordinates.y )
+  {
+    clampedPosition.y = alternativePosition.y + visiblePopUpSize.height;
+    flipTail = true;
+  }
+
+  mPopupPanel.GetRootActor().SetPosition( clampedPosition );
+  mPopupPanel.SetTailPosition( tailOffsetPosition, flipTail );
 }
 
 void TextInput::HidePopup(bool animate, bool signalFinished )
 {
-  if ( ( mPopUpPanel.GetState() == TextInputPopup::StateShowing ) || ( mPopUpPanel.GetState() == TextInputPopup::StateShown )  )
+  if ( ( mPopupPanel.GetState() == TextInputPopup::StateShowing ) || ( mPopupPanel.GetState() == TextInputPopup::StateShown )  )
   {
-    mPopUpPanel.Hide( animate );
+    mPopupPanel.Hide( animate );
 
     if( animate && signalFinished )
     {
-      mPopUpPanel.HideFinishedSignal().Connect( this, &TextInput::OnPopupHideFinished );
+      mPopupPanel.HideFinishedSignal().Connect( this, &TextInput::OnPopupHideFinished );
     }
   }
 }
 
-void TextInput::ShowPopup(bool animate)
+void TextInput::ShowPopup( bool animate )
 {
   Vector3 position;
+  Vector2 alternativePopupPosition;
 
   if(mHighlightMeshActor && mState == StateEdit)
   {
     Vector3 topHandle;
+    Vector3 bottomHandle; // referring to the bottom most point of the handle or the bottom line of selection.
     Size rowSize;
     // When text is selected, show popup above top handle (and text), or below bottom handle.
     // topHandle: referring to the top most point of the handle or the top line of selection.
     if ( mSelectionHandleTwoActualPosition.y > mSelectionHandleOneActualPosition.y )
     {
       topHandle = mSelectionHandleOneActualPosition;
+      bottomHandle = mSelectionHandleTwoActualPosition;
       rowSize= GetRowRectFromCharacterPosition( mSelectionHandleOnePosition );
     }
     else
     {
       topHandle = mSelectionHandleTwoActualPosition;
+      bottomHandle = mSelectionHandleOneActualPosition;
       rowSize = GetRowRectFromCharacterPosition( mSelectionHandleTwoPosition );
     }
     topHandle.y += -mPopupOffsetFromText.y - rowSize.height;
     position = Vector3(topHandle.x, topHandle.y, 0.0f);
 
-    // bottomHandle: referring to the bottom most point of the handle or the bottom line of selection.
-    Vector3 bottomHandle;
-    bottomHandle.y = std::max ( mSelectionHandleTwoActualPosition.y , mSelectionHandleOneActualPosition.y );
-    bottomHandle.y += GetSelectionHandleSize().y + mPopupOffsetFromText.w;
-    mPopUpPanel.SetAlternativeOffset(Vector2( mBoundingRectangleWorldCoordinates.x, bottomHandle.y - topHandle.y));
-
-    float xPosition = ( fabsf( topHandle.x - bottomHandle.x ) )*0.5f + std::min( topHandle.x , bottomHandle.x );
+    float xPosition = ( fabsf( topHandle.x - bottomHandle.x ) )*0.5f + std::min( mSelectionHandleOneActualPosition.x , mSelectionHandleTwoActualPosition.x );
 
     position.x = xPosition;
+
+    // Alternative position if no upper space
+    bottomHandle.y += GetSelectionHandleSize().y + mPopupOffsetFromText.w;
+    alternativePopupPosition = Vector2 ( position.x, bottomHandle.y );
   }
   else
   {
@@ -3762,81 +3762,73 @@ void TextInput::ShowPopup(bool animate)
     const Size rowSize = GetRowRectFromCharacterPosition( mCursorPosition );
     position.y -= ( mPopupOffsetFromText.y + rowSize.height );
     // if can't be positioned above, then position below row.
-    Vector2 alternativePopUpPosition( mBoundingRectangleWorldCoordinates.x, position.y ); // default if no grab handle
+    alternativePopupPosition = Vector2( position.x, position.y ); // default if no grab handle
     if ( mGrabHandle )
     {
       // If grab handle enabled then position pop-up below the grab handle.
-      alternativePopUpPosition.y = rowSize.height + mGrabHandle.GetCurrentSize().height + mPopupOffsetFromText.w +50.0f;
+      alternativePopupPosition.y = rowSize.height + mGrabHandle.GetCurrentSize().height + mPopupOffsetFromText.w +50.0f;
     }
-    mPopUpPanel.SetAlternativeOffset( alternativePopUpPosition );
   }
 
-  // reposition popup above the desired cursor posiiton.
-  Vector3 textViewSize = mDisplayedTextView.GetCurrentSize();
-  textViewSize.z = 0.0f;
-  // World position = world position of local position i.e. top-left corner of TextView
-  Vector3 worldPosition = mDisplayedTextView.GetCurrentWorldPosition() - ( textViewSize * 0.5f ) + position;
-
-  SetPopupPosition( worldPosition );
+  SetPopupPosition( position, alternativePopupPosition );
 
   // Show popup
-  mPopUpPanel.Show(animate);
+  mPopupPanel.Show( Self(), animate );
   StartMonitoringStageForTouch();
 
-  mPopUpPanel.PressedSignal().Connect( this, &TextInput::OnPopupButtonPressed );
+  mPopupPanel.PressedSignal().Connect( this, &TextInput::OnPopupButtonPressed );
 }
 
 void TextInput::ShowPopupCutCopyPaste()
 {
   ClearPopup();
 
-  mPopUpPanel.CreateOrderedListOfOptions(); // todo Move this so only run when order has changed
+  mPopupPanel.CreateOrderedListOfOptions(); // todo Move this so only run when order has changed
   // Check the selected text is whole text or not.
   if( IsTextSelected() && ( mStyledText.size() != GetSelectedText().size() ) )
   {
-    mPopUpPanel.TogglePopUpButtonOnOff( TextInputPopup::ButtonsSelectAll, true );
+    mPopupPanel.TogglePopupButtonOnOff( TextInputPopup::ButtonsSelectAll, true );
   }
 
   if ( !mStyledText.empty() )
   {
-
-    mPopUpPanel.TogglePopUpButtonOnOff( TextInputPopup::ButtonsCopy, true );
-    mPopUpPanel.TogglePopUpButtonOnOff( TextInputPopup::ButtonsCut, true );
+    mPopupPanel.TogglePopupButtonOnOff( TextInputPopup::ButtonsCopy, true );
+    mPopupPanel.TogglePopupButtonOnOff( TextInputPopup::ButtonsCut, true );
   }
 
   if( mClipboard && mClipboard.NumberOfItems() )
   {
-    mPopUpPanel.TogglePopUpButtonOnOff( TextInputPopup::ButtonsPaste, true );
-    mPopUpPanel.TogglePopUpButtonOnOff( TextInputPopup::ButtonsClipboard, true );
+    mPopupPanel.TogglePopupButtonOnOff( TextInputPopup::ButtonsPaste, true );
+    mPopupPanel.TogglePopupButtonOnOff( TextInputPopup::ButtonsClipboard, true );
   }
 
   AddPopupOptions();
 
-  mPopUpPanel.Hide(false);
+  mPopupPanel.Hide(false);
   ShowPopup();
 }
 
-void TextInput::SetUpPopUpSelection()
+void TextInput::SetUpPopupSelection( bool showCutButton )
 {
   ClearPopup();
-  mPopUpPanel.CreateOrderedListOfOptions(); // todo Move this so only run when order has changed
+  mPopupPanel.CreateOrderedListOfOptions(); // todo Move this so only run when order has changed
   // If no text exists then don't offer to select
   if ( !mStyledText.empty() )
   {
-    mPopUpPanel.TogglePopUpButtonOnOff( TextInputPopup::ButtonsSelectAll, true );
-    mPopUpPanel.TogglePopUpButtonOnOff( TextInputPopup::ButtonsSelect, true );
-    mPopUpPanel.TogglePopUpButtonOnOff( TextInputPopup::ButtonsCut, true );
+    mPopupPanel.TogglePopupButtonOnOff( TextInputPopup::ButtonsSelectAll, true );
+    mPopupPanel.TogglePopupButtonOnOff( TextInputPopup::ButtonsSelect, true );
+    mPopupPanel.TogglePopupButtonOnOff( TextInputPopup::ButtonsCut, showCutButton );
   }
   // if clipboard has valid contents then offer paste option
   if( mClipboard && mClipboard.NumberOfItems() )
   {
-    mPopUpPanel.TogglePopUpButtonOnOff( TextInputPopup::ButtonsPaste, true );
-    mPopUpPanel.TogglePopUpButtonOnOff( TextInputPopup::ButtonsClipboard, true );
+    mPopupPanel.TogglePopupButtonOnOff( TextInputPopup::ButtonsPaste, true );
+    mPopupPanel.TogglePopupButtonOnOff( TextInputPopup::ButtonsClipboard, true );
   }
 
   AddPopupOptions();
 
-  mPopUpPanel.Hide(false);
+  mPopupPanel.Hide(false);
 }
 
 bool TextInput::ReturnClosestIndex(const Vector2& source, std::size_t& closestIndex )
@@ -3883,7 +3875,7 @@ bool TextInput::ReturnClosestIndex(const Vector2& source, std::size_t& closestIn
         if( fabsf( closestYdifference - currentYdifference )  < CHARACTER_THRESHOLD )
         {
           // ignore new line character.
-          if( !info.mIsNewLineChar )
+          if( !info.mIsNewParagraphChar )
           {
             matchedCharacters.push_back( info );
             numberOfMatchedCharacters++;
@@ -3897,7 +3889,7 @@ bool TextInput::ReturnClosestIndex(const Vector2& source, std::size_t& closestIn
     // and check if user is touching below previous line.
     const Toolkit::TextView::CharacterLayoutInfo& lastInfo( mTextLayoutInfo.mCharacterLayoutInfoTable[mTextLayoutInfo.mCharacterLayoutInfoTable.size() - 1] );
 
-    if( ( lastInfo.mIsVisible ) && ( lastInfo.mIsNewLineChar ) && ( sourceScrollOffset.y > lastInfo.mPosition.y ) )
+    if( ( lastInfo.mIsVisible ) && ( lastInfo.mIsNewParagraphChar ) && ( sourceScrollOffset.y > lastInfo.mPosition.y ) )
     {
       closestIndex = mTextLayoutInfo.mCharacterLayoutInfoTable.size();
     }
@@ -4155,7 +4147,7 @@ Vector3 TextInput::GetActualPositionFromCharacterPosition(std::size_t characterP
       }
 
       Toolkit::TextView::CharacterLayoutInfo info = mTextLayoutInfo.mCharacterLayoutInfoTable[ visualCharacterPosition ];
-      if( ( visualCharacterPosition > 0 ) && info.mIsNewLineChar && !IsScrollEnabled() )
+      if( ( visualCharacterPosition > 0 ) && info.mIsNewParagraphChar && !IsScrollEnabled() )
       {
         // Prevents the cursor to exceed the boundary if the last visible character is a 'new line character' and the scroll is not enabled.
         const Vector3& size = GetControlSize();
@@ -4167,7 +4159,7 @@ Vector3 TextInput::GetActualPositionFromCharacterPosition(std::size_t characterP
         info = mTextLayoutInfo.mCharacterLayoutInfoTable[ visualCharacterPosition ];
       }
 
-      if(!info.mIsNewLineChar)
+      if(!info.mIsNewParagraphChar)
       {
         cursorPosition = PositionCursorAfterWordWrap( characterPosition ); // Get position of cursor/handles taking in account auto word wrap.
       }
@@ -4215,7 +4207,7 @@ Vector3 TextInput::GetActualPositionFromCharacterPosition(std::size_t characterP
       // between RTL and LTR text...
       if(characterPosition != mTextLayoutInfo.mCharacterLogicalToVisualMap.size())
       {
-        std::size_t visualCharacterAltPosition = mTextLayoutInfo.mCharacterLogicalToVisualMap[characterPosition] - 1;
+        std::size_t visualCharacterAltPosition = mTextLayoutInfo.mCharacterLogicalToVisualMap[characterPosition]; // VCC TODO: find why in the previous patch it was a -1 here.
 
         DALI_ASSERT_ALWAYS(visualCharacterAltPosition < mTextLayoutInfo.mCharacterLayoutInfoTable.size());
         const Toolkit::TextView::CharacterLayoutInfo& infoAlt = mTextLayoutInfo.mCharacterLayoutInfoTable[ visualCharacterAltPosition ];
@@ -4367,7 +4359,7 @@ std::size_t TextInput::GetRowStartFromCharacterPosition(std::size_t logicalPosit
   {
     logicalPosition--;
     std::size_t visualPosition = GetVisualPosition(logicalPosition);
-    if(mTextLayoutInfo.mCharacterLayoutInfoTable[visualPosition].mIsNewLineChar)
+    if(mTextLayoutInfo.mCharacterLayoutInfoTable[visualPosition].mIsNewParagraphChar)
     {
       logicalPosition++;
       break;
@@ -4437,7 +4429,7 @@ Size TextInput::GetRowRectFromCharacterPosition(std::size_t characterPosition, V
     --it;
 
     if( (it->mPosition.y < referenceLine) ||
-        (it->mIsNewLineChar) ||
+        (it->mIsNewParagraphChar) ||
         (!it->mIsVisible) )
     {
       break;
@@ -4454,7 +4446,7 @@ Size TextInput::GetRowRectFromCharacterPosition(std::size_t characterPosition, V
   while(it != end)
   {
     if( (it->mPosition.y > referenceLine) ||
-        (it->mIsNewLineChar) ||
+        (it->mIsNewParagraphChar) ||
         (!it->mIsVisible) )
     {
       break;
@@ -4480,7 +4472,7 @@ Size TextInput::GetRowRectFromCharacterPosition(std::size_t characterPosition, V
 
 bool TextInput::WasTouchedCheck( const Actor& touchedActor ) const
 {
-  Actor popUpPanel = mPopUpPanel.GetRootActor();
+  Actor popUpPanel = mPopupPanel.GetRootActor();
 
   if ( ( touchedActor == Self() ) || ( touchedActor == popUpPanel ) )
   {
@@ -4521,7 +4513,7 @@ void TextInput::OnStageTouched(const TouchEvent& event)
 
       bool popUpShown( false );
 
-      if ( ( mPopUpPanel.GetState() == TextInputPopup::StateShowing ) || ( mPopUpPanel.GetState() == TextInputPopup::StateShown ) )
+      if ( ( mPopupPanel.GetState() == TextInputPopup::StateShowing ) || ( mPopupPanel.GetState() == TextInputPopup::StateShown ) )
       {
         popUpShown = true;
       }
@@ -4558,16 +4550,7 @@ void TextInput::SelectText(std::size_t start, std::size_t end)
     // When replacing highlighted text keyboard should ignore current word at cursor hence notify keyboard that the cursor is at the start of the highlight.
     mSelectingText = true;
 
-    mCursorPosition = std::min( start, end ); // Set cursor position to start of highlighted text.
-
-    ImfManager imfManager = ImfManager::Get();
-    if ( imfManager )
-    {
-      imfManager.SetCursorPosition ( mCursorPosition );
-      imfManager.SetSurroundingText( GetText() );
-      imfManager.NotifyCursorPosition();
-    }
-    // As the imfManager has been notified of the new cursor position we do not need to reset the pre-edit as it will be updated instead.
+    std::size_t selectionStartPosition = std::min( start, end );
 
     // Hide grab handle when selecting.
     ShowGrabHandleAndSetVisibility( false );
@@ -4581,7 +4564,7 @@ void TextInput::SelectText(std::size_t start, std::size_t end)
       UpdateHighlight();
 
       const TextStyle oldInputStyle( mInputStyle );
-      mInputStyle = GetStyleAt( mCursorPosition ); // Inherit style from selected position.
+      mInputStyle = GetStyleAt( selectionStartPosition ); // Inherit style from selected position.
 
       if( oldInputStyle != mInputStyle )
       {
@@ -4656,12 +4639,12 @@ void TextInput::KeyboardStatusChanged(bool keyboardShown)
     ShowGrabHandleAndSetVisibility( false );
 
     // If the keyboard is not now being shown, then hide the popup panel
-    mPopUpPanel.Hide( true );
+    mPopupPanel.Hide( true );
   }
 }
 
 // Removes highlight and resumes edit mode state
-void TextInput::RemoveHighlight()
+void TextInput::RemoveHighlight( bool hidePopup )
 {
   DALI_LOG_INFO(gLogFilter, Debug::General, "RemoveHighlight\n");
 
@@ -4691,7 +4674,10 @@ void TextInput::RemoveHighlight()
     // NOTE: We cannot dereference mHighlightMesh, due
     // to a bug in how the scene-graph MeshRenderer uses the Mesh data incorrectly.
 
-    HidePopup();
+    if ( hidePopup )
+    {
+      HidePopup();
+    }
   }
 
   mSelectionHandleOnePosition = 0;
@@ -4714,7 +4700,6 @@ void TextInput::CreateHighlight()
 
     mHighlightMeshActor = MeshActor::New( mHighlightMesh );
     mHighlightMeshActor.SetName( "HighlightMeshActor" );
-    mHighlightMeshActor.SetInheritShaderEffect( false );
     mHighlightMeshActor.SetParentOrigin( ParentOrigin::TOP_LEFT );
     mHighlightMeshActor.SetAnchorPoint( AnchorPoint::TOP_LEFT );
     mHighlightMeshActor.SetPosition( 0.0f, 0.0f, DISPLAYED_HIGHLIGHT_Z_OFFSET );
@@ -4780,6 +4765,7 @@ void TextInput::PasteText( const Text& text )
   if( update )
   {
     CursorUpdate();
+    EmitTextModified();
   }
 
   if( insertedStringLength < text.GetLength() )
@@ -5170,42 +5156,67 @@ void TextInput::SetProperty( BaseObject* object, Property::Index propertyIndex,
       }
       case Toolkit::TextInput::CUT_AND_PASTE_COLOR_PROPERTY:
       {
-        textInputImpl.mPopUpPanel.SetCutPastePopUpColor( value.Get< Vector4 >() );
+        textInputImpl.mPopupPanel.SetCutPastePopupColor( value.Get< Vector4 >() );
         break;
       }
       case Toolkit::TextInput::CUT_AND_PASTE_PRESSED_COLOR_PROPERTY:
       {
-        textInputImpl.mPopUpPanel.SetCutPastePopUpPressedColor( value.Get< Vector4 >() );
+        textInputImpl.mPopupPanel.SetCutPastePopupPressedColor( value.Get< Vector4 >() );
+        break;
+      }
+      case Toolkit::TextInput::CUT_AND_PASTE_BORDER_COLOR_PROPERTY:
+      {
+        textInputImpl.mPopupPanel.SetCutPastePopupBorderColor( value.Get< Vector4 >() );
+        break;
+      }
+      case Toolkit::TextInput::CUT_AND_PASTE_ICON_COLOR_PROPERTY:
+      {
+        textInputImpl.mPopupPanel.SetCutPastePopupIconColor( value.Get< Vector4 >() );
+        break;
+      }
+      case Toolkit::TextInput::CUT_AND_PASTE_ICON_PRESSED_COLOR_PROPERTY:
+      {
+        textInputImpl.mPopupPanel.SetCutPastePopupIconPressedColor( value.Get< Vector4 >() );
+        break;
+      }
+      case Toolkit::TextInput::CUT_AND_PASTE_TEXT_COLOR_PROPERTY:
+      {
+        textInputImpl.mPopupPanel.SetCutPastePopupTextColor( value.Get< Vector4 >() );
+        break;
+      }
+      case Toolkit::TextInput::CUT_AND_PASTE_TEXT_PRESSED_COLOR_PROPERTY:
+      {
+        textInputImpl.mPopupPanel.SetCutPastePopupTextPressedColor( value.Get< Vector4 >() );
         break;
       }
       case Toolkit::TextInput::CUT_BUTTON_POSITION_PRIORITY_PROPERTY:
       {
-        textInputImpl.mPopUpPanel.SetButtonPriorityPosition( TextInputPopup::ButtonsCut, value.Get<unsigned int>() );
+        textInputImpl.mPopupPanel.SetButtonPriorityPosition( TextInputPopup::ButtonsCut, value.Get<unsigned int>() );
         break;
       }
       case Toolkit::TextInput::COPY_BUTTON_POSITION_PRIORITY_PROPERTY:
       {
-        textInputImpl.mPopUpPanel.SetButtonPriorityPosition( TextInputPopup::ButtonsCopy, value.Get<unsigned int>() );
+        textInputImpl.mPopupPanel.SetButtonPriorityPosition( TextInputPopup::ButtonsCopy, value.Get<unsigned int>() );
         break;
       }
       case Toolkit::TextInput::PASTE_BUTTON_POSITION_PRIORITY_PROPERTY:
       {
-        textInputImpl.mPopUpPanel.SetButtonPriorityPosition( TextInputPopup::ButtonsPaste, value.Get<unsigned int>() );
+        textInputImpl.mPopupPanel.SetButtonPriorityPosition( TextInputPopup::ButtonsPaste, value.Get<unsigned int>() );
         break;
       }
       case Toolkit::TextInput::SELECT_BUTTON_POSITION_PRIORITY_PROPERTY:
       {
-        textInputImpl.mPopUpPanel.SetButtonPriorityPosition( TextInputPopup::ButtonsSelect, value.Get<unsigned int>() );
+        textInputImpl.mPopupPanel.SetButtonPriorityPosition( TextInputPopup::ButtonsSelect, value.Get<unsigned int>() );
         break;
       }
       case Toolkit::TextInput::SELECT_ALL_BUTTON_POSITION_PRIORITY_PROPERTY:
       {
-        textInputImpl.mPopUpPanel.SetButtonPriorityPosition( TextInputPopup::ButtonsSelectAll, value.Get<unsigned int>() );
+        textInputImpl.mPopupPanel.SetButtonPriorityPosition( TextInputPopup::ButtonsSelectAll, value.Get<unsigned int>() );
         break;
       }
       case Toolkit::TextInput::CLIPBOARD_BUTTON_POSITION_PRIORITY_PROPERTY:
       {
-        textInputImpl.mPopUpPanel.SetButtonPriorityPosition( TextInputPopup::ButtonsClipboard, value.Get<unsigned int>() );
+        textInputImpl.mPopupPanel.SetButtonPriorityPosition( TextInputPopup::ButtonsClipboard, value.Get<unsigned int>() );
         break;
       }
       case Toolkit::TextInput::POP_UP_OFFSET_FROM_TEXT_PROPERTY:
@@ -5213,6 +5224,10 @@ void TextInput::SetProperty( BaseObject* object, Property::Index propertyIndex,
         textInputImpl.SetOffsetFromText( value.Get< Vector4 >() );
         break;
       }
+      case Toolkit::TextInput::CURSOR_COLOR_PROPERTY:
+      {
+        textInputImpl.mCursor.SetColor( value.Get< Vector4 >() );
+      }
     }
   }
 }
@@ -5236,42 +5251,67 @@ Property::Value TextInput::GetProperty( BaseObject* object, Property::Index prop
       }
       case Toolkit::TextInput::CUT_AND_PASTE_COLOR_PROPERTY:
       {
-        value = textInputImpl.mPopUpPanel.GetCutPastePopUpColor();
+        value = textInputImpl.mPopupPanel.GetCutPastePopupColor();
         break;
       }
       case Toolkit::TextInput::CUT_AND_PASTE_PRESSED_COLOR_PROPERTY:
       {
-        value = textInputImpl.mPopUpPanel.GetCutPastePopUpPressedColor();
+        value = textInputImpl.mPopupPanel.GetCutPastePopupPressedColor();
+        break;
+      }
+      case Toolkit::TextInput::CUT_AND_PASTE_BORDER_COLOR_PROPERTY :
+      {
+        value = textInputImpl.mPopupPanel.GetCutPastePopupBorderColor();
+        break;
+      }
+      case Toolkit::TextInput::CUT_AND_PASTE_ICON_COLOR_PROPERTY:
+      {
+        value = textInputImpl.mPopupPanel.GetCutPastePopupIconColor();
+        break;
+      }
+      case Toolkit::TextInput::CUT_AND_PASTE_ICON_PRESSED_COLOR_PROPERTY:
+      {
+        value = textInputImpl.mPopupPanel.GetCutPastePopupIconPressedColor();
+        break;
+      }
+      case Toolkit::TextInput::CUT_AND_PASTE_TEXT_COLOR_PROPERTY:
+      {
+        value = textInputImpl.mPopupPanel.GetCutPastePopupTextColor();
+        break;
+      }
+      case Toolkit::TextInput::CUT_AND_PASTE_TEXT_PRESSED_COLOR_PROPERTY:
+      {
+        value = textInputImpl.mPopupPanel.GetCutPastePopupTextPressedColor();
         break;
       }
       case Toolkit::TextInput::CUT_BUTTON_POSITION_PRIORITY_PROPERTY:
       {
-        value = textInputImpl.mPopUpPanel.GetButtonPriorityPosition( TextInputPopup::ButtonsCut );
+        value = textInputImpl.mPopupPanel.GetButtonPriorityPosition( TextInputPopup::ButtonsCut );
         break;
       }
       case Toolkit::TextInput::COPY_BUTTON_POSITION_PRIORITY_PROPERTY:
       {
-        value =  textInputImpl.mPopUpPanel.GetButtonPriorityPosition( TextInputPopup::ButtonsCopy );
+        value =  textInputImpl.mPopupPanel.GetButtonPriorityPosition( TextInputPopup::ButtonsCopy );
         break;
       }
       case Toolkit::TextInput::PASTE_BUTTON_POSITION_PRIORITY_PROPERTY:
       {
-        value = textInputImpl.mPopUpPanel.GetButtonPriorityPosition( TextInputPopup::ButtonsPaste );
+        value = textInputImpl.mPopupPanel.GetButtonPriorityPosition( TextInputPopup::ButtonsPaste );
         break;
       }
       case Toolkit::TextInput::SELECT_BUTTON_POSITION_PRIORITY_PROPERTY:
       {
-        value = textInputImpl.mPopUpPanel.GetButtonPriorityPosition( TextInputPopup::ButtonsSelect );
+        value = textInputImpl.mPopupPanel.GetButtonPriorityPosition( TextInputPopup::ButtonsSelect );
         break;
       }
       case Toolkit::TextInput::SELECT_ALL_BUTTON_POSITION_PRIORITY_PROPERTY:
       {
-        value = textInputImpl.mPopUpPanel.GetButtonPriorityPosition( TextInputPopup::ButtonsSelectAll );
+        value = textInputImpl.mPopupPanel.GetButtonPriorityPosition( TextInputPopup::ButtonsSelectAll );
         break;
       }
       case Toolkit::TextInput::CLIPBOARD_BUTTON_POSITION_PRIORITY_PROPERTY:
       {
-        value = textInputImpl.mPopUpPanel.GetButtonPriorityPosition( TextInputPopup::ButtonsClipboard );
+        value = textInputImpl.mPopupPanel.GetButtonPriorityPosition( TextInputPopup::ButtonsClipboard );
         break;
       }
       case Toolkit::TextInput::POP_UP_OFFSET_FROM_TEXT_PROPERTY:
@@ -5279,6 +5319,10 @@ Property::Value TextInput::GetProperty( BaseObject* object, Property::Index prop
         value = textInputImpl.GetOffsetFromText();
         break;
       }
+      case Toolkit::TextInput::CURSOR_COLOR_PROPERTY:
+      {
+        value = textInputImpl.mCursor.GetCurrentColor();
+      }
     }
   }
   return value;