Add exception handling in text-controller
[platform/core/uifw/dali-toolkit.git] / dali-toolkit / internal / text / text-controller-impl.cpp
index a96d23c..045fb8a 100644 (file)
@@ -507,10 +507,14 @@ void Controller::Impl::ClearGlyphModelData(CharacterIndex startIndex, CharacterI
     mModel->mVisualModel->mCharactersPerGlyph.Erase(charactersPerGlyphBuffer + mTextUpdateInfo.mStartGlyphIndex,
                                                     charactersPerGlyphBuffer + endGlyphIndexPlusOne);
 
-    // Clear the positions buffer.
-    Vector2* positionsBuffer = mModel->mVisualModel->mGlyphPositions.Begin();
-    mModel->mVisualModel->mGlyphPositions.Erase(positionsBuffer + mTextUpdateInfo.mStartGlyphIndex,
-                                                positionsBuffer + endGlyphIndexPlusOne);
+    // Should pass if mGlyphPositions has already been cleared in Controller::Relayouter::Relayout
+    if(0u != mModel->mVisualModel->mGlyphPositions.Count())
+    {
+      // Clear the positions buffer.
+      Vector2* positionsBuffer = mModel->mVisualModel->mGlyphPositions.Begin();
+      mModel->mVisualModel->mGlyphPositions.Erase(positionsBuffer + mTextUpdateInfo.mStartGlyphIndex,
+                                                  positionsBuffer + endGlyphIndexPlusOne);
+    }
   }
 
   if(NO_OPERATION != (LAYOUT & operations))
@@ -1209,7 +1213,9 @@ void Controller::Impl::SetTextSelectionRange(const uint32_t* pStart, const uint3
 
   if(mEventData->mSelectionEnabled && (pStart || pEnd))
   {
-    uint32_t length = static_cast<uint32_t>(mModel->mLogicalModel->mText.Count());
+    uint32_t length   = static_cast<uint32_t>(mModel->mLogicalModel->mText.Count());
+    uint32_t oldStart = mEventData->mLeftSelectionPosition;
+    uint32_t oldEnd   = mEventData->mRightSelectionPosition;
 
     if(pStart)
     {
@@ -1233,6 +1239,11 @@ void Controller::Impl::SetTextSelectionRange(const uint32_t* pStart, const uint3
       mEventData->mUpdateLeftSelectionPosition  = true;
       mEventData->mUpdateRightSelectionPosition = true;
     }
+
+    if(mSelectableControlInterface != nullptr)
+    {
+      mSelectableControlInterface->SelectionChanged(oldStart, oldEnd, mEventData->mLeftSelectionPosition, mEventData->mRightSelectionPosition);
+    }
   }
 }
 
@@ -1253,7 +1264,7 @@ bool Controller::Impl::SetPrimaryCursorPosition(CharacterIndex index, bool focus
     return false;
   }
 
-  if(mEventData->mPrimaryCursorPosition == index)
+  if(mEventData->mPrimaryCursorPosition == index && mEventData->mState != EventData::SELECTING)
   {
     // Nothing for same cursor position.
     return false;
@@ -1265,9 +1276,18 @@ bool Controller::Impl::SetPrimaryCursorPosition(CharacterIndex index, bool focus
   // If there is no focus, only the value is updated.
   if(focused)
   {
+    bool     wasInSelectingState = mEventData->mState == EventData::SELECTING;
+    uint32_t oldStart            = mEventData->mLeftSelectionPosition;
+    uint32_t oldEnd              = mEventData->mRightSelectionPosition;
     ChangeState(EventData::EDITING);
     mEventData->mLeftSelectionPosition = mEventData->mRightSelectionPosition = mEventData->mPrimaryCursorPosition;
     mEventData->mUpdateCursorPosition                                        = true;
+
+    if(mSelectableControlInterface != nullptr && wasInSelectingState)
+    {
+      mSelectableControlInterface->SelectionChanged(oldStart, oldEnd, mEventData->mLeftSelectionPosition, mEventData->mRightSelectionPosition);
+    }
+
     ScrollTextToMatchCursor();
   }
 
@@ -1384,9 +1404,17 @@ void Controller::Impl::RetrieveSelection(std::string& selectedText, bool deleteA
 
 void Controller::Impl::SetSelection(int start, int end)
 {
+  uint32_t oldStart = mEventData->mLeftSelectionPosition;
+  uint32_t oldEnd   = mEventData->mRightSelectionPosition;
+
   mEventData->mLeftSelectionPosition  = start;
   mEventData->mRightSelectionPosition = end;
   mEventData->mUpdateCursorPosition   = true;
+
+  if(mSelectableControlInterface != nullptr)
+  {
+    mSelectableControlInterface->SelectionChanged(oldStart, oldEnd, start, end);
+  }
 }
 
 std::pair<int, int> Controller::Impl::GetSelectionIndexes() const