Merge changes I2df640e0,Ia1188305,I7fae506e,I7967a7cc,Ib0fdcdf4, ... into devel/master
authorDavid Steele <david.steele@samsung.com>
Fri, 30 Oct 2020 13:19:09 +0000 (13:19 +0000)
committerGerrit Code Review <gerrit@review>
Fri, 30 Oct 2020 13:19:09 +0000 (13:19 +0000)
* changes:
  [AT-SPI] MERGING MARKER
  [AT-SPI] Correct VISIBLE and SHOWING states
  [AT-SPI] Windows fixes
  [AT-SPI] Fixed uint underflow risk
  [AT-SPI] Guard added for potential null pointer dereference
  [AT-SPI] Implemented reading popup description
  [AT-SPI] Improving utc coverage ToggleButton tests
  [AT-SPI] More coverage
  [AT-SPI] Improving utc coverage
  [AT-SPI] Set both ScreenReaderEnabled and IsEnabled in TestEnableSC
  [AT-SPI] Rewritten UtcDaliControlAccessibilityModal
  [AT-SPI] Pass correct object to dynamic_cast
  [AT-SPI] UTC correction
  [AT-SPI] More UTC fixes
  [AT-SPI] Execute tct under dbus-launch
  [AT-SPI] UTC fixes
  [AT-SPI] Add TestDBusWrapper and bypass compilation problems
  [AT-SPI] Implement accessibility for Popup
  [AT-SPI] Fix cmake cmp0004 error
  [AT-SPI] Catch exception by reference
  [AT-SPI] Migrate Accessibility tests to dali-toolkit-internal
  [AT-SPI] Add notification for a11y name/description change
  [AT-SPI] TextController: emit characters before delete
  [AT-SPI] EmitStateChanged for togglable PushButton
  [AT-SPI] Add FOCUSABLE state to TextField and TextEditor
  [AT-SPI] Add Pause and Resume signals
  [AT-SPI] Let MarkFilter find the closest mark
  [AT-SPI] Emit ObjectPropertyChangeEvent::VALUE
  [AT-SPI] Implement proper accessibility for Slider
  [AT-SPI] Try auto-scrolling in GrabHighlight
  [AT-SPI] Override IsScrollable for Scrollable
  [AT-SPI] Support reading states and tooltips of ToggleButton
  [AT-SPI] Support gaining keyboard focus in TextField, TextEditor
  [AT-SPI] Allow two finger pan gesture
  [AT-SPI] Move setting highlightability property for controls to inheriting classes
  [AT-SPI] Make Accessible::GetName() fall back to actor name
  [AT-SPI] Fix role setting
  [AT-SPI] Squashed implementation

1  2 
dali-toolkit/internal/controls/text-controls/text-editor-impl.cpp
dali-toolkit/internal/controls/text-controls/text-editor-impl.h
dali-toolkit/internal/text/text-controller.cpp
dali-toolkit/internal/text/text-controller.h

@@@ -37,6 -37,7 +37,7 @@@
  #include <dali-toolkit/devel-api/text/rendering-backend.h>
  #include <dali-toolkit/devel-api/controls/control-devel.h>
  #include <dali-toolkit/devel-api/controls/control-depth-index-ranges.h>
+ #include <dali-toolkit/devel-api/focus-manager/keyinput-focus-manager.h>
  #include <dali-toolkit/public-api/visuals/visual-properties.h>
  #include <dali-toolkit/internal/text/text-enumerations-impl.h>
  #include <dali-toolkit/internal/text/rendering/text-backend.h>
