- bool removedPrevious = false;
- bool removedSelected = false;
- bool maxLengthReached = false;
-
- DALI_ASSERT_DEBUG( NULL != mImpl->mEventData && "Unexpected InsertText" )
-
- if( NULL == mImpl->mEventData )
- {
- return;
- }
-
- DALI_LOG_INFO( gLogFilter, Debug::Verbose, "Controller::InsertText %p %s (%s) mPrimaryCursorPosition %d mPreEditFlag %d mPreEditStartPosition %d mPreEditLength %d\n",
- this, text.c_str(), (COMMIT == type ? "COMMIT" : "PRE_EDIT"),
- mImpl->mEventData->mPrimaryCursorPosition, mImpl->mEventData->mPreEditFlag, mImpl->mEventData->mPreEditStartPosition, mImpl->mEventData->mPreEditLength );
-
- // TODO: At the moment the underline runs are only for pre-edit.
- mImpl->mModel->mVisualModel->mUnderlineRuns.Clear();
-
- // Remove the previous InputMethodContext pre-edit.
- if( mImpl->mEventData->mPreEditFlag && ( 0u != mImpl->mEventData->mPreEditLength ) )
- {
- removedPrevious = RemoveText( -static_cast<int>( mImpl->mEventData->mPrimaryCursorPosition - mImpl->mEventData->mPreEditStartPosition ),
- mImpl->mEventData->mPreEditLength,
- DONT_UPDATE_INPUT_STYLE );
-
- mImpl->mEventData->mPrimaryCursorPosition = mImpl->mEventData->mPreEditStartPosition;
- mImpl->mEventData->mPreEditLength = 0u;
- }
- else
- {
- // Remove the previous Selection.
- removedSelected = RemoveSelectedText();
-
- }
-
- Vector<Character> utf32Characters;
- Length characterCount = 0u;
-
- if( !text.empty() )
- {
- // Convert text into UTF-32
- utf32Characters.Resize( text.size() );
-
- // This is a bit horrible but std::string returns a (signed) char*
- const uint8_t* utf8 = reinterpret_cast<const uint8_t*>( text.c_str() );
-
- // Transform a text array encoded in utf8 into an array encoded in utf32.
- // It returns the actual number of characters.
- characterCount = Utf8ToUtf32( utf8, text.size(), utf32Characters.Begin() );
- utf32Characters.Resize( characterCount );
-
- DALI_ASSERT_DEBUG( text.size() >= utf32Characters.Count() && "Invalid UTF32 conversion length" );
- DALI_LOG_INFO( gLogFilter, Debug::Verbose, "UTF8 size %d, UTF32 size %d\n", text.size(), utf32Characters.Count() );
- }
-
- if( 0u != utf32Characters.Count() ) // Check if Utf8ToUtf32 conversion succeeded
- {
- // The placeholder text is no longer needed
- if( mImpl->IsShowingPlaceholderText() )
- {
- ResetText();
- }
-
- mImpl->ChangeState( EventData::EDITING );
-
- // Handle the InputMethodContext (predicitive text) state changes
- if( COMMIT == type )
- {
- // InputMethodContext is no longer handling key-events
- mImpl->ClearPreEditFlag();
- }
- else // PRE_EDIT
- {
- if( !mImpl->mEventData->mPreEditFlag )
- {
- DALI_LOG_INFO( gLogFilter, Debug::Verbose, "Entered PreEdit state\n" );
-
- // Record the start of the pre-edit text
- mImpl->mEventData->mPreEditStartPosition = mImpl->mEventData->mPrimaryCursorPosition;
- }
-
- mImpl->mEventData->mPreEditLength = utf32Characters.Count();
- mImpl->mEventData->mPreEditFlag = true;
-
- DALI_LOG_INFO( gLogFilter, Debug::Verbose, "mPreEditStartPosition %d mPreEditLength %d\n", mImpl->mEventData->mPreEditStartPosition, mImpl->mEventData->mPreEditLength );
- }
-
- const Length numberOfCharactersInModel = mImpl->mModel->mLogicalModel->mText.Count();
-
- // Restrict new text to fit within Maximum characters setting.
- Length maxSizeOfNewText = std::min( ( mImpl->mMaximumNumberOfCharacters - numberOfCharactersInModel ), characterCount );
- maxLengthReached = ( characterCount > maxSizeOfNewText );
-
- // The cursor position.
- CharacterIndex& cursorIndex = mImpl->mEventData->mPrimaryCursorPosition;
-
- // Update the text's style.
-
- // Updates the text style runs by adding characters.
- mImpl->mModel->mLogicalModel->UpdateTextStyleRuns( cursorIndex, maxSizeOfNewText );
-
- // Get the character index from the cursor index.
- const CharacterIndex styleIndex = ( cursorIndex > 0u ) ? cursorIndex - 1u : 0u;
-
- // Retrieve the text's style for the given index.
- InputStyle style;
- mImpl->RetrieveDefaultInputStyle( style );
- mImpl->mModel->mLogicalModel->RetrieveStyle( styleIndex, style );
-
- // Whether to add a new text color run.
- const bool addColorRun = ( style.textColor != mImpl->mEventData->mInputStyle.textColor ) && !mImpl->mEventData->mInputStyle.isDefaultColor;
-
- // Whether to add a new font run.
- const bool addFontNameRun = ( style.familyName != mImpl->mEventData->mInputStyle.familyName ) && mImpl->mEventData->mInputStyle.isFamilyDefined;
- const bool addFontWeightRun = ( style.weight != mImpl->mEventData->mInputStyle.weight ) && mImpl->mEventData->mInputStyle.isWeightDefined;
- const bool addFontWidthRun = ( style.width != mImpl->mEventData->mInputStyle.width ) && mImpl->mEventData->mInputStyle.isWidthDefined;
- const bool addFontSlantRun = ( style.slant != mImpl->mEventData->mInputStyle.slant ) && mImpl->mEventData->mInputStyle.isSlantDefined;
- const bool addFontSizeRun = ( style.size != mImpl->mEventData->mInputStyle.size ) && mImpl->mEventData->mInputStyle.isSizeDefined ;
-
- // Add style runs.
- if( addColorRun )
- {
- const VectorBase::SizeType numberOfRuns = mImpl->mModel->mLogicalModel->mColorRuns.Count();
- mImpl->mModel->mLogicalModel->mColorRuns.Resize( numberOfRuns + 1u );
-
- ColorRun& colorRun = *( mImpl->mModel->mLogicalModel->mColorRuns.Begin() + numberOfRuns );
- colorRun.color = mImpl->mEventData->mInputStyle.textColor;
- colorRun.characterRun.characterIndex = cursorIndex;
- colorRun.characterRun.numberOfCharacters = maxSizeOfNewText;
- }
-
- if( addFontNameRun ||
- addFontWeightRun ||
- addFontWidthRun ||
- addFontSlantRun ||
- addFontSizeRun )
- {
- const VectorBase::SizeType numberOfRuns = mImpl->mModel->mLogicalModel->mFontDescriptionRuns.Count();
- mImpl->mModel->mLogicalModel->mFontDescriptionRuns.Resize( numberOfRuns + 1u );
-
- FontDescriptionRun& fontDescriptionRun = *( mImpl->mModel->mLogicalModel->mFontDescriptionRuns.Begin() + numberOfRuns );
-
- if( addFontNameRun )
- {
- fontDescriptionRun.familyLength = mImpl->mEventData->mInputStyle.familyName.size();
- fontDescriptionRun.familyName = new char[fontDescriptionRun.familyLength];
- memcpy( fontDescriptionRun.familyName, mImpl->mEventData->mInputStyle.familyName.c_str(), fontDescriptionRun.familyLength );
- fontDescriptionRun.familyDefined = true;
-
- // The memory allocated for the font family name is freed when the font description is removed from the logical model.
- }
-
- if( addFontWeightRun )
- {
- fontDescriptionRun.weight = mImpl->mEventData->mInputStyle.weight;
- fontDescriptionRun.weightDefined = true;
- }
-
- if( addFontWidthRun )
- {
- fontDescriptionRun.width = mImpl->mEventData->mInputStyle.width;
- fontDescriptionRun.widthDefined = true;
- }
-
- if( addFontSlantRun )
- {
- fontDescriptionRun.slant = mImpl->mEventData->mInputStyle.slant;
- fontDescriptionRun.slantDefined = true;
- }
-
- if( addFontSizeRun )
- {
- fontDescriptionRun.size = static_cast<PointSize26Dot6>( mImpl->mEventData->mInputStyle.size * 64.f );
- fontDescriptionRun.sizeDefined = true;
- }
-
- fontDescriptionRun.characterRun.characterIndex = cursorIndex;
- fontDescriptionRun.characterRun.numberOfCharacters = maxSizeOfNewText;
- }
-
- // Insert at current cursor position.
- Vector<Character>& modifyText = mImpl->mModel->mLogicalModel->mText;
-
- auto pos = modifyText.End();
- if( cursorIndex < numberOfCharactersInModel )
- {
- pos = modifyText.Begin() + cursorIndex;
- }
- unsigned int realPos = pos - modifyText.Begin();
- modifyText.Insert( pos, utf32Characters.Begin(), utf32Characters.Begin() + maxSizeOfNewText );
-
- if( NULL != mImpl->mEditableControlInterface )
- {
- mImpl->mEditableControlInterface->TextInserted( realPos, maxSizeOfNewText, text );
- }
-
- // Mark the first paragraph to be updated.
- if( Layout::Engine::SINGLE_LINE_BOX == mImpl->mLayoutEngine.GetLayout() )
- {
- mImpl->mTextUpdateInfo.mCharacterIndex = 0;
- mImpl->mTextUpdateInfo.mNumberOfCharactersToRemove = mImpl->mTextUpdateInfo.mPreviousNumberOfCharacters;
- mImpl->mTextUpdateInfo.mNumberOfCharactersToAdd = numberOfCharactersInModel + maxSizeOfNewText;
- mImpl->mTextUpdateInfo.mClearAll = true;
- }
- else
- {
- mImpl->mTextUpdateInfo.mCharacterIndex = std::min( cursorIndex, mImpl->mTextUpdateInfo.mCharacterIndex );
- mImpl->mTextUpdateInfo.mNumberOfCharactersToAdd += maxSizeOfNewText;
- }
-
- // Update the cursor index.
- cursorIndex += maxSizeOfNewText;
-
- DALI_LOG_INFO( gLogFilter, Debug::Verbose, "Inserted %d characters, new size %d new cursor %d\n", maxSizeOfNewText, mImpl->mModel->mLogicalModel->mText.Count(), mImpl->mEventData->mPrimaryCursorPosition );
- }
-
- if( ( 0u == mImpl->mModel->mLogicalModel->mText.Count() ) &&
- mImpl->IsPlaceholderAvailable() )
- {
- // Show place-holder if empty after removing the pre-edit text
- ShowPlaceholderText();
- mImpl->mEventData->mUpdateCursorPosition = true;
- mImpl->ClearPreEditFlag();
- }
- else if( removedPrevious ||
- removedSelected ||
- ( 0 != utf32Characters.Count() ) )
- {
- // Queue an inserted event
- mImpl->QueueModifyEvent( ModifyEvent::TEXT_INSERTED );
-
- mImpl->mEventData->mUpdateCursorPosition = true;
- if( removedSelected )
- {
- mImpl->mEventData->mScrollAfterDelete = true;
- }
- else
- {
- mImpl->mEventData->mScrollAfterUpdatePosition = true;
- }
- }
-
- if( maxLengthReached )
- {
- DALI_LOG_INFO( gLogFilter, Debug::Verbose, "MaxLengthReached (%d)\n", mImpl->mModel->mLogicalModel->mText.Count() );
-
- mImpl->ResetInputMethodContext();
-
- if( NULL != mImpl->mEditableControlInterface )
- {
- // Do this last since it provides callbacks into application code
- mImpl->mEditableControlInterface->MaxLengthReached();
- }
- }