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