X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=dali-toolkit%2Finternal%2Ftext%2Ftext-controller-text-updater.cpp;h=d94636519a50858dd92485f9a9853e029f33ee62;hb=699c8c5f00b8ea4bba12b4e6e6f91b022cb261b4;hp=c22e207b0fb9687b4fc5388429bdcd8a845073f5;hpb=f2039d47f9bed8104575da80a2ecf0bb6e37ff8d;p=platform%2Fcore%2Fuifw%2Fdali-toolkit.git diff --git a/dali-toolkit/internal/text/text-controller-text-updater.cpp b/dali-toolkit/internal/text/text-controller-text-updater.cpp index c22e207..d946365 100644 --- a/dali-toolkit/internal/text/text-controller-text-updater.cpp +++ b/dali-toolkit/internal/text/text-controller-text-updater.cpp @@ -81,7 +81,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; @@ -153,7 +156,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->TextChanged(); + impl.mEditableControlInterface->TextChanged(true); } } @@ -253,7 +256,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 +381,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; @@ -433,7 +442,7 @@ void Controller::TextUpdater::PasteText(Controller& controller, const std::strin if(NULL != impl.mEditableControlInterface) { // Do this last since it provides callbacks into application code - impl.mEditableControlInterface->TextChanged(); + impl.mEditableControlInterface->TextChanged(true); } } @@ -461,8 +470,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 +556,13 @@ bool Controller::TextUpdater::RemoveText( currentText.Erase(first, last); + if(impl.mMarkupProcessorEnabled) + { + RemoveTextAnchor(controller, cursorOffset, numberOfCharacters, previousCursorIndex); + } + // Cursor position retreat - oldCursorIndex = cursorIndex; + previousCursorIndex = cursorIndex; eventData->mScrollAfterDelete = true; @@ -580,6 +594,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 +621,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 +644,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