!39105 复制和选择文本功能在CopyOption和TextSelectable为不同值的表现

Merge pull request !39105 from 范盼/AI_Copy_Select
This commit is contained in:
openharmony_ci 2024-07-31 03:01:55 +00:00 committed by Gitee
commit c2c9a95eee
No known key found for this signature in database
GPG Key ID: 173E9B9CA92EEF8F
8 changed files with 47 additions and 38 deletions

View File

@ -29,8 +29,6 @@ constexpr int32_t AI_TEXT_MAX_LENGTH = 500;
constexpr int32_t AI_TEXT_GAP = 100;
constexpr int32_t AI_DELAY_TIME = 100;
constexpr uint32_t SECONDS_TO_MILLISECONDS = 1000;
constexpr const char COPY_ACTION[] = "复制";
constexpr const char SELECT_ACTION[] = "选择文本";
const std::unordered_map<TextDataDetectType, std::string> TEXT_DETECT_MAP = {
{ TextDataDetectType::PHONE_NUMBER, "phoneNum" }, { TextDataDetectType::URL, "url" },
@ -57,8 +55,8 @@ void DataDetectorAdapter::GetAIEntityMenu()
"ArkUITextInitDataDetect");
}
bool DataDetectorAdapter::ShowAIEntityMenu(
const AISpan& aiSpan, const NG::RectF& aiRect, const RefPtr<NG::FrameNode>& targetNode, bool isShowSelectText)
bool DataDetectorAdapter::ShowAIEntityMenu(const AISpan& aiSpan, const NG::RectF& aiRect,
const RefPtr<NG::FrameNode>& targetNode, bool isShowCopy, bool isShowSelectText)
{
if (textDetectResult_.menuOptionAndAction.empty()) {
TAG_LOGW(AceLogTag::ACE_TEXT, "menu option is empty, please try again");
@ -68,7 +66,20 @@ bool DataDetectorAdapter::ShowAIEntityMenu(
mainContainerId_ = Container::CurrentId();
std::vector<std::pair<std::string, std::function<void()>>> menuOptions;
for (auto menuOption : textDetectResult_.menuOptionAndAction[TEXT_DETECT_MAP.at(aiSpan.type)]) {
auto menuOptionAndAction = textDetectResult_.menuOptionAndAction[TEXT_DETECT_MAP.at(aiSpan.type)];
if (menuOptionAndAction.empty()) {
return false;
}
if (!isShowSelectText) {
// delete the last option: selectText.
menuOptionAndAction.pop_back();
if (!isShowCopy) {
// delete the last option: copy.
menuOptionAndAction.pop_back();
}
}
for (auto menuOption : menuOptionAndAction) {
std::function<void()> onClickEvent = [aiSpan, menuOption, weak = AceType::WeakClaim(this),
targetNodeWeak = AceType::WeakClaim(AceType::RawPtr(targetNode))]() {
auto dataDetectorAdapter = weak.Upgrade();
@ -77,9 +88,7 @@ bool DataDetectorAdapter::ShowAIEntityMenu(
CHECK_NULL_VOID(targetNode);
dataDetectorAdapter->OnClickAIMenuOption(aiSpan, menuOption, targetNode);
};
if (isShowSelectText || !(menuOption.first == std::string(SELECT_ACTION))) {
menuOptions.push_back(std::make_pair(menuOption.first, onClickEvent));
}
menuOptions.push_back(std::make_pair(menuOption.first, onClickEvent));
}
auto pipeline = NG::PipelineContext::GetCurrentContextSafely();
CHECK_NULL_RETURN(pipeline, false);
@ -107,10 +116,8 @@ void DataDetectorAdapter::OnClickAIMenuOption(const AISpan& aiSpan,
auto bundleName = runtimeContext->GetBundleName();
hasClickedMenuOption_ = true;
if (onClickMenu_ && menuOption.first == std::string(COPY_ACTION)) {
onClickMenu_(std::string(COPY_ACTION));
} else if (onClickMenu_ && menuOption.first == std::string(SELECT_ACTION)) {
onClickMenu_(std::string(SELECT_ACTION));
if (onClickMenu_ && std::holds_alternative<std::function<std::string()>>(menuOption.second)) {
onClickMenu_(std::get<std::function<std::string()>>(menuOption.second)());
} else if (std::holds_alternative<std::function<void(sptr<IRemoteObject>, std::string)>>(menuOption.second)) {
std::get<std::function<void(sptr<IRemoteObject>, std::string)>>(menuOption.second)(token, aiSpan.content);
} else if (std::holds_alternative<std::function<void(int32_t, std::string)>>(menuOption.second)) {

View File

@ -26,8 +26,8 @@ void DataDetectorAdapter::ParseAIJson(
const std::unique_ptr<JsonValue>& jsonValue, TextDataDetectType type, int32_t startPos) {}
void DataDetectorAdapter::StartAITask() {}
bool DataDetectorAdapter::ShowAIEntityMenu(
const AISpan& aiSpan, const NG::RectF& aiRect, const RefPtr<NG::FrameNode>& targetNode, bool isShowSelectText)
bool DataDetectorAdapter::ShowAIEntityMenu(const AISpan& aiSpan, const NG::RectF& aiRect,
const RefPtr<NG::FrameNode>& targetNode, bool isShowCopy, bool isShowSelectText)
{
return true;
}

View File

@ -80,7 +80,7 @@ public:
aiDetectInitialized_ = false;
}
bool ShowAIEntityMenu(const AISpan& aiSpan, const NG::RectF& aiRect, const RefPtr<NG::FrameNode>& targetNode,
bool isShowSelectText = true);
bool isShowCopy = true, bool isShowSelectText = true);
void ResponseBestMatchItem(const AISpan& aiSpan);
private:

View File

@ -6368,7 +6368,7 @@ void RichEditorPattern::HandleOnCopyStyledString()
subSpanString->EncodeTlv(tlvData);
clipboard_->AddSpanStringRecord(pasteData, tlvData);
clipboard_->AddTextRecord(pasteData, subSpanString->GetString());
clipboard_->SetData(pasteData, HandleOnCopyOptions());
clipboard_->SetData(pasteData, copyOption_);
}
void RichEditorPattern::OnCopyOperation(bool isUsingExternalKeyboard)
@ -6408,7 +6408,7 @@ void RichEditorPattern::OnCopyOperation(bool isUsingExternalKeyboard)
for (auto resultObj = copyResultObjects.rbegin(); resultObj != copyResultObjects.rend(); ++resultObj) {
resultProcessor(*resultObj);
}
clipboard_->SetData(pasteData, HandleOnCopyOptions());
clipboard_->SetData(pasteData, copyOption_);
}
void RichEditorPattern::HandleOnCopy(bool isUsingExternalKeyboard)
@ -6416,7 +6416,7 @@ void RichEditorPattern::HandleOnCopy(bool isUsingExternalKeyboard)
CHECK_NULL_VOID(clipboard_);
TAG_LOGD(AceLogTag::ACE_RICH_TEXT, "isUsingExternalKeyboard=%{public}d, copyOption=%{public}d",
isUsingExternalKeyboard, copyOption_);
if (HandleOnCopyOptions() == CopyOptions::None) {
if (copyOption_ == CopyOptions::None) {
return;
}
auto host = GetHost();

View File

@ -64,8 +64,8 @@
namespace OHOS::Ace::NG {
namespace {
constexpr double DIMENSION_VALUE = 16.0;
constexpr const char COPY_ACTION[] = "复制";
constexpr const char SELECT_ACTION[] = "选择文本";
constexpr char COPY[] = "copy";
constexpr char SELECT_TEXT[] = "selectText";
constexpr const char SYMBOL_COLOR[] = "BLACK";
constexpr int32_t API_PROTEXTION_GREATER_NINE = 9;
const std::u16string SYMBOL_TRANS = u"\uF0001";
@ -517,14 +517,6 @@ std::string TextPattern::GetSelectedText(int32_t start, int32_t end) const
return value;
}
CopyOptions TextPattern::HandleOnCopyOptions()
{
if (copyOption_ == CopyOptions::None && dataDetectorAdapter_->hasClickedMenuOption_) {
return CopyOptions::Local;
}
return copyOption_;
}
void TextPattern::HandleOnCopy()
{
CHECK_NULL_VOID(clipboard_);
@ -537,7 +529,7 @@ void TextPattern::HandleOnCopy()
if (isSpanStringMode_ && !externalParagraph_) {
HandleOnCopySpanString();
} else if (!value.empty()) {
clipboard_->SetData(value, HandleOnCopyOptions());
clipboard_->SetData(value, copyOption_);
}
}
HiddenMenu();
@ -561,7 +553,7 @@ void TextPattern::HandleOnCopySpanString()
std::vector<uint8_t> tlvData;
subSpanString->EncodeTlv(tlvData);
clipboard_->AddSpanStringRecord(pasteData, tlvData);
clipboard_->SetData(pasteData, HandleOnCopyOptions());
clipboard_->SetData(pasteData, copyOption_);
}
void TextPattern::HiddenMenu()
@ -878,10 +870,10 @@ void TextPattern::SetOnClickMenu(const AISpan& aiSpan, const CalculateHandleFunc
CHECK_NULL_VOID(pattern);
pattern->CloseSelectOverlay();
pattern->HandleSelectionChange(aiSpan.start, aiSpan.end);
if (action == std::string(COPY_ACTION)) {
if (action == COPY) {
pattern->HandleOnCopy();
pattern->ResetSelection();
} else if (action == std::string(SELECT_ACTION)) {
} else if (action == SELECT_TEXT) {
if (calculateHandleFunc == nullptr) {
pattern->CalculateHandleOffsetAndShowOverlay();
} else {
@ -927,7 +919,18 @@ bool TextPattern::ShowAIEntityMenu(const AISpan& aiSpan, const CalculateHandleFu
aiRect = textSelector_.firstHandle.CombineRectT(textSelector_.secondHandle);
}
return dataDetectorAdapter_->ShowAIEntityMenu(aiSpan, aiRect, host, IsSelectableAndCopy());
bool isShowCopy = true;
bool isShowSelectText = true;
auto textLayoutProperty = GetLayoutProperty<TextLayoutProperty>();
CHECK_NULL_RETURN(textLayoutProperty, false);
auto mode = textLayoutProperty->GetTextSelectableModeValue(TextSelectableMode::SELECTABLE_UNFOCUSABLE);
if (copyOption_ == CopyOptions::None) {
isShowCopy = false;
isShowSelectText = false;
} else if (mode == TextSelectableMode::UNSELECTABLE) {
isShowSelectText = false;
}
return dataDetectorAdapter_->ShowAIEntityMenu(aiSpan, aiRect, host, isShowCopy, isShowSelectText);
}
void TextPattern::HandleDoubleClickEvent(GestureEvent& info)

View File

@ -533,7 +533,6 @@ public:
bool IsSelectAll();
void HandleOnCopy();
void HandleOnCopySpanString();
virtual CopyOptions HandleOnCopyOptions();
virtual void HandleOnSelectAll();
void SetTextSelectableMode(TextSelectableMode value);

View File

@ -30,8 +30,8 @@ class IRemoteObject;
namespace OHOS::Ace {
constexpr int32_t UNSUPPORTED_CODE = 801;
using FuncVariant =
std::variant<std::function<void(sptr<IRemoteObject>, std::string)>, std::function<void(int32_t, std::string)>,
using FuncVariant = std::variant<std::function<std::string()>, std::function<void(sptr<IRemoteObject>, std::string)>,
std::function<void(int32_t, std::string)>,
std::function<void(int32_t, std::string, std::string, int32_t, std::string)>>;
struct TextDataDetectInfo {

View File

@ -26,8 +26,8 @@ void DataDetectorAdapter::ParseAIJson(
const std::unique_ptr<JsonValue>& jsonValue, TextDataDetectType type, int32_t startPos) {}
void DataDetectorAdapter::StartAITask() {}
bool DataDetectorAdapter::ShowAIEntityMenu(
const AISpan& aiSpan, const NG::RectF& aiRect, const RefPtr<NG::FrameNode>& targetNode, bool isShowSelectText)
bool DataDetectorAdapter::ShowAIEntityMenu(const AISpan& aiSpan, const NG::RectF& aiRect,
const RefPtr<NG::FrameNode>& targetNode, bool isShowCopy, bool isShowSelectText)
{
return true;
}