2 * Copyright 2012 Samsung Electronics Co., Ltd
4 * Licensed under the Flora License, Version 1.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.tizenopensource.org/license
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.
18 #include "mgr-app-common-debug.h"
19 #include "mgr-app-common-error.h"
20 #include "mgr-app-view-manager.h"
21 #include "mgr-app-widget.h"
22 #include "mgr-app-view-factory.h"
23 #include "mgr-app-common-util.h"
24 #include "mgr-app-uigadget.h"
28 #include <package-manager.h>
31 #define WRT_PREFIX "wgt"
32 #define JAVA_PREFIX "jar"
33 #define DEB_PREFIX "deb"
34 #define RPM_PREFIX "rpm"
37 #define STR_ICON "icon"
38 #define STR_PNG ".png"
39 #define STR_EDJ ".edj"
40 #define DEFAULT_ICON_FILE "/opt/ug/res/images/ug-setting-manage-applications-efl/ManageApplications_default.png"
41 #define STR_NAVI_TITLE "Manage applications"
43 #define EDC_FILE "/opt/ug/res/edje/ug-setting-manage-applications-efl/ug-setting-manage-applications-efl.edj"
44 #define EDC_GROUPS "mgr-app-list"
46 #define ELM_TEXT "elm.text"
47 #define ITC_ITEM_STYLE "dialogue/1text.1icon.2"
48 #define ITC_SEP_21_ITEM_STYLE "dialogue/separator/21/with_line"
49 #define GENLIST_BLOCK_CNT 10
51 #define MAX_BUF_SIZE 32
52 #define MAX_APP_CNT 1024
56 #define STR_INSTALL "install"
57 #define STR_UNINSTALL "uninstall"
58 #define STR_START "start"
61 #define STR_CANCEL "cancel"
64 typedef struct _app_list_view_data_t app_list_view_data_t;
66 struct _app_list_view_data_t {
71 mgr_app_app_info_t *app_info_list;
73 int appinfo_cnt_total;
77 static Evas_Object *mgr_app_view_app_list_create(void *data);
78 static Evas_Object *mgr_app_view_app_list_set_cbar(void *data);
79 static mgr_app_result_e mgr_app_view_app_list_set_navibar(void *data);
80 static mgr_app_result_e mgr_app_view_app_list_destory(void *data);
81 static mgr_app_result_e mgr_app_view_app_list_update(void *data);
82 static mgr_app_result_e mgr_app_view_app_list_cleanup(void *data);
84 static Evas_Object *__create_genlist_app_list(Evas_Object *parent, void *data);
85 static char *__convert_char_to_string(char ch);
86 static void __register_index_item(Evas_Object *index, char *letter, Elm_Object_Item *item, Eina_Bool init);
87 static void _index_del_item_cb(void *data, Evas_Object *obj, void *event_info);
90 mgr_app_view_t mgr_app_view_app_list = {
91 .create = mgr_app_view_app_list_create,
92 .setcbar = mgr_app_view_app_list_set_cbar,
93 .setnavibar = mgr_app_view_app_list_set_navibar,
94 .destroy = mgr_app_view_app_list_destory,
95 .update = mgr_app_view_app_list_update,
98 static Elm_Genlist_Item_Class *itc = NULL;
99 static Elm_Genlist_Item_Class *itc_sep_21 = NULL;
102 static void _app_list_next_cb(void *data, Evas_Object *obj, void *event_info)
105 mgr_app_view_create(&mgr_app_view_app_list, data);
109 static void _app_list_back_cb(void *data, Evas_Object *obj, void *event_info)
112 ret_if(data == NULL);
113 struct ug_data *ugd = (struct ug_data*)data;
114 mgr_app_view_common_back_cb(data, EINA_FALSE);
116 elm_genlist_item_class_free(itc);
117 elm_genlist_item_class_free(itc_sep_21);
119 /* bg must delete before starting on_destroy */
120 evas_object_del(ugd->bg);
122 ug_destroy_me(ugd->ug);
126 /* get the state of item */
127 static Eina_Bool _gl_state_get(void *data, Evas_Object *obj, const char *part)
135 /* callback for 'deletion' */
136 static void _gl_del(void *data, Evas_Object *obj)
140 ret_if(data == NULL);
141 mgr_app_app_info_t *app_info = (mgr_app_app_info_t*)data;
143 MGR_APP_MEM_FREE(app_info->pkg_name);
144 MGR_APP_MEM_FREE(app_info->app_name);
145 MGR_APP_MEM_FREE(app_info->pkg_type);
146 MGR_APP_MEM_FREE(app_info->icon_path);
147 //MGR_APP_MEM_FREE(app_info);
153 /* callback for 'selection' */
154 static void _gl_sel(void *data, Evas_Object *obj, void *event_info)
158 ret_if(data == NULL);
159 ret_if(event_info == NULL);
161 struct ug_data *ugd = (struct ug_data*)data;
162 Elm_Object_Item *item = (Elm_Object_Item *)event_info;
164 mgr_app_app_info_t *app_info = (mgr_app_app_info_t*)elm_object_item_data_get(item);
165 ret_if(app_info == NULL);
167 elm_genlist_item_selected_set(item, 0);
169 /* create app info view */
170 ugd->data = (void*)app_info;
171 mgr_app_view_create(&mgr_app_view_app_info, (void*)ugd);
176 static char *_gl_label_get(void *data, Evas_Object *obj, const char *part)
180 retv_if(data == NULL, NULL);
181 mgr_app_app_info_t *app_info = (mgr_app_app_info_t*)data;
184 char *app_name = app_info->app_name;
185 char *icon_path = app_info->icon_path;
186 char *pkg_type = app_info->pkg_type;
188 MGR_APP_DEBUG("package_name:[%s], x_slp_packagetype:[%s], icon_path:[%s]\n", app_name, pkg_type, icon_path);
189 MGR_APP_DEBUG("part:%s\n", part);
191 /* label for 'elm.text' part */
192 if (app_name && !strncmp(part, ELM_TEXT, strlen(ELM_TEXT))) {
193 MGR_APP_MEM_STRDUP(label, app_name);
195 MGR_APP_MEM_STRDUP(label, dgettext("sys_string", "IDS_COM_POP_ERROR"));
202 static Evas_Object *_gl_icon_get(void *data, Evas_Object *obj, const char *part)
206 retv_if(data == NULL, NULL);
207 mgr_app_app_info_t *app_info = (mgr_app_app_info_t*)data;
209 retv_if(app_info->icon_path == NULL, NULL);
210 char *icon_path = NULL;
211 icon_path = app_info->icon_path;
213 Evas_Object *icon = NULL;
215 MGR_APP_DEBUG("icon_path:[%s]\n", icon_path);
216 MGR_APP_DEBUG("part:%s\n", part);
218 /* icon for 'elm.icon' part */
219 icon = elm_icon_add(obj);
220 retv_if(icon == NULL, NULL);
221 evas_object_size_hint_weight_set(icon, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
222 evas_object_size_hint_align_set(icon, EVAS_HINT_FILL, EVAS_HINT_FILL);
223 evas_object_size_hint_aspect_set(icon, EVAS_ASPECT_CONTROL_VERTICAL, 1, 1);
225 elm_icon_file_set(icon, icon_path, STR_ICON);
226 evas_object_show(icon);
232 static void _index_delayed_changed(void *data, Evas_Object *obj, void *event_info)
235 // called on a change but delayed in case multiple changes happen in a
237 elm_genlist_item_bring_in(elm_object_item_data_get(event_info), ELM_GENLIST_ITEM_SCROLLTO_TOP);
241 static void _index_changed(void *data, Evas_Object *obj, void *event_info)
244 // this is calld on every change, no matter how often
248 static void _index_selected(void *data, Evas_Object *obj, void *event_info)
251 // called on final select
252 elm_genlist_item_bring_in(elm_object_item_data_get(event_info), ELM_GENLIST_ITEM_SCROLLTO_TOP);
256 static int _app_list_qsort_cb(const void *a, const void *b)
261 MGR_APP_DEBUG_ERR("a is null");
264 MGR_APP_DEBUG_ERR("b is null");
268 mgr_app_app_info_t *app_info1 = (mgr_app_app_info_t*)a;
269 mgr_app_app_info_t *app_info2 = (mgr_app_app_info_t*)b;
271 if (!app_info1->app_name) {
272 MGR_APP_DEBUG_ERR("app_info1->app_name is null");
276 if (!app_info2->app_name) {
277 MGR_APP_DEBUG_ERR("app_info2->app_name is null");
282 len = (strlen(app_info1->app_name) >= strlen(app_info2->app_name)) ? strlen(app_info1->app_name) : strlen(app_info2->app_name);
285 return strncasecmp(app_info1->app_name, app_info2->app_name, len);
288 static ail_cb_ret_e _appinfo_func_cb(const ail_appinfo_h ail_info, void *user_data)
292 retv_if(mgr_app_view_app_list.view_common_data == NULL, AIL_CB_RET_CONTINUE);
293 mgr_app_view_common_data_t *view_common_data = mgr_app_view_app_list.view_common_data;
295 retv_if(view_common_data->user_view_data == NULL, AIL_CB_RET_CONTINUE);
296 app_list_view_data_t *app_list_view_data = view_common_data->user_view_data;
298 retv_if(user_data == NULL, AIL_CB_RET_CONTINUE);
299 mgr_app_app_info_t *p_app_info_list = (mgr_app_app_info_t *)user_data;
301 if (app_list_view_data->initialize) {
302 p_app_info_list = p_app_info_list + app_list_view_data->app_info_idx++;
306 char *package_name = NULL;
307 char *app_name = NULL;
308 char *icon_path = NULL;
309 char *x_slp_packagetype = NULL;
310 bool nodisplay = EINA_FALSE;
311 bool removable = EINA_FALSE;
312 bool taskmanage = EINA_FALSE;
314 ail_appinfo_get_str(ail_info, AIL_PROP_PACKAGE_STR, &package_name);
316 MGR_APP_DEBUG_ERR(">>> get package_name failed");
317 return AIL_CB_RET_CONTINUE;
319 ail_appinfo_get_str(ail_info, AIL_PROP_NAME_STR, &app_name);
321 MGR_APP_DEBUG_ERR(">>> get app_name failed");
322 return AIL_CB_RET_CONTINUE;
324 ail_appinfo_get_str(ail_info, AIL_PROP_ICON_STR, &icon_path);
325 ail_appinfo_get_str(ail_info, AIL_PROP_X_SLP_PACKAGETYPE_STR, &x_slp_packagetype);
326 ail_appinfo_get_bool(ail_info, AIL_PROP_NODISPLAY_BOOL, &nodisplay);
327 ail_appinfo_get_bool(ail_info, AIL_PROP_X_SLP_REMOVABLE_BOOL , &removable);
328 ail_appinfo_get_bool(ail_info, AIL_PROP_X_SLP_TASKMANAGE_BOOL , &taskmanage);
332 /* setting icon path */
336 /* TODO - avoid the slow-down change effect due to edj icon */
337 if (((p = strrchr(icon_path, '.'))) && (!strcasecmp(p, ".edj"))) {
338 icon_path = DEFAULT_ICON_FILE;
339 } else if ((stream = fopen(icon_path, "r")) != NULL && strlen(icon_path) > strlen(STR_PNG)) {
343 char *p_extension = NULL;
344 p_extension = icon_path + (strlen(icon_path) - strlen(STR_PNG));
346 /* default icon : icon_path's extension is wrong */
347 if (strncmp(p_extension, STR_PNG, strlen(STR_PNG)) != 0 && strncmp(p_extension, STR_EDJ, strlen(STR_EDJ)) != 0) {
348 icon_path = DEFAULT_ICON_FILE;
350 /* default icon : icon_path isn't exist */
352 icon_path = DEFAULT_ICON_FILE;
358 /* default icon : icon_path == NULL */
360 icon_path = DEFAULT_ICON_FILE;
363 MGR_APP_MEM_STRDUP(p_app_info_list->pkg_name, package_name);
364 MGR_APP_MEM_STRDUP(p_app_info_list->app_name, app_name);
365 MGR_APP_MEM_STRDUP(p_app_info_list->icon_path, icon_path);
366 MGR_APP_MEM_STRDUP(p_app_info_list->pkg_type, x_slp_packagetype);
367 p_app_info_list->nodisplay = nodisplay;
368 p_app_info_list->removable = removable;
369 p_app_info_list->taskmanage = taskmanage;
370 p_app_info_list->pid = 0;
373 return AIL_CB_RET_CONTINUE;
376 static void _popup_progressbar_by_uninstall(void *data)
380 ret_if(data == NULL);
381 struct ug_data *ugd = (struct ug_data*)data;
383 Evas_Object *popup = NULL;
384 Evas_Object *layout = NULL;
385 Evas_Object *progressbar = NULL;
387 popup = elm_popup_add(ugd->win_main);
389 layout = mgr_app_create_layout(popup, "layout", "application", "default");
390 ret_if(layout == NULL);
392 progressbar = elm_progressbar_add(popup);
393 elm_object_style_set(progressbar, "list_process");
394 evas_object_size_hint_align_set(progressbar, EVAS_HINT_FILL, 0.5);
395 evas_object_size_hint_weight_set(progressbar, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
396 elm_progressbar_pulse(progressbar, EINA_TRUE);
397 evas_object_show(progressbar);
399 elm_object_part_content_set(layout, "elm.swallow.content", progressbar);
401 elm_object_part_text_set(popup, "title,text", dgettext(PACKAGE, "IDS_ST_POP_UNINSTALLING_ING"));
402 elm_popup_timeout_set(popup, 1.0);
403 elm_object_content_set(popup, layout);
404 evas_object_show(popup);
409 static void _notify_by_uninstall(void *data)
413 ret_if(data == NULL);
414 struct ug_data *ugd = (struct ug_data*)data;
416 Evas_Object *noti = elm_notify_add(ugd->navi_bar);
417 elm_notify_orient_set(noti, ELM_NOTIFY_ORIENT_BOTTOM);
419 Evas_Object *layout = elm_layout_add(noti);
420 elm_layout_theme_set(layout, "standard", "selectioninfo", "vertical/bottom_12");
422 elm_object_content_set(noti, layout);
423 elm_notify_timeout_set(noti, 2);
424 edje_object_part_text_set(_EDJ(layout), ELM_TEXT, dgettext(PACKAGE, "IDS_ST_POP_UNINSTALLED"));
425 evas_object_show(noti);
430 static void _list_update_by_install(char *pkg_type, const char *pkg_name, void *data)
434 ret_if(pkg_type == NULL);
435 ret_if(data == NULL);
436 struct ug_data *ugd = (struct ug_data*)data;
438 ret_if(mgr_app_view_app_list.view_common_data == NULL);
439 mgr_app_view_common_data_t *view_common_data = mgr_app_view_app_list.view_common_data;
441 ret_if(view_common_data->user_view_data == NULL);
442 app_list_view_data_t *app_list_view_data = view_common_data->user_view_data;
445 /* create app info data */
446 mgr_app_app_info_t *app_info_new = (mgr_app_app_info_t*)malloc(sizeof(mgr_app_app_info_t));
447 ret_if(app_info_new == NULL);
448 memset(app_info_new, 0, sizeof(mgr_app_app_info_t));
452 ail_filter_h filter = {0};
453 ail_filter_new(&filter);
454 ail_filter_add_str(filter, AIL_PROP_X_SLP_PACKAGETYPE_STR, pkg_type);
455 ail_filter_add_str(filter, AIL_PROP_PACKAGE_STR, pkg_name);
456 if (!strncmp(pkg_type, JAVA_PREFIX, strlen(JAVA_PREFIX))) {
457 ail_filter_add_bool(filter, AIL_PROP_NODISPLAY_BOOL, EINA_FALSE);
459 app_list_view_data->initialize = EINA_FALSE;
460 ail_filter_list_appinfo_foreach(filter, _appinfo_func_cb, (void*)app_info_new);
461 ail_filter_destroy(filter);
463 if (!app_info_new->app_name) {
464 MGR_APP_DEBUG_ERR("app_info_new->app_name is null");
465 MGR_APP_MEM_FREE(app_info_new);
470 Elm_Object_Item *item = elm_genlist_first_item_get(app_list_view_data->genlist);
472 elm_genlist_item_append(app_list_view_data->genlist, itc_sep_21, NULL, NULL, ELM_GENLIST_ITEM_NONE, NULL, NULL);
474 mgr_app_app_info_t *app_info = NULL;
476 for (i = 0; i < app_list_view_data->app_info_idx-1; i++) {
478 app_info = (mgr_app_app_info_t*)elm_object_item_data_get(item);
480 MGR_APP_DEBUG_ERR("app_info is null");
481 MGR_APP_MEM_FREE(app_info_new);
486 len = (strlen(app_info_new->app_name) >= strlen(app_info->app_name)) ? strlen(app_info_new->app_name) : strlen(app_info->app_name);
488 if (strncasecmp(app_info_new->app_name, app_info->app_name, len) < 0) {
490 Elm_Object_Item *prev_item = elm_genlist_item_prev_get(item);
491 Elm_Object_Item *new_item = elm_genlist_item_insert_before(app_list_view_data->genlist, itc, (void*)app_info_new, NULL, item, ELM_GENLIST_ITEM_NONE, _gl_sel, (void*)ugd);
492 ret_if(new_item == NULL);
494 char *letter_new = __convert_char_to_string(app_info_new->app_name[0]);
495 ret_if(letter_new == NULL);
496 char *letter = __convert_char_to_string(app_info->app_name[0]);
498 MGR_APP_MEM_FREE(letter_new);
502 /* the top of item */
504 if (letter_new[0] == letter[0]) {
505 /* B'-B, index item must be replaced from B to B' */
506 elm_object_item_del(item);
508 /* B'-C, just add the index item */
509 __register_index_item(app_list_view_data->index, letter_new, new_item, EINA_FALSE);
513 mgr_app_app_info_t *app_info_prev = elm_object_item_data_get(prev_item);
514 if (!app_info_prev) {
515 MGR_APP_MEM_FREE(letter);
519 char *letter_prev = __convert_char_to_string(app_info_prev->app_name[0]);
521 MGR_APP_MEM_FREE(letter);
525 if (letter_prev[0] == letter_new[0]) {
526 /* B-B', nothing to do for index */
528 } else if (letter_prev[0] < letter_new[0] && letter_new[0] < letter[0]) {
529 /* A-B'-C, B' must be inserted to index */
530 __register_index_item(app_list_view_data->index, letter_new, new_item, EINA_FALSE);
532 } else if (letter_prev[0] < letter_new[0] && letter_new[0] == letter[0]) {
533 /* A-B'-B, index item must be replaced from B to B' */
534 elm_object_item_del(item);
536 MGR_APP_MEM_FREE(letter_prev);
539 MGR_APP_MEM_FREE(letter_new);
540 MGR_APP_MEM_FREE(letter);
541 app_list_view_data->app_info_idx++;
545 item = elm_genlist_item_next_get(item);
547 MGR_APP_DEBUG_ERR("item is null");
548 MGR_APP_MEM_FREE(app_info_new);
552 /* check the item and append after last item */
553 if (item == elm_genlist_last_item_get(app_list_view_data->genlist)) {
554 char *letter_new = __convert_char_to_string(app_info_new->app_name[0]);
555 ret_if(letter_new == NULL);
557 Elm_Object_Item *new_item = elm_genlist_item_append(app_list_view_data->genlist, itc, (void*)app_info_new, NULL, ELM_GENLIST_ITEM_NONE, _gl_sel, (void*)ugd);
558 ret_if(new_item == NULL);
560 __register_index_item(app_list_view_data->index, letter_new, new_item, EINA_FALSE);
562 MGR_APP_MEM_FREE(letter_new);
563 app_list_view_data->app_info_idx++;
570 elm_genlist_realized_items_update(app_list_view_data->genlist);
575 static void _list_update_by_uninstall(char *pkg_type, const char *pkg_name, void *data)
579 ret_if(pkg_type == NULL);
580 ret_if(data == NULL);
581 struct ug_data *ugd = (struct ug_data*)data;
583 ret_if(mgr_app_view_app_list.view_common_data == NULL);
584 mgr_app_view_common_data_t *view_common_data = mgr_app_view_app_list.view_common_data;
586 ret_if(view_common_data->user_view_data == NULL);
587 app_list_view_data_t *app_list_view_data = view_common_data->user_view_data;
590 Elm_Object_Item *item = elm_genlist_first_item_get(app_list_view_data->genlist);
591 ret_if(item == NULL);
592 item = elm_genlist_item_next_get(item);
593 ret_if(item == NULL);
594 mgr_app_app_info_t *app_info = NULL;
596 for (i = 0; i < app_list_view_data->app_info_idx-1; i++) {
598 app_info = (mgr_app_app_info_t*)elm_object_item_data_get(item);
599 ret_if(app_info == NULL);
601 MGR_APP_DEBUG_ERR("pkg_type: %s, %s", pkg_type, app_info->pkg_type);
602 MGR_APP_DEBUG_ERR("pkg_name: %s, %s", pkg_name, app_info->pkg_name);
604 if (!strncmp(pkg_type, app_info->pkg_type, strlen(pkg_type)) && !strncmp(pkg_name, app_info->pkg_name, strlen(pkg_name))) {
605 Elm_Object_Item *idx_item = elm_index_item_find(app_list_view_data->index, item);
606 elm_object_item_del(idx_item);
607 elm_object_item_del(item);
608 MGR_APP_DEBUG_ERR("deleted");
609 app_list_view_data->app_info_idx--;
612 item = elm_genlist_item_next_get(item);
613 ret_if(item == NULL);
617 elm_genlist_realized_items_update(app_list_view_data->genlist);
622 int mgr_app_view_listen_cb(int req_id, const char *pkg_type, const char *pkg_name, const char *key, const char *val, const void *pmsg, void *data)
626 MGR_APP_DEBUG("key:%s val:%s", key, val);
627 MGR_APP_DEBUG("pkg_type:%s pkg_name:%s", pkg_type, pkg_name);
628 retv_if(data == NULL, -1);
629 struct ug_data *ugd = (struct ug_data*)data;
631 char *buf_pkg_type = NULL;
632 if (!strncmp(pkg_type, STR_JAD, strlen(STR_JAD))) {
633 MGR_APP_MEM_STRDUP(buf_pkg_type, JAVA_PREFIX);
635 MGR_APP_MEM_STRDUP(buf_pkg_type, pkg_type);
638 if (!strncmp(key, STR_START, strlen(key)) && !strncmp(val, STR_UNINSTALL, strlen(val))) {
639 ugd->uninstall = EINA_TRUE;
640 _popup_progressbar_by_uninstall((void*)ugd);
641 } else if (!strncmp(key, STR_START, strlen(key)) && !strncmp(val, STR_INSTALL, strlen(val))) {
642 ugd->uninstall = EINA_FALSE;
643 } else if (!strncmp(key, STR_END, strlen(key)) && !strncmp(val, STR_OK, strlen(val))) {
644 if (ugd->uninstall) {
645 _list_update_by_uninstall(buf_pkg_type, pkg_name, (void*)ugd);
647 _list_update_by_install(buf_pkg_type, pkg_name, (void*)ugd);
650 /* check the info view was opened */
651 GList *view_list = mgr_app_view_get_viewlist(data);
653 MGR_APP_MEM_FREE(buf_pkg_type);
657 GList *info_view = g_list_find(view_list, &mgr_app_view_app_info);
659 struct ug_data *ugd = (struct ug_data*)data;
660 if (ugd->uninstall) {
661 _app_info_back_cb(data, NULL, NULL);
662 _notify_by_uninstall((void*)ugd);
663 ugd->uninstall = EINA_FALSE;
666 } else if (!strncmp(key, STR_END, strlen(key)) && !strncmp(val, STR_CANCEL, strlen(val))) {
670 MGR_APP_MEM_FREE(buf_pkg_type);
673 /* the return value occured infinite loop */
674 /* package manager example has no return value */
678 static char *__convert_char_to_string(char ch)
682 char *str_buf = NULL;
683 str_buf = (char*)malloc(sizeof(char)*MAX_BUF_SIZE);
684 retv_if(str_buf == NULL, NULL);
685 memset(str_buf, 0, sizeof(char)*MAX_BUF_SIZE);
687 if (ch >= 'A' && ch <= 'Z') {
688 snprintf(str_buf, MAX_BUF_SIZE, "%c", ch);
689 } else if (ch >= 'a' && ch <= 'z') {
690 snprintf(str_buf, MAX_BUF_SIZE, "%c", ch - 'a' + 'A');
691 } else if (ch >= '0' && ch <= '9') {
692 snprintf(str_buf, MAX_BUF_SIZE, "%c", ch);
694 snprintf(str_buf, MAX_BUF_SIZE, "%s", "etc");
701 static int _compare_index_item_letter_cb(const void *a, const void *b)
705 retv_if(a == NULL, -1);
706 retv_if(b == NULL, -1);
708 const Elm_Object_Item *it1 = (const Elm_Object_Item*)a;
709 const Elm_Object_Item *it2 = (const Elm_Object_Item*)b;
711 const char *letter1 = elm_index_item_letter_get(it1);
712 const char *letter2 = elm_index_item_letter_get(it1);
714 MGR_APP_DEBUG_ERR("letter1: %s, letter2: %s", letter1, letter2);
717 len = (strlen(letter1) >= strlen(letter2)) ? strlen(letter1) : strlen(letter2);
720 return strncasecmp(letter1, letter2, len);
724 * _compare_data_index_item_letter_cb be used when _compare_index_item_letter_cb return 0.
726 static int _compare_data_index_item_letter_cb(const void *a, const void *b)
730 retv_if(a == NULL, -1);
731 retv_if(b == NULL, -1);
733 const Elm_Object_Item *it1 = (const Elm_Object_Item*)a;
734 const Elm_Object_Item *it2 = (const Elm_Object_Item*)b;
736 mgr_app_app_info_t *app_info1 = elm_object_item_data_get(it1);
737 mgr_app_app_info_t *app_info2 = elm_object_item_data_get(it1);
739 MGR_APP_DEBUG_ERR("letter1: %s, letter2: %s", app_info1->app_name, app_info2->app_name);
745 static void __register_index_item(Evas_Object *index, char *letter, Elm_Object_Item *item, Eina_Bool init)
749 MGR_APP_DEBUG_ERR("letter: %s", letter);
751 ret_if(mgr_app_view_app_list.view_common_data == NULL);
752 mgr_app_view_common_data_t *view_common_data = mgr_app_view_app_list.view_common_data;
754 ret_if(view_common_data->user_view_data == NULL);
755 app_list_view_data_t *app_list_view_data = view_common_data->user_view_data;
757 Elm_Object_Item *new_index_item = NULL;
760 Elm_Object_Item *temp_index_item = NULL;
761 Elm_Object_Item *temp_item = NULL;
762 const char *temp_letter = NULL;
765 temp_item = elm_genlist_first_item_get(app_list_view_data->genlist);
766 ret_if(temp_item == NULL);
768 for (i = 0; i < app_list_view_data->app_info_idx; i++) {
769 temp_index_item = elm_index_item_find(index, temp_item);
771 /* indexed genlist item */
772 if (temp_index_item) {
773 temp_letter = elm_index_item_letter_get(temp_index_item);
774 ret_if(temp_letter == NULL);
776 if (letter[0] < temp_letter[0]) {
777 elm_index_item_prepend_relative(index, letter, item, temp_item);
781 temp_item = elm_genlist_item_next_get(temp_item);
784 elm_index_item_append(index, letter, NULL, item);
787 new_index_item = elm_index_item_find(index, item);
788 ret_if(new_index_item == NULL);
789 elm_object_item_del_cb_set(new_index_item, _index_del_item_cb);
790 elm_object_item_data_set(new_index_item, (void*)item);
792 app_list_view_data->index_cnt++;
797 static void _index_del_item_cb(void *data, Evas_Object *obj, void *event_info)
801 ret_if(data == NULL);
802 Elm_Object_Item *item = (Elm_Object_Item*)data;
803 Elm_Object_Item *next_item = elm_genlist_item_next_get(item);
805 ret_if(mgr_app_view_app_list.view_common_data == NULL);
806 mgr_app_view_common_data_t *view_common_data = mgr_app_view_app_list.view_common_data;
808 ret_if(view_common_data->user_view_data == NULL);
809 app_list_view_data_t *app_list_view_data = view_common_data->user_view_data;
811 /* change the index item */
813 mgr_app_app_info_t *next_app_info = (mgr_app_app_info_t*)elm_object_item_data_get(next_item);
814 ret_if(next_app_info == NULL);
816 char *next_letter = __convert_char_to_string(next_app_info->app_name[0]);
817 ret_if(next_letter == NULL);
819 ret_if(event_info == NULL);
820 Elm_Object_Item *index_item = (Elm_Object_Item*)event_info;
822 const char *letter = elm_index_item_letter_get(index_item);
823 ret_if(letter == NULL);
825 Elm_Object_Item *prev_item = elm_genlist_item_prev_get(item);
828 /* case: B-B', del:B */
829 if (letter[0] == next_letter[0]) {
830 __register_index_item(app_list_view_data->index, next_letter, next_item, EINA_FALSE);
833 mgr_app_app_info_t *prev_app_info = (mgr_app_app_info_t*)elm_object_item_data_get(prev_item);
834 if (!prev_app_info) {
835 MGR_APP_MEM_FREE(next_letter);
839 char *prev_letter = __convert_char_to_string(prev_app_info->app_name[0]);
841 MGR_APP_MEM_FREE(next_letter);
845 /* case: A-B'-B-B'', del:B */
846 if (letter[0] == prev_letter[0]) {
847 __register_index_item(app_list_view_data->index, prev_letter, prev_item, EINA_FALSE);
849 /* case: A-B-B'-B'', del:B */
850 } else if (letter[0] == next_letter[0]) {
851 __register_index_item(app_list_view_data->index, next_letter, next_item, EINA_FALSE);
854 MGR_APP_MEM_FREE(prev_letter);
856 MGR_APP_MEM_FREE(next_letter);
859 MGR_APP_DEBUG("next_item is null");
862 app_list_view_data->index_cnt--;
866 static Evas_Object *__create_genlist_app_list(Evas_Object *parent, void *data)
870 retv_if(mgr_app_view_app_list.view_common_data == NULL, NULL);
871 mgr_app_view_common_data_t *view_common_data = mgr_app_view_app_list.view_common_data;
873 retv_if(view_common_data->user_view_data == NULL, NULL);
874 app_list_view_data_t *app_list_view_data = view_common_data->user_view_data;
876 retv_if(data == NULL, NULL);
877 struct ug_data *ugd = (struct ug_data*)data;
878 Evas_Object *genlist = NULL;
879 Evas_Object *index = NULL;
882 /* set the genlist item style */
883 itc = elm_genlist_item_class_new();
884 retv_if(itc == NULL, NULL);
885 itc_sep_21 = elm_genlist_item_class_new();
886 retv_if(itc_sep_21 == NULL, NULL);
888 itc->item_style = ITC_ITEM_STYLE;
889 itc->func.text_get = _gl_label_get;
890 itc->func.content_get = _gl_icon_get;
891 itc->func.state_get = NULL;
892 itc->func.del = _gl_del;
894 itc_sep_21->item_style = ITC_SEP_21_ITEM_STYLE;
895 itc_sep_21->func.text_get = NULL;
896 itc_sep_21->func.content_get= NULL;
897 itc_sep_21->func.state_get = NULL;
898 itc_sep_21->func.del = NULL;
902 index = elm_index_add(parent);
903 retv_if(index == NULL, NULL);
904 elm_object_part_content_set(parent, "elm.swallow.content.index", index);
905 evas_object_show(index);
909 genlist = elm_genlist_add(parent);
910 retv_if(genlist == NULL, NULL);
911 elm_object_part_content_set(parent, "elm.swallow.content.genlist", genlist);
912 evas_object_size_hint_weight_set(genlist, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
913 evas_object_size_hint_align_set(genlist, EVAS_HINT_FILL, EVAS_HINT_FILL);
914 elm_genlist_mode_set(genlist, ELM_LIST_COMPRESS);
915 elm_genlist_block_count_set(genlist, GENLIST_BLOCK_CNT);
916 elm_genlist_scroller_policy_set(genlist, ELM_SCROLLER_POLICY_OFF, ELM_SCROLLER_POLICY_OFF);
917 evas_object_show(genlist);
920 app_list_view_data->genlist = genlist;
921 app_list_view_data->index = index;
922 app_list_view_data->index_cnt = 0;
925 /* get app_info from AIL */
926 mgr_app_app_info_t *app_info_list = NULL;
927 mgr_app_app_info_t *p_app_info_list = NULL;
929 ail_filter_h filter_deb = {0};
930 ail_filter_h filter_rpm = {0};
931 ail_filter_h filter_wrt = {0};
932 ail_filter_h filter_jar = {0};
934 ail_filter_new(&filter_deb);
935 ail_filter_new(&filter_rpm);
936 ail_filter_new(&filter_wrt);
937 ail_filter_new(&filter_jar);
939 ail_filter_add_str(filter_deb, AIL_PROP_X_SLP_PACKAGETYPE_STR, DEB_PREFIX);
940 ail_filter_add_str(filter_rpm, AIL_PROP_X_SLP_PACKAGETYPE_STR, RPM_PREFIX);
941 ail_filter_add_str(filter_wrt, AIL_PROP_X_SLP_PACKAGETYPE_STR, WRT_PREFIX);
942 ail_filter_add_str(filter_jar, AIL_PROP_X_SLP_PACKAGETYPE_STR, JAVA_PREFIX);
943 ail_filter_add_bool(filter_jar, AIL_PROP_NODISPLAY_BOOL, EINA_FALSE);
945 int appinfo_cnt_deb = 0;
946 int appinfo_cnt_rpm = 0;
947 int appinfo_cnt_wrt = 0;
948 int appinfo_cnt_jar = 0;
949 int appinfo_cnt_total = 0;
951 ail_filter_count_appinfo(filter_deb, &appinfo_cnt_deb);
952 ail_filter_count_appinfo(filter_rpm, &appinfo_cnt_rpm);
953 ail_filter_count_appinfo(filter_wrt, &appinfo_cnt_wrt);
954 ail_filter_count_appinfo(filter_jar, &appinfo_cnt_jar);
956 appinfo_cnt_total = appinfo_cnt_deb + appinfo_cnt_rpm + appinfo_cnt_wrt + appinfo_cnt_jar;
958 app_info_list = (mgr_app_app_info_t*)malloc(sizeof(mgr_app_app_info_t) * appinfo_cnt_total);
959 if (!app_info_list) {
960 MGR_APP_DEBUG_ERR("app_info_list allocation failed");
961 ail_filter_destroy(filter_deb);
962 ail_filter_destroy(filter_rpm);
963 ail_filter_destroy(filter_wrt);
964 ail_filter_destroy(filter_jar);
967 memset(app_info_list, 0, sizeof(mgr_app_app_info_t) * appinfo_cnt_total);
968 p_app_info_list = app_info_list;
970 app_list_view_data->app_info_idx = 0;
971 app_list_view_data->app_info_list = app_info_list;
972 app_list_view_data->appinfo_cnt_total = appinfo_cnt_total;
973 app_list_view_data->initialize = EINA_TRUE;
975 ail_filter_list_appinfo_foreach(filter_deb, _appinfo_func_cb, (void*)app_info_list);
976 ail_filter_list_appinfo_foreach(filter_rpm, _appinfo_func_cb, (void*)app_info_list);
977 ail_filter_list_appinfo_foreach(filter_wrt, _appinfo_func_cb, (void*)app_info_list);
978 ail_filter_list_appinfo_foreach(filter_jar, _appinfo_func_cb, (void*)app_info_list);
980 ail_filter_destroy(filter_deb);
981 ail_filter_destroy(filter_rpm);
982 ail_filter_destroy(filter_wrt);
983 ail_filter_destroy(filter_jar);
986 /* sorting by app_name */
987 app_info_list = p_app_info_list;
988 qsort(app_info_list, appinfo_cnt_total, sizeof(mgr_app_app_info_t), _app_list_qsort_cb);
991 /* add genlist item order by ASC */
992 Elm_Object_Item *item = NULL;
994 char prev_letter[MAX_BUF_SIZE] = {0, };
997 app_info_list = p_app_info_list;
999 for (j = 0; j < appinfo_cnt_total; j++) {
1001 /* add the space to top of the dialogue */
1002 if (app_list_view_data->initialize) {
1003 app_list_view_data->initialize = EINA_FALSE;
1004 elm_genlist_item_append(genlist, itc_sep_21, NULL, NULL, ELM_GENLIST_ITEM_NONE, NULL, NULL);
1007 MGR_APP_DEBUG("%s", app_info_list->app_name);
1009 mgr_app_app_info_t *app_info = app_info_list;
1011 item = elm_genlist_item_append(genlist, itc, (void*)app_info, NULL, ELM_GENLIST_ITEM_NONE, _gl_sel, (void*)ugd);
1013 /* fast scroll insertion */
1014 letter = __convert_char_to_string(app_info_list->app_name[0]);
1015 if (item && strncmp(letter, prev_letter, MAX_BUF_SIZE) != 0) {
1016 __register_index_item(index, letter, item, EINA_TRUE);
1017 strncpy(prev_letter, letter, MAX_BUF_SIZE);
1020 MGR_APP_MEM_FREE(letter);
1021 app_info_list = app_info_list + 1;
1024 evas_object_smart_callback_add(index, "delay,changed", _index_delayed_changed, index);
1025 evas_object_smart_callback_add(index, "changed", _index_changed, NULL);
1026 evas_object_smart_callback_add(index, "selected", _index_selected, NULL);
1029 /* register pkg-mgr listener */
1031 retv_if(ugd->pc_listen == NULL, NULL);
1032 result = pkgmgr_client_listen_status(ugd->pc_listen, mgr_app_view_listen_cb, (void*)ugd);
1034 MGR_APP_DEBUG_ERR("status listen failed!\n");
1035 MGR_APP_MEM_FREE(genlist);
1043 static Evas_Object *mgr_app_view_app_list_create(void *data)
1047 retv_if(data == NULL, NULL);
1049 retv_if(mgr_app_view_app_list.view_common_data == NULL, NULL);
1050 mgr_app_view_common_data_t *view_common_data = mgr_app_view_app_list.view_common_data;
1052 MGR_APP_MEM_MALLOC(view_common_data->user_view_data, 1, app_list_view_data_t);
1053 retv_if(view_common_data->user_view_data == NULL, NULL);
1054 app_list_view_data_t *app_list_view_data = view_common_data->user_view_data;
1056 app_list_view_data->layout = mgr_app_create_layout_file(view_common_data->common_navibar, EDC_FILE, EDC_GROUPS);
1057 retv_if(app_list_view_data->layout == NULL, NULL);
1059 app_list_view_data->genlist = __create_genlist_app_list(app_list_view_data->layout, data);
1062 return app_list_view_data->layout;
1065 static Evas_Object *mgr_app_view_app_list_set_cbar(void *data)
1072 static mgr_app_result_e mgr_app_view_app_list_set_navibar(void *data)
1075 mgr_app_view_manager_set_navibar(mgr_app_view_app_list.view_common_data, STR_NAVI_TITLE, NULL, _app_list_back_cb, NULL, NULL);
1080 static mgr_app_result_e mgr_app_view_app_list_destory(void *data)
1084 retv_if(mgr_app_view_app_list.view_common_data == NULL, MGR_APP_ERROR);
1085 mgr_app_view_app_list.view_common_data->view_layout = NULL;
1090 static mgr_app_result_e mgr_app_view_app_list_update(void *data)
1094 retv_if(mgr_app_view_app_list.view_common_data == NULL, MGR_APP_ERROR);
1095 mgr_app_view_common_data_t *view_common_data = mgr_app_view_app_list.view_common_data;
1097 retv_if(view_common_data->user_view_data == NULL, MGR_APP_ERROR);
1098 app_list_view_data_t *app_list_view_data = view_common_data->user_view_data;
1100 if (app_list_view_data->genlist != NULL) {
1101 elm_genlist_clear(app_list_view_data->genlist);
1102 evas_object_del(app_list_view_data->genlist);
1103 app_list_view_data->genlist = NULL;
1106 app_list_view_data->genlist = __create_genlist_app_list(app_list_view_data->layout, data);
1111 static mgr_app_result_e mgr_app_view_app_list_cleanup(void *data)