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_selector.h"
21 #include <isf_control.h>
23 #include <tzplatform_config.h>
24 #include <inputmethod_manager.h>
26 #define IM_SETTING_SELECTOR_PACKAGE PACKAGE
27 #define IM_SETTING_SELECTOR_LOCALE_DIR tzplatform_mkpath(TZ_SYS_RO_APP, PACKAGE_NAME"/res/locale")
28 #define IM_SETTING_SELECTOR_TITLE "IDS_ST_HEADER_DEFAULT_KEYBOARD_ABB"
29 #define IM_SETTING_SELECT_KEYBOARD "IDS_IME_BODY_SELECT_KEYBOARD"
31 static std::vector<ime_info_s> g_ime_info_list;
32 static Elm_Genlist_Item_Class *itc_im_selector = NULL;
33 static Evas_Object *group_radio = NULL;
34 static int g_active_ime_id = -1;
41 class ime_info_compare
44 bool operator()(const ime_info_s &first, const ime_info_s &sec)
46 return (strcasecmp(first.label, sec.label) < 0);
50 static int selected_index = 0;
52 static void im_setting_selector_text_domain_set(void)
54 bindtextdomain(IM_SETTING_SELECTOR_PACKAGE, IM_SETTING_SELECTOR_LOCALE_DIR);
55 textdomain(IM_SETTING_SELECTOR_PACKAGE);
59 im_setting_selector_main_window_create(const char *name)
61 Evas_Object *eo = elm_win_add(NULL, name, ELM_WIN_BASIC);
65 Evas_Coord w = -1, h = -1;
67 elm_win_title_set(eo, name);
68 elm_win_borderless_set(eo, EINA_TRUE);
69 elm_win_alpha_set(eo, EINA_TRUE);
70 elm_win_conformant_set(eo, EINA_TRUE);
71 elm_win_autodel_set(eo, EINA_TRUE);
72 if (elm_win_wm_rotation_supported_get(eo)) {
73 int rots[4] = {0, 90, 180, 270};
74 elm_win_wm_rotation_available_rotations_set(eo, rots, 4);
76 e = evas_object_evas_get(eo);
78 ee = ecore_evas_ecore_evas_get(e);
80 ecore_evas_name_class_set(ee, "SYSTEM_POPUP", "SYSTEM_POPUP");
84 elm_win_screen_size_get(eo, NULL, NULL, &w, &h);
86 evas_object_resize(eo, w, h);
92 static void im_setting_selector_sort_ime_info(std::vector<ime_info_s> &preinstall, std::vector<ime_info_s> &user)
94 std::sort(preinstall.begin(), preinstall.end(), ime_info_compare());
95 std::sort(user.begin(), user.end(), ime_info_compare());
96 for (unsigned int i = 0; i < preinstall.size(); ++i)
98 g_ime_info_list.push_back(preinstall[i]);
100 for (unsigned int i = 0; i < user.size(); ++i)
102 g_ime_info_list.push_back(user[i]);
106 static void im_setting_selector_load_ime_info(void)
108 std::vector<ime_info_s> ime_info_list_preinstall;
109 std::vector<ime_info_s> ime_info_list_user;
110 g_ime_info_list.clear();
111 char *active_ime_appid = NULL;
113 int ret = ime_manager_get_active_ime(&active_ime_appid);
114 if (ret == IME_MANAGER_ERROR_NONE)
115 LOGD("get active ime : %s\n", active_ime_appid);
117 LOGW("Failed to get active ime. error : %d\n", ret);
119 ime_info_s *info = NULL;
120 int cnt = isf_control_get_all_ime_info(&info);
123 for (int i = 0; i < cnt; ++i)
125 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);
126 if (info[i].is_enabled && info[i].is_preinstalled) {
127 ime_info_list_preinstall.push_back(info[i]);
128 } else if (info[i].is_enabled) {
129 ime_info_list_user.push_back(info[i]);
135 im_setting_selector_sort_ime_info(ime_info_list_preinstall, ime_info_list_user);
136 for (unsigned int i = 0; i < g_ime_info_list.size(); ++i)
138 if (active_ime_appid && (!strcmp(active_ime_appid, g_ime_info_list[i].appid)))
144 if (active_ime_appid)
146 free(active_ime_appid);
151 static void im_setting_selector_select_keyboard_cb(void *data, Evas_Object *obj, void *event_info)
153 /* call input method list application*/
154 int ret = ime_manager_show_ime_list();
155 if (ret != IME_MANAGER_ERROR_NONE) {
156 LOGW("Failed to show IME list. error : %d\n", ret);
161 static void im_setting_selector_update_radio_state(Elm_Object_Item *item, Evas_Object *obj, int index)
163 if (index < 0 || index >= (int)g_ime_info_list.size()) {
164 LOGW("Wrong value. index : %d, g_ime_info_list.size() : %zu\n", index, g_ime_info_list.size());
169 elm_genlist_item_selected_set(item, EINA_FALSE);
170 /* Update check button */
171 Evas_Object *radio = elm_object_item_part_content_get(item, "elm.swallow.end");
173 radio = elm_object_item_part_content_get(item, "elm.icon");
175 evas_object_data_set(radio, "parent_genlist", obj);
176 elm_radio_value_set(group_radio, index);
180 static Eina_Bool _ime_select_idler_cb(void *data)
182 appdata *ad = (appdata *)data;
183 if (!ad) return ECORE_CALLBACK_CANCEL;
185 LOGD("set active IME\n");
186 isf_control_set_active_ime(g_ime_info_list[selected_index].appid);
189 elm_naviframe_item_pop(ad->naviframe);
193 return ECORE_CALLBACK_CANCEL;
196 static void im_setting_selector_ime_sel_cb(void *data, Evas_Object *obj, void *event_info)
198 sel_cb_data *cb_data = (sel_cb_data *)data;
201 int index = cb_data->index;
202 appdata *ad = (appdata *)cb_data->data;
206 Elm_Object_Item *item = (Elm_Object_Item *)event_info;
210 selected_index = index;
211 im_setting_selector_update_radio_state(item, obj, index);
212 ecore_idler_add(_ime_select_idler_cb, ad);
215 static Evas_Object *im_setting_selector_genlist_create(appdata *ad, Evas_Object* parent, Evas_Object* conform)
217 Evas_Object *genlist = elm_genlist_add(parent);
218 elm_genlist_mode_set(genlist, ELM_LIST_COMPRESS);
220 /* Circle Surface Creation */
221 if (ad->circle_surface == NULL)
222 ad->circle_surface = eext_circle_surface_conformant_add(conform);
223 Evas_Object *circle_genlist = eext_circle_object_genlist_add(genlist, ad->circle_surface);
224 eext_rotary_object_event_activated_set(circle_genlist, EINA_TRUE);
226 evas_object_size_hint_weight_set(genlist, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
227 evas_object_size_hint_align_set(genlist, EVAS_HINT_FILL, EVAS_HINT_FILL);
228 elm_scroller_content_min_limit(genlist, EINA_FALSE, EINA_TRUE);
229 evas_object_show(genlist);
233 static char *im_setting_selector_genlist_item_label_get(void *data, Evas_Object *obj, const char *part)
235 sel_cb_data *cb_data = (sel_cb_data *)data;
239 int index = cb_data->index;
240 if (index < 0 || index >= (int)g_ime_info_list.size()) {
241 LOGW("Wrong value. index : %d, g_ime_info_list.size() : %zu\n", index, g_ime_info_list.size());
245 if (!strcmp(part, "elm.text") ||
246 !strcmp(part, "elm.text.main") ||
247 !strcmp(part, "elm.text.main.left")) {
248 return strdup(g_ime_info_list[index].label);
254 static Evas_Object *im_setting_selector_genlist_item_icon_get(void *data, Evas_Object *obj, const char *part)
256 sel_cb_data *cb_data = (sel_cb_data *)data;
260 int index = cb_data->index;
261 Elm_Object_Item *it = elm_genlist_nth_item_get(obj, index);
263 if (!strcmp(part, "elm.swallow.end") ||
264 !strcmp(part, "elm.icon")) {
265 Evas_Object *radio = elm_radio_add(obj);
266 elm_object_style_set(radio, "list");
267 elm_radio_state_value_set(radio, index);
268 evas_object_propagate_events_set(radio, EINA_TRUE);
269 elm_radio_group_add(radio, group_radio);
270 evas_object_show(radio);
272 elm_atspi_accessible_relationship_append(it, ELM_ATSPI_RELATION_DESCRIBED_BY, radio);
273 elm_atspi_accessible_relationship_append(radio, ELM_ATSPI_RELATION_CONTROLLED_BY, it);
281 im_setting_selector_genlist_item_del_cb(void *data, Evas_Object *obj)
283 sel_cb_data *cb_data = (sel_cb_data *)data;
290 static void im_setting_selector_genlist_item_class_create(void)
292 itc_im_selector = elm_genlist_item_class_new();
293 if (itc_im_selector) {
295 itc_im_selector->item_style = "1text.1icon.1";
297 itc_im_selector->item_style = "type1";
299 itc_im_selector->func.text_get = im_setting_selector_genlist_item_label_get;
300 itc_im_selector->func.content_get = im_setting_selector_genlist_item_icon_get;
301 itc_im_selector->func.state_get = NULL;
302 itc_im_selector->func.del = im_setting_selector_genlist_item_del_cb;
306 static void im_setting_selector_add_ime(void *data) {
307 appdata *ad = (appdata *)data;
311 im_setting_selector_genlist_item_class_create();
314 for (i = 0; i < g_ime_info_list.size(); i++) {
315 sel_cb_data *cb_data = new sel_cb_data;
316 cb_data->data = data;
319 elm_genlist_item_append(ad->genlist,
323 ELM_GENLIST_ITEM_NONE,
324 im_setting_selector_ime_sel_cb,
327 elm_radio_value_set(group_radio, g_active_ime_id);
330 Evas_Object *im_setting_selector_list_create(void *data)
332 appdata *ad = (appdata *)data;
335 ad->genlist = im_setting_selector_genlist_create(ad, ad->popup, ad->conform);
336 im_setting_selector_add_ime(ad);
340 static Evas_Object *im_setting_selector_naviframe_create(Evas_Object* parent)
342 Evas_Object *naviframe = elm_naviframe_add(parent);
343 elm_naviframe_prev_btn_auto_pushed_set(naviframe, EINA_TRUE);
344 eext_object_event_callback_add(naviframe, EEXT_CALLBACK_BACK, eext_naviframe_back_cb, NULL);
345 evas_object_size_hint_weight_set(naviframe, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
346 evas_object_size_hint_align_set(naviframe, EVAS_HINT_FILL, EVAS_HINT_FILL);
347 elm_object_part_content_set(parent, "elm.swallow.content", naviframe);
348 evas_object_show(naviframe);
353 static Eina_Bool im_setting_list_navi_item_pop_cb(void *data, Elm_Object_Item *it)
355 static bool in_exit = false;
366 im_setting_selector_popup_block_clicked_cb(void *data EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
368 evas_object_del(obj);
372 Evas_Object *im_setting_selector_popup_create(void *data)
374 appdata *ad = (appdata *)data;
377 if (NULL == group_radio)
379 group_radio = elm_radio_add(ad->win);
380 elm_radio_state_value_set(group_radio, -1);
382 ad->popup = elm_popup_add(ad->win);
383 elm_popup_align_set(ad->popup, ELM_NOTIFY_ALIGN_FILL, 1.0);
384 evas_object_smart_callback_add(ad->popup, "block,clicked", im_setting_selector_popup_block_clicked_cb, NULL);
385 elm_object_domain_translatable_part_text_set(ad->popup, "title,text", PACKAGE, IM_SETTING_SELECTOR_TITLE);
387 ad->naviframe = im_setting_selector_naviframe_create(ad->win);
388 ad->genlist = im_setting_selector_list_create(data);
390 Evas_Object *back_btn = elm_button_add(ad->naviframe);
391 elm_object_style_set(back_btn, "naviframe/back_btn/default");
392 Elm_Object_Item *nf_main_item = elm_naviframe_item_push(ad->naviframe,
398 elm_naviframe_item_pop_cb_set(nf_main_item, im_setting_list_navi_item_pop_cb, ad);
400 if (APP_TYPE_NORMAL == ad->app_type) {
401 Evas_Object *btn = elm_button_add(ad->popup);
402 elm_object_domain_translatable_text_set(btn, PACKAGE, IM_SETTING_SELECT_KEYBOARD);
403 elm_object_part_content_set(ad->popup, "button1", btn);
404 evas_object_smart_callback_add(btn, "clicked", im_setting_selector_select_keyboard_cb, ad);
407 elm_object_content_set(ad->popup, ad->genlist);
408 evas_object_show(ad->popup);
415 im_setting_selector_title_text_get(void *data, Evas_Object *obj, const char *part)
417 return strdup(dgettext(PACKAGE, IM_SETTING_SELECTOR_TITLE));
420 static Evas_Object *im_setting_selector_conform_create(Evas_Object *parentWin)
422 Evas_Object *conform = elm_conformant_add(parentWin);
423 elm_win_indicator_mode_set(parentWin, ELM_WIN_INDICATOR_SHOW);
424 elm_win_indicator_opacity_set(parentWin, ELM_WIN_INDICATOR_OPAQUE);
425 evas_object_size_hint_weight_set(conform, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
426 evas_object_size_hint_align_set(conform, EVAS_HINT_FILL, EVAS_HINT_FILL);
428 Evas_Object *bg = elm_bg_add(conform);
429 elm_object_style_set(bg, "indicator/headerbg");
430 elm_object_part_content_set(conform, "elm.swallow.indicator_bg", bg);
431 evas_object_show(bg);
433 Evas_Coord w = -1, h = -1;
434 elm_win_screen_size_get(parentWin, NULL, NULL, &w, &h);
435 if (w > 0 && h > 0) {
436 evas_object_resize(conform, w, h);
438 evas_object_event_callback_add(parentWin, EVAS_CALLBACK_RESIZE, NULL, conform);
439 evas_object_show(conform);
443 static Eina_Bool _naviframe_pop_cb(void *data, Elm_Object_Item *it)
449 static void im_setting_selector_screen_create(void *data)
452 Evas_Object *genlist = NULL;
454 ad = (appdata *) data;
455 if (ad == NULL) return;
457 Elm_Genlist_Item_Class *ttc = elm_genlist_item_class_new();
460 ttc->item_style = "title";
461 ttc->func.text_get = im_setting_selector_title_text_get;
463 ad->conform = im_setting_selector_conform_create(ad->win);
464 ad->naviframe = im_setting_selector_naviframe_create(ad->conform);
465 genlist = im_setting_selector_genlist_create(ad, ad->win, ad->conform);
466 evas_object_show(ad->win);
468 im_setting_selector_genlist_item_class_create();
470 elm_genlist_mode_set(genlist, ELM_LIST_SCROLL);
471 elm_genlist_item_append(genlist, ttc, NULL, NULL, ELM_GENLIST_ITEM_NONE, NULL, NULL);
473 if (NULL == group_radio) {
474 group_radio = elm_radio_add(genlist);
475 elm_radio_state_value_set(group_radio, g_active_ime_id);
479 for (unsigned int i = 0; i < g_ime_info_list.size(); i++) {
480 sel_cb_data *cb_data = new sel_cb_data;
481 cb_data->data = data;
483 elm_genlist_item_append(genlist,
487 ELM_GENLIST_ITEM_NONE,
488 im_setting_selector_ime_sel_cb,
492 elm_radio_state_value_set(group_radio, g_active_ime_id);
493 elm_radio_value_set(group_radio, g_active_ime_id);
494 elm_genlist_item_class_free(ttc);
495 Elm_Object_Item *navi_it = elm_naviframe_item_push(ad->naviframe, NULL, NULL, NULL, genlist, "empty");
496 elm_naviframe_item_pop_cb_set(navi_it, _naviframe_pop_cb, ad);
499 elm_atspi_accessible_name_set(ad->naviframe, dgettext(PACKAGE, IM_SETTING_SELECTOR_TITLE));
505 im_setting_selector_app_create(void *data)
507 appdata *ad = (appdata *)data;
510 im_setting_selector_text_domain_set();
511 ad->win = im_setting_selector_main_window_create(PACKAGE);
512 im_setting_selector_load_ime_info();
514 im_setting_selector_screen_create(ad);
516 im_setting_selector_popup_create(ad);
517 evas_object_show(ad->win);
522 im_setting_selector_app_pause(void *data)
527 void im_setting_selector_app_terminate(void *data)
529 g_ime_info_list.clear();
530 if (NULL != itc_im_selector)
532 elm_genlist_item_class_free(itc_im_selector);
533 itc_im_selector = NULL;