2 * Copyright (c) 2014 Samsung Electronics Co., Ltd. All rights reserved.
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 #include "input_method_setting_list.h"
18 #include "input_method_setting_list_ui.h"
19 #include "input_method_setting_list_popup_view.h"
21 #include <efl_extension.h>
23 #include <isf_control.h>
25 #include <inputmethod_manager.h>
28 #define IM_SETTING_LIST_POPUP_VIEW_TITLE "IDS_ST_HEADER_DEFAULT_KEYBOARD_ABB"
30 static std::vector<ime_info_s> g_active_ime_info_list;
31 static Elm_Genlist_Item_Class *itc_im_list = NULL;
32 static Evas_Object *group_radio = NULL;
33 static int g_active_ime_id = -1;
40 class ime_info_compare
43 bool operator()(const ime_info_s &first, const ime_info_s &sec)
45 return (strcasecmp(first.label, sec.label) < 0);
49 static int selected_index = 0;
51 static void im_setting_list_sort_ime_info(std::vector<ime_info_s> &preinstall, std::vector<ime_info_s> &user)
53 std::sort(preinstall.begin(), preinstall.end(), ime_info_compare());
54 std::sort(user.begin(), user.end(), ime_info_compare());
55 for (unsigned int i = 0; i < preinstall.size(); ++i)
57 g_active_ime_info_list.push_back(preinstall[i]);
59 for (unsigned int i = 0; i < user.size(); ++i)
61 g_active_ime_info_list.push_back(user[i]);
65 static void im_setting_list_load_active_ime_info(void)
67 std::vector<ime_info_s> active_ime_info_list_preinstall;
68 std::vector<ime_info_s> active_ime_info_list_user;
69 g_active_ime_info_list.clear();
70 char *active_ime_appid = NULL;
72 int ret = ime_manager_get_active_ime(&active_ime_appid);
73 if (ret == IME_MANAGER_ERROR_NONE)
74 LOGD("get active ime : %s\n", active_ime_appid);
76 LOGW("Failed to get active ime. error : %d\n", ret);
78 ime_info_s *info = NULL;
79 int cnt = isf_control_get_all_ime_info(&info);
82 for (int i = 0; i < cnt; ++i)
84 SECURE_LOGD("%s %s %d %d %d\n", info[i].appid, info[i].label, info[i].is_enabled, info[i].is_preinstalled, info[i].has_option);
85 if (info[i].is_enabled && info[i].is_preinstalled) {
86 active_ime_info_list_preinstall.push_back(info[i]);
87 } else if (info[i].is_enabled) {
88 active_ime_info_list_user.push_back(info[i]);
94 im_setting_list_sort_ime_info(active_ime_info_list_preinstall, active_ime_info_list_user);
95 for (unsigned int i = 0; i < g_active_ime_info_list.size(); ++i)
97 if (active_ime_appid && (!strcmp(active_ime_appid, g_active_ime_info_list[i].appid)))
103 if (active_ime_appid)
105 free(active_ime_appid);
109 static void im_setting_list_update_radio_state(Elm_Object_Item *item, Evas_Object *obj, int index)
111 if (index < 0 || index >= (int)g_active_ime_info_list.size()) {
112 LOGW("Wrong value. index : %d, g_active_ime_info_list.size() : %zu\n", index, g_active_ime_info_list.size());
117 elm_genlist_item_selected_set(item, EINA_FALSE);
118 /* Update radio button */
119 Evas_Object *radio = elm_object_item_part_content_get(item, "elm.swallow.end");
121 radio = elm_object_item_part_content_get(item, "elm.icon");
123 evas_object_data_set(radio, "parent_genlist", obj);
124 elm_radio_value_set(group_radio, index);
128 void im_setting_list_update_window_selector(void *data)
130 appdata *ad = (appdata *)data;
133 im_setting_list_load_active_ime_info();
134 im_setting_list_update_window(ad);
137 static Eina_Bool _ime_select_idler_cb(void *data)
139 appdata *ad = (appdata *)data;
140 if (!ad) return ECORE_CALLBACK_CANCEL;
142 LOGD("set active IME\n");
143 if (isf_control_set_active_ime(g_active_ime_info_list[selected_index].appid) != 0)
144 LOGW("Failed to set active IME : %s\n", g_active_ime_info_list[selected_index].appid);
146 LOGD("update window selector\n");
147 im_setting_list_update_window_selector(ad);
149 LOGD("delete popup\n");
151 evas_object_del(ad->popup);
155 if (ad->app_type == APP_TYPE_NORMAL) {
157 elm_naviframe_item_pop(ad->naviframe);
161 elm_naviframe_item_pop(ad->naviframe);
165 return ECORE_CALLBACK_CANCEL;
168 static void im_setting_list_ime_sel_cb(void *data, Evas_Object *obj, void *event_info)
170 sel_cb_data *cb_data = (sel_cb_data *)data;
174 appdata *ad = (appdata *)cb_data->data;
178 int index = cb_data->index;
179 selected_index = index;
181 Elm_Object_Item *item = (Elm_Object_Item *)event_info;
186 im_setting_list_update_radio_state(item, obj, index);
188 ecore_idler_add(_ime_select_idler_cb, ad);
191 static void gl_lang_changed(void *data, Evas_Object *obj, void *event_info)
193 im_setting_list_load_active_ime_info();
195 elm_genlist_realized_items_update(obj);
198 #if !(defined(_WEARABLE) || defined(_MOBILE))
199 static void gl_realized_cb(void *data, Evas_Object *obj, void *event_info)
201 Elm_Object_Item *it = (Elm_Object_Item *)event_info;
202 Elm_Object_Item *first_item = elm_genlist_first_item_get(obj);
203 Elm_Object_Item *last_item = elm_genlist_last_item_get(obj);
205 if (it == first_item && it == last_item) {
206 elm_object_item_signal_emit(it, "elm,state,group,single", "elm");
208 else if (it == first_item) {
209 elm_object_item_signal_emit(it, "elm,state,group,top", "elm");
211 else if (it == last_item) {
212 elm_object_item_signal_emit(it, "elm,state,group,bottom", "elm");
215 elm_object_item_signal_emit(it, "elm,state,group,middle", "elm");
220 static Evas_Object *im_setting_list_genlist_create(appdata *ad, Evas_Object* parent, Evas_Object* conform)
224 Evas_Object *genlist = elm_genlist_add(parent);
225 elm_genlist_mode_set(genlist, ELM_LIST_COMPRESS);
227 /* Circle Surface Creation */
228 if (ad->circle_surface == NULL)
229 ad->circle_surface = eext_circle_surface_conformant_add(conform);
230 Evas_Object *circle_genlist = eext_circle_object_genlist_add(genlist, ad->circle_surface);
231 eext_rotary_object_event_activated_set(circle_genlist, EINA_TRUE);
233 evas_object_size_hint_weight_set(genlist, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
234 evas_object_size_hint_align_set(genlist, EVAS_HINT_FILL, EVAS_HINT_FILL);
235 elm_scroller_content_min_limit(genlist, EINA_FALSE, EINA_TRUE);
236 evas_object_smart_callback_add(genlist, "language,changed", gl_lang_changed, NULL);
237 #if !(defined(_WEARABLE) || defined(_MOBILE))
238 evas_object_smart_callback_add(genlist, "realized", gl_realized_cb, NULL);
240 evas_object_show(genlist);
244 static char *im_setting_list_genlist_item_label_get(void *data, Evas_Object *obj, const char *part)
246 sel_cb_data *cb_data = (sel_cb_data *)data;
250 int index = cb_data->index;
251 if (index < 0 || index >= (int)g_active_ime_info_list.size()) {
252 LOGW("Wrong value. index : %d, g_active_ime_info_list.size() : %zu\n", index, g_active_ime_info_list.size());
256 if (!strcmp(part, "elm.text") ||
257 !strcmp(part, "elm.text.main") ||
258 !strcmp(part, "elm.text.main.left")) {
259 return strdup(g_active_ime_info_list[index].label);
265 static Evas_Object *im_setting_list_genlist_item_icon_get(void *data, Evas_Object *obj, const char *part)
267 sel_cb_data *cb_data = (sel_cb_data *)data;
271 int index = cb_data->index;
272 Elm_Object_Item *it = elm_genlist_nth_item_get(obj, index);
274 if (!strcmp(part, "elm.swallow.end") ||
275 !strcmp(part, "elm.icon")) {
276 Evas_Object *radio = elm_radio_add(obj);
277 elm_object_style_set(radio, "list");
278 elm_radio_state_value_set(radio, index);
279 evas_object_propagate_events_set(radio, EINA_TRUE);
280 elm_radio_group_add(radio, group_radio);
281 evas_object_show(radio);
283 elm_atspi_accessible_relationship_append(it, ELM_ATSPI_RELATION_DESCRIBED_BY, radio);
284 elm_atspi_accessible_relationship_append(radio, ELM_ATSPI_RELATION_CONTROLLED_BY, it);
291 static void im_setting_list_genlist_item_del_cb(void *data, Evas_Object *obj)
293 sel_cb_data *cb_data = (sel_cb_data *)data;
300 static void im_setting_list_genlist_item_class_create(void)
302 itc_im_list = elm_genlist_item_class_new();
305 itc_im_list->item_style = "1text.1icon.1";
307 itc_im_list->item_style = "type1";
309 itc_im_list->item_style = "1line";
311 itc_im_list->func.text_get = im_setting_list_genlist_item_label_get;
312 itc_im_list->func.content_get = im_setting_list_genlist_item_icon_get;
313 itc_im_list->func.state_get = NULL;
314 itc_im_list->func.del = im_setting_list_genlist_item_del_cb;
319 static Evas_Object *im_setting_list_list_create(void *data)
321 appdata *ad = (appdata *)data;
324 im_setting_list_genlist_item_class_create();
325 Evas_Object *genlist = NULL;
326 genlist = im_setting_list_genlist_create(ad, ad->popup, ad->conform);
330 for (i = 0; i < g_active_ime_info_list.size(); i++) {
331 sel_cb_data *cb_data = new sel_cb_data;
332 cb_data->data = data;
334 elm_genlist_item_append(genlist,
338 ELM_GENLIST_ITEM_NONE,
339 im_setting_list_ime_sel_cb,
342 elm_radio_value_set(group_radio, g_active_ime_id);
348 im_setting_list_popup_block_clicked_cb(void *data EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
350 appdata *ad = (appdata *)data;
354 evas_object_del(ad->popup);
359 static void im_setting_list_popup_view_back_cb(void *data, Evas_Object *obj, void *event_info)
361 appdata *ad = (appdata *)data;
364 eext_object_event_callback_del(obj, EEXT_CALLBACK_BACK, im_setting_list_popup_view_back_cb);
366 evas_object_del(ad->popup);
371 static Evas_Object *im_setting_list_popup_create(void *data)
373 appdata *ad = (appdata *)data;
376 Evas_Object *parentWin = ad->win;
377 if (NULL == group_radio)
379 group_radio = elm_radio_add(parentWin);
380 elm_radio_state_value_set(group_radio, -1);
383 Evas_Object *popup = elm_popup_add(parentWin);
384 elm_popup_align_set(popup, ELM_NOTIFY_ALIGN_FILL, 1.0);
385 evas_object_smart_callback_add(popup, "block,clicked", im_setting_list_popup_block_clicked_cb, data);
386 elm_object_domain_translatable_part_text_set(popup, "title,text", PACKAGE, IM_SETTING_LIST_POPUP_VIEW_TITLE);
387 #if defined(_MOBILE) || defined(_WEARABLE)
388 elm_object_style_set(popup, "theme_bg");
390 eext_object_event_callback_add(popup, EEXT_CALLBACK_BACK, im_setting_list_popup_view_back_cb, data);
393 Evas_Object *genlist = im_setting_list_list_create(data);
394 elm_object_content_set(popup, genlist);
395 evas_object_show(popup);
401 static void _active_keyboard_changed_cb(keynode_t* node, void* data)
403 im_setting_list_load_active_ime_info();
404 if (group_radio != NULL) {
405 elm_radio_value_set(group_radio, g_active_ime_id);
410 im_setting_list_default_keyboard_title_text_get(void *data, Evas_Object *obj, const char *part)
412 return strdup(dgettext(PACKAGE, IM_SETTING_LIST_POPUP_VIEW_TITLE));
415 static Eina_Bool _pop_cb(void *data, Elm_Object_Item *it)
418 appdata *ad = (appdata *)data;
419 if (ad && ad->main_circle_genlist)
420 eext_rotary_object_event_activated_set(ad->main_circle_genlist, EINA_TRUE);
423 vconf_ignore_key_changed(VCONFKEY_ISF_ACTIVE_KEYBOARD_UUID, _active_keyboard_changed_cb);
428 static void im_setting_list_screen_create(void *data)
431 Evas_Object *genlist = NULL;
433 ad = (appdata *) data;
434 if (ad == NULL) return;
436 Elm_Genlist_Item_Class *ttc = elm_genlist_item_class_new();
439 ttc->item_style = "title";
440 ttc->func.text_get = im_setting_list_default_keyboard_title_text_get;
442 im_setting_list_genlist_item_class_create();
443 genlist = im_setting_list_genlist_create(ad, ad->win, ad->conform);
445 elm_genlist_mode_set(genlist, ELM_LIST_SCROLL);
446 elm_genlist_item_append(genlist, ttc, NULL, NULL, ELM_GENLIST_ITEM_NONE, NULL, NULL);
448 if (NULL == group_radio) {
449 group_radio = elm_radio_add(ad->win);
450 elm_radio_state_value_set(group_radio, g_active_ime_id);
454 for (unsigned int i = 0; i < g_active_ime_info_list.size(); i++) {
455 sel_cb_data *cb_data = new sel_cb_data;
456 cb_data->data = data;
458 elm_genlist_item_append(genlist,
462 ELM_GENLIST_ITEM_NONE,
463 im_setting_list_ime_sel_cb,
467 elm_radio_state_value_set(group_radio, g_active_ime_id);
468 elm_radio_value_set(group_radio, g_active_ime_id);
469 elm_genlist_item_class_free(ttc);
472 im_setting_list_add_padding(genlist);
475 Elm_Object_Item *navi_it = elm_naviframe_item_push(ad->naviframe, NULL, NULL, NULL, genlist, "empty");
477 elm_atspi_accessible_name_set(navi_it, dgettext(PACKAGE, IM_SETTING_LIST_POPUP_VIEW_TITLE));
479 elm_naviframe_item_pop_cb_set(navi_it, _pop_cb, ad);
481 vconf_notify_key_changed(VCONFKEY_ISF_ACTIVE_KEYBOARD_UUID, _active_keyboard_changed_cb, data);
485 void im_setting_list_popup_view_del(void *data)
487 appdata *ad = (appdata *)data;
492 evas_object_del(ad->popup);
497 elm_naviframe_item_pop(ad->naviframe);
502 im_setting_list_popup_view_create(void *data)
504 appdata *ad = (appdata *)data;
508 im_setting_list_load_active_ime_info();
510 im_setting_list_screen_create(data);
512 im_setting_list_popup_create(data);