Provide TextChanged() signal after PASTE
[platform/core/uifw/dali-toolkit.git] / dali-toolkit / internal / text / text-controller.cpp
index 83c81a3..bcac025 100644 (file)
@@ -89,7 +89,6 @@ void Controller::SetText( const std::string& text )
   {
     // If popup shown then hide it by switching to Editing state
     if( ( EventData::SELECTING == mImpl->mEventData->mState )          ||
-        ( EventData::SELECTION_CHANGED == mImpl->mEventData->mState )  ||
         ( EventData::EDITING_WITH_POPUP == mImpl->mEventData->mState ) ||
         ( EventData::EDITING_WITH_GRAB_HANDLE == mImpl->mEventData->mState ) )
     {
@@ -229,7 +228,7 @@ int Controller::GetMaximumNumberOfCharacters()
   return mImpl->mMaximumNumberOfCharacters;
 }
 
-void Controller::SetDefaultFontFamily( const std::string& defaultFontFamily, bool userDefined )
+void Controller::SetDefaultFontFamily( const std::string& defaultFontFamily )
 {
   if( !mImpl->mFontDefaults )
   {
@@ -237,8 +236,8 @@ void Controller::SetDefaultFontFamily( const std::string& defaultFontFamily, boo
   }
 
   mImpl->mFontDefaults->mFontDescription.family = defaultFontFamily;
-  DALI_LOG_INFO( gLogFilter, Debug::General, "Controller::SetDefaultFontFamily %s userDefined: %s\n", defaultFontFamily.c_str(), userDefined ? "true":"false" );
-  mImpl->mUserDefinedFontFamily = userDefined;
+  DALI_LOG_INFO( gLogFilter, Debug::General, "Controller::SetDefaultFontFamily %s\n", defaultFontFamily.c_str());
+  mImpl->mUserDefinedFontFamily = true;
 
   // Clear the font-specific data
   ClearFontData();
@@ -404,11 +403,10 @@ void Controller::UpdateAfterFontChange( std::string& newDefaultFont )
 {
   DALI_LOG_INFO( gLogFilter, Debug::Concise, "Controller::UpdateAfterFontChange");
 
-  ClearFontData();
-
   if ( !mImpl->mUserDefinedFontFamily ) // If user defined font then should not update when system font changes
   {
     DALI_LOG_INFO( gLogFilter, Debug::Concise, "Controller::UpdateAfterFontChange newDefaultFont(%s)\n", newDefaultFont.c_str() );
+    ClearFontData();
     mImpl->mFontDefaults->mFontDescription.family = newDefaultFont;
     mImpl->UpdateModel( ALL_OPERATIONS );
     mImpl->QueueModifyEvent( ModifyEvent::TEXT_REPLACED );
@@ -726,7 +724,9 @@ bool Controller::Relayout( const Size& size )
     return glyphsRemoved;
   }
 
-  if( size != mImpl->mVisualModel->mControlSize )
+  const bool newSize = ( size != mImpl->mVisualModel->mControlSize );
+
+  if( newSize )
   {
     DALI_LOG_INFO( gLogFilter, Debug::Verbose, "new size (previous size %f,%f)\n", mImpl->mVisualModel->mControlSize.width, mImpl->mVisualModel->mControlSize.height );
 
@@ -752,9 +752,9 @@ bool Controller::Relayout( const Size& size )
   // Do not re-do any operation until something changes.
   mImpl->mOperationsPending = NO_OPERATION;
 
-  // Keep the current offset and alignment as it will be used to update the decorator's positions.
+  // Keep the current offset and alignment as it will be used to update the decorator's positions (if the size changes).
   Vector2 offset;
-  if( mImpl->mEventData )
+  if( newSize && mImpl->mEventData )
   {
     offset = mImpl->mAlignmentOffset + mImpl->mEventData->mScrollPosition;
   }
@@ -764,11 +764,14 @@ bool Controller::Relayout( const Size& size )
 
   if( mImpl->mEventData )
   {
-    // If there is a nex size, the scroll position needs to be clamped.
-    mImpl->ClampHorizontalScroll( layoutSize );
+    if( newSize )
+    {
+      // If there is a new size, the scroll position needs to be clamped.
+      mImpl->ClampHorizontalScroll( layoutSize );
 
-    // Update the decorator's positions.
-    mImpl->mEventData->mDecorator->UpdatePositions( mImpl->mAlignmentOffset + mImpl->mEventData->mScrollPosition - offset );
+      // Update the decorator's positions is needed if there is a new size.
+      mImpl->mEventData->mDecorator->UpdatePositions( mImpl->mAlignmentOffset + mImpl->mEventData->mScrollPosition - offset );
+    }
 
     // Move the cursor, grab handle etc.
     updated = mImpl->ProcessInputEvents() || updated;
@@ -784,18 +787,18 @@ void Controller::ProcessModifyEvents()
 
   for( unsigned int i=0; i<events.size(); ++i )
   {
-    if( ModifyEvent::TEXT_REPLACED == events[0].type )
+    if( ModifyEvent::TEXT_REPLACED == events[i].type )
     {
       // A (single) replace event should come first, otherwise we wasted time processing NOOP events
       DALI_ASSERT_DEBUG( 0 == i && "Unexpected TEXT_REPLACED event" );
 
       TextReplacedEvent();
     }
-    else if( ModifyEvent::TEXT_INSERTED == events[0].type )
+    else if( ModifyEvent::TEXT_INSERTED == events[i].type )
     {
       TextInsertedEvent();
     }
-    else if( ModifyEvent::TEXT_DELETED == events[0].type )
+    else if( ModifyEvent::TEXT_DELETED == events[i].type )
     {
       // Placeholder-text cannot be deleted
       if( !mImpl->IsShowingPlaceholderText() )
@@ -923,11 +926,8 @@ void Controller::TextDeletedEvent()
                                                            REORDER );
 
   // Queue a cursor reposition event; this must wait until after DoRelayout()
-  if( 0u == mImpl->mLogicalModel->mText.Count() )
-  {
-    mImpl->mEventData->mUpdateCursorPosition = true;
-  }
-  else
+  mImpl->mEventData->mUpdateCursorPosition = true;
+  if( 0u != mImpl->mLogicalModel->mText.Count() )
   {
     mImpl->mEventData->mScrollAfterDelete = true;
   }
@@ -1180,8 +1180,7 @@ void Controller::CalculateTextAlignment( const Size& size )
     }
     case LayoutEngine::HORIZONTAL_ALIGN_CENTER:
     {
-      const int intOffset = static_cast<int>( 0.5f * ( size.width - actualSize.width ) ); // try to avoid pixel alignment.
-      mImpl->mAlignmentOffset.x = static_cast<float>( intOffset );
+      mImpl->mAlignmentOffset.x = floorf( 0.5f * ( size.width - actualSize.width ) ); // try to avoid pixel alignment.
       break;
     }
     case LayoutEngine::HORIZONTAL_ALIGN_END:
@@ -1201,8 +1200,7 @@ void Controller::CalculateTextAlignment( const Size& size )
     }
     case LayoutEngine::VERTICAL_ALIGN_CENTER:
     {
-      const int intOffset = static_cast<int>( 0.5f * ( size.height - actualSize.height ) ); // try to avoid pixel alignment.
-      mImpl->mAlignmentOffset.y = static_cast<float>( intOffset );
+      mImpl->mAlignmentOffset.y = floorf( 0.5f * ( size.height - actualSize.height ) ); // try to avoid pixel alignment.
       break;
     }
     case LayoutEngine::VERTICAL_ALIGN_BOTTOM:
@@ -1486,8 +1484,7 @@ bool Controller::RemoveSelectedText()
 {
   bool textRemoved( false );
 
-  if ( EventData::SELECTING         == mImpl->mEventData->mState ||
-       EventData::SELECTION_CHANGED == mImpl->mEventData->mState )
+  if( EventData::SELECTING == mImpl->mEventData->mState )
   {
     std::string removedString;
     mImpl->RetrieveSelection( removedString, true );
@@ -1611,6 +1608,9 @@ void Controller::LongPressEvent( Gesture::State state, float x, float y  )
       }
       else
       {
+        // Reset the imf manger to commit the pre-edit before selecting the text.
+        mImpl->ResetImfManager();
+
         SelectEvent( x, y, false );
       }
     }
@@ -1621,14 +1621,7 @@ void Controller::SelectEvent( float x, float y, bool selectAll )
 {
   if( mImpl->mEventData )
   {
-    if ( mImpl->mEventData->mState == EventData::SELECTING )
-    {
-      mImpl->ChangeState( EventData::SELECTION_CHANGED );
-    }
-    else
-    {
-      mImpl->ChangeState( EventData::SELECTING );
-    }
+    mImpl->ChangeState( EventData::SELECTING );
 
     if( selectAll )
     {
@@ -1716,6 +1709,9 @@ void Controller::PasteText( const std::string& stringToPaste )
   InsertText( stringToPaste, Text::Controller::COMMIT );
   mImpl->ChangeState( EventData::EDITING );
   mImpl->RequestRelayout();
+
+  // Do this last since it provides callbacks into application code
+  mImpl->mControlInterface.TextChanged();
 }
 
 void Controller::PasteClipboardItemEvent()
@@ -1815,6 +1811,7 @@ ImfManager::ImfCallbackData Controller::OnImfEvent( ImfManager& imfManager, cons
     case ImfManager::COMMIT:
     {
       InsertText( imfEvent.predictiveString, Text::Controller::COMMIT );
+      update=true;
       requestRelayout = true;
       break;
     }
@@ -1895,8 +1892,7 @@ bool Controller::BackspaceKeyEvent()
 
   bool removed( false );
 
-  if ( EventData::SELECTING         == mImpl->mEventData->mState ||
-       EventData::SELECTION_CHANGED == mImpl->mEventData->mState )
+  if( EventData::SELECTING == mImpl->mEventData->mState )
   {
     removed = RemoveSelectedText();
   }
@@ -1908,11 +1904,10 @@ bool Controller::BackspaceKeyEvent()
 
   if( removed )
   {
-    // This is to reset the virtual keyboard to Upper-case
-    if( 0u == mImpl->mLogicalModel->mText.Count() )
-    {
-      NotifyImfManager();
-    }
+    DALI_LOG_INFO( gLogFilter, Debug::Verbose, "Controller::KeyEvent %p DALI_KEY_BACKSPACE RemovedText\n", this );
+    // Notifiy the IMF manager after text changed
+    // Automatic  Upper-case and restarting prediction on an existing word require this.
+    NotifyImfManager();
 
     if( 0u != mImpl->mLogicalModel->mText.Count() ||
         !mImpl->IsPlaceholderAvailable() )