@@@ -142,8 -143,6 +143,8 @@@ DALI_DEVEL_PROPERTY_REGISTRATION( Toolk
  DALI_DEVEL_PROPERTY_REGISTRATION( Toolkit, TextEditor, "maxLength",                      INTEGER,   MAX_LENGTH                           )
  DALI_DEVEL_PROPERTY_REGISTRATION( Toolkit, TextEditor, "selectedTextStart",              INTEGER,   SELECTED_TEXT_START                  )
  DALI_DEVEL_PROPERTY_REGISTRATION( Toolkit, TextEditor, "selectedTextEnd",                INTEGER,   SELECTED_TEXT_END                    )
 +DALI_DEVEL_PROPERTY_REGISTRATION( Toolkit, TextEditor, "horizontalScrollPosition",       FLOAT,     HORIZONTAL_SCROLL_POSITION           )
 +DALI_DEVEL_PROPERTY_REGISTRATION( Toolkit, TextEditor, "verticalScrollPosition",         INTEGER,   VERTICAL_SCROLL_POSITION             )
  DALI_DEVEL_PROPERTY_REGISTRATION( Toolkit, TextEditor, "enableEditing",                  BOOLEAN,   ENABLE_EDITING                       )
  DALI_DEVEL_PROPERTY_REGISTRATION_READ_ONLY( Toolkit, TextEditor, "selectedText",         STRING,    SELECTED_TEXT                        )
  
@@@ -723,26 -722,6 +724,26 @@@ void TextEditor::SetProperty( BaseObjec
          impl.SetEditable( editable );
          break;
        }
 +      case Toolkit::DevelTextEditor::Property::HORIZONTAL_SCROLL_POSITION:
 +      {
 +        float horizontalScroll = value.Get< float >();
 +        DALI_LOG_INFO( gLogFilter, Debug::General, "TextEditor %p HORIZONTAL_SCROLL_POSITION %d\n", impl.mController.Get(), horizontalScroll );
 +        if (horizontalScroll >= 0.0f)
 +        {
 +          impl.ScrollBy( Vector2(horizontalScroll - impl.GetHorizontalScrollPosition(), 0 ));
 +        }
 +        break;
 +      }
 +      case Toolkit::DevelTextEditor::Property::VERTICAL_SCROLL_POSITION:
 +      {
 +        float verticalScroll = value.Get< float >();
 +        DALI_LOG_INFO( gLogFilter, Debug::General, "TextEditor %p VERTICAL_SCROLL_POSITION %d\n", impl.mController.Get(), verticalScroll );
 +        if (verticalScroll >= 0.0f)
 +        {
 +          impl.ScrollBy( Vector2(0, verticalScroll - impl.GetVerticalScrollPosition() ));
 +        }
 +        break;
 +      }
      } // switch
    } // texteditor
  }
@@@ -1079,16 -1058,6 +1080,16 @@@ Property::Value TextEditor::GetProperty
          value = impl.IsEditable();
          break;
        }
 +      case Toolkit::DevelTextEditor::Property::HORIZONTAL_SCROLL_POSITION:
 +      {
 +        value = impl.GetHorizontalScrollPosition();
 +        break;
 +      }
 +      case Toolkit::DevelTextEditor::Property::VERTICAL_SCROLL_POSITION:
 +      {
 +        value = impl.GetVerticalScrollPosition();
 +        break;
 +      }
      } //switch
    }
  
@@@ -1112,32 -1081,6 +1113,32 @@@ void TextEditor::SelectNone(
    }
  }
  
 +void TextEditor::ScrollBy(Vector2 scroll)
 +{
 +  if( mController && mController->IsShowingRealText() )
 +  {
 +    mController->ScrollBy(scroll);
 +  }
 +}
 +
 +float TextEditor::GetHorizontalScrollPosition()
 +{
 +  if( mController && mController->IsShowingRealText() )
 +  {
 +    return mController->GetHorizontalScrollPosition();
 +  }
 +  return 0;
 +}
 +
 +float TextEditor::GetVerticalScrollPosition()
 +{
 +  if( mController && mController->IsShowingRealText() )
 +  {
 +    return mController->GetVerticalScrollPosition();
 +  }
 +  return 0;
 +}
 +
  string TextEditor::GetSelectedText() const
  {
    string selectedText = "";
@@@ -1158,6 -1101,11 +1159,11 @@@ DevelTextEditor::MaxLengthReachedSignal
    return mMaxLengthReachedSignal;
  }
  
