1 /*
2 * Copyright (c) 2024 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15 #include "native_text_changed_listener.h"
16 #include "input_method_utils.h"
17 #include "native_inputmethod_utils.h"
18
19 namespace OHOS {
20 namespace MiscServices {
~NativeTextChangedListener()21 NativeTextChangedListener::~NativeTextChangedListener()
22 {
23 textEditor_ = nullptr;
24 }
InsertText(const std::u16string & text)25 void NativeTextChangedListener::InsertText(const std::u16string &text)
26 {
27 if (textEditor_ == nullptr) {
28 IMSA_HILOGE("textEditor_ is nullptr");
29 return;
30 }
31
32 if (textEditor_->insertTextFunc == nullptr) {
33 IMSA_HILOGE("insertTextFunc is nullptr");
34 return;
35 }
36
37 textEditor_->insertTextFunc(textEditor_, text.c_str(), text.length());
38 }
39
DeleteForward(int32_t length)40 void NativeTextChangedListener::DeleteForward(int32_t length)
41 {
42 if (textEditor_ == nullptr) {
43 IMSA_HILOGE("textEditor_ is nullptr");
44 return;
45 }
46
47 if (textEditor_->deleteForwardFunc == nullptr) {
48 IMSA_HILOGE("deleteForwardFunc is nullptr");
49 return;
50 }
51
52 textEditor_->deleteForwardFunc(textEditor_, length);
53 }
54
DeleteBackward(int32_t length)55 void NativeTextChangedListener::DeleteBackward(int32_t length)
56 {
57 if (textEditor_ == nullptr) {
58 IMSA_HILOGE("textEditor_ is nullptr");
59 return;
60 }
61
62 if (textEditor_->deleteBackwardFunc == nullptr) {
63 IMSA_HILOGE("deleteBackwardFunc is nullptr");
64 return;
65 }
66
67 textEditor_->deleteBackwardFunc(textEditor_, length);
68 }
69
SendKeyboardStatus(const OHOS::MiscServices::KeyboardStatus & status)70 void NativeTextChangedListener::SendKeyboardStatus(const OHOS::MiscServices::KeyboardStatus &status)
71 {
72 if (textEditor_ == nullptr) {
73 IMSA_HILOGE("textEditor_ is nullptr");
74 return;
75 }
76
77 if (textEditor_->sendKeyboardStatusFunc == nullptr) {
78 IMSA_HILOGE("sendKeyboardStatusFunc is nullptr");
79 return;
80 }
81
82 textEditor_->sendKeyboardStatusFunc(textEditor_, ConvertToCKeyboardStatus(status));
83 }
84
SendFunctionKey(const OHOS::MiscServices::FunctionKey & functionKey)85 void NativeTextChangedListener::SendFunctionKey(const OHOS::MiscServices::FunctionKey &functionKey)
86 {
87 if (textEditor_ == nullptr) {
88 IMSA_HILOGE("textEditor_ is nullptr");
89 return;
90 }
91
92 if (textEditor_->sendEnterKeyFunc == nullptr) {
93 IMSA_HILOGE("sendEnterKeyFunc is nullptr");
94 return;
95 }
96
97 auto enterKeyType = ConvertToCEnterKeyType(functionKey.GetEnterKeyType());
98
99 textEditor_->sendEnterKeyFunc(textEditor_, enterKeyType);
100 }
101
MoveCursor(const OHOS::MiscServices::Direction direction)102 void NativeTextChangedListener::MoveCursor(const OHOS::MiscServices::Direction direction)
103 {
104 if (textEditor_ == nullptr) {
105 IMSA_HILOGE("textEditor_ is nullptr");
106 return;
107 }
108
109 if (textEditor_->moveCursorFunc == nullptr) {
110 IMSA_HILOGE("moveCursorFunc is nullptr");
111 return;
112 }
113
114 textEditor_->moveCursorFunc(textEditor_, ConvertToCDirection(direction));
115 }
116
HandleSetSelection(int32_t start,int32_t end)117 void NativeTextChangedListener::HandleSetSelection(int32_t start, int32_t end)
118 {
119 if (textEditor_ == nullptr) {
120 IMSA_HILOGE("textEditor_ is nullptr");
121 return;
122 }
123
124 if (textEditor_->handleSetSelectionFunc == nullptr) {
125 IMSA_HILOGE("handleSetSelectionFunc is nullptr");
126 return;
127 }
128
129 textEditor_->handleSetSelectionFunc(textEditor_, start, end);
130 }
131
HandleExtendAction(int32_t action)132 void NativeTextChangedListener::HandleExtendAction(int32_t action)
133 {
134 if (textEditor_ == nullptr) {
135 IMSA_HILOGE("textEditor_ is nullptr");
136 return;
137 }
138
139 if (textEditor_->handleExtendActionFunc == nullptr) {
140 IMSA_HILOGE("handleExtendActionFunc is nullptr");
141 return;
142 }
143
144 textEditor_->handleExtendActionFunc(textEditor_, ConvertToCExtendAction(action));
145 }
146
GetLeftTextOfCursor(int32_t number)147 std::u16string NativeTextChangedListener::GetLeftTextOfCursor(int32_t number)
148 {
149 if (textEditor_ == nullptr) {
150 IMSA_HILOGE("textEditor_ is nullptr");
151 return u"";
152 }
153
154 if (textEditor_->getLeftTextOfCursorFunc == nullptr) {
155 IMSA_HILOGE("getLeftTextOfCursorFunc is nullptr");
156 return u"";
157 }
158
159 if (number <= 0 || number > MAX_TEXT_LENGTH) {
160 IMSA_HILOGE("number is invalid");
161 return u"";
162 }
163
164 size_t length = static_cast<size_t>(number + 1);
165 char16_t *text = new (std::nothrow) char16_t[length];
166 if (text == nullptr) {
167 IMSA_HILOGE("text is nullptr");
168 return u"";
169 }
170
171 textEditor_->getLeftTextOfCursorFunc(textEditor_, number, text, &length);
172
173 std::u16string textStr(text, length);
174 delete[] text;
175 return textStr;
176 }
177
GetRightTextOfCursor(int32_t number)178 std::u16string NativeTextChangedListener::GetRightTextOfCursor(int32_t number)
179 {
180 if (textEditor_ == nullptr) {
181 IMSA_HILOGE("textEditor_ is nullptr");
182 return u"";
183 }
184
185 if (textEditor_->getRightTextOfCursorFunc == nullptr) {
186 IMSA_HILOGE("getRightTextOfCursorFunc is nullptr");
187 return u"";
188 }
189
190 if (number <= 0 || number > MAX_TEXT_LENGTH) {
191 IMSA_HILOGE("number is invalid");
192 return u"";
193 }
194
195 size_t length = static_cast<size_t>(number + 1);
196 char16_t *text = new (std::nothrow) char16_t[length];
197 if (text == nullptr) {
198 IMSA_HILOGE("text is nullptr");
199 return u"";
200 }
201
202 textEditor_->getRightTextOfCursorFunc(textEditor_, number, text, &length);
203 std::u16string textStr(text, length);
204 delete[] text;
205 return textStr;
206 }
207
GetTextIndexAtCursor()208 int32_t NativeTextChangedListener::GetTextIndexAtCursor()
209 {
210 if (textEditor_ == nullptr) {
211 IMSA_HILOGE("textEditor_ is nullptr");
212 return 0;
213 }
214
215 if (textEditor_->getTextIndexAtCursorFunc == nullptr) {
216 IMSA_HILOGE("getTextIndexAtCursorFunc is nullptr");
217 return 0;
218 }
219
220 return textEditor_->getTextIndexAtCursorFunc(textEditor_);
221 }
222
ReceivePrivateCommand(const std::unordered_map<std::string,PrivateDataValue> & privateCommand)223 int32_t NativeTextChangedListener::ReceivePrivateCommand(
224 const std::unordered_map<std::string, PrivateDataValue> &privateCommand)
225 {
226 if (textEditor_ == nullptr) {
227 IMSA_HILOGE("textEditor_ is nullptr");
228 return ErrorCode::ERROR_NULL_POINTER;
229 }
230
231 if (textEditor_->receivePrivateCommandFunc == nullptr) {
232 IMSA_HILOGE("receivePrivateCommandFunc is nullptr");
233 return ErrorCode::ERROR_NULL_POINTER;
234 }
235
236 InputMethod_PrivateCommand **command = new (std::nothrow) InputMethod_PrivateCommand *[privateCommand.size()];
237 if (command == nullptr) {
238 IMSA_HILOGE("command is nullptr");
239 return ErrorCode::ERROR_NULL_POINTER;
240 }
241
242 size_t index = 0;
243 for (const auto &item : privateCommand) {
244 command[index] = new InputMethod_PrivateCommand();
245 command[index]->key = item.first;
246 command[index]->value = item.second;
247 ++index;
248 }
249
250 auto errCode = textEditor_->receivePrivateCommandFunc(textEditor_, command, privateCommand.size());
251
252 for (size_t i = 0; i < index; ++i) {
253 delete command[i];
254 }
255 delete[] command;
256 return errCode;
257 }
258
SetPreviewText(const std::u16string & text,const OHOS::MiscServices::Range & range)259 int32_t NativeTextChangedListener::SetPreviewText(const std::u16string &text, const OHOS::MiscServices::Range &range)
260 {
261 if (textEditor_ == nullptr) {
262 IMSA_HILOGE("textEditor_ is nullptr");
263 return ErrorCode::ERROR_NULL_POINTER;
264 }
265
266 if (textEditor_->setPreviewTextFunc == nullptr) {
267 IMSA_HILOGE("setPreviewTextFunc is nullptr");
268 return ErrorCode::ERROR_NULL_POINTER;
269 }
270
271 return textEditor_->setPreviewTextFunc(textEditor_, text.c_str(), text.length(), range.start, range.end);
272 }
273
FinishTextPreview()274 void NativeTextChangedListener::FinishTextPreview()
275 {
276 if (textEditor_ == nullptr) {
277 IMSA_HILOGE("textEditor_ is nullptr");
278 return;
279 }
280
281 if (textEditor_->finishTextPreviewFunc == nullptr) {
282 IMSA_HILOGE("finishTextPreviewFunc is nullptr");
283 return;
284 }
285
286 textEditor_->finishTextPreviewFunc(textEditor_);
287 }
288
OnDetach()289 void NativeTextChangedListener::OnDetach()
290 {
291 ClearInputMethodProxy();
292 }
293
ConvertToCKeyboardStatus(OHOS::MiscServices::KeyboardStatus status)294 InputMethod_KeyboardStatus NativeTextChangedListener::ConvertToCKeyboardStatus(
295 OHOS::MiscServices::KeyboardStatus status)
296 {
297 switch (status) {
298 case OHOS::MiscServices::KeyboardStatus::HIDE:
299 return IME_KEYBOARD_STATUS_HIDE;
300 case OHOS::MiscServices::KeyboardStatus::SHOW:
301 return IME_KEYBOARD_STATUS_SHOW;
302 default:
303 return IME_KEYBOARD_STATUS_NONE;
304 }
305 }
306
ConvertToCEnterKeyType(OHOS::MiscServices::EnterKeyType enterKeyType)307 InputMethod_EnterKeyType NativeTextChangedListener::ConvertToCEnterKeyType(
308 OHOS::MiscServices::EnterKeyType enterKeyType)
309 {
310 switch (enterKeyType) {
311 case OHOS::MiscServices::EnterKeyType::NONE:
312 return IME_ENTER_KEY_NONE;
313 case OHOS::MiscServices::EnterKeyType::GO:
314 return IME_ENTER_KEY_GO;
315 case OHOS::MiscServices::EnterKeyType::SEARCH:
316 return IME_ENTER_KEY_SEARCH;
317 case OHOS::MiscServices::EnterKeyType::SEND:
318 return IME_ENTER_KEY_SEND;
319 case OHOS::MiscServices::EnterKeyType::NEXT:
320 return IME_ENTER_KEY_NEXT;
321 case OHOS::MiscServices::EnterKeyType::DONE:
322 return IME_ENTER_KEY_DONE;
323 case OHOS::MiscServices::EnterKeyType::PREVIOUS:
324 return IME_ENTER_KEY_PREVIOUS;
325 case OHOS::MiscServices::EnterKeyType::NEW_LINE:
326 return IME_ENTER_KEY_NEWLINE;
327 default:
328 return IME_ENTER_KEY_UNSPECIFIED;
329 }
330 }
331
ConvertToCDirection(OHOS::MiscServices::Direction direction)332 InputMethod_Direction NativeTextChangedListener::ConvertToCDirection(OHOS::MiscServices::Direction direction)
333 {
334 switch (direction) {
335 case OHOS::MiscServices::Direction::NONE:
336 return IME_DIRECTION_NONE;
337 case OHOS::MiscServices::Direction::UP:
338 return IME_DIRECTION_UP;
339 case OHOS::MiscServices::Direction::DOWN:
340 return IME_DIRECTION_DOWN;
341 case OHOS::MiscServices::Direction::LEFT:
342 return IME_DIRECTION_LEFT;
343 case OHOS::MiscServices::Direction::RIGHT:
344 return IME_DIRECTION_RIGHT;
345 default:
346 return IME_DIRECTION_NONE;
347 }
348 }
349
ConvertToCExtendAction(int32_t action)350 InputMethod_ExtendAction NativeTextChangedListener::ConvertToCExtendAction(int32_t action)
351 {
352 switch (action) {
353 case static_cast<int32_t>(OHOS::MiscServices::ExtendAction::SELECT_ALL):
354 return IME_EXTEND_ACTION_SELECT_ALL;
355 case static_cast<int32_t>(OHOS::MiscServices::ExtendAction::CUT):
356 return IME_EXTEND_ACTION_CUT;
357 case static_cast<int32_t>(OHOS::MiscServices::ExtendAction::COPY):
358 return IME_EXTEND_ACTION_COPY;
359 case static_cast<int32_t>(OHOS::MiscServices::ExtendAction::PASTE):
360 return IME_EXTEND_ACTION_PASTE;
361 default:
362 IMSA_HILOGE("invalid action:%{public}d", action);
363 return IME_EXTEND_ACTION_SELECT_ALL;
364 }
365 }
366 } // namespace MiscServices
367 } // namespace OHOS