Text controller checks data type of the clipboard 30/309930/2
authorBowon Ryu <bowon.ryu@samsung.com>
Thu, 18 Apr 2024 07:46:55 +0000 (16:46 +0900)
committerBowon Ryu <bowon.ryu@samsung.com>
Mon, 22 Apr 2024 03:18:05 +0000 (12:18 +0900)
IsClipboardEmpty works meaningfully.
Temporary code has been applied to paste html type.
Once multiple types and data can be stored in the clipboard, this code should be removed.

Change-Id: I29b279acf19dd1c3397568b55e0567d314c41990
Signed-off-by: Bowon Ryu <bowon.ryu@samsung.com>
automated-tests/src/dali-toolkit/dali-toolkit-test-utils/toolkit-clipboard.cpp
automated-tests/src/dali-toolkit/dali-toolkit-test-utils/toolkit-clipboard.h
automated-tests/src/dali-toolkit/utc-Dali-TextField.cpp
dali-toolkit/internal/text/controller/text-controller-impl.cpp
dali-toolkit/internal/text/controller/text-controller-impl.h
dali-toolkit/internal/text/controller/text-controller.cpp

index 39d04e3..b8e1a03 100644 (file)
@@ -65,6 +65,11 @@ public:
   Dali::Clipboard::DataReceivedSignalType& DataReceivedSignal();
 
   /**
+   * @copydoc Dali::Clipboard::HasType()
+   */
+  bool HasType(const std::string& mimeType);
+
+  /**
    * @copydoc Dali::Clipboard::SetData()
    */
   bool SetData(const Dali::Clipboard::ClipData& clipData);
@@ -152,6 +157,11 @@ Dali::Clipboard::DataReceivedSignalType& Clipboard::DataReceivedSignal()
   return mDataReceivedSignal;
 }
 