+ Text::ControllerPtr TextEditor::getController()
+ {
+   return mController;
+ }
  bool TextEditor::DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor )
  {
    Dali::BaseHandle handle( object );
@@@ -1268,6 -1216,9 +1274,9 @@@ void TextEditor::OnInitialize(
    self.SetResizePolicy( ResizePolicy::FILL_TO_PARENT, Dimension::HEIGHT );
    self.OnSceneSignal().Connect( this, &TextEditor::OnSceneConnect );
  
+   //Enable highightability
+   self.SetProperty( Toolkit::DevelControl::Property::ACCESSIBILITY_HIGHLIGHTABLE, true );
    DevelControl::SetInputMethodContext( *this, mInputMethodContext );
  
    // Creates an extra control to be used as stencil buffer.
    mStencil.SetResizePolicy( ResizePolicy::FILL_TO_PARENT, Dimension::ALL_DIMENSIONS );
  
    self.Add( mStencil );
+   DevelControl::SetAccessibilityConstructor( self, []( Dali::Actor actor ) {
+     return std::unique_ptr< Dali::Accessibility::Accessible >(
+       new AccessibleImpl( actor, Dali::Accessibility::Role::ENTRY ) );
+   } );
  }
  
  void TextEditor::OnStyleChange( Toolkit::StyleManager styleManager, StyleChange::Type change )
@@@ -1516,6 -1472,12 +1530,12 @@@ void TextEditor::OnKeyInputFocusLost(
    EmitKeyInputFocusSignal( false ); // Calls back into the Control hence done last.
  }
  
+ bool TextEditor::OnAccessibilityActivated()
+ {
+   SetKeyInputFocus();
+   return true;
+ }
  void TextEditor::OnTap( const TapGesture& gesture )
  {
    DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextEditor::OnTap %p\n", mController.Get() );
@@@ -1574,6 -1536,30 +1594,30 @@@ void TextEditor::RequestTextRelayout(
    RelayoutRequest();
  }
  
+ void TextEditor::TextInserted( unsigned int position, unsigned int length, const std::string &content )
+ {
+   if( Accessibility::IsUp() )
+   {
+     Control::Impl::GetAccessibilityObject( Self() )->EmitTextInserted( position, length, content );
+   }
+ }
+ void TextEditor::TextDeleted( unsigned int position, unsigned int length, const std::string &content )
+ {
+   if( Accessibility::IsUp() )
+   {
+       Control::Impl::GetAccessibilityObject( Self() )->EmitTextDeleted( position, length, content );
+   }
+ }
+ void TextEditor::CaretMoved( unsigned int position )
+ {
+   if( Accessibility::IsUp() )
+   {
+     Control::Impl::GetAccessibilityObject( Self() )->EmitTextCaretMoved( position );
+   }
+ }
  void TextEditor::TextChanged()
  {
    Dali::Toolkit::TextEditor handle( GetOwner() );
@@@ -1914,6 -1900,220 +1958,220 @@@ TextEditor::~TextEditor(
    }
  }
  
+ std::string TextEditor::AccessibleImpl::GetName()
+ {
+   auto slf = Toolkit::TextEditor::DownCast( self );
+   return slf.GetProperty( Toolkit::TextEditor::Property::TEXT )
+       .Get< std::string >();
+ }
+ std::string TextEditor::AccessibleImpl::GetText( size_t startOffset,
+                                                  size_t endOffset )
+ {
+   if( endOffset <= startOffset )
+     return {};
+   auto slf = Toolkit::TextEditor::DownCast( self );
+   auto txt =
+       slf.GetProperty( Toolkit::TextEditor::Property::TEXT ).Get< std::string >();
+   if( startOffset > txt.size() || endOffset > txt.size() )
+     return {};
+   return txt.substr( startOffset, endOffset - startOffset );
+ }
+ size_t TextEditor::AccessibleImpl::GetCharacterCount()
+ {
+   auto slf = Toolkit::TextEditor::DownCast( self );
+   auto txt =
+       slf.GetProperty( Toolkit::TextEditor::Property::TEXT ).Get< std::string >();
+   return txt.size();
+ }
+ size_t TextEditor::AccessibleImpl::GetCaretOffset()
+ {
+   auto slf = Toolkit::TextEditor::DownCast( self );
+   return Dali::Toolkit::GetImpl( slf ).getController()->GetCursorPosition();
+ }
+ bool TextEditor::AccessibleImpl::SetCaretOffset(size_t offset)
+ {
+   auto slf = Toolkit::TextEditor::DownCast( self );
+   auto txt = slf.GetProperty( Toolkit::TextEditor::Property::TEXT ).Get< std::string >();
+   if (offset > txt.size())
+     return false;
+   auto& slfImpl = Dali::Toolkit::GetImpl( slf );
+   slfImpl.getController()->ResetCursorPosition( offset );
+   slfImpl.RequestTextRelayout();
+   return true;
+ }
+ Dali::Accessibility::Range TextEditor::AccessibleImpl::GetTextAtOffset(
+     size_t offset, Dali::Accessibility::TextBoundary boundary )
+ {
+   auto slf = Toolkit::TextEditor::DownCast( self );
+   auto txt = slf.GetProperty( Toolkit::TextEditor::Property::TEXT ).Get< std::string >();
+   auto txt_size = txt.size();
+   auto range = Dali::Accessibility::Range{};
+   switch(boundary)
+   {
+     case Dali::Accessibility::TextBoundary::CHARACTER:
+       {
+         if (offset < txt_size)
+         {
+           range.content = txt[offset];
+           range.startOffset = offset;
+           range.endOffset = offset + 1;
+         }
+       }
+       break;
+     case Dali::Accessibility::TextBoundary::WORD:
+     case Dali::Accessibility::TextBoundary::LINE:
+       {
+         auto txt_c_string = txt.c_str();
+         auto breaks = std::vector< char >( txt_size, 0 );
+         if(boundary == Dali::Accessibility::TextBoundary::WORD)
+           Accessibility::Accessible::FindWordSeparationsUtf8((const utf8_t *) txt_c_string, txt_size, "", breaks.data());
+         else
+           Accessibility::Accessible::FindLineSeparationsUtf8((const utf8_t *) txt_c_string, txt_size, "", breaks.data());
+         auto index = 0u;
+         auto counter = 0u;
+         while( index < txt_size && counter <= offset )
+         {
+           auto start = index;
+           if(breaks[index])
+           {
+             while(breaks[index])
+               index++;
+             counter++;
+           }
+           else
+           {
+             if (boundary == Dali::Accessibility::TextBoundary::WORD)
+               index++;
+             if (boundary == Dali::Accessibility::TextBoundary::LINE)
+               counter++;
+           }
+           if ((counter > 0) && ((counter - 1) == offset))
+           {
+             range.content = txt.substr(start, index - start + 1);
+             range.startOffset = start;
+             range.endOffset = index + 1;
+           }
+           if (boundary == Dali::Accessibility::TextBoundary::LINE)
+               index++;
+         }
+       }
+       break;
+     case Dali::Accessibility::TextBoundary::SENTENCE:
+       {
+         /* not supported by efl */
+       }
+       break;
+     case Dali::Accessibility::TextBoundary::PARAGRAPH:
+       {
+         /* Paragraph is not supported by libunibreak library */
+       }
+       break;
+     default:
+       break;
+   }
+   return range;
+ }
+ Dali::Accessibility::Range
+ TextEditor::AccessibleImpl::GetSelection( size_t selectionNum )
+ {
+   // Since DALi supports only one selection indexes higher than 0 are ignored
+   if( selectionNum > 0 )
+     return {};
+   auto slf = Toolkit::TextEditor::DownCast( self );
+   auto ctrl = Dali::Toolkit::GetImpl( slf ).getController();
+   std::string ret;
+   ctrl->RetrieveSelection( ret );
+   auto r = ctrl->GetSelectionIndexes();
+   return { static_cast<size_t>(r.first), static_cast<size_t>(r.second), ret };
+ }
+ bool TextEditor::AccessibleImpl::RemoveSelection( size_t selectionNum )
+ {
+   // Since DALi supports only one selection indexes higher than 0 are ignored
+   if( selectionNum > 0 )
+     return false;
+   auto slf = Toolkit::TextEditor::DownCast( self );
+   Dali::Toolkit::GetImpl( slf ).getController()->SetSelection( 0, 0 );
+   return true;
+ }
+ bool TextEditor::AccessibleImpl::SetSelection( size_t selectionNum,
+                                                size_t startOffset,
+                                                size_t endOffset )
+ {
+   // Since DALi supports only one selection indexes higher than 0 are ignored
+   if( selectionNum > 0 )
+     return false;
+   auto slf = Toolkit::TextEditor::DownCast( self );
+   Dali::Toolkit::GetImpl( slf ).getController()->SetSelection( startOffset,
+                                                                endOffset );
+   return true;
+ }
+ bool TextEditor::AccessibleImpl::CopyText( size_t startPosition,
+                                            size_t endPosition )
+ {
+   if( endPosition <= startPosition )
+     return false;
+   auto slf = Toolkit::TextEditor::DownCast( self );
+   auto txt = slf.GetProperty( Toolkit::TextEditor::Property::TEXT ).Get<std::string>();
+   Dali::Toolkit::GetImpl( slf ).getController()->CopyStringToClipboard( txt.substr(startPosition, endPosition - startPosition) );
+   return true;
+ }
+ bool TextEditor::AccessibleImpl::CutText( size_t startPosition,
+                                           size_t endPosition )
+ {
+   if( endPosition <= startPosition )
+     return false;
+   auto slf = Toolkit::TextEditor::DownCast( self );
+   auto txt = slf.GetProperty( Toolkit::TextEditor::Property::TEXT ).Get<std::string>();
+   Dali::Toolkit::GetImpl( slf ).getController()->CopyStringToClipboard( txt.substr(startPosition, endPosition - startPosition) );
+   slf.SetProperty( Toolkit::TextEditor::Property::TEXT,
+                    txt.substr( 0, startPosition ) + txt.substr( endPosition - startPosition, txt.size()));
+   return true;
+ }
+ Dali::Accessibility::States TextEditor::AccessibleImpl::CalculateStates()
+ {
+   using namespace Dali::Accessibility;
+   auto states = Control::Impl::AccessibleImpl::CalculateStates();
+   states[State::EDITABLE] = true;
+   states[State::FOCUSABLE] = true;
+   Toolkit::Control focusControl = Toolkit::KeyInputFocusManager::Get().GetCurrentFocusControl();
+   if (self == focusControl)
+   {
+     states[State::FOCUSED] = true;
+   }
+   return states;
+ }
  } // namespace Internal
  
  } // namespace Toolkit
@@@ -21,6 -21,7 +21,7 @@@
  // EXTERNAL INCLUDES
  #include <dali/devel-api/adaptor-framework/clipboard-event-notifier.h>
  #include <dali/devel-api/adaptor-framework/input-method-context.h>
+ #include <dali/devel-api/adaptor-framework/accessibility.h>
  #include <dali/public-api/animation/animation.h>
  
  // INTERNAL INCLUDES
@@@ -35,6 -36,7 +36,7 @@@
  #include <dali-toolkit/internal/text/text-controller.h>
  #include <dali-toolkit/internal/text/text-vertical-scroller.h>
  #include <dali-toolkit/internal/text/rendering/text-renderer.h>
+ #include <dali-toolkit/internal/controls/control/control-data-impl.h>
  
  namespace Dali
  {
@@@ -150,6 -152,11 +152,11 @@@ private: // From Contro
    void OnKeyInputFocusLost() override;
  
    /**
+    * @copydoc Control::OnAccessibilityActivated()
+    */
+   bool OnAccessibilityActivated() override;
+   /**
     * @copydoc Control::OnTap()
     */
    void OnTap( const TapGesture& tap ) override;
    /**
     * @copydoc Text::EditableControlInterface::TextChanged()
     */
+   void TextInserted( unsigned int position, unsigned int length, const std::string &content ) override;
+   /**
+    * @copydoc Text::EditableControlInterface::TextDeleted()
+    */
+   void TextDeleted( unsigned int position, unsigned int length, const std::string &content ) override;
+   /**
+    * @copydoc Text::EditableControlInterface::CaretMoved()
+    */
+   void CaretMoved( unsigned int position ) override;
+   /**
+    * @copydoc Text::EditableControlInterface::TextChanged()
+    */
    void TextChanged() override;
  
    /**
@@@ -226,25 -248,6 +248,25 @@@ public
    void SelectNone() override;
  
    /**
 +   * @copydoc Dali::Toolkit::DevelTextEditor::ScrollBy()
 +   */
 +  void ScrollBy(Vector2 Scroll);
 +
 +  /**
 +   * @brief Get Horizontal scroll position of TextEditor.
 +   *
 +   * @return Horizontal scroll position (in pixels) of TextEditor.
 +   */
 +  float GetHorizontalScrollPosition();
 +
 +  /**
 +   * @brief Get Vertical scroll position of TextEditor.
 +   *
 +   * @return Vertical scroll position (in pixels) of TextEditor.
 +   */
 +  float GetVerticalScrollPosition();
 +
 +  /**
     * @copydoc Text::SelectableControlInterface::GetSelectedText()
     */
    string GetSelectedText() const override;
     * @copydoc Text::EditableControlInterface::SetEditable()
     */
    void SetEditable( bool editable ) override;
+   Text::ControllerPtr getController();
  
  private: // Implementation
  
@@@ -375,6 -379,29 +398,29 @@@ private: // Dat
    bool mScrollAnimationEnabled:1;
    bool mScrollBarEnabled:1;
    bool mScrollStarted:1;
+   struct AccessibleImpl : public Control::Impl::AccessibleImpl,
+                           public virtual Dali::Accessibility::Text,
+                           public virtual Dali::Accessibility::EditableText
+   {
+     using Control::Impl::AccessibleImpl::AccessibleImpl;
+     std::string GetName() override;
+     std::string GetText( size_t startOffset, size_t endOffset ) override;
+     size_t GetCharacterCount() override;
+     size_t GetCaretOffset() override;
+     bool SetCaretOffset(size_t offset) override;
+     Dali::Accessibility::Range
+     GetTextAtOffset( size_t offset,
+                      Dali::Accessibility::TextBoundary boundary ) override;
+     Dali::Accessibility::Range GetSelection( size_t selectionNum ) override;
+     bool RemoveSelection( size_t selectionNum ) override;
+     bool SetSelection( size_t selectionNum, size_t startOffset,
+                        size_t endOffset ) override;
+     bool CopyText( size_t startPosition, size_t endPosition ) override;
+     bool CutText( size_t startPosition, size_t endPosition ) override;
+     Dali::Accessibility::States CalculateStates() override;
+   };
  };
  
  } // namespace Internal
index 6fe0d0c,3035062..aed8d32
mode 100755,100644..100644
@@@ -733,6 -733,31 +733,31 @@@ void Controller::UpdateAfterFontChange
    }
  }
  
+ void Controller::RetrieveSelection( std::string& selectedText ) const
+ {
+   mImpl->RetrieveSelection( selectedText, false );
+ }
+ void Controller::SetSelection( int start, int end )
+ {
+   mImpl->SetSelection( start, end );
+ }
+ std::pair< int, int > Controller::GetSelectionIndexes() const
+ {
+   return mImpl->GetSelectionIndexes();
+ }
+ void Controller::CopyStringToClipboard( const std::string& source )
+ {
+   mImpl->CopyStringToClipboard( source );
+ }
+ void Controller::SendSelectionToClipboard( bool deleteAfterSending )
+ {
+   mImpl->SendSelectionToClipboard( deleteAfterSending );
+ }
  // public : Default style & Input style
  
  void Controller::SetDefaultFontFamily( const std::string& defaultFontFamily )
@@@ -2239,56 -2264,6 +2264,56 @@@ void Controller::SetEditable( bool edit
    }
  }
  
 +void Controller::ScrollBy( Vector2 scroll )
 +{
 +  if( mImpl->mEventData && (fabs(scroll.x) > Math::MACHINE_EPSILON_0 || fabs(scroll.y) > Math::MACHINE_EPSILON_0))
 +  {
 +      const Vector2& layoutSize = mImpl->mModel->mVisualModel->GetLayoutSize();
 +      const Vector2 currentScroll = mImpl->mModel->mScrollPosition;
 +
 +      scroll.x = -scroll.x;
 +      scroll.y = -scroll.y;
 +
 +      if( fabs(scroll.x) > Math::MACHINE_EPSILON_0 )
 +      {
 +        mImpl->mModel->mScrollPosition.x += scroll.x;
 +        mImpl->ClampHorizontalScroll( layoutSize );
 +      }
 +
 +      if( fabs(scroll.y) > Math::MACHINE_EPSILON_0 )
 +      {
 +        mImpl->mModel->mScrollPosition.y += scroll.y;
 +        mImpl->ClampVerticalScroll( layoutSize );
 +      }
 +
 +      if (mImpl->mModel->mScrollPosition != currentScroll)
 +      {
 +        mImpl->mEventData->mDecorator->UpdatePositions( mImpl->mModel->mScrollPosition - currentScroll );
 +        mImpl->RequestRelayout();
 +      }
 +  }
 +}
 +
 +float Controller::GetHorizontalScrollPosition()
 +{
 +  if( mImpl->mEventData )
 +  {
 +    //scroll values are negative internally so we convert them to positive numbers
 +    return -mImpl->mModel->mScrollPosition.x;
 +  }
 +  return 0;
 +}
 +
 +float Controller::GetVerticalScrollPosition()
 +{
 +  if( mImpl->mEventData )
 +  {
 +    //scroll values are negative internally so we convert them to positive numbers
 +    return -mImpl->mModel->mScrollPosition.y;
 +  }
 +  return 0;
 +}
 +
  void Controller::DecorationEvent( HandleType handleType, HandleState state, float x, float y )
  {
    EventHandler::DecorationEvent(*this, handleType, state, x, y);
@@@ -2497,13 -2472,17 +2522,17 @@@ void Controller::InsertText( const std:
      // Insert at current cursor position.
      Vector<Character>& modifyText = mImpl->mModel->mLogicalModel->mText;
  
+     auto pos = modifyText.End();
      if( cursorIndex < numberOfCharactersInModel )
      {
-       modifyText.Insert( modifyText.Begin() + cursorIndex, utf32Characters.Begin(), utf32Characters.Begin() + maxSizeOfNewText );
+       pos = modifyText.Begin() + cursorIndex;
      }
-     else
+     unsigned int realPos = pos - modifyText.Begin();
+     modifyText.Insert( pos, utf32Characters.Begin(), utf32Characters.Begin() + maxSizeOfNewText );
+     if( NULL != mImpl->mEditableControlInterface )
      {
-       modifyText.Insert( modifyText.End(), utf32Characters.Begin(), utf32Characters.Begin() + maxSizeOfNewText );
+       mImpl->mEditableControlInterface->TextInserted( realPos, maxSizeOfNewText, text );
      }
  
      // Mark the first paragraph to be updated.
@@@ -2669,6 -2648,13 +2698,13 @@@ bool Controller::RemoveText( int cursor
        Vector<Character>::Iterator first = currentText.Begin() + cursorIndex;
        Vector<Character>::Iterator last  = first + numberOfCharacters;
  
+       if( NULL != mImpl->mEditableControlInterface )
+       {
+         std::string utf8;
+         Utf32ToUtf8( first, numberOfCharacters, utf8 );
+         mImpl->mEditableControlInterface->TextDeleted( cursorIndex, numberOfCharacters, utf8 );
+       }
        currentText.Erase( first, last );
  
        // Cursor position retreat
@@@ -3094,6 -3080,14 +3130,14 @@@ void Controller::ResetCursorPosition( C
    }
  }
  
+ CharacterIndex Controller::GetCursorPosition()
+ {
+   if( !mImpl->mEventData )
+     return 0;
+   return mImpl->mEventData->mPrimaryCursorPosition;
+ }
  void Controller::ResetScrollPosition()
  {
    if( NULL != mImpl->mEventData )
index 6bd8706,f600f84..d627324
mode 100755,100644..100644
@@@ -662,6 -662,38 +662,38 @@@ public: // Update
     */
    void UpdateAfterFontChange( const std::string& newDefaultFont );
  
+   /**
+    * @brief The method acquires currently selected text
+    * @param selectedText variable to place selected text in
+    */
+   void RetrieveSelection( std::string& selectedText ) const;
+   /**
+    * @brief The method sets selection in given range
+    * @param start index of first character
+    * @param end   index of first character after selection
+    */
+   void SetSelection( int start, int end );
+   /**
+    * @brief This method retrieve indexes of current selection
+    *
+    * @return a pair, where first element is left index of selection and second is the right one
+    */
+   std::pair< int, int > GetSelectionIndexes() const;
+   /**
+    * Place string in system clipboard
+    * @param source std::string
+    */
+   void CopyStringToClipboard( const std::string& source );
+   /**
+    * Place currently selected text in system clipboard
+    * @param deleteAfterSending flag pointing if text should be deleted after sending to clipboard
+    */
+   void SendSelectionToClipboard( bool deleteAfterSending );
  public: // Default style & Input style
  
    /**
@@@ -1531,21 -1563,6 +1563,21 @@@ public: // Text-input Event Queuing
    virtual void SetEditable( bool editable );
  
    /**
 +   * @copydoc Dali::Toolkit::Internal::TextEditor::ScrollBy()
 +   */
 +  virtual void ScrollBy( Vector2 scroll );
 +
 +  /**
 +   * @copydoc Dali::Toolkit::Internal::TextEditor::GetHorizontalScrollPosition()
 +   */
 +  float GetHorizontalScrollPosition();
 +
 +  /**
 +   * @copydoc Dali::Toolkit::Internal::TextEditor::GetVerticalScrollPosition()
 +   */
 +  float GetVerticalScrollPosition();
 +
 +  /**
     * @brief Event received from input method context
     *
     * @param[in] inputMethodContext The input method context.
     */
    Actor CreateBackgroundActor();
  
+   /**
+    * @brief Used to reset the cursor position after setting a new text.
+    *
+    * @param[in] cursorIndex Where to place the cursor.
+    */
+   void ResetCursorPosition( CharacterIndex cursorIndex );
+   /**
+    * @brief The method acquires current position of cursor
+    * @return unsigned value with cursor position
+    */
+   CharacterIndex GetCursorPosition();
  protected: // Inherit from Text::Decorator::ControllerInterface.
  
    /**
@@@ -1717,13 -1747,6 +1762,6 @@@ private: // Helpers
    void ClearStyleData();
  
    /**
-    * @brief Used to reset the cursor position after setting a new text.
-    *
-    * @param[in] cursorIndex Where to place the cursor.
-    */
-   void ResetCursorPosition( CharacterIndex cursorIndex );
-   /**
     * @brief Used to reset the scroll position after setting a new text.
     */
    void ResetScrollPosition();