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"
27 #include <package-manager.h>
30 #define WRT_PREFIX "wgt"
31 #define TPK_PREFIX "tpk"
32 #define RPM_PREFIX "rpm"
34 #define STR_ICON "icon"
35 #define STR_PNG ".png"
36 #define STR_EDJ ".edj"
37 #define DEFAULT_ICON_FILE "/opt/ug/res/images/ug-setting-manage-applications-efl/ManageApplications_default.png"
39 #define EDC_FILE "/opt/ug/res/edje/ug-setting-manage-applications-efl/ug-setting-manage-applications-efl.edj"
40 #define EDC_GROUPS "mgr-app-list"
42 #define ELM_TEXT "elm.text"
43 #define ITC_ITEM_STYLE "dialogue/1text.1icon.2"
44 #define ITC_SEP_21_ITEM_STYLE "dialogue/separator/21/with_line"
45 #define GENLIST_BLOCK_CNT 10
47 #define MAX_BUF_SIZE 32
48 #define MAX_APP_CNT 1024
52 #define STR_INSTALL "install"
53 #define STR_UNINSTALL "uninstall"
54 #define STR_START "start"
57 #define STR_CANCEL "cancel"
58 #define STR_ERROR "error"
59 #define STR_FAIL "fail"
60 #define STR_POPUP_OK "OK"
62 typedef struct _app_list_view_data_t app_list_view_data_t;
64 struct _app_list_view_data_t {
69 mgr_app_app_info_t *app_info_list;
71 int appinfo_cnt_total;
75 static Evas_Object *mgr_app_view_app_list_create(void *data);
76 static Evas_Object *mgr_app_view_app_list_set_cbar(void *data);
77 static mgr_app_result_e mgr_app_view_app_list_set_navibar(void *data);
78 static mgr_app_result_e mgr_app_view_app_list_destory(void *data);
79 static mgr_app_result_e mgr_app_view_app_list_update(void *data);
80 static mgr_app_result_e mgr_app_view_app_list_cleanup(void *data);
82 static Evas_Object *__create_genlist_app_list(Evas_Object *parent, void *data);
83 static char *__convert_char_to_string(char ch);
84 static void __register_index_item(Evas_Object *index, char *letter, Elm_Object_Item *item, Eina_Bool init);
85 static void _index_del_item_cb(void *data, Evas_Object *obj, void *event_info);
88 mgr_app_view_t mgr_app_view_app_list = {
89 .create = mgr_app_view_app_list_create,
90 .setcbar = mgr_app_view_app_list_set_cbar,
91 .setnavibar = mgr_app_view_app_list_set_navibar,
92 .destroy = mgr_app_view_app_list_destory,
93 .update = mgr_app_view_app_list_update,
96 static Elm_Genlist_Item_Class *itc = NULL;
97 static Elm_Genlist_Item_Class *itc_sep_21 = NULL;
100 static void _app_list_next_cb(void *data, Evas_Object *obj, void *event_info)
103 mgr_app_view_create(&mgr_app_view_app_list, data);
107 static void _app_list_back_cb(void *data, Evas_Object *obj, void *event_info)
110 ret_if(data == NULL);
111 struct ug_data *ugd = (struct ug_data*)data;
112 mgr_app_view_common_back_cb(data, EINA_FALSE);
114 elm_genlist_item_class_free(itc);
115 elm_genlist_item_class_free(itc_sep_21);
117 /* bg must delete before starting on_destroy */
118 evas_object_del(ugd->bg);
120 ug_destroy_me(ugd->ug);
124 /* get the state of item */
125 static Eina_Bool _gl_state_get(void *data, Evas_Object *obj, const char *part)
133 /* callback for 'deletion' */
134 static void _gl_del(void *data, Evas_Object *obj)
138 ret_if(data == NULL);
139 mgr_app_app_info_t *app_info = (mgr_app_app_info_t*)data;
141 MGR_APP_MEM_FREE(app_info->pkg_name);
142 MGR_APP_MEM_FREE(app_info->app_name);
143 MGR_APP_MEM_FREE(app_info->pkg_type);
144 MGR_APP_MEM_FREE(app_info->icon_path);
145 //MGR_APP_MEM_FREE(app_info);
151 /* callback for 'selection' */
152 static void _gl_sel(void *data, Evas_Object *obj, void *event_info)
156 ret_if(data == NULL);
157 ret_if(event_info == NULL);
159 struct ug_data *ugd = (struct ug_data*)data;
160 Elm_Object_Item *item = (Elm_Object_Item *)event_info;
162 mgr_app_app_info_t *app_info = (mgr_app_app_info_t*)elm_object_item_data_get(item);
163 ret_if(app_info == NULL);
165 elm_genlist_item_selected_set(item, 0);
167 /* create app info view */
168 ugd->data = (void*)app_info;
169 mgr_app_view_create(&mgr_app_view_app_info, (void*)ugd);
174 static char *_gl_label_get(void *data, Evas_Object *obj, const char *part)
178 retv_if(data == NULL, NULL);
179 mgr_app_app_info_t *app_info = (mgr_app_app_info_t*)data;
182 char *package_name = app_info->pkg_name;
183 char *app_name = app_info->app_name;
184 char *icon_path = app_info->icon_path;
185 char *pkg_type = app_info->pkg_type;
187 MGR_APP_DEBUG("package_name:[%s], app_name:[%s], x_slp_packagetype:[%s], icon_path:[%s]\n", package_name, app_name, pkg_type, icon_path);
188 MGR_APP_DEBUG("part:%s\n", part);
190 /* label for 'elm.text' part */
191 if (app_name && !strncmp(part, ELM_TEXT, strlen(ELM_TEXT))) {
192 MGR_APP_MEM_STRDUP(label, app_name);
194 MGR_APP_MEM_STRDUP(label, dgettext("sys_string", "IDS_COM_POP_ERROR"));
201 static Evas_Object *_gl_icon_get(void *data, Evas_Object *obj, const char *part)
205 retv_if(data == NULL, NULL);
206 mgr_app_app_info_t *app_info = (mgr_app_app_info_t*)data;
208 retv_if(app_info->icon_path == NULL, NULL);
209 char *icon_path = NULL;
210 icon_path = app_info->icon_path;
212 Evas_Object *icon = NULL;
214 MGR_APP_DEBUG("icon_path:[%s]\n", icon_path);
215 MGR_APP_DEBUG("part:%s\n", part);
217 /* icon for 'elm.icon' part */
218 icon = elm_icon_add(obj);
219 retv_if(icon == NULL, NULL);
220 evas_object_size_hint_weight_set(icon, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
221 evas_object_size_hint_align_set(icon, EVAS_HINT_FILL, EVAS_HINT_FILL);
222 evas_object_size_hint_aspect_set(icon, EVAS_ASPECT_CONTROL_VERTICAL, 1, 1);
224 elm_icon_file_set(icon, icon_path, STR_ICON);
225 evas_object_show(icon);
231 static void _index_delayed_changed(void *data, Evas_Object *obj, void *event_info)
234 // called on a change but delayed in case multiple changes happen in a
236 elm_genlist_item_bring_in(elm_object_item_data_get(event_info), ELM_GENLIST_ITEM_SCROLLTO_TOP);
240 static void _index_changed(void *data, Evas_Object *obj, void *event_info)
243 // this is calld on every change, no matter how often
247 static void _index_selected(void *data, Evas_Object *obj, void *event_info)
250 // called on final select
251 elm_genlist_item_bring_in(elm_object_item_data_get(event_info), ELM_GENLIST_ITEM_SCROLLTO_TOP);
255 static int _app_list_qsort_cb(const void *a, const void *b)
260 MGR_APP_DEBUG_ERR("a is null");
263 MGR_APP_DEBUG_ERR("b is null");
267 mgr_app_app_info_t *app_info1 = (mgr_app_app_info_t*)a;
268 mgr_app_app_info_t *app_info2 = (mgr_app_app_info_t*)b;
270 if (!app_info1->app_name) {
271 MGR_APP_DEBUG_ERR("app_info1->app_name is null");
275 if (!app_info2->app_name) {
276 MGR_APP_DEBUG_ERR("app_info2->app_name is null");
281 len = (strlen(app_info1->app_name) >= strlen(app_info2->app_name)) ? strlen(app_info1->app_name) : strlen(app_info2->app_name);
284 return strncasecmp(app_info1->app_name, app_info2->app_name, len);
287 static ail_cb_ret_e _appinfo_func_cb(const ail_appinfo_h ail_info, void *user_data)
291 retv_if(mgr_app_view_app_list.view_common_data == NULL, AIL_CB_RET_CONTINUE);
292 mgr_app_view_common_data_t *view_common_data = mgr_app_view_app_list.view_common_data;
294 retv_if(view_common_data->user_view_data == NULL, AIL_CB_RET_CONTINUE);
295 app_list_view_data_t *app_list_view_data = view_common_data->user_view_data;
297 retv_if(user_data == NULL, AIL_CB_RET_CONTINUE);
298 mgr_app_app_info_t *p_app_info_list = (mgr_app_app_info_t *)user_data;
300 if (app_list_view_data->initialize) {
301 p_app_info_list = p_app_info_list + app_list_view_data->app_info_idx++;
304 char *package_name = NULL;
305 char *app_name = NULL;
306 char *icon_path = NULL;
307 char *x_slp_packagetype = NULL;
308 bool nodisplay = EINA_FALSE;
309 bool removable = EINA_FALSE;
310 bool taskmanage = EINA_FALSE;
312 ail_appinfo_get_str(ail_info, AIL_PROP_PACKAGE_STR, &package_name);
314 MGR_APP_DEBUG_ERR(">>> get package_name failed");
315 return AIL_CB_RET_CONTINUE;
317 ail_appinfo_get_str(ail_info, AIL_PROP_NAME_STR, &app_name);
319 MGR_APP_DEBUG_ERR(">>> get app_name failed");
320 return AIL_CB_RET_CONTINUE;
322 ail_appinfo_get_str(ail_info, AIL_PROP_ICON_STR, &icon_path);
323 ail_appinfo_get_str(ail_info, AIL_PROP_X_SLP_PACKAGETYPE_STR, &x_slp_packagetype);
324 ail_appinfo_get_bool(ail_info, AIL_PROP_NODISPLAY_BOOL, &nodisplay);
325 ail_appinfo_get_bool(ail_info, AIL_PROP_X_SLP_REMOVABLE_BOOL , &removable);
326 ail_appinfo_get_bool(ail_info, AIL_PROP_X_SLP_TASKMANAGE_BOOL , &taskmanage);
329 /* setting icon path */
333 /* TODO - avoid the slow-down change effect due to edj icon */
334 if (((p = strrchr(icon_path, '.'))) && (!strcasecmp(p, ".edj"))) {
335 icon_path = DEFAULT_ICON_FILE;
336 } else if ((stream = fopen(icon_path, "r")) != NULL && strlen(icon_path) > strlen(STR_PNG)) {
340 char *p_extension = NULL;
341 p_extension = icon_path + (strlen(icon_path) - strlen(STR_PNG));
343 /* default icon : icon_path's extension is wrong */
344 if (strncmp(p_extension, STR_PNG, strlen(STR_PNG)) != 0 && strncmp(p_extension, STR_EDJ, strlen(STR_EDJ)) != 0) {
345 icon_path = DEFAULT_ICON_FILE;
347 /* default icon : icon_path isn't exist */
349 icon_path = DEFAULT_ICON_FILE;
355 /* default icon : icon_path == NULL */
357 icon_path = DEFAULT_ICON_FILE;
360 MGR_APP_MEM_STRDUP(p_app_info_list->pkg_name, package_name);
361 MGR_APP_MEM_STRDUP(p_app_info_list->app_name, app_name);
362 MGR_APP_MEM_STRDUP(p_app_info_list->icon_path, icon_path);
363 MGR_APP_MEM_STRDUP(p_app_info_list->pkg_type, x_slp_packagetype);
364 p_app_info_list->nodisplay = nodisplay;
365 p_app_info_list->removable = removable;
366 p_app_info_list->taskmanage = taskmanage;
368 MGR_APP_DEBUG("package_name: %s ", package_name);
369 MGR_APP_DEBUG("app_name: %s", app_name);
370 MGR_APP_DEBUG("icon_path: %s", icon_path);
371 MGR_APP_DEBUG("x_slp_packagetype: %s ", x_slp_packagetype);
372 MGR_APP_DEBUG("nodisplay: %d", nodisplay);
373 MGR_APP_DEBUG("removable: %d", removable);
374 MGR_APP_DEBUG("taskmanage: %d", taskmanage);
377 return AIL_CB_RET_CONTINUE;
380 static void _response_cb(void *data, Evas_Object *obj, void *event_info)
384 evas_object_del(data);
389 static void _notify_by_uninstall(void *data)
393 ret_if(data == NULL);
394 struct ug_data *ugd = (struct ug_data*)data;
396 Evas_Object *noti = elm_notify_add(ugd->navi_bar);
397 elm_notify_orient_set(noti, ELM_NOTIFY_ORIENT_BOTTOM);
399 Evas_Object *layout = elm_layout_add(noti);
400 elm_layout_theme_set(layout, "standard", "selectioninfo", "vertical/bottom_12");
402 elm_object_content_set(noti, layout);
403 elm_notify_timeout_set(noti, 2);
404 edje_object_part_text_set(_EDJ(layout), ELM_TEXT, dgettext(PACKAGE, "IDS_ST_POP_UNINSTALLED"));
405 evas_object_show(noti);
410 static void _list_update_by_install(char *pkg_type, const char *pkg_name, void *data)
414 ret_if(pkg_type == NULL);
415 ret_if(data == NULL);
416 struct ug_data *ugd = (struct ug_data*)data;
418 ret_if(mgr_app_view_app_list.view_common_data == NULL);
419 mgr_app_view_common_data_t *view_common_data = mgr_app_view_app_list.view_common_data;
421 ret_if(view_common_data->user_view_data == NULL);
422 app_list_view_data_t *app_list_view_data = view_common_data->user_view_data;
425 /* create app info data */
426 mgr_app_app_info_t *app_info_new = (mgr_app_app_info_t*)malloc(sizeof(mgr_app_app_info_t));
427 ret_if(app_info_new == NULL);
428 memset(app_info_new, 0, sizeof(mgr_app_app_info_t));
432 ail_filter_h filter = {0};
433 ail_filter_new(&filter);
434 ail_filter_add_str(filter, AIL_PROP_X_SLP_PACKAGETYPE_STR, pkg_type);
435 ail_filter_add_str(filter, AIL_PROP_PACKAGE_STR, pkg_name);
436 app_list_view_data->initialize = EINA_FALSE;
437 ail_filter_list_appinfo_foreach(filter, _appinfo_func_cb, (void*)app_info_new);
438 ail_filter_destroy(filter);
440 if (!app_info_new->app_name) {
441 MGR_APP_DEBUG_ERR("app_info_new->app_name is null");
442 MGR_APP_MEM_FREE(app_info_new);
447 Elm_Object_Item *item = elm_genlist_first_item_get(app_list_view_data->genlist);
449 elm_genlist_item_append(app_list_view_data->genlist, itc_sep_21, NULL, NULL, ELM_GENLIST_ITEM_NONE, NULL, NULL);
451 mgr_app_app_info_t *app_info = NULL;
453 for (i = 0; i < app_list_view_data->app_info_idx; i++) {
455 app_info = (mgr_app_app_info_t*)elm_object_item_data_get(item);
457 MGR_APP_DEBUG_ERR("app_info is null");
458 MGR_APP_MEM_FREE(app_info_new);
463 len = (strlen(app_info_new->app_name) >= strlen(app_info->app_name)) ? strlen(app_info_new->app_name) : strlen(app_info->app_name);
465 if (strncasecmp(app_info_new->app_name, app_info->app_name, len) < 0) {
467 Elm_Object_Item *prev_item = elm_genlist_item_prev_get(item);
468 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);
469 ret_if(new_item == NULL);
471 char *letter_new = __convert_char_to_string(app_info_new->app_name[0]);
472 ret_if(letter_new == NULL);
473 char *letter = __convert_char_to_string(app_info->app_name[0]);
475 MGR_APP_MEM_FREE(letter_new);
479 /* the top of item */
481 if (letter_new[0] == letter[0]) {
482 /* B'-B, index item must be replaced from B to B' */
483 elm_object_item_del(item);
485 /* B'-C, just add the index item */
486 __register_index_item(app_list_view_data->index, letter_new, new_item, EINA_FALSE);
490 mgr_app_app_info_t *app_info_prev = elm_object_item_data_get(prev_item);
491 if (!app_info_prev) {
492 MGR_APP_MEM_FREE(letter);
496 char *letter_prev = __convert_char_to_string(app_info_prev->app_name[0]);
498 MGR_APP_MEM_FREE(letter);
502 if (letter_prev[0] == letter_new[0]) {
503 /* B-B', nothing to do for index */
505 } else if (letter_prev[0] < letter_new[0] && letter_new[0] < letter[0]) {
506 /* A-B'-C, B' must be inserted to index */
507 __register_index_item(app_list_view_data->index, letter_new, new_item, EINA_FALSE);
509 } else if (letter_prev[0] < letter_new[0] && letter_new[0] == letter[0]) {
510 /* A-B'-B, index item must be replaced from B to B' */
511 elm_object_item_del(item);
513 MGR_APP_MEM_FREE(letter_prev);
516 MGR_APP_MEM_FREE(letter_new);
517 MGR_APP_MEM_FREE(letter);
518 app_list_view_data->app_info_idx++;
522 item = elm_genlist_item_next_get(item);
524 MGR_APP_DEBUG_ERR("item is null");
525 MGR_APP_MEM_FREE(app_info_new);
529 /* check the item and append after last item */
530 if (item == elm_genlist_last_item_get(app_list_view_data->genlist)) {
531 char *letter_new = __convert_char_to_string(app_info_new->app_name[0]);
532 ret_if(letter_new == NULL);
534 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);
535 ret_if(new_item == NULL);
537 __register_index_item(app_list_view_data->index, letter_new, new_item, EINA_FALSE);
539 MGR_APP_MEM_FREE(letter_new);
540 app_list_view_data->app_info_idx++;
547 elm_genlist_realized_items_update(app_list_view_data->genlist);
552 static void _list_update_by_uninstall(char *pkg_type, const char *pkg_name, void *data)
556 ret_if(pkg_type == NULL);
558 ret_if(mgr_app_view_app_list.view_common_data == NULL);
559 mgr_app_view_common_data_t *view_common_data = mgr_app_view_app_list.view_common_data;
561 ret_if(view_common_data->user_view_data == NULL);
562 app_list_view_data_t *app_list_view_data = view_common_data->user_view_data;
565 Elm_Object_Item *item = elm_genlist_first_item_get(app_list_view_data->genlist);
566 ret_if(item == NULL);
567 item = elm_genlist_item_next_get(item);
568 ret_if(item == NULL);
569 mgr_app_app_info_t *app_info = NULL;
571 for (i = 0; i < app_list_view_data->app_info_idx; i++) {
573 app_info = (mgr_app_app_info_t*)elm_object_item_data_get(item);
574 ret_if(app_info == NULL);
576 MGR_APP_DEBUG("pkg_type: %s, %s", pkg_type, app_info->pkg_type);
577 MGR_APP_DEBUG("pkg_name: %s, %s", pkg_name, app_info->pkg_name);
579 if (!strncmp(pkg_type, app_info->pkg_type, strlen(pkg_type)) && !strncmp(pkg_name, app_info->pkg_name, strlen(pkg_name))) {
580 Elm_Object_Item *idx_item = elm_index_item_find(app_list_view_data->index, item);
581 elm_object_item_del(idx_item);
582 elm_object_item_del(item);
583 MGR_APP_DEBUG("deleted");
584 app_list_view_data->app_info_idx--;
586 /* temporary code - tpk backend should be passed full pkg name */
587 } else if (0 == strcmp(pkg_type, TPK_PREFIX) && strstr(app_info->pkg_name, pkg_name)) {
588 Elm_Object_Item *idx_item = elm_index_item_find(app_list_view_data->index, item);
589 elm_object_item_del(idx_item);
590 elm_object_item_del(item);
591 MGR_APP_DEBUG("deleted");
592 app_list_view_data->app_info_idx--;
595 item = elm_genlist_item_next_get(item);
596 ret_if(item == NULL);
600 elm_genlist_realized_items_update(app_list_view_data->genlist);
605 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)
609 MGR_APP_DEBUG("key:%s val:%s", key, val);
610 MGR_APP_DEBUG("pkg_type:%s pkg_name:%s", pkg_type, pkg_name);
611 retv_if(data == NULL, -1);
612 struct ug_data *ugd = (struct ug_data*)data;
614 if (!strncmp(key, STR_START, strlen(key)) && !strncmp(val, STR_UNINSTALL, strlen(val))) {
615 ugd->uninstall = EINA_TRUE;
616 } else if (!strncmp(key, STR_START, strlen(key)) && !strncmp(val, STR_INSTALL, strlen(val))) {
617 ugd->uninstall = EINA_FALSE;
618 } else if (!strncmp(key, STR_ERROR, strlen(key))) {
619 } else if (!strncmp(key, STR_END, strlen(key)) && !strncmp(val, STR_FAIL, strlen(val))) {
620 mgr_app_destroy_popup_progressbar();
621 mgr_app_create_popup_text_1button(ugd->win_main, "Uninstall failed", STR_POPUP_OK, _response_cb);
622 } else if (!strncmp(key, STR_END, strlen(key)) && !strncmp(val, STR_OK, strlen(val))) {
623 if (ugd->uninstall) {
624 mgr_app_destroy_popup_progressbar();
625 mgr_app_create_popup_text_1button(ugd->win_main, "Uninstall complete", STR_POPUP_OK, _response_cb);
626 _list_update_by_uninstall(pkg_type, pkg_name, (void*)ugd);
628 _list_update_by_install(pkg_type, pkg_name, (void*)ugd);
631 /* check the info view was opened */
632 GList *view_list = mgr_app_view_get_viewlist(data);
637 GList *info_view = g_list_find(view_list, &mgr_app_view_app_info);
639 struct ug_data *ugd = (struct ug_data*)data;
640 if (ugd->uninstall) {
641 _app_info_back_cb(data, NULL, NULL);
642 _notify_by_uninstall((void*)ugd);
643 ugd->uninstall = EINA_FALSE;
646 } else if (!strncmp(key, STR_END, strlen(key)) && !strncmp(val, STR_CANCEL, strlen(val))) {
651 /* the return value occured infinite loop */
652 /* package manager example has no return value */
656 static char *__convert_char_to_string(char ch)
660 char *str_buf = NULL;
661 str_buf = (char*)malloc(sizeof(char)*MAX_BUF_SIZE);
662 retv_if(str_buf == NULL, NULL);
663 memset(str_buf, 0, sizeof(char)*MAX_BUF_SIZE);
665 if (ch >= 'A' && ch <= 'Z') {
666 snprintf(str_buf, MAX_BUF_SIZE, "%c", ch);
667 } else if (ch >= 'a' && ch <= 'z') {
668 snprintf(str_buf, MAX_BUF_SIZE, "%c", ch - 'a' + 'A');
669 } else if (ch >= '0' && ch <= '9') {
670 snprintf(str_buf, MAX_BUF_SIZE, "%c", ch);
672 snprintf(str_buf, MAX_BUF_SIZE, "%s", "etc");
679 static int _compare_index_item_letter_cb(const void *a, const void *b)
683 retv_if(a == NULL, -1);
684 retv_if(b == NULL, -1);
686 const Elm_Object_Item *it1 = (const Elm_Object_Item*)a;
687 const Elm_Object_Item *it2 = (const Elm_Object_Item*)b;
689 const char *letter1 = elm_index_item_letter_get(it1);
690 const char *letter2 = elm_index_item_letter_get(it2);
692 MGR_APP_DEBUG("letter1: %s, letter2: %s", letter1, letter2);
695 len = (strlen(letter1) >= strlen(letter2)) ? strlen(letter1) : strlen(letter2);
698 return strncasecmp(letter1, letter2, len);
702 * _compare_data_index_item_letter_cb be used when _compare_index_item_letter_cb return 0.
704 static int _compare_data_index_item_letter_cb(const void *a, const void *b)
708 retv_if(a == NULL, -1);
709 retv_if(b == NULL, -1);
711 const Elm_Object_Item *it1 = (const Elm_Object_Item*)a;
712 const Elm_Object_Item *it2 = (const Elm_Object_Item*)b;
714 mgr_app_app_info_t *app_info1 = elm_object_item_data_get(it1);
715 mgr_app_app_info_t *app_info2 = elm_object_item_data_get(it2);
717 MGR_APP_DEBUG("letter1: %s, letter2: %s", app_info1->app_name, app_info2->app_name);
723 static void __register_index_item(Evas_Object *index, char *letter, Elm_Object_Item *item, Eina_Bool init)
727 MGR_APP_DEBUG("letter: %s", letter);
729 ret_if(mgr_app_view_app_list.view_common_data == NULL);
730 mgr_app_view_common_data_t *view_common_data = mgr_app_view_app_list.view_common_data;
732 ret_if(view_common_data->user_view_data == NULL);
733 app_list_view_data_t *app_list_view_data = view_common_data->user_view_data;
735 Elm_Object_Item *new_index_item = NULL;
738 Elm_Object_Item *temp_index_item = NULL;
739 Elm_Object_Item *temp_item = NULL;
740 const char *temp_letter = NULL;
743 temp_item = elm_genlist_first_item_get(app_list_view_data->genlist);
744 ret_if(temp_item == NULL);
746 for (i = 0; i < app_list_view_data->app_info_idx; i++) {
747 temp_index_item = elm_index_item_find(index, temp_item);
749 /* indexed genlist item */
750 if (temp_index_item) {
751 temp_letter = elm_index_item_letter_get(temp_index_item);
752 ret_if(temp_letter == NULL);
754 if (letter[0] < temp_letter[0]) {
755 elm_index_item_prepend_relative(index, letter, item, temp_item);
759 temp_item = elm_genlist_item_next_get(temp_item);
762 elm_index_item_append(index, letter, NULL, item);
765 new_index_item = elm_index_item_find(index, item);
766 ret_if(new_index_item == NULL);
767 elm_object_item_del_cb_set(new_index_item, _index_del_item_cb);
768 elm_object_item_data_set(new_index_item, (void*)item);
770 app_list_view_data->index_cnt++;
775 static void _index_del_item_cb(void *data, Evas_Object *obj, void *event_info)
779 ret_if(data == NULL);
780 Elm_Object_Item *item = (Elm_Object_Item*)data;
781 Elm_Object_Item *next_item = elm_genlist_item_next_get(item);
783 ret_if(mgr_app_view_app_list.view_common_data == NULL);
784 mgr_app_view_common_data_t *view_common_data = mgr_app_view_app_list.view_common_data;
786 ret_if(view_common_data->user_view_data == NULL);
787 app_list_view_data_t *app_list_view_data = view_common_data->user_view_data;
789 /* change the index item */
791 mgr_app_app_info_t *next_app_info = (mgr_app_app_info_t*)elm_object_item_data_get(next_item);
792 ret_if(next_app_info == NULL);
794 char *next_letter = __convert_char_to_string(next_app_info->app_name[0]);
795 ret_if(next_letter == NULL);
797 ret_if(event_info == NULL);
798 Elm_Object_Item *index_item = (Elm_Object_Item*)event_info;
800 const char *letter = elm_index_item_letter_get(index_item);
801 ret_if(letter == NULL);
803 Elm_Object_Item *prev_item = elm_genlist_item_prev_get(item);
806 /* case: B-B', del:B */
807 if (letter[0] == next_letter[0]) {
808 __register_index_item(app_list_view_data->index, next_letter, next_item, EINA_FALSE);
811 mgr_app_app_info_t *prev_app_info = (mgr_app_app_info_t*)elm_object_item_data_get(prev_item);
812 if (!prev_app_info) {
813 MGR_APP_MEM_FREE(next_letter);
817 char *prev_letter = __convert_char_to_string(prev_app_info->app_name[0]);
819 MGR_APP_MEM_FREE(next_letter);
823 /* case: A-B'-B-B'', del:B */
824 if (letter[0] == prev_letter[0]) {
825 __register_index_item(app_list_view_data->index, prev_letter, prev_item, EINA_FALSE);
827 /* case: A-B-B'-B'', del:B */
828 } else if (letter[0] == next_letter[0]) {
829 __register_index_item(app_list_view_data->index, next_letter, next_item, EINA_FALSE);
832 MGR_APP_MEM_FREE(prev_letter);
834 MGR_APP_MEM_FREE(next_letter);
837 MGR_APP_DEBUG("next_item is null");
840 app_list_view_data->index_cnt--;
844 static Evas_Object *__create_genlist_app_list(Evas_Object *parent, void *data)
848 retv_if(mgr_app_view_app_list.view_common_data == NULL, NULL);
849 mgr_app_view_common_data_t *view_common_data = mgr_app_view_app_list.view_common_data;
851 retv_if(view_common_data->user_view_data == NULL, NULL);
852 app_list_view_data_t *app_list_view_data = view_common_data->user_view_data;
854 retv_if(data == NULL, NULL);
855 struct ug_data *ugd = (struct ug_data*)data;
856 Evas_Object *genlist = NULL;
857 Evas_Object *index = NULL;
858 Elm_Object_Item *item_sep_21 = NULL;
861 /* set the genlist item style */
862 itc = elm_genlist_item_class_new();
863 retv_if(itc == NULL, NULL);
864 \r itc_sep_21 = elm_genlist_item_class_new();
865 retv_if(itc_sep_21 == NULL, NULL);
867 itc->item_style = ITC_ITEM_STYLE;
868 itc->func.text_get = _gl_label_get;
869 itc->func.content_get = _gl_icon_get;
870 itc->func.state_get = NULL;
871 itc->func.del = _gl_del;
873 itc_sep_21->item_style = ITC_SEP_21_ITEM_STYLE;
874 itc_sep_21->func.text_get = NULL;
875 itc_sep_21->func.content_get= NULL;
876 itc_sep_21->func.state_get = NULL;
877 itc_sep_21->func.del = NULL;
881 index = elm_index_add(parent);
882 retv_if(index == NULL, NULL);
883 elm_object_part_content_set(parent, "elm.swallow.content.index", index);
884 evas_object_show(index);
888 genlist = elm_genlist_add(parent);
889 retv_if(genlist == NULL, NULL);
890 elm_object_part_content_set(parent, "elm.swallow.content.genlist", genlist);
891 evas_object_size_hint_weight_set(genlist, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
892 evas_object_size_hint_align_set(genlist, EVAS_HINT_FILL, EVAS_HINT_FILL);
893 elm_genlist_mode_set(genlist, ELM_LIST_COMPRESS);
894 elm_genlist_block_count_set(genlist, GENLIST_BLOCK_CNT);
895 elm_genlist_scroller_policy_set(genlist, ELM_SCROLLER_POLICY_OFF, ELM_SCROLLER_POLICY_OFF);
896 elm_object_style_set(genlist, "dialogue");
897 evas_object_show(genlist);
900 app_list_view_data->genlist = genlist;
901 app_list_view_data->index = index;
902 app_list_view_data->index_cnt = 0;
905 /* get app_info from AIL */
906 mgr_app_app_info_t *app_info_list = NULL;
907 mgr_app_app_info_t *p_app_info_list = NULL;
909 ail_filter_h filter_rpm = {0};
910 ail_filter_h filter_wrt = {0};
911 ail_filter_h filter_tpk = {0};
913 ail_filter_new(&filter_rpm);
914 ail_filter_new(&filter_wrt);
915 ail_filter_new(&filter_tpk);
917 ail_filter_add_str(filter_rpm, AIL_PROP_X_SLP_PACKAGETYPE_STR, RPM_PREFIX);
918 ail_filter_add_str(filter_wrt, AIL_PROP_X_SLP_PACKAGETYPE_STR, WRT_PREFIX);
919 ail_filter_add_str(filter_tpk, AIL_PROP_X_SLP_PACKAGETYPE_STR, TPK_PREFIX);
921 int appinfo_cnt_rpm = 0;
922 int appinfo_cnt_wrt = 0;
923 int appinfo_cnt_tpk = 0;
924 int appinfo_cnt_total = 0;
926 ail_filter_count_appinfo(filter_rpm, &appinfo_cnt_rpm);
927 ail_filter_count_appinfo(filter_wrt, &appinfo_cnt_wrt);
928 ail_filter_count_appinfo(filter_tpk, &appinfo_cnt_tpk);
930 appinfo_cnt_total = appinfo_cnt_rpm + appinfo_cnt_wrt + appinfo_cnt_tpk;
932 app_info_list = (mgr_app_app_info_t*)malloc(sizeof(mgr_app_app_info_t) * appinfo_cnt_total);
933 if (!app_info_list) {
934 MGR_APP_DEBUG_ERR("app_info_list allocation failed");
935 ail_filter_destroy(filter_rpm);
936 ail_filter_destroy(filter_wrt);
937 ail_filter_destroy(filter_tpk);
940 memset(app_info_list, 0, sizeof(mgr_app_app_info_t) * appinfo_cnt_total);
941 p_app_info_list = app_info_list;
943 app_list_view_data->app_info_idx = 0;
944 app_list_view_data->app_info_list = app_info_list;
945 app_list_view_data->appinfo_cnt_total = appinfo_cnt_total;
946 app_list_view_data->initialize = EINA_TRUE;
948 ail_filter_list_appinfo_foreach(filter_rpm, _appinfo_func_cb, (void*)app_info_list);
949 ail_filter_list_appinfo_foreach(filter_wrt, _appinfo_func_cb, (void*)app_info_list);
950 ail_filter_list_appinfo_foreach(filter_tpk, _appinfo_func_cb, (void*)app_info_list);
952 ail_filter_destroy(filter_rpm);
953 ail_filter_destroy(filter_wrt);
954 ail_filter_destroy(filter_tpk);
957 /* sorting by app_name */
958 app_info_list = p_app_info_list;
959 qsort(app_info_list, appinfo_cnt_total, sizeof(mgr_app_app_info_t), _app_list_qsort_cb);
962 /* add genlist item order by ASC */
963 Elm_Object_Item *item = NULL;
965 char prev_letter[MAX_BUF_SIZE] = {0, };
968 app_info_list = p_app_info_list;
970 for (j = 0; j < appinfo_cnt_total; j++) {
972 /* add the space to top of the dialogue */
973 if (app_list_view_data->initialize && elm_genlist_first_item_get(genlist)) {
974 app_list_view_data->initialize = EINA_FALSE;
975 item_sep_21 = elm_genlist_item_prepend(genlist, itc_sep_21, NULL, NULL, ELM_GENLIST_ITEM_NONE, NULL, NULL);
977 elm_genlist_item_select_mode_set(item_sep_21, ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY);
980 MGR_APP_DEBUG("%s", app_info_list->app_name);
982 mgr_app_app_info_t *app_info = app_info_list;
984 item = elm_genlist_item_append(genlist, itc, (void*)app_info, NULL, ELM_GENLIST_ITEM_NONE, _gl_sel, (void*)ugd);
986 /* fast scroll insertion */
987 letter = __convert_char_to_string(app_info_list->app_name[0]);
988 if (item && strncmp(letter, prev_letter, MAX_BUF_SIZE) != 0) {
989 __register_index_item(index, letter, item, EINA_TRUE);
990 strncpy(prev_letter, letter, MAX_BUF_SIZE);
993 MGR_APP_MEM_FREE(letter);
994 app_info_list = app_info_list + 1;
997 evas_object_smart_callback_add(index, "delay,changed", _index_delayed_changed, index);
998 evas_object_smart_callback_add(index, "changed", _index_changed, NULL);
999 evas_object_smart_callback_add(index, "selected", _index_selected, NULL);
1002 /* register pkg-mgr listener */
1004 retv_if(ugd->pc_listen == NULL, NULL);
1005 result = pkgmgr_client_listen_status(ugd->pc_listen, mgr_app_view_listen_cb, (void*)ugd);
1007 MGR_APP_DEBUG_ERR("status listen failed!\n");
1008 MGR_APP_MEM_FREE(genlist);
1016 static Evas_Object *mgr_app_view_app_list_create(void *data)
1020 retv_if(data == NULL, NULL);
1022 retv_if(mgr_app_view_app_list.view_common_data == NULL, NULL);
1023 mgr_app_view_common_data_t *view_common_data = mgr_app_view_app_list.view_common_data;
1025 MGR_APP_MEM_MALLOC(view_common_data->user_view_data, 1, app_list_view_data_t);
1026 retv_if(view_common_data->user_view_data == NULL, NULL);
1027 app_list_view_data_t *app_list_view_data = view_common_data->user_view_data;
1029 app_list_view_data->layout = mgr_app_create_layout_file(view_common_data->common_navibar, EDC_FILE, EDC_GROUPS);
1030 retv_if(app_list_view_data->layout == NULL, NULL);
1032 app_list_view_data->genlist = __create_genlist_app_list(app_list_view_data->layout, data);
1035 return app_list_view_data->layout;
1038 static Evas_Object *mgr_app_view_app_list_set_cbar(void *data)
1045 static mgr_app_result_e mgr_app_view_app_list_set_navibar(void *data)
1048 mgr_app_view_manager_set_navibar(mgr_app_view_app_list.view_common_data, dgettext(PACKAGE, "IDS_ST_BODY_MANAGE_APPLICATIONS"), NULL, _app_list_back_cb, NULL, NULL);
1053 static mgr_app_result_e mgr_app_view_app_list_destory(void *data)
1057 retv_if(mgr_app_view_app_list.view_common_data == NULL, MGR_APP_ERROR);
1058 mgr_app_view_app_list.view_common_data->view_layout = NULL;
1063 static mgr_app_result_e mgr_app_view_app_list_update(void *data)
1067 retv_if(mgr_app_view_app_list.view_common_data == NULL, MGR_APP_ERROR);
1068 mgr_app_view_common_data_t *view_common_data = mgr_app_view_app_list.view_common_data;
1070 retv_if(view_common_data->user_view_data == NULL, MGR_APP_ERROR);
1071 app_list_view_data_t *app_list_view_data = view_common_data->user_view_data;
1073 if (app_list_view_data->genlist != NULL) {
1074 elm_genlist_clear(app_list_view_data->genlist);
1075 evas_object_del(app_list_view_data->genlist);
1076 app_list_view_data->genlist = NULL;
1079 app_list_view_data->genlist = __create_genlist_app_list(app_list_view_data->layout, data);
1084 static mgr_app_result_e mgr_app_view_app_list_cleanup(void *data)