X-Git-Url: http://review.tizen.org/git/?p=platform%2Fcore%2Fuifw%2Fdali-toolkit.git;a=blobdiff_plain;f=dali-toolkit%2Finternal%2Ftext%2Ftext-controller-text-updater.cpp;h=c200c386dfdaf76f7cfcd705c3bad7330de80ce5;hp=6fb472ecc9280e1e4e371fffa92763454e994c14;hb=55913cc4a36f6b7171482d01f365c4b67d62660f;hpb=3d28744e61ba8b68daa957827a55224f11bbf2f0 diff --git a/dali-toolkit/internal/text/text-controller-text-updater.cpp b/dali-toolkit/internal/text/text-controller-text-updater.cpp index 6fb472e..c200c38 100644 --- a/dali-toolkit/internal/text/text-controller-text-updater.cpp +++ b/dali-toolkit/internal/text/text-controller-text-updater.cpp @@ -69,6 +69,11 @@ void Controller::TextUpdater::SetText(Controller& controller, const std::string& (EventData::EDITING_WITH_GRAB_HANDLE == eventData->mState) || (EventData::EDITING_WITH_PASTE_POPUP == eventData->mState)) { + if((impl.mSelectableControlInterface != nullptr) && (EventData::SELECTING == eventData->mState)) + { + impl.mSelectableControlInterface->SelectionChanged(eventData->mLeftSelectionPosition, eventData->mRightSelectionPosition, eventData->mPrimaryCursorPosition, eventData->mPrimaryCursorPosition); + } + impl.ChangeState(EventData::EDITING); } } @@ -81,7 +86,10 @@ void Controller::TextUpdater::SetText(Controller& controller, const std::string& MarkupProcessData markupProcessData(logicalModel->mColorRuns, logicalModel->mFontDescriptionRuns, - logicalModel->mEmbeddedItems); + logicalModel->mEmbeddedItems, + logicalModel->mAnchors, + logicalModel->mUnderlinedCharacterRuns, + logicalModel->mBackgroundColorRuns); Length textSize = 0u; const uint8_t* utf8 = NULL; @@ -136,6 +144,8 @@ void Controller::TextUpdater::SetText(Controller& controller, const std::string& controller.ShowPlaceholderText(); } + unsigned int oldCursorPos = (nullptr != eventData ? eventData->mPrimaryCursorPosition : 0); + // Resets the cursor position. controller.ResetCursorPosition(lastCursorIndex); @@ -153,6 +163,7 @@ void Controller::TextUpdater::SetText(Controller& controller, const std::string& // Do this last since it provides callbacks into application code. if(NULL != impl.mEditableControlInterface) { + impl.mEditableControlInterface->CursorPositionChanged(oldCursorPos, lastCursorIndex); impl.mEditableControlInterface->TextChanged(true); } } @@ -169,9 +180,10 @@ void Controller::TextUpdater::InsertText(Controller& controller, const std::stri return; } - bool removedPrevious = false; - bool removedSelected = false; - bool maxLengthReached = false; + bool removedPrevious = false; + bool removedSelected = false; + bool maxLengthReached = false; + unsigned int oldCursorPos = eventData->mPrimaryCursorPosition; DALI_LOG_INFO(gLogFilter, Debug::Verbose, "Controller::InsertText %p %s (%s) mPrimaryCursorPosition %d mPreEditFlag %d mPreEditStartPosition %d mPreEditLength %d\n", &controller, text.c_str(), (COMMIT == type ? "COMMIT" : "PRE_EDIT"), eventData->mPrimaryCursorPosition, eventData->mPreEditFlag, eventData->mPreEditStartPosition, eventData->mPreEditLength); @@ -253,7 +265,8 @@ void Controller::TextUpdater::InsertText(Controller& controller, const std::stri const Length numberOfCharactersInModel = logicalModel->mText.Count(); // Restrict new text to fit within Maximum characters setting. - Length maxSizeOfNewText = std::min((impl.mMaximumNumberOfCharacters - numberOfCharactersInModel), characterCount); + Length temp_length = (impl.mMaximumNumberOfCharacters > numberOfCharactersInModel ? impl.mMaximumNumberOfCharacters - numberOfCharactersInModel : 0); + Length maxSizeOfNewText = std::min(temp_length, characterCount); maxLengthReached = (characterCount > maxSizeOfNewText); // The cursor position. @@ -377,6 +390,11 @@ void Controller::TextUpdater::InsertText(Controller& controller, const std::stri textUpdateInfo.mNumberOfCharactersToAdd += maxSizeOfNewText; } + if(impl.mMarkupProcessorEnabled) + { + InsertTextAnchor(controller, maxSizeOfNewText, cursorIndex); + } + // Update the cursor index. cursorIndex += maxSizeOfNewText; @@ -409,6 +427,11 @@ void Controller::TextUpdater::InsertText(Controller& controller, const std::stri } } + if(nullptr != impl.mEditableControlInterface) + { + impl.mEditableControlInterface->CursorPositionChanged(oldCursorPos, eventData->mPrimaryCursorPosition); + } + if(maxLengthReached) { DALI_LOG_INFO(gLogFilter, Debug::Verbose, "MaxLengthReached (%d)\n", logicalModel->mText.Count()); @@ -461,8 +484,8 @@ bool Controller::TextUpdater::RemoveText( if(!impl.IsShowingPlaceholderText()) { // Delete at current cursor position - Vector& currentText = logicalModel->mText; - CharacterIndex& oldCursorIndex = eventData->mPrimaryCursorPosition; + Vector& currentText = logicalModel->mText; + CharacterIndex& previousCursorIndex = eventData->mPrimaryCursorPosition; CharacterIndex cursorIndex = 0; @@ -547,8 +570,18 @@ bool Controller::TextUpdater::RemoveText( currentText.Erase(first, last); + if(impl.mMarkupProcessorEnabled) + { + RemoveTextAnchor(controller, cursorOffset, numberOfCharacters, previousCursorIndex); + } + + if(nullptr != impl.mEditableControlInterface) + { + impl.mEditableControlInterface->CursorPositionChanged(previousCursorIndex, cursorIndex); + } + // Cursor position retreat - oldCursorIndex = cursorIndex; + previousCursorIndex = cursorIndex; eventData->mScrollAfterDelete = true; @@ -580,6 +613,16 @@ bool Controller::TextUpdater::RemoveSelectedText(Controller& controller) { textRemoved = true; impl.ChangeState(EventData::EDITING); + + if(impl.mMarkupProcessorEnabled) + { + int cursorOffset = -1; + int numberOfCharacters = removedString.length(); + CharacterIndex& cursorIndex = impl.mEventData->mPrimaryCursorPosition; + CharacterIndex previousCursorIndex = cursorIndex + numberOfCharacters; + + RemoveTextAnchor(controller, cursorOffset, numberOfCharacters, previousCursorIndex); + } } } @@ -597,6 +640,9 @@ void Controller::TextUpdater::ResetText(Controller& controller) // Reset the embedded images buffer. logicalModel->ClearEmbeddedImages(); + // Reset the anchors buffer. + logicalModel->ClearAnchors(); + // We have cleared everything including the placeholder-text impl.PlaceholderCleared(); @@ -617,6 +663,128 @@ void Controller::TextUpdater::ResetText(Controller& controller) impl.mOperationsPending = ALL_OPERATIONS; } +void Controller::TextUpdater::InsertTextAnchor(Controller& controller, int numberOfCharacters, CharacterIndex previousCursorIndex) +{ + Controller::Impl& impl = *controller.mImpl; + ModelPtr& model = impl.mModel; + LogicalModelPtr& logicalModel = model->mLogicalModel; + + for(auto& anchor : logicalModel->mAnchors) + { + if(anchor.endIndex < previousCursorIndex) // [anchor] CUR + { + continue; + } + if(anchor.startIndex < previousCursorIndex) // [anCURr] + { + anchor.endIndex += numberOfCharacters; + } + else // CUR [anchor] + { + anchor.startIndex += numberOfCharacters; + anchor.endIndex += numberOfCharacters; + } + DALI_LOG_INFO(gLogFilter, Debug::General, "Controller::InsertTextAnchor[%p] Anchor[%s] start[%d] end[%d]\n", &controller, anchor.href, anchor.startIndex, anchor.endIndex); + } +} + +void Controller::TextUpdater::RemoveTextAnchor(Controller& controller, int cursorOffset, int numberOfCharacters, CharacterIndex previousCursorIndex) +{ + Controller::Impl& impl = *controller.mImpl; + ModelPtr& model = impl.mModel; + LogicalModelPtr& logicalModel = model->mLogicalModel; + Vector::Iterator it = logicalModel->mAnchors.Begin(); + + while(it != logicalModel->mAnchors.End()) + { + Anchor& anchor = *it; + + if(anchor.endIndex <= previousCursorIndex && cursorOffset == 0) // [anchor] CUR >> + { + // Nothing happens. + } + else if(anchor.endIndex <= previousCursorIndex && cursorOffset == -1) // [anchor] << CUR + { + int endIndex = anchor.endIndex; + int offset = previousCursorIndex - endIndex; + int index = endIndex - (numberOfCharacters - offset); + + if(index < endIndex) + { + endIndex = index; + } + + if((int)anchor.startIndex >= endIndex) + { + if(anchor.href) + { + delete[] anchor.href; + } + it = logicalModel->mAnchors.Erase(it); + continue; + } + else + { + anchor.endIndex = endIndex; + } + } + else if(anchor.startIndex >= previousCursorIndex && cursorOffset == -1) // << CUR [anchor] + { + anchor.startIndex -= numberOfCharacters; + anchor.endIndex -= numberOfCharacters; + } + else if(anchor.startIndex >= previousCursorIndex && cursorOffset == 0) // CUR >> [anchor] + { + int startIndex = anchor.startIndex; + int endIndex = anchor.endIndex; + int index = previousCursorIndex + numberOfCharacters - 1; + + if(startIndex > index) + { + anchor.startIndex -= numberOfCharacters; + anchor.endIndex -= numberOfCharacters; + } + else if(endIndex > index + 1) + { + anchor.endIndex -= numberOfCharacters; + } + else + { + if(anchor.href) + { + delete[] anchor.href; + } + it = logicalModel->mAnchors.Erase(it); + continue; + } + } + else if(cursorOffset == -1) // [<< CUR] + { + int startIndex = anchor.startIndex; + int index = previousCursorIndex - numberOfCharacters; + + if(startIndex >= index) + { + anchor.startIndex = index; + } + anchor.endIndex -= numberOfCharacters; + } + else if(cursorOffset == 0) // [CUR >>] + { + anchor.endIndex -= numberOfCharacters; + } + else + { + // When this condition is reached, someting is wrong. + DALI_LOG_ERROR("Controller::RemoveTextAnchor[%p] Invaild state cursorOffset[%d]\n", &controller, cursorOffset); + } + + DALI_LOG_INFO(gLogFilter, Debug::General, "Controller::RemoveTextAnchor[%p] Anchor[%s] start[%d] end[%d]\n", &controller, anchor.href, anchor.startIndex, anchor.endIndex); + + it++; + } +} + } // namespace Text } // namespace Toolkit