Fix issue detected by static analysis tool
[platform/core/uifw/inputdelegator.git] / src / w-input-keyboard.cpp
1 /*
2  * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  * Licensed under the Apache License, Version 2.0 (the License);
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an AS IS BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #include "Debug.h"
18
19 #include <app.h>
20 #include <Elementary.h>
21
22 #include <stdlib.h>
23
24 #include "w-input-keyboard.h"
25 #include "w-input-selector.h"
26
27 extern InputKeyboardData g_input_keyboard_data;
28 extern App_Data* app_data;
29
30 Evas_Object *entry;
31
32 bool input_keyboard_init(app_control_h app_control)
33 {
34         int ret = -1;
35         char *default_text = NULL;
36         char *guide_text = NULL;
37         char *return_key_type = NULL;
38         char *max_text_length = NULL;
39         char *cursor_position_set = NULL;
40
41         input_keyboard_deinit();
42
43         ret = app_control_get_extra_data(app_control, APP_CONTROL_DATA_INPUT_DEFAULT_TEXT, &default_text);
44         if (ret == APP_CONTROL_ERROR_NONE) {
45                 if (default_text) {
46                         g_input_keyboard_data.default_text = string(default_text);
47                         free(default_text);
48                 }
49         }
50         ret = app_control_get_extra_data(app_control, APP_CONTROL_DATA_INPUT_GUIDE_TEXT, &guide_text);
51         if (ret == APP_CONTROL_ERROR_NONE) {
52                 if (guide_text) {
53                         g_input_keyboard_data.guide_text = string(guide_text);
54                         free(guide_text);
55                 }
56         }
57         ret = app_control_get_extra_data(app_control, "return_key_type", &return_key_type);
58         if (ret == APP_CONTROL_ERROR_NONE) {
59                 if (return_key_type) {
60                         g_input_keyboard_data.return_key_type = string(return_key_type);
61                         free(return_key_type);
62                 }
63         }
64         ret = app_control_get_extra_data(app_control, "max_text_length", &max_text_length);
65         if (ret == APP_CONTROL_ERROR_NONE) {
66                 if (max_text_length) {
67                         g_input_keyboard_data.max_text_length = atoi(max_text_length);
68                         free(max_text_length);
69                 }
70         }
71         ret = app_control_get_extra_data(app_control, "cursor_position_set", &cursor_position_set);
72         if (ret == APP_CONTROL_ERROR_NONE) {
73                 if (cursor_position_set) {
74                         g_input_keyboard_data.cursor_position_set = atoi(cursor_position_set);
75                         free(cursor_position_set);
76                 }
77         }
78
79         return true;
80 }
81
82 void input_keyboard_deinit(void)
83 {
84         g_input_keyboard_data.return_key_type = string(_("IDS_AMEMO_BUTTON_SEND"));
85         g_input_keyboard_data.max_text_length = KEYBOARD_EDITOR_CHAR_COUNT_MAX;
86         g_input_keyboard_data.cursor_position_set = 0;
87
88         return;
89 }
90
91 void exit_keyboard()
92 {
93         app_control_h app_control;
94         int ret = app_control_create(&app_control);
95         if (ret != APP_CONTROL_ERROR_NONE) {
96                 PRINTFUNC(DLOG_ERROR, "Can not create app_control : %d", ret);
97                 return;
98         }
99
100         const char *getText = elm_entry_entry_get(entry);
101         SECURE_LOGD("button key clicked!! : getText = %s", getText);
102
103         char cursorPosition[512];
104         snprintf(cursorPosition, sizeof(cursorPosition), "%d", elm_entry_cursor_pos_get(entry));
105
106         char *app_id = NULL;
107         app_control_get_caller(app_data->source_app_control, &app_id);
108         if (app_id != NULL)
109                 app_control_set_app_id(app_control, app_id);
110         app_control_set_operation(app_control, APP_CONTROL_OPERATION_DEFAULT);
111         set_source_caller_app_id(app_control);
112         free(app_id);
113         reply_to_sender_by_callback(getText, "keyboard", NULL, cursorPosition);
114         app_control_destroy(app_control);
115         ui_app_exit();
116 }
117
118 void btn_clicked_cb(void *data, Evas_Object *obj, void *event_info)
119 {
120         exit_keyboard();
121 }
122
123 static Eina_Bool custom_back_cb(void *data, Elm_Object_Item *it)
124 {
125         _back_to_genlist_for_selector();
126         return EINA_TRUE;
127 }
128
129 static void maxlength_cb(void *data, Evas_Object *obj, void *event_info)
130 {
131         LOGD("maxlength_cb : size = %d", KEYBOARD_EDITOR_CHAR_COUNT_MAX);
132         char text[512];
133         const char *guide = _(MAX_TEXT_LENGTH_REACH);
134         snprintf(text, sizeof(text), guide, g_input_keyboard_data.max_text_length);
135         show_popup_toast((const char *)text, false);
136 }
137
138 static void enter_keydown_cb(void *data, Evas_Object *obj, void *event_info)
139 {
140         LOGD("enter_keydown_cb");
141         Evas_Object *entry = obj;
142         if (entry == NULL)
143                 return;
144
145         Ecore_IMF_Context *imf_context = NULL;
146         imf_context = (Ecore_IMF_Context*)elm_entry_imf_context_get(entry);
147         if (imf_context)
148                 ecore_imf_context_input_panel_hide(imf_context);
149
150         elm_object_focus_set(entry, EINA_FALSE);
151
152         exit_keyboard();
153 }
154
155 void create_fullscreen_editor(void *data)
156 {
157         App_Data *ad = (App_Data *)data;
158
159         Evas_Object *box = elm_box_add(ad->naviframe);
160         evas_object_size_hint_weight_set(box, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
161         evas_object_show(box);
162         elm_win_resize_object_add(ad->naviframe, box);
163
164         entry = elm_entry_add(box);
165
166         static Elm_Entry_Filter_Limit_Size limit_filter_data;
167         limit_filter_data.max_char_count = g_input_keyboard_data.max_text_length;
168         elm_entry_markup_filter_append(entry, elm_entry_filter_limit_size, &limit_filter_data);
169         evas_object_smart_callback_add(entry, "maxlength,reached", maxlength_cb, data);
170
171         elm_entry_single_line_set(entry, EINA_TRUE);
172         elm_entry_scrollable_set(entry, EINA_TRUE);
173         elm_scroller_policy_set(entry, ELM_SCROLLER_POLICY_OFF, ELM_SCROLLER_POLICY_AUTO);
174         elm_object_part_text_set(entry, "elm.guide", g_input_keyboard_data.guide_text.c_str());
175         elm_entry_entry_set(entry, g_input_keyboard_data.default_text.c_str());
176         elm_entry_cursor_end_set(entry);
177         evas_object_size_hint_weight_set(entry, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
178         evas_object_size_hint_align_set(entry, EVAS_HINT_FILL, EVAS_HINT_FILL);
179         if (g_input_keyboard_data.return_key_type == string("DONE")) {
180                 elm_entry_input_panel_return_key_type_set(entry, ELM_INPUT_PANEL_RETURN_KEY_TYPE_DONE);
181                 evas_object_smart_callback_add(entry, "activated", enter_keydown_cb, ad);
182         }
183         if (g_input_keyboard_data.cursor_position_set != 0) {
184                 elm_entry_cursor_pos_set(entry, g_input_keyboard_data.cursor_position_set);
185         }
186         evas_object_show(entry);
187         elm_box_pack_end(box, entry);
188
189         Evas_Object *btn = elm_button_add(box);
190         elm_object_text_set(btn, g_input_keyboard_data.return_key_type.c_str());
191         evas_object_size_hint_weight_set(btn, EVAS_HINT_EXPAND, 0.5);
192         evas_object_size_hint_align_set(btn, EVAS_HINT_FILL, EVAS_HINT_FILL);
193         evas_object_smart_callback_add(btn, "clicked", btn_clicked_cb, NULL);
194         evas_object_show(btn);
195         elm_box_pack_end(box, btn);
196         evas_object_resize(ad->naviframe, 360, 360);
197         evas_object_show(ad->naviframe);
198
199         const char *item_style = NULL;
200         if (_WEARABLE)
201                 item_style = "empty";
202         Elm_Object_Item *nf_item = elm_naviframe_item_push(ad->naviframe, NULL, NULL, NULL, box, item_style);
203         elm_naviframe_item_pop_cb_set(nf_item, custom_back_cb, NULL);
204 }
205
206 static void editfield_focused_cb(void *data, Evas_Object *obj, void *event_info)
207 {
208         Evas_Object *editfield = (Evas_Object *)data;
209         elm_object_signal_emit(editfield, "elm,state,focused", "");
210
211         if (!elm_entry_is_empty(obj))
212                 elm_object_signal_emit(editfield, "elm,action,show,button", "");
213 }
214
215 static void editfield_unfocused_cb(void *data, Evas_Object *obj, void *event_info)
216 {
217         Evas_Object *editfield = (Evas_Object *)data;
218         elm_object_signal_emit(editfield, "elm,state,unfocused", "");
219         elm_object_signal_emit(editfield, "elm,action,hide,button", "");
220 }
221
222 static Evas_Object *create_multiline_editfield_layout(Evas_Object *parent, void *data)
223 {
224         App_Data *ad = (App_Data *)data;
225         Evas_Object *editfield;
226
227         editfield = elm_layout_add(parent);
228         elm_layout_theme_set(editfield, "layout", "editfield", "multiline");
229         evas_object_size_hint_align_set(editfield, EVAS_HINT_FILL, 0.0);
230         evas_object_size_hint_weight_set(editfield, EVAS_HINT_EXPAND, 0.0);
231
232         entry = elm_entry_add(editfield);
233         static Elm_Entry_Filter_Limit_Size limit_filter_data;
234         limit_filter_data.max_char_count = g_input_keyboard_data.max_text_length;
235         elm_entry_markup_filter_append(entry, elm_entry_filter_limit_size, &limit_filter_data);
236         evas_object_smart_callback_add(entry, "maxlength,reached", maxlength_cb, data);
237
238         elm_entry_scrollable_set(entry, EINA_TRUE);
239         elm_scroller_policy_set(entry, ELM_SCROLLER_POLICY_OFF, ELM_SCROLLER_POLICY_AUTO);
240         elm_object_part_text_set(entry, "elm.guide", g_input_keyboard_data.guide_text.c_str());
241         elm_entry_entry_set(entry, g_input_keyboard_data.default_text.c_str());
242         elm_entry_cursor_end_set(entry);
243         evas_object_smart_callback_add(entry, "focused", editfield_focused_cb, editfield);
244         evas_object_smart_callback_add(entry, "unfocused", editfield_unfocused_cb, editfield);
245         if (g_input_keyboard_data.return_key_type == string("DONE")) {
246                 elm_entry_input_panel_return_key_type_set(entry, ELM_INPUT_PANEL_RETURN_KEY_TYPE_DONE);
247                 evas_object_smart_callback_add(entry, "activated", enter_keydown_cb, ad);
248         }
249         if (g_input_keyboard_data.cursor_position_set != 0) {
250                 elm_entry_cursor_pos_set(entry, g_input_keyboard_data.cursor_position_set);
251         }
252
253         evas_object_show(entry);
254         elm_object_part_content_set(editfield, "elm.swallow.content", entry);
255
256         return editfield;
257 }
258
259 static Evas_Object *create_editfield_view(void *data)
260 {
261         App_Data *ad = (App_Data *)data;
262
263         Evas_Object *main_scroller, *main_box, *editfield;
264
265         main_scroller = elm_scroller_add(ad->naviframe);
266         elm_scroller_bounce_set(main_scroller, EINA_FALSE, EINA_TRUE);
267         evas_object_size_hint_weight_set(main_scroller, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
268         evas_object_size_hint_align_set(main_scroller, EVAS_HINT_FILL, EVAS_HINT_FILL);
269         evas_object_show(main_scroller);
270
271         main_box = elm_box_add(main_scroller);
272         evas_object_size_hint_align_set(main_box, EVAS_HINT_FILL, 0.0);
273         evas_object_size_hint_weight_set(main_box, EVAS_HINT_EXPAND, 0.0);
274         evas_object_show(main_box);
275
276         editfield = create_multiline_editfield_layout(main_box, data);
277         elm_box_pack_end(main_box, editfield);
278         evas_object_show(editfield);
279
280         Evas_Object *btn = elm_button_add(main_box);
281         elm_object_text_set(btn, "OK");
282         evas_object_size_hint_weight_set(btn, 0.5, 0.5);
283         evas_object_size_hint_align_set(btn, EVAS_HINT_FILL, EVAS_HINT_FILL);
284         evas_object_smart_callback_add(btn, "clicked", btn_clicked_cb, NULL);
285         evas_object_show(btn);
286         elm_box_pack_end(main_box, btn);
287
288         elm_object_content_set(main_scroller, main_box);
289
290         evas_object_show(ad->naviframe);
291         const char *item_style = NULL;
292         if (_WEARABLE)
293                 item_style = "empty";
294         Elm_Object_Item *nf_item = elm_naviframe_item_push(ad->naviframe, NULL, NULL, NULL, main_scroller, item_style);
295         elm_naviframe_item_pop_cb_set(nf_item, custom_back_cb, NULL);
296
297         return main_scroller;
298 }
299
300 bool input_keyboard_launch(Evas_Object *window, void *data) {
301         if (window == NULL) {
302                 PRINTFUNC(DLOG_ERROR, "Can not get window");
303                 return false;
304         }
305
306         if (_WEARABLE)
307                 create_fullscreen_editor(data);
308         else
309                 create_editfield_view(data);
310
311         return true;
312 }
313