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"
60 typedef struct _app_list_view_data_t app_list_view_data_t;
62 struct _app_list_view_data_t {
67 mgr_app_app_info_t *app_info_list;
69 int appinfo_cnt_total;
73 static Evas_Object *mgr_app_view_app_list_create(void *data);
74 static Evas_Object *mgr_app_view_app_list_set_cbar(void *data);
75 static mgr_app_result_e mgr_app_view_app_list_set_navibar(void *data);
76 static mgr_app_result_e mgr_app_view_app_list_destory(void *data);
77 static mgr_app_result_e mgr_app_view_app_list_update(void *data);
78 static mgr_app_result_e mgr_app_view_app_list_cleanup(void *data);
80 static Evas_Object *__create_genlist_app_list(Evas_Object *parent, void *data);
81 static char *__convert_char_to_string(char ch);
82 static void __register_index_item(Evas_Object *index, char *letter, Elm_Object_Item *item, Eina_Bool init);
83 static void _index_del_item_cb(void *data, Evas_Object *obj, void *event_info);
86 mgr_app_view_t mgr_app_view_app_list = {
87 .create = mgr_app_view_app_list_create,
88 .setcbar = mgr_app_view_app_list_set_cbar,
89 .setnavibar = mgr_app_view_app_list_set_navibar,
90 .destroy = mgr_app_view_app_list_destory,
91 .update = mgr_app_view_app_list_update,
94 static Elm_Genlist_Item_Class *itc = NULL;
95 static Elm_Genlist_Item_Class *itc_sep_21 = NULL;
98 static void _app_list_next_cb(void *data, Evas_Object *obj, void *event_info)
101 mgr_app_view_create(&mgr_app_view_app_list, data);
105 static void _app_list_back_cb(void *data, Evas_Object *obj, void *event_info)
108 ret_if(data == NULL);
109 struct ug_data *ugd = (struct ug_data*)data;
110 mgr_app_view_common_back_cb(data, EINA_FALSE);
112 elm_genlist_item_class_free(itc);
113 elm_genlist_item_class_free(itc_sep_21);
115 /* bg must delete before starting on_destroy */
116 evas_object_del(ugd->bg);
118 ug_destroy_me(ugd->ug);
122 /* get the state of item */
123 static Eina_Bool _gl_state_get(void *data, Evas_Object *obj, const char *part)
131 /* callback for 'deletion' */
132 static void _gl_del(void *data, Evas_Object *obj)
136 ret_if(data == NULL);
137 mgr_app_app_info_t *app_info = (mgr_app_app_info_t*)data;
139 MGR_APP_MEM_FREE(app_info->pkg_name);
140 MGR_APP_MEM_FREE(app_info->app_name);
141 MGR_APP_MEM_FREE(app_info->pkg_type);
142 MGR_APP_MEM_FREE(app_info->icon_path);
143 //MGR_APP_MEM_FREE(app_info);
149 /* callback for 'selection' */
150 static void _gl_sel(void *data, Evas_Object *obj, void *event_info)
154 ret_if(data == NULL);
155 ret_if(event_info == NULL);
157 struct ug_data *ugd = (struct ug_data*)data;
158 Elm_Object_Item *item = (Elm_Object_Item *)event_info;
160 mgr_app_app_info_t *app_info = (mgr_app_app_info_t*)elm_object_item_data_get(item);
161 ret_if(app_info == NULL);
163 elm_genlist_item_selected_set(item, 0);
165 /* create app info view */
166 ugd->data = (void*)app_info;
167 mgr_app_view_create(&mgr_app_view_app_info, (void*)ugd);
172 static char *_gl_label_get(void *data, Evas_Object *obj, const char *part)
176 retv_if(data == NULL, NULL);
177 mgr_app_app_info_t *app_info = (mgr_app_app_info_t*)data;
180 char *package_name = app_info->pkg_name;
181 char *app_name = app_info->app_name;
182 char *icon_path = app_info->icon_path;
183 char *pkg_type = app_info->pkg_type;
185 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);
186 MGR_APP_DEBUG("part:%s\n", part);
188 /* label for 'elm.text' part */
189 if (app_name && !strncmp(part, ELM_TEXT, strlen(ELM_TEXT))) {
190 MGR_APP_MEM_STRDUP(label, app_name);
192 MGR_APP_MEM_STRDUP(label, dgettext("sys_string", "IDS_COM_POP_ERROR"));
199 static Evas_Object *_gl_icon_get(void *data, Evas_Object *obj, const char *part)
203 retv_if(data == NULL, NULL);
204 mgr_app_app_info_t *app_info = (mgr_app_app_info_t*)data;
206 retv_if(app_info->icon_path == NULL, NULL);
207 char *icon_path = NULL;
208 icon_path = app_info->icon_path;
210 Evas_Object *icon = NULL;
212 MGR_APP_DEBUG("icon_path:[%s]\n", icon_path);
213 MGR_APP_DEBUG("part:%s\n", part);
215 /* icon for 'elm.icon' part */
216 icon = elm_icon_add(obj);
217 retv_if(icon == NULL, NULL);
218 evas_object_size_hint_weight_set(icon, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
219 evas_object_size_hint_align_set(icon, EVAS_HINT_FILL, EVAS_HINT_FILL);
220 evas_object_size_hint_aspect_set(icon, EVAS_ASPECT_CONTROL_VERTICAL, 1, 1);
222 elm_icon_file_set(icon, icon_path, STR_ICON);
223 evas_object_show(icon);
229 static void _index_delayed_changed(void *data, Evas_Object *obj, void *event_info)
232 // called on a change but delayed in case multiple changes happen in a
234 elm_genlist_item_bring_in(elm_object_item_data_get(event_info), ELM_GENLIST_ITEM_SCROLLTO_TOP);
238 static void _index_changed(void *data, Evas_Object *obj, void *event_info)
241 // this is calld on every change, no matter how often
245 static void _index_selected(void *data, Evas_Object *obj, void *event_info)
248 // called on final select
249 elm_genlist_item_bring_in(elm_object_item_data_get(event_info), ELM_GENLIST_ITEM_SCROLLTO_TOP);
253 static int _app_list_qsort_cb(const void *a, const void *b)
258 MGR_APP_DEBUG_ERR("a is null");
261 MGR_APP_DEBUG_ERR("b is null");
265 mgr_app_app_info_t *app_info1 = (mgr_app_app_info_t*)a;
266 mgr_app_app_info_t *app_info2 = (mgr_app_app_info_t*)b;
268 if (!app_info1->app_name) {
269 MGR_APP_DEBUG_ERR("app_info1->app_name is null");
273 if (!app_info2->app_name) {
274 MGR_APP_DEBUG_ERR("app_info2->app_name is null");
279 len = (strlen(app_info1->app_name) >= strlen(app_info2->app_name)) ? strlen(app_info1->app_name) : strlen(app_info2->app_name);
282 return strncasecmp(app_info1->app_name, app_info2->app_name, len);
285 static ail_cb_ret_e _appinfo_func_cb(const ail_appinfo_h ail_info, void *user_data)
289 retv_if(mgr_app_view_app_list.view_common_data == NULL, AIL_CB_RET_CONTINUE);
290 mgr_app_view_common_data_t *view_common_data = mgr_app_view_app_list.view_common_data;
292 retv_if(view_common_data->user_view_data == NULL, AIL_CB_RET_CONTINUE);
293 app_list_view_data_t *app_list_view_data = view_common_data->user_view_data;
295 retv_if(user_data == NULL, AIL_CB_RET_CONTINUE);
296 mgr_app_app_info_t *p_app_info_list = (mgr_app_app_info_t *)user_data;
298 if (app_list_view_data->initialize) {
299 p_app_info_list = p_app_info_list + app_list_view_data->app_info_idx++;
302 char *package_name = NULL;
303 char *app_name = NULL;
304 char *icon_path = NULL;
305 char *x_slp_packagetype = NULL;
306 bool nodisplay = EINA_FALSE;
307 bool removable = EINA_FALSE;
308 bool taskmanage = EINA_FALSE;
310 ail_appinfo_get_str(ail_info, AIL_PROP_PACKAGE_STR, &package_name);
312 MGR_APP_DEBUG_ERR(">>> get package_name failed");
313 return AIL_CB_RET_CONTINUE;
315 ail_appinfo_get_str(ail_info, AIL_PROP_NAME_STR, &app_name);
317 MGR_APP_DEBUG_ERR(">>> get app_name failed");
318 return AIL_CB_RET_CONTINUE;
320 ail_appinfo_get_str(ail_info, AIL_PROP_ICON_STR, &icon_path);
321 ail_appinfo_get_str(ail_info, AIL_PROP_X_SLP_PACKAGETYPE_STR, &x_slp_packagetype);
322 ail_appinfo_get_bool(ail_info, AIL_PROP_NODISPLAY_BOOL, &nodisplay);
323 ail_appinfo_get_bool(ail_info, AIL_PROP_X_SLP_REMOVABLE_BOOL , &removable);
324 ail_appinfo_get_bool(ail_info, AIL_PROP_X_SLP_TASKMANAGE_BOOL , &taskmanage);
327 /* setting icon path */
331 /* TODO - avoid the slow-down change effect due to edj icon */
332 if (((p = strrchr(icon_path, '.'))) && (!strcasecmp(p, ".edj"))) {
333 icon_path = DEFAULT_ICON_FILE;
334 } else if ((stream = fopen(icon_path, "r")) != NULL && strlen(icon_path) > strlen(STR_PNG)) {
338 char *p_extension = NULL;
339 p_extension = icon_path + (strlen(icon_path) - strlen(STR_PNG));
341 /* default icon : icon_path's extension is wrong */
342 if (strncmp(p_extension, STR_PNG, strlen(STR_PNG)) != 0 && strncmp(p_extension, STR_EDJ, strlen(STR_EDJ)) != 0) {
343 icon_path = DEFAULT_ICON_FILE;
345 /* default icon : icon_path isn't exist */
347 icon_path = DEFAULT_ICON_FILE;
353 /* default icon : icon_path == NULL */
355 icon_path = DEFAULT_ICON_FILE;
358 MGR_APP_MEM_STRDUP(p_app_info_list->pkg_name, package_name);
359 MGR_APP_MEM_STRDUP(p_app_info_list->app_name, app_name);
360 MGR_APP_MEM_STRDUP(p_app_info_list->icon_path, icon_path);
361 MGR_APP_MEM_STRDUP(p_app_info_list->pkg_type, x_slp_packagetype);
362 p_app_info_list->nodisplay = nodisplay;
363 p_app_info_list->removable = removable;
364 p_app_info_list->taskmanage = taskmanage;
366 MGR_APP_DEBUG("package_name: %s ", package_name);
367 MGR_APP_DEBUG("app_name: %s", app_name);
368 MGR_APP_DEBUG("icon_path: %s", icon_path);
369 MGR_APP_DEBUG("x_slp_packagetype: %s ", x_slp_packagetype);
370 MGR_APP_DEBUG("nodisplay: %d", nodisplay);
371 MGR_APP_DEBUG("removable: %d", removable);
372 MGR_APP_DEBUG("taskmanage: %d", taskmanage);
375 return AIL_CB_RET_CONTINUE;
378 static void _popup_progressbar_by_uninstall(void *data)
382 ret_if(data == NULL);
383 struct ug_data *ugd = (struct ug_data*)data;
385 Evas_Object *popup = NULL;
386 Evas_Object *layout = NULL;
387 Evas_Object *progressbar = NULL;
389 popup = elm_popup_add(ugd->win_main);
\r
390 ret_if(popup == NULL);
392 progressbar = elm_progressbar_add(popup);
393 ret_if(progressbar == NULL);
394 elm_object_style_set(progressbar, "list_process");
395 evas_object_size_hint_align_set(progressbar, EVAS_HINT_FILL, 0.5);
396 evas_object_size_hint_weight_set(progressbar, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
397 elm_progressbar_pulse(progressbar, EINA_TRUE);
398 evas_object_show(progressbar);
400 elm_object_part_text_set(popup, "title,text", dgettext(PACKAGE, "IDS_ST_POP_UNINSTALLING_ING"));
401 elm_popup_timeout_set(popup, 1.0);
402 elm_object_content_set(popup, progressbar);
403 evas_object_show(popup);
408 static void _notify_by_uninstall(void *data)
412 ret_if(data == NULL);
413 struct ug_data *ugd = (struct ug_data*)data;
415 Evas_Object *noti = elm_notify_add(ugd->navi_bar);
416 elm_notify_orient_set(noti, ELM_NOTIFY_ORIENT_BOTTOM);
418 Evas_Object *layout = elm_layout_add(noti);
419 elm_layout_theme_set(layout, "standard", "selectioninfo", "vertical/bottom_12");
421 elm_object_content_set(noti, layout);
422 elm_notify_timeout_set(noti, 2);
423 edje_object_part_text_set(_EDJ(layout), ELM_TEXT, dgettext(PACKAGE, "IDS_ST_POP_UNINSTALLED"));
424 evas_object_show(noti);
429 static void _list_update_by_install(char *pkg_type, const char *pkg_name, void *data)
433 ret_if(pkg_type == NULL);
434 ret_if(data == NULL);
435 struct ug_data *ugd = (struct ug_data*)data;
437 ret_if(mgr_app_view_app_list.view_common_data == NULL);
438 mgr_app_view_common_data_t *view_common_data = mgr_app_view_app_list.view_common_data;
440 ret_if(view_common_data->user_view_data == NULL);
441 app_list_view_data_t *app_list_view_data = view_common_data->user_view_data;
444 /* create app info data */
445 mgr_app_app_info_t *app_info_new = (mgr_app_app_info_t*)malloc(sizeof(mgr_app_app_info_t));
446 ret_if(app_info_new == NULL);
447 memset(app_info_new, 0, sizeof(mgr_app_app_info_t));
451 ail_filter_h filter = {0};
452 ail_filter_new(&filter);
453 ail_filter_add_str(filter, AIL_PROP_X_SLP_PACKAGETYPE_STR, pkg_type);
454 ail_filter_add_str(filter, AIL_PROP_PACKAGE_STR, pkg_name);
455 app_list_view_data->initialize = EINA_FALSE;
456 ail_filter_list_appinfo_foreach(filter, _appinfo_func_cb, (void*)app_info_new);
457 ail_filter_destroy(filter);
459 if (!app_info_new->app_name) {
460 MGR_APP_DEBUG_ERR("app_info_new->app_name is null");
461 MGR_APP_MEM_FREE(app_info_new);
466 Elm_Object_Item *item = elm_genlist_first_item_get(app_list_view_data->genlist);
468 elm_genlist_item_append(app_list_view_data->genlist, itc_sep_21, NULL, NULL, ELM_GENLIST_ITEM_NONE, NULL, NULL);
470 mgr_app_app_info_t *app_info = NULL;
472 for (i = 0; i < app_list_view_data->app_info_idx; i++) {
474 app_info = (mgr_app_app_info_t*)elm_object_item_data_get(item);
476 MGR_APP_DEBUG_ERR("app_info is null");
477 MGR_APP_MEM_FREE(app_info_new);
482 len = (strlen(app_info_new->app_name) >= strlen(app_info->app_name)) ? strlen(app_info_new->app_name) : strlen(app_info->app_name);
484 if (strncasecmp(app_info_new->app_name, app_info->app_name, len) < 0) {
486 Elm_Object_Item *prev_item = elm_genlist_item_prev_get(item);
487 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);
488 ret_if(new_item == NULL);
490 char *letter_new = __convert_char_to_string(app_info_new->app_name[0]);
491 ret_if(letter_new == NULL);
492 char *letter = __convert_char_to_string(app_info->app_name[0]);
494 MGR_APP_MEM_FREE(letter_new);
498 /* the top of item */
500 if (letter_new[0] == letter[0]) {
501 /* B'-B, index item must be replaced from B to B' */
502 elm_object_item_del(item);
504 /* B'-C, just add the index item */
505 __register_index_item(app_list_view_data->index, letter_new, new_item, EINA_FALSE);
509 mgr_app_app_info_t *app_info_prev = elm_object_item_data_get(prev_item);
510 if (!app_info_prev) {
511 MGR_APP_MEM_FREE(letter);
515 char *letter_prev = __convert_char_to_string(app_info_prev->app_name[0]);
517 MGR_APP_MEM_FREE(letter);
521 if (letter_prev[0] == letter_new[0]) {
522 /* B-B', nothing to do for index */
524 } else if (letter_prev[0] < letter_new[0] && letter_new[0] < letter[0]) {
525 /* A-B'-C, B' must be inserted to index */
526 __register_index_item(app_list_view_data->index, letter_new, new_item, EINA_FALSE);
528 } else if (letter_prev[0] < letter_new[0] && letter_new[0] == letter[0]) {
529 /* A-B'-B, index item must be replaced from B to B' */
530 elm_object_item_del(item);
532 MGR_APP_MEM_FREE(letter_prev);
535 MGR_APP_MEM_FREE(letter_new);
536 MGR_APP_MEM_FREE(letter);
537 app_list_view_data->app_info_idx++;
541 item = elm_genlist_item_next_get(item);
543 MGR_APP_DEBUG_ERR("item is null");
544 MGR_APP_MEM_FREE(app_info_new);
548 /* check the item and append after last item */
549 if (item == elm_genlist_last_item_get(app_list_view_data->genlist)) {
550 char *letter_new = __convert_char_to_string(app_info_new->app_name[0]);
551 ret_if(letter_new == NULL);
553 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);
554 ret_if(new_item == NULL);
556 __register_index_item(app_list_view_data->index, letter_new, new_item, EINA_FALSE);
558 MGR_APP_MEM_FREE(letter_new);
559 app_list_view_data->app_info_idx++;
566 elm_genlist_realized_items_update(app_list_view_data->genlist);
571 static void _list_update_by_uninstall(char *pkg_type, const char *pkg_name, void *data)
575 ret_if(pkg_type == NULL);
577 ret_if(mgr_app_view_app_list.view_common_data == NULL);
578 mgr_app_view_common_data_t *view_common_data = mgr_app_view_app_list.view_common_data;
580 ret_if(view_common_data->user_view_data == NULL);
581 app_list_view_data_t *app_list_view_data = view_common_data->user_view_data;
584 Elm_Object_Item *item = elm_genlist_first_item_get(app_list_view_data->genlist);
585 ret_if(item == NULL);
586 item = elm_genlist_item_next_get(item);
587 ret_if(item == NULL);
588 mgr_app_app_info_t *app_info = NULL;
590 for (i = 0; i < app_list_view_data->app_info_idx; i++) {
592 app_info = (mgr_app_app_info_t*)elm_object_item_data_get(item);
593 ret_if(app_info == NULL);
595 MGR_APP_DEBUG("pkg_type: %s, %s", pkg_type, app_info->pkg_type);
596 MGR_APP_DEBUG("pkg_name: %s, %s", pkg_name, app_info->pkg_name);
598 if (!strncmp(pkg_type, app_info->pkg_type, strlen(pkg_type)) && !strncmp(pkg_name, app_info->pkg_name, strlen(pkg_name))) {
599 Elm_Object_Item *idx_item = elm_index_item_find(app_list_view_data->index, item);
600 elm_object_item_del(idx_item);
601 elm_object_item_del(item);
602 MGR_APP_DEBUG("deleted");
603 app_list_view_data->app_info_idx--;
605 /* temporary code - tpk backend should be passed full pkg name */
606 } else if (0 == strcmp(pkg_type, TPK_PREFIX) && strstr(app_info->pkg_name, pkg_name)) {
607 Elm_Object_Item *idx_item = elm_index_item_find(app_list_view_data->index, item);
608 elm_object_item_del(idx_item);
609 elm_object_item_del(item);
610 MGR_APP_DEBUG("deleted");
611 app_list_view_data->app_info_idx--;
614 item = elm_genlist_item_next_get(item);
615 ret_if(item == NULL);
619 elm_genlist_realized_items_update(app_list_view_data->genlist);
624 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)
628 MGR_APP_DEBUG("key:%s val:%s", key, val);
629 MGR_APP_DEBUG("pkg_type:%s pkg_name:%s", pkg_type, pkg_name);
630 retv_if(data == NULL, -1);
631 struct ug_data *ugd = (struct ug_data*)data;
633 if (!strncmp(key, STR_START, strlen(key)) && !strncmp(val, STR_UNINSTALL, strlen(val))) {
634 ugd->uninstall = EINA_TRUE;
635 _popup_progressbar_by_uninstall((void*)ugd);
636 } else if (!strncmp(key, STR_START, strlen(key)) && !strncmp(val, STR_INSTALL, strlen(val))) {
637 ugd->uninstall = EINA_FALSE;
638 } else if (!strncmp(key, STR_END, strlen(key)) && !strncmp(val, STR_OK, strlen(val))) {
639 if (ugd->uninstall) {
640 _list_update_by_uninstall(pkg_type, pkg_name, (void*)ugd);
642 _list_update_by_install(pkg_type, pkg_name, (void*)ugd);
645 /* check the info view was opened */
646 GList *view_list = mgr_app_view_get_viewlist(data);
651 GList *info_view = g_list_find(view_list, &mgr_app_view_app_info);
653 struct ug_data *ugd = (struct ug_data*)data;
654 if (ugd->uninstall) {
655 _app_info_back_cb(data, NULL, NULL);
656 _notify_by_uninstall((void*)ugd);
657 ugd->uninstall = EINA_FALSE;
660 } else if (!strncmp(key, STR_END, strlen(key)) && !strncmp(val, STR_CANCEL, strlen(val))) {
665 /* the return value occured infinite loop */
666 /* package manager example has no return value */
670 static char *__convert_char_to_string(char ch)
674 char *str_buf = NULL;
675 str_buf = (char*)malloc(sizeof(char)*MAX_BUF_SIZE);
676 retv_if(str_buf == NULL, NULL);
677 memset(str_buf, 0, sizeof(char)*MAX_BUF_SIZE);
679 if (ch >= 'A' && ch <= 'Z') {
680 snprintf(str_buf, MAX_BUF_SIZE, "%c", ch);
681 } else if (ch >= 'a' && ch <= 'z') {
682 snprintf(str_buf, MAX_BUF_SIZE, "%c", ch - 'a' + 'A');
683 } else if (ch >= '0' && ch <= '9') {
684 snprintf(str_buf, MAX_BUF_SIZE, "%c", ch);
686 snprintf(str_buf, MAX_BUF_SIZE, "%s", "etc");
693 static int _compare_index_item_letter_cb(const void *a, const void *b)
697 retv_if(a == NULL, -1);
698 retv_if(b == NULL, -1);
700 const Elm_Object_Item *it1 = (const Elm_Object_Item*)a;
701 const Elm_Object_Item *it2 = (const Elm_Object_Item*)b;
703 const char *letter1 = elm_index_item_letter_get(it1);
704 const char *letter2 = elm_index_item_letter_get(it2);
706 MGR_APP_DEBUG("letter1: %s, letter2: %s", letter1, letter2);
709 len = (strlen(letter1) >= strlen(letter2)) ? strlen(letter1) : strlen(letter2);
712 return strncasecmp(letter1, letter2, len);
716 * _compare_data_index_item_letter_cb be used when _compare_index_item_letter_cb return 0.
718 static int _compare_data_index_item_letter_cb(const void *a, const void *b)
722 retv_if(a == NULL, -1);
723 retv_if(b == NULL, -1);
725 const Elm_Object_Item *it1 = (const Elm_Object_Item*)a;
726 const Elm_Object_Item *it2 = (const Elm_Object_Item*)b;
728 mgr_app_app_info_t *app_info1 = elm_object_item_data_get(it1);
729 mgr_app_app_info_t *app_info2 = elm_object_item_data_get(it2);
731 MGR_APP_DEBUG("letter1: %s, letter2: %s", app_info1->app_name, app_info2->app_name);
737 static void __register_index_item(Evas_Object *index, char *letter, Elm_Object_Item *item, Eina_Bool init)
741 MGR_APP_DEBUG("letter: %s", letter);
743 ret_if(mgr_app_view_app_list.view_common_data == NULL);
744 mgr_app_view_common_data_t *view_common_data = mgr_app_view_app_list.view_common_data;
746 ret_if(view_common_data->user_view_data == NULL);
747 app_list_view_data_t *app_list_view_data = view_common_data->user_view_data;
749 Elm_Object_Item *new_index_item = NULL;
752 Elm_Object_Item *temp_index_item = NULL;
753 Elm_Object_Item *temp_item = NULL;
754 const char *temp_letter = NULL;
757 temp_item = elm_genlist_first_item_get(app_list_view_data->genlist);
758 ret_if(temp_item == NULL);
760 for (i = 0; i < app_list_view_data->app_info_idx; i++) {
761 temp_index_item = elm_index_item_find(index, temp_item);
763 /* indexed genlist item */
764 if (temp_index_item) {
765 temp_letter = elm_index_item_letter_get(temp_index_item);
766 ret_if(temp_letter == NULL);
768 if (letter[0] < temp_letter[0]) {
769 elm_index_item_prepend_relative(index, letter, item, temp_item);
773 temp_item = elm_genlist_item_next_get(temp_item);
776 elm_index_item_append(index, letter, NULL, item);
779 new_index_item = elm_index_item_find(index, item);
780 ret_if(new_index_item == NULL);
781 elm_object_item_del_cb_set(new_index_item, _index_del_item_cb);
782 elm_object_item_data_set(new_index_item, (void*)item);
784 app_list_view_data->index_cnt++;
789 static void _index_del_item_cb(void *data, Evas_Object *obj, void *event_info)
793 ret_if(data == NULL);
794 Elm_Object_Item *item = (Elm_Object_Item*)data;
795 Elm_Object_Item *next_item = elm_genlist_item_next_get(item);
797 ret_if(mgr_app_view_app_list.view_common_data == NULL);
798 mgr_app_view_common_data_t *view_common_data = mgr_app_view_app_list.view_common_data;
800 ret_if(view_common_data->user_view_data == NULL);
801 app_list_view_data_t *app_list_view_data = view_common_data->user_view_data;
803 /* change the index item */
805 mgr_app_app_info_t *next_app_info = (mgr_app_app_info_t*)elm_object_item_data_get(next_item);
806 ret_if(next_app_info == NULL);
808 char *next_letter = __convert_char_to_string(next_app_info->app_name[0]);
809 ret_if(next_letter == NULL);
811 ret_if(event_info == NULL);
812 Elm_Object_Item *index_item = (Elm_Object_Item*)event_info;
814 const char *letter = elm_index_item_letter_get(index_item);
815 ret_if(letter == NULL);
817 Elm_Object_Item *prev_item = elm_genlist_item_prev_get(item);
820 /* case: B-B', del:B */
821 if (letter[0] == next_letter[0]) {
822 __register_index_item(app_list_view_data->index, next_letter, next_item, EINA_FALSE);
825 mgr_app_app_info_t *prev_app_info = (mgr_app_app_info_t*)elm_object_item_data_get(prev_item);
826 if (!prev_app_info) {
827 MGR_APP_MEM_FREE(next_letter);
831 char *prev_letter = __convert_char_to_string(prev_app_info->app_name[0]);
833 MGR_APP_MEM_FREE(next_letter);
837 /* case: A-B'-B-B'', del:B */
838 if (letter[0] == prev_letter[0]) {
839 __register_index_item(app_list_view_data->index, prev_letter, prev_item, EINA_FALSE);
841 /* case: A-B-B'-B'', del:B */
842 } else if (letter[0] == next_letter[0]) {
843 __register_index_item(app_list_view_data->index, next_letter, next_item, EINA_FALSE);
846 MGR_APP_MEM_FREE(prev_letter);
848 MGR_APP_MEM_FREE(next_letter);
851 MGR_APP_DEBUG("next_item is null");
854 app_list_view_data->index_cnt--;
858 static Evas_Object *__create_genlist_app_list(Evas_Object *parent, void *data)
862 retv_if(mgr_app_view_app_list.view_common_data == NULL, NULL);
863 mgr_app_view_common_data_t *view_common_data = mgr_app_view_app_list.view_common_data;
865 retv_if(view_common_data->user_view_data == NULL, NULL);
866 app_list_view_data_t *app_list_view_data = view_common_data->user_view_data;
868 retv_if(data == NULL, NULL);
869 struct ug_data *ugd = (struct ug_data*)data;
870 Evas_Object *genlist = NULL;
871 Evas_Object *index = NULL;
872 Elm_Object_Item *item_sep_21 = NULL;
875 /* set the genlist item style */
876 itc = elm_genlist_item_class_new();
877 retv_if(itc == NULL, NULL);
878 \r itc_sep_21 = elm_genlist_item_class_new();
879 retv_if(itc_sep_21 == NULL, NULL);
881 itc->item_style = ITC_ITEM_STYLE;
882 itc->func.text_get = _gl_label_get;
883 itc->func.content_get = _gl_icon_get;
884 itc->func.state_get = NULL;
885 itc->func.del = _gl_del;
887 itc_sep_21->item_style = ITC_SEP_21_ITEM_STYLE;
888 itc_sep_21->func.text_get = NULL;
889 itc_sep_21->func.content_get= NULL;
890 itc_sep_21->func.state_get = NULL;
891 itc_sep_21->func.del = NULL;
895 index = elm_index_add(parent);
896 retv_if(index == NULL, NULL);
897 elm_object_part_content_set(parent, "elm.swallow.content.index", index);
898 evas_object_show(index);
902 genlist = elm_genlist_add(parent);
903 retv_if(genlist == NULL, NULL);
904 elm_object_part_content_set(parent, "elm.swallow.content.genlist", genlist);
905 evas_object_size_hint_weight_set(genlist, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
906 evas_object_size_hint_align_set(genlist, EVAS_HINT_FILL, EVAS_HINT_FILL);
907 elm_genlist_mode_set(genlist, ELM_LIST_COMPRESS);
908 elm_genlist_block_count_set(genlist, GENLIST_BLOCK_CNT);
909 elm_genlist_scroller_policy_set(genlist, ELM_SCROLLER_POLICY_OFF, ELM_SCROLLER_POLICY_OFF);
910 elm_object_style_set(genlist, "dialogue");
911 evas_object_show(genlist);
914 app_list_view_data->genlist = genlist;
915 app_list_view_data->index = index;
916 app_list_view_data->index_cnt = 0;
919 /* get app_info from AIL */
920 mgr_app_app_info_t *app_info_list = NULL;
921 mgr_app_app_info_t *p_app_info_list = NULL;
923 ail_filter_h filter_rpm = {0};
924 ail_filter_h filter_wrt = {0};
925 ail_filter_h filter_tpk = {0};
927 ail_filter_new(&filter_rpm);
928 ail_filter_new(&filter_wrt);
929 ail_filter_new(&filter_tpk);
931 ail_filter_add_str(filter_rpm, AIL_PROP_X_SLP_PACKAGETYPE_STR, RPM_PREFIX);
932 ail_filter_add_str(filter_wrt, AIL_PROP_X_SLP_PACKAGETYPE_STR, WRT_PREFIX);
933 ail_filter_add_str(filter_tpk, AIL_PROP_X_SLP_PACKAGETYPE_STR, TPK_PREFIX);
935 int appinfo_cnt_rpm = 0;
936 int appinfo_cnt_wrt = 0;
937 int appinfo_cnt_tpk = 0;
938 int appinfo_cnt_total = 0;
940 ail_filter_count_appinfo(filter_rpm, &appinfo_cnt_rpm);
941 ail_filter_count_appinfo(filter_wrt, &appinfo_cnt_wrt);
942 ail_filter_count_appinfo(filter_tpk, &appinfo_cnt_tpk);
944 appinfo_cnt_total = appinfo_cnt_rpm + appinfo_cnt_wrt + appinfo_cnt_tpk;
946 app_info_list = (mgr_app_app_info_t*)malloc(sizeof(mgr_app_app_info_t) * appinfo_cnt_total);
947 if (!app_info_list) {
948 MGR_APP_DEBUG_ERR("app_info_list allocation failed");
949 ail_filter_destroy(filter_rpm);
950 ail_filter_destroy(filter_wrt);
951 ail_filter_destroy(filter_tpk);
954 memset(app_info_list, 0, sizeof(mgr_app_app_info_t) * appinfo_cnt_total);
955 p_app_info_list = app_info_list;
957 app_list_view_data->app_info_idx = 0;
958 app_list_view_data->app_info_list = app_info_list;
959 app_list_view_data->appinfo_cnt_total = appinfo_cnt_total;
960 app_list_view_data->initialize = EINA_TRUE;
962 ail_filter_list_appinfo_foreach(filter_rpm, _appinfo_func_cb, (void*)app_info_list);
963 ail_filter_list_appinfo_foreach(filter_wrt, _appinfo_func_cb, (void*)app_info_list);
964 ail_filter_list_appinfo_foreach(filter_tpk, _appinfo_func_cb, (void*)app_info_list);
966 ail_filter_destroy(filter_rpm);
967 ail_filter_destroy(filter_wrt);
968 ail_filter_destroy(filter_tpk);
971 /* sorting by app_name */
972 app_info_list = p_app_info_list;
973 qsort(app_info_list, appinfo_cnt_total, sizeof(mgr_app_app_info_t), _app_list_qsort_cb);
976 /* add genlist item order by ASC */
977 Elm_Object_Item *item = NULL;
979 char prev_letter[MAX_BUF_SIZE] = {0, };
982 app_info_list = p_app_info_list;
984 for (j = 0; j < appinfo_cnt_total; j++) {
986 /* add the space to top of the dialogue */
987 if (app_list_view_data->initialize && elm_genlist_first_item_get(genlist)) {
988 app_list_view_data->initialize = EINA_FALSE;
989 item_sep_21 = elm_genlist_item_prepend(genlist, itc_sep_21, NULL, NULL, ELM_GENLIST_ITEM_NONE, NULL, NULL);
991 elm_genlist_item_select_mode_set(item_sep_21, ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY);
994 MGR_APP_DEBUG("%s", app_info_list->app_name);
996 mgr_app_app_info_t *app_info = app_info_list;
998 item = elm_genlist_item_append(genlist, itc, (void*)app_info, NULL, ELM_GENLIST_ITEM_NONE, _gl_sel, (void*)ugd);
1000 /* fast scroll insertion */
1001 letter = __convert_char_to_string(app_info_list->app_name[0]);
1002 if (item && strncmp(letter, prev_letter, MAX_BUF_SIZE) != 0) {
1003 __register_index_item(index, letter, item, EINA_TRUE);
1004 strncpy(prev_letter, letter, MAX_BUF_SIZE);
1007 MGR_APP_MEM_FREE(letter);
1008 app_info_list = app_info_list + 1;
1011 evas_object_smart_callback_add(index, "delay,changed", _index_delayed_changed, index);
1012 evas_object_smart_callback_add(index, "changed", _index_changed, NULL);
1013 evas_object_smart_callback_add(index, "selected", _index_selected, NULL);
1016 /* register pkg-mgr listener */
1018 retv_if(ugd->pc_listen == NULL, NULL);
1019 result = pkgmgr_client_listen_status(ugd->pc_listen, mgr_app_view_listen_cb, (void*)ugd);
1021 MGR_APP_DEBUG_ERR("status listen failed!\n");
1022 MGR_APP_MEM_FREE(genlist);
1030 static Evas_Object *mgr_app_view_app_list_create(void *data)
1034 retv_if(data == NULL, NULL);
1036 retv_if(mgr_app_view_app_list.view_common_data == NULL, NULL);
1037 mgr_app_view_common_data_t *view_common_data = mgr_app_view_app_list.view_common_data;
1039 MGR_APP_MEM_MALLOC(view_common_data->user_view_data, 1, app_list_view_data_t);
1040 retv_if(view_common_data->user_view_data == NULL, NULL);
1041 app_list_view_data_t *app_list_view_data = view_common_data->user_view_data;
1043 app_list_view_data->layout = mgr_app_create_layout_file(view_common_data->common_navibar, EDC_FILE, EDC_GROUPS);
1044 retv_if(app_list_view_data->layout == NULL, NULL);
1046 app_list_view_data->genlist = __create_genlist_app_list(app_list_view_data->layout, data);
1049 return app_list_view_data->layout;
1052 static Evas_Object *mgr_app_view_app_list_set_cbar(void *data)
1059 static mgr_app_result_e mgr_app_view_app_list_set_navibar(void *data)
1062 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);
1067 static mgr_app_result_e mgr_app_view_app_list_destory(void *data)
1071 retv_if(mgr_app_view_app_list.view_common_data == NULL, MGR_APP_ERROR);
1072 mgr_app_view_app_list.view_common_data->view_layout = NULL;
1077 static mgr_app_result_e mgr_app_view_app_list_update(void *data)
1081 retv_if(mgr_app_view_app_list.view_common_data == NULL, MGR_APP_ERROR);
1082 mgr_app_view_common_data_t *view_common_data = mgr_app_view_app_list.view_common_data;
1084 retv_if(view_common_data->user_view_data == NULL, MGR_APP_ERROR);
1085 app_list_view_data_t *app_list_view_data = view_common_data->user_view_data;
1087 if (app_list_view_data->genlist != NULL) {
1088 elm_genlist_clear(app_list_view_data->genlist);
1089 evas_object_del(app_list_view_data->genlist);
1090 app_list_view_data->genlist = NULL;
1093 app_list_view_data->genlist = __create_genlist_app_list(app_list_view_data->layout, data);
1098 static mgr_app_result_e mgr_app_view_app_list_cleanup(void *data)