2c66b16a5cc3ebc40f0d0d4e71096e16d21e81d5
[platform/core/uifw/inputmethod-setting.git] / im_setting_list / input_method_setting_list_popup_view.cpp
1 /*
2  * Copyright (c) 2014 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 "input_method_setting_list.h"
18 #include "input_method_setting_list_ui.h"
19 #include "input_method_setting_list_popup_view.h"
20 #include "../common/input_method_setting_genlist.h"
21 #include "../common/ime_info.h"
22
23 #include <string>
24 #include <efl_extension.h>
25 #include <vector>
26 #include <isf_control.h>
27 #include <inputmethod_manager.h>
28 #include <vconf.h>
29
30 #define IM_SETTING_LIST_POPUP_VIEW_TITLE          "IDS_ST_HEADER_DEFAULT_KEYBOARD_ABB"
31
32 static std::vector<ime_info_s>      g_active_ime_info_list;
33 static Elm_Genlist_Item_Class       *itc_im_list = NULL;
34 static Evas_Object                  *group_radio = NULL;
35 static int                          g_active_ime_id = -1;
36
37 static int selected_index = 0;
38
39 static void im_setting_list_update_radio_state(Elm_Object_Item *item, Evas_Object *obj, int index)
40 {
41     if (index < 0 || index >= (int)g_active_ime_info_list.size()) {
42         LOGW("Wrong value. index : %d, g_active_ime_info_list.size() : %zu\n", index, g_active_ime_info_list.size());
43         return;
44     }
45
46     if (item && obj) {
47         elm_genlist_item_selected_set(item, EINA_FALSE);
48         /* Update radio button */
49         Evas_Object *radio = elm_object_item_part_content_get(item, "elm.swallow.end");
50         if (radio == NULL) {
51             radio = elm_object_item_part_content_get(item, "elm.icon");
52         }
53         evas_object_data_set(radio, "parent_genlist", obj);
54         elm_radio_value_set(group_radio, index);
55     }
56 }
57
58 void im_setting_list_update_window_selector(void *data)
59 {
60     appdata *ad = (appdata *)data;
61     if (!ad)
62         return;
63
64     im_setting_load_ime_info(g_active_ime_info_list, g_active_ime_id, true);
65     im_setting_list_update_window(ad);
66 }
67
68 static Eina_Bool _ime_select_idler_cb(void *data)
69 {
70     appdata *ad = (appdata *)data;
71     if (!ad) return ECORE_CALLBACK_CANCEL;
72
73     LOGD("set active IME\n");
74     if (isf_control_set_active_ime(g_active_ime_info_list[selected_index].appid) != 0)
75         LOGW("Failed to set active IME : %s\n", g_active_ime_info_list[selected_index].appid);
76
77     LOGD("update window selector\n");
78     im_setting_list_update_window_selector(ad);
79
80     LOGD("delete popup\n");
81     if (ad->popup) {
82         evas_object_del(ad->popup);
83     }
84     ad->popup = NULL;
85
86     if (ad->app_type == APP_TYPE_NORMAL) {
87         if (ad->naviframe)
88             elm_naviframe_item_pop(ad->naviframe);
89     } else {
90 #ifdef _WEARABLE
91         if (ad->naviframe)
92             elm_naviframe_item_pop(ad->naviframe);
93 #endif
94     }
95
96     return ECORE_CALLBACK_CANCEL;
97 }
98
99 static void im_setting_list_ime_sel_cb(void *data, Evas_Object *obj, void *event_info)
100 {
101     sel_cb_data *cb_data = (sel_cb_data *)data;
102     if (!cb_data)
103         return;
104
105     appdata *ad = (appdata *)cb_data->data;
106     if (!ad)
107         return;
108
109     int index = cb_data->index;
110     selected_index = index;
111
112     Elm_Object_Item *item = (Elm_Object_Item *)event_info;
113     if (!item) {
114         return;
115     }
116
117     im_setting_list_update_radio_state(item, obj, index);
118
119     ecore_idler_add(_ime_select_idler_cb, ad);
120 }
121
122 static void gl_lang_changed(void *data, Evas_Object *obj, void *event_info)
123 {
124     im_setting_load_ime_info(g_active_ime_info_list, g_active_ime_id, true);
125
126     elm_genlist_realized_items_update(obj);
127 }
128
129 static char *im_setting_list_genlist_item_label_get(void *data, Evas_Object *obj, const char *part)
130 {
131     sel_cb_data *cb_data = (sel_cb_data *)data;
132     if (!cb_data)
133         return NULL;
134
135     int index = cb_data->index;
136     if (index < 0 || index >= (int)g_active_ime_info_list.size()) {
137         LOGW("Wrong value. index : %d, g_active_ime_info_list.size() : %zu\n", index, g_active_ime_info_list.size());
138         return NULL;
139     }
140
141     if (!strcmp(part, "elm.text") ||
142         !strcmp(part, "elm.text.main") ||
143         !strcmp(part, "elm.text.main.left")) {
144         return strdup(g_active_ime_info_list[index].label);
145     }
146
147     return NULL;
148 }
149
150 static void im_setting_list_genlist_item_del_cb(void *data, Evas_Object *obj)
151 {
152     sel_cb_data *cb_data = (sel_cb_data *)data;
153     if (!cb_data)
154         return;
155
156     delete cb_data;
157 }
158
159 static void im_setting_list_genlist_item_class_create(void)
160 {
161     itc_im_list = elm_genlist_item_class_new();
162     if (itc_im_list) {
163         itc_im_list->item_style = IME_SETTING_LIST_1LINE_STYLE;
164         itc_im_list->func.text_get = im_setting_list_genlist_item_label_get;
165         itc_im_list->func.content_get = im_setting_genlist_item_icon_get;
166         itc_im_list->func.state_get = NULL;
167         itc_im_list->func.del = im_setting_list_genlist_item_del_cb;
168     }
169 }
170
171 #ifndef _WEARABLE
172 static Evas_Object *im_setting_list_list_create(void *data)
173 {
174     appdata *ad = (appdata *)data;
175     if (!ad)
176         return NULL;
177     im_setting_list_genlist_item_class_create();
178     Evas_Object *genlist = NULL;
179     genlist = im_setting_genlist_create(ad->popup, ad->conform);
180     elm_scroller_content_min_limit(ad->genlist, EINA_FALSE, EINA_TRUE);
181     evas_object_smart_callback_add(genlist, "language,changed", gl_lang_changed, NULL);
182     unsigned int i = 0;
183
184     /* keyboard list */
185     for (i = 0; i < g_active_ime_info_list.size(); i++) {
186         sel_cb_data *cb_data = new sel_cb_data;
187         cb_data->data = data;
188         cb_data->index = i;
189         cb_data->group_radio = group_radio;
190         elm_genlist_item_append(genlist,
191             itc_im_list,
192             (void *)(cb_data),
193             NULL,
194             ELM_GENLIST_ITEM_NONE,
195             im_setting_list_ime_sel_cb,
196             (void *)(cb_data));
197     }
198     elm_radio_value_set(group_radio, g_active_ime_id);
199
200     return genlist;
201 }
202
203 static void
204 im_setting_list_popup_block_clicked_cb(void *data EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
205 {
206     appdata *ad = (appdata *)data;
207     if (!ad)
208         return;
209     if (ad->popup) {
210         evas_object_del(ad->popup);
211     }
212     ad->popup = NULL;
213 }
214
215 static void im_setting_list_popup_view_back_cb(void *data, Evas_Object *obj, void *event_info)
216 {
217     appdata *ad = (appdata *)data;
218     if (!ad)
219         return;
220     eext_object_event_callback_del(obj, EEXT_CALLBACK_BACK, im_setting_list_popup_view_back_cb);
221     if (ad->popup) {
222         evas_object_del(ad->popup);
223     }
224     ad->popup = NULL;
225 }
226
227 static Evas_Object *im_setting_list_popup_create(void *data)
228 {
229     appdata *ad = (appdata *)data;
230     if (!ad || !ad->win)
231         return NULL;
232     Evas_Object *parentWin = ad->win;
233     if (NULL == group_radio)
234     {
235         group_radio = elm_radio_add(parentWin);
236         elm_radio_state_value_set(group_radio, -1);
237     }
238
239     Evas_Object *popup = elm_popup_add(parentWin);
240     elm_popup_align_set(popup, ELM_NOTIFY_ALIGN_FILL, 1.0);
241     evas_object_smart_callback_add(popup, "block,clicked", im_setting_list_popup_block_clicked_cb, data);
242     elm_object_domain_translatable_part_text_set(popup, "title,text", PACKAGE, IM_SETTING_LIST_POPUP_VIEW_TITLE);
243 #if defined(_MOBILE) || defined(_WEARABLE)
244     elm_object_style_set(popup, "theme_bg");
245 #endif
246     eext_object_event_callback_add(popup, EEXT_CALLBACK_BACK, im_setting_list_popup_view_back_cb, data);
247     ad->popup = popup;
248
249     Evas_Object *genlist = im_setting_list_list_create(data);
250     elm_object_content_set(popup, genlist);
251     evas_object_show(popup);
252     return popup;
253 }
254 #endif
255
256 #ifdef _WEARABLE
257 static void _active_keyboard_changed_cb(keynode_t* node, void* data)
258 {
259     im_setting_load_ime_info(g_active_ime_info_list, g_active_ime_id, true);
260     if (group_radio != NULL) {
261         elm_radio_value_set(group_radio, g_active_ime_id);
262     }
263 }
264
265 static char *
266 im_setting_list_default_keyboard_title_text_get(void *data, Evas_Object *obj, const char *part)
267 {
268     return strdup(dgettext(PACKAGE, IM_SETTING_LIST_POPUP_VIEW_TITLE));
269 }
270
271 static Eina_Bool _pop_cb(void *data, Elm_Object_Item *it)
272 {
273 #ifdef _CIRCLE
274     appdata *ad = (appdata *)data;
275     if (ad && ad->main_circle_genlist)
276         eext_rotary_object_event_activated_set(ad->main_circle_genlist, EINA_TRUE);
277 #endif
278
279     vconf_ignore_key_changed(VCONFKEY_ISF_ACTIVE_KEYBOARD_UUID, _active_keyboard_changed_cb);
280
281     return EINA_TRUE;
282 }
283
284 static void im_setting_list_screen_create(void *data)
285 {
286     appdata *ad = NULL;
287     Evas_Object *genlist = NULL;
288
289     ad = (appdata *) data;
290     if (ad == NULL) return;
291
292     Elm_Genlist_Item_Class *ttc = elm_genlist_item_class_new();
293     if (!ttc) return;
294
295     ttc->item_style = "title";
296     ttc->func.text_get = im_setting_list_default_keyboard_title_text_get;
297
298     im_setting_list_genlist_item_class_create();
299     genlist = im_setting_genlist_create(ad->win, ad->conform);
300     elm_scroller_content_min_limit(genlist, EINA_FALSE, EINA_TRUE);
301     evas_object_smart_callback_add(genlist, "language,changed", gl_lang_changed, NULL);
302
303     elm_genlist_mode_set(genlist, ELM_LIST_SCROLL);
304     elm_genlist_item_append(genlist, ttc, NULL, NULL, ELM_GENLIST_ITEM_NONE, NULL, NULL);
305
306     if (NULL == group_radio) {
307         group_radio = elm_radio_add(ad->win);
308         elm_radio_state_value_set(group_radio, g_active_ime_id);
309     }
310
311     /* keyboard list */
312     for (unsigned int i = 0; i < g_active_ime_info_list.size(); i++) {
313         sel_cb_data *cb_data = new sel_cb_data;
314         cb_data->data = data;
315         cb_data->index = i;
316         cb_data->group_radio = group_radio;
317         elm_genlist_item_append(genlist,
318             itc_im_list,
319             (void *)(cb_data),
320             NULL,
321             ELM_GENLIST_ITEM_NONE,
322             im_setting_list_ime_sel_cb,
323             (void *)(cb_data));
324     }
325
326     elm_radio_state_value_set(group_radio, g_active_ime_id);
327     elm_radio_value_set(group_radio, g_active_ime_id);
328     elm_genlist_item_class_free(ttc);
329
330 #ifdef _CIRCLE
331     im_setting_list_add_padding(genlist);
332 #endif
333
334     Elm_Object_Item *navi_it = elm_naviframe_item_push(ad->naviframe, NULL, NULL, NULL, genlist, "empty");
335 #ifdef _WEARABLE
336     elm_atspi_accessible_name_set(navi_it, dgettext(PACKAGE, IM_SETTING_LIST_POPUP_VIEW_TITLE));
337 #endif
338     elm_naviframe_item_pop_cb_set(navi_it, _pop_cb, ad);
339
340     vconf_notify_key_changed(VCONFKEY_ISF_ACTIVE_KEYBOARD_UUID, _active_keyboard_changed_cb, data);
341 }
342 #endif
343
344 void im_setting_list_popup_view_del(void *data)
345 {
346     appdata *ad = (appdata *)data;
347     if (!ad || !ad->win)
348         return;
349
350     if (ad->popup) {
351         evas_object_del(ad->popup);
352     }
353     ad->popup = NULL;
354
355     if (ad->naviframe) {
356         elm_naviframe_item_pop(ad->naviframe);
357     }
358 }
359
360 void
361 im_setting_list_popup_view_create(void *data)
362 {
363     appdata *ad = (appdata *)data;
364     if (!ad || !ad->win)
365         return;
366
367     im_setting_load_ime_info(g_active_ime_info_list, g_active_ime_id, true);
368
369 #ifdef _WEARABLE
370     im_setting_list_screen_create(data);
371 #else
372     im_setting_list_popup_create(data);
373 #endif
374 }