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