+bool Clipboard::HasType(const std::string& mimeType)
+{
+  return mMimeType == mimeType ? true : false;
+}
+
 bool Clipboard::SetData(const Dali::Clipboard::ClipData& clipData)
 {
   mMimeType = clipData.GetMimeType();
index 7ad3187..4685e6d 100644 (file)
@@ -131,6 +131,13 @@ public:
   DataReceivedSignalType& DataReceivedSignal();
 
   /**
+   * @brief Check if there is data in the clipboard with a given mime type.
+   * @param[in] mimeType mime type to search for.
+   * @return bool true if there is data, otherwise false.
+   */
+  bool HasType(const std::string& mimeType);
+
+  /**
    * @brief Send the given data to the clipboard.
    * @param[in] clipData data to send to the clipboard
    * @return bool true if the internal clipboard sending was successful.
index ccc6bb3..0e0711f 100644 (file)
@@ -3244,7 +3244,56 @@ int utcDaliTextFieldEvent08(void)
     event.AddPoint(GetPointUpInside(position));
     application.ProcessEvent(event);
   }
-  DALI_TEST_EQUALS(field.GetProperty<std::string>(TextEditor::Property::TEXT), std::string("testTextFieldEvent"), TEST_LOCATION);
+  DALI_TEST_EQUALS(field.GetProperty<std::string>(TextField::Property::TEXT), std::string("testTextFieldEvent"), TEST_LOCATION);
+
+  Dali::Clipboard::ClipData htmlData("application/xhtml+xml", "testTextFieldEventHtml");
+  clipboard.SetData(htmlData);
+
+  field.SetProperty(TextField::Property::TEXT, "");
+
+  // Render and notify
+  application.SendNotification();
+  application.Render();
+
+  // Long Press
+  TestGenerateLongPress(application, 1.0f, 25.0f, 20);
+
+  // Render and notify
+  application.SendNotification();
+  application.Render();
+
+  Wait(application, 500);
+
+  TestEndLongPress(application, 1.0f, 25.0f, 520);
+
+  // Long Press
+  TestGenerateLongPress(application, 1.0f, 25.0f, 600);
+
+  // Render and notify
+  application.Render();
+
+  Wait(application, 500);
+
+  stage = application.GetScene();
+  layer = stage.GetRootLayer();
+  actor = layer.FindChildByName("optionPaste");
+
+  if(actor)
+  {
+    Vector3 worldPosition = actor.GetCurrentProperty<Vector3>(Actor::Property::WORLD_POSITION);
+    Vector2 halfStageSize = stage.GetSize() / 2.0f;
+    Vector2 position(worldPosition.x + halfStageSize.width, worldPosition.y + halfStageSize.height);
+
+    Dali::Integration::TouchEvent event;
+    event = Dali::Integration::TouchEvent();
+    event.AddPoint(GetPointDownInside(position));
+    application.ProcessEvent(event);
+
+    event = Dali::Integration::TouchEvent();
+    event.AddPoint(GetPointUpInside(position));
+    application.ProcessEvent(event);
+  }
+  DALI_TEST_EQUALS(field.GetProperty<std::string>(TextField::Property::TEXT), std::string("testTextFieldEventHtml"), TEST_LOCATION);
 
   END_TEST;
 }
index f70d8af..10a76f1 100644 (file)
@@ -53,6 +53,7 @@ constexpr float MAX_FLOAT = std::numeric_limits<float>::max();
 
 const char* EMPTY_STRING         = "";
 const char* MIME_TYPE_TEXT_PLAIN = "text/plain;charset=utf-8";
+const char* MIME_TYPE_HTML       = "application/xhtml+xml";
 
 } // namespace
 
@@ -1161,6 +1162,12 @@ bool Controller::Impl::CopyStringToClipboard(const std::string& source)
   return false;
 }
 
+bool Controller::Impl::IsClipboardEmpty()
+{
+  bool result(Clipboard::IsAvailable() && EnsureClipboardCreated() && (mClipboard.HasType(MIME_TYPE_TEXT_PLAIN) || mClipboard.HasType(MIME_TYPE_HTML)));
+  return !result;
+}
+
 void Controller::Impl::SendSelectionToClipboard(bool deleteAfterSending)
 {
   std::string selectedText;
index 56ca85b..cc6a818 100644 (file)
@@ -616,12 +616,6 @@ struct Controller::Impl
     return mClipboard != nullptr ? true : false;
   }
 
-  bool IsClipboardEmpty()
-  {
-    bool result(Clipboard::IsAvailable() && EnsureClipboardCreated() && mClipboard.NumberOfItems());
-    return !result; // If NumberOfItems greater than 0, return false
-  }
-
   bool IsClipboardVisible()
   {
     bool result(Clipboard::IsAvailable() && EnsureClipboardCreated() && mClipboard.IsVisible());
@@ -629,6 +623,14 @@ struct Controller::Impl
   }
 
   /**
+   * @brief Whether the clipboard is empty or not.
+   * Checks the types that the text controller can paste and returns the result.
+   *
+   * @return Return whether or not the clipboard is empty.
+   */
+  bool IsClipboardEmpty();
+
+  /**
    * @copydoc Controller::GetLayoutDirection()
    */
   Dali::LayoutDirection::Type GetLayoutDirection(Dali::Actor& actor) const;
index d17e187..548224b 100644 (file)
@@ -48,6 +48,7 @@ Debug::Filter* gLogFilter = Debug::Filter::New(Debug::NoLogging, true, "LOG_TEXT
 
 const char* EMPTY_STRING         = "";
 const char* MIME_TYPE_TEXT_PLAIN = "text/plain;charset=utf-8";
+const char* MIME_TYPE_HTML       = "application/xhtml+xml";
 
 template<typename Type>
 void EnsureCreated(Type*& object)
@@ -1728,11 +1729,27 @@ void Controller::PasteClipboardItemEvent(uint32_t id, const char* mimeType, cons
   mImpl->mClipboard.DataReceivedSignal().Disconnect(this, &Controller::PasteClipboardItemEvent);
 
   // If the id is 0u, it is an invalid response.
+  if(id == 0u)
+  {
+    return;
+  }
+
   // text-controller allows only plain text type.
-  if(id != 0u && !strncmp(mimeType, MIME_TYPE_TEXT_PLAIN, strlen(MIME_TYPE_TEXT_PLAIN)))
+  if(!strncmp(mimeType, MIME_TYPE_TEXT_PLAIN, strlen(MIME_TYPE_TEXT_PLAIN)))
   {
     EventHandler::PasteClipboardItemEvent(*this, data);
   }
+  else if(!strncmp(mimeType, MIME_TYPE_HTML, strlen(MIME_TYPE_HTML)))
+  {
+    // This does not mean that text controls can parse html.
+    // This is temporary code, as text controls do not support html type data.
+    // Simply remove the tags inside the angle brackets.
+    // Once multiple types and data can be stored in the clipboard, this code should be removed.
+    std::regex reg("<[^>]*>");
+    std::string result = regex_replace(data, reg, "");
+
+    EventHandler::PasteClipboardItemEvent(*this, result.c_str());
+  }
 }
 
 void Controller::PasteText()
@@ -1742,8 +1759,11 @@ void Controller::PasteText()
     // Connect the signal before calling GetData() of the clipboard.
     mImpl->mClipboard.DataReceivedSignal().Connect(this, &Controller::PasteClipboardItemEvent);
 
+    // If there is no plain text type data on the clipboard, request html type data.
+    std::string mimeType = mImpl->mClipboard.HasType(MIME_TYPE_TEXT_PLAIN) ? MIME_TYPE_TEXT_PLAIN : MIME_TYPE_HTML;
+
     // Request clipboard service to retrieve an item.
-    uint id = mImpl->mClipboard.GetData(MIME_TYPE_TEXT_PLAIN);
+    uint id = mImpl->mClipboard.GetData(mimeType);
     if(id == 0u)
     {
       // If the return id is 0u, the signal is not emitted, we must disconnect signal here.