change default icon
[apps/core/preloaded/ug-setting-manage-applications-efl.git] / ug / src / mgr-app-view-app-list.c
1 /*
2  *      Copyright 2012  Samsung Electronics Co., Ltd
3  *
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
7  *
8  *              http://floralicense.org/license/
9  *
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.
15  */
16
17
18 #include "mgr-app-common-debug.h"
19 #include "mgr-app-common-error.h"
20 #include "mgr-app-common-util.h"
21 #include "mgr-app-view-main.h"
22 #include "mgr-app-view-common.h"
23 #include "mgr-app-string.h"
24 #include "mgr-app-widget.h"
25 #include "mgr-app-uigadget.h"
26
27 #include <stdbool.h>
28 #include <package-manager.h>
29 #include <pkgmgr-info.h>
30 #include <appsvc.h>
31 #include <app_manager.h>
32
33 #define WRT_PREFIX                      "wgt"
34 #define TPK_PREFIX                      "tpk"
35 #define RPM_PREFIX                      "rpm"
36
37 #define STR_ICON                        "icon"
38
39 #define EDC_FILE                        EDJDIR"/ug-setting-manage-applications-efl/ug-setting-manage-applications-efl.edj"
40 #define EDC_GROUPS                      "mgr-app-list"
41
42 #define ELM_TEXT                        "elm.text"
43 #define ITC_ITEM_STYLE          "dialogue/1text.1icon.2"
44 #define ITC_SEP_ITEM_STYLE      "dialogue/separator"
45 #define GENLIST_BLOCK_CNT       10
46
47 #define MAX_BUF_SIZE            32
48 #define MAX_APP_CNT                     1024
49 #define ALPHA_CNT                       26
50 #define DIGIT_CNT                       10
51
52 #define STR_INSTALL                     "install"
53 #define STR_UNINSTALL           "uninstall"
54 #define STR_START                       "start"
55 #define STR_END                         "end"
56 #define STR_OK                          "ok"
57 #define STR_CANCEL                      "cancel"
58 #define STR_ERROR                       "error"
59 #define STR_FAIL                        "fail"
60 #define STR_POPUP_OK            "OK"
61
62 static Evas_Object *_genlist = NULL;
63 static Evas_Object *_index = NULL;
64 static int _index_cnt = 0;
65 static Eina_Bool _initialize = false;
66 static GList *_installed_list = NULL;
67 static int _installed_cnt = 0;
68 static int _target_idx = 0;
69 static Elm_Object_Item *_tabbar_item[VIEW_TYPE_MAX] = {NULL,};
70 static Elm_Object_Item *_navi_it = NULL;
71
72 static Elm_Genlist_Item_Class *itc = NULL;
73 static Elm_Genlist_Item_Class *itc_sep = NULL;
74
75 static char *_convert_char_to_string(char ch);
76 static void _register_index_item(Evas_Object *index, char *letter, Elm_Object_Item *item, Eina_Bool init);
77 static void _index_del_item_cb(void *data, Evas_Object *obj, void *event_info);
78 static void _insert_to_app_list(mgr_app_app_info_t *app_info_new, void *user_data);
79
80 static void _free_resources(struct ug_data * ugd)
81 {
82         MGR_APP_BEGIN();
83
84         mgr_app_app_info_t *app_info = NULL;
85         int i = 0;
86
87         for (i = 0; i < _installed_cnt; i++ ) {
88                 app_info = (mgr_app_app_info_t *)g_list_nth_data(_installed_list, 0);
89                 if (NULL == app_info) {
90                         continue;
91                 }
92                 MGR_APP_MEM_FREE(app_info->pkg_label);
93                 MGR_APP_MEM_FREE(app_info->pkg_name);
94                 MGR_APP_MEM_FREE(app_info->pkg_type);
95                 MGR_APP_MEM_FREE(app_info->icon_path);
96                 MGR_APP_MEM_FREE(app_info->main_appid);
97                 _installed_list = g_list_remove(_installed_list, app_info);
98         }
99
100         elm_genlist_item_class_free(itc);
101         elm_genlist_item_class_free(itc_sep);
102 }
103
104 static void _app_list_back_cb(void *data, Evas_Object *obj, void *event_info)
105 {
106         MGR_APP_BEGIN();
107         ret_if(data == NULL);
108         struct ug_data *ugd = (struct ug_data*)data;
109
110         mgr_app_doubletap_sensor_disable();
111
112         _free_resources(ugd);
113
114         mgrapp_set_view_type(VIEW_TYPE_NONE);
115
116         elm_naviframe_item_pop(ugd->navi_bar);
117
118         /* bg must delete before starting on_destroy */
119         if (ugd && ugd->bg) {
120                 evas_object_del(ugd->bg);
121                 ugd->bg = NULL;
122         }
123
124         if (ugd && ugd->ug) {
125                 ug_destroy_me(ugd->ug);
126                 ugd->ug = NULL;
127         }
128
129         MGR_APP_END();
130 }
131
132 /* callback for 'deletion' */
133 static void _gl_del(void *data, Evas_Object *obj)
134 {
135         MGR_APP_BEGIN();
136
137         ret_if(data == NULL);
138         mgr_app_app_info_t *app_info = (mgr_app_app_info_t *)data;
139
140 #if 0
141         // TODO
142         MGR_APP_MEM_FREE(app_info->pkg_name);
143         MGR_APP_MEM_FREE(app_info->pkg_label);
144         MGR_APP_MEM_FREE(app_info->pkg_type);
145         MGR_APP_MEM_FREE(app_info->icon_path);
146         MGR_APP_MEM_FREE(app_info->main_appid);
147         //MGR_APP_MEM_FREE(app_info);
148 #endif
149
150         MGR_APP_END();
151 }
152
153 /* callback for 'selection' */
154 static void _gl_sel(void *data, Evas_Object *obj, void *event_info)
155 {
156         MGR_APP_BEGIN();
157
158         ret_if(data == NULL);
159         ret_if(event_info == NULL);
160
161         struct ug_data *ugd = (struct ug_data*)data;
162         Elm_Object_Item *item = (Elm_Object_Item *)event_info;
163
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);
166
167         elm_genlist_item_selected_set(item, 0);
168
169         /* create app info view */
170         ugd->data = (void*)app_info;
171         mgrapp_view_info_create(app_info->pkg_name, (void*)ugd);
172
173         MGR_APP_END();
174 }
175
176 static char *_gl_label_get(void *data, Evas_Object *obj, const char *part)
177 {
178         MGR_APP_BEGIN();
179
180         retv_if(data == NULL, NULL);
181         mgr_app_app_info_t *app_info = (mgr_app_app_info_t *)data;
182
183         char *label             = NULL;
184         char *package_label = app_info->pkg_label;
185         char *icon_path         = app_info->icon_path;
186
187         MGR_APP_DEBUG("package_label:[%s], icon_path:[%s]\n", package_label, icon_path);
188         MGR_APP_DEBUG("part:%s\n", part);
189
190         /* label for 'elm.text' part */
191         if (package_label && 0 == strcmp(part, ELM_TEXT)) {
192                 MGR_APP_MEM_STRDUP(label, package_label);
193         } else {
194                 MGR_APP_MEM_STRDUP(label, MGRAPP_STR_ERROR);
195         }
196
197         MGR_APP_END();
198         return label;
199 }
200
201 static Evas_Object *_gl_icon_get(void *data, Evas_Object *obj, const char *part)
202 {
203         MGR_APP_BEGIN();
204
205         retv_if(data == NULL, NULL);
206         mgr_app_app_info_t *app_info = (mgr_app_app_info_t *)data;
207
208         retv_if(app_info->icon_path == NULL, NULL);
209         char *icon_path = NULL;
210         icon_path = app_info->icon_path;
211
212         Evas_Object *icon = NULL;
213
214         MGR_APP_DEBUG("icon_path:[%s]\n", icon_path);
215         MGR_APP_DEBUG("part:%s\n", part);
216
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);
223
224         elm_image_file_set(icon, icon_path, STR_ICON);
225         evas_object_show(icon);
226
227         MGR_APP_END();
228         return icon;
229 }
230
231 static void _index_delayed_changed(void *data, Evas_Object *obj, void *event_info)
232 {
233         MGR_APP_BEGIN();
234         // called on a change but delayed in case multiple changes happen in a
235         // short timespan
236         elm_genlist_item_bring_in(elm_object_item_data_get(event_info), ELM_GENLIST_ITEM_SCROLLTO_TOP);
237         MGR_APP_END();
238 }
239
240 static void _index_changed(void *data, Evas_Object *obj, void *event_info)
241 {
242         MGR_APP_BEGIN();
243         // this is calld on every change, no matter how often
244         MGR_APP_END();
245 }
246
247 static void _index_selected(void *data, Evas_Object *obj, void *event_info)
248 {
249         MGR_APP_BEGIN();
250         // called on final select
251         elm_genlist_item_bring_in(elm_object_item_data_get(event_info), ELM_GENLIST_ITEM_SCROLLTO_TOP);
252         MGR_APP_END();
253 }
254
255 static gint _app_list_qsort_cb(gconstpointer a, gconstpointer b)
256 {
257         MGR_APP_BEGIN();
258
259         retv_if(NULL == a, 0);
260         retv_if(NULL == b, 0);
261
262         mgr_app_app_info_t *app_info1 = (mgr_app_app_info_t *)a;
263         mgr_app_app_info_t *app_info2 = (mgr_app_app_info_t *)b;
264         char *pkg_label1 = NULL;
265         char *pkg_label2 = NULL;
266         int len = 0;
267         int r = 0;
268
269         pkg_label1 = app_info1->pkg_label;
270         pkg_label2 = app_info2->pkg_label;
271         retv_if(NULL == pkg_label1, 0);
272         retv_if(NULL == pkg_label2, 0);
273
274         MGR_APP_DEBUG("pkg_label1: %s", pkg_label1);
275         MGR_APP_DEBUG("pkg_label2: %s", pkg_label2);
276         
277         len = (strlen(pkg_label1) >= strlen(pkg_label2)) ? strlen(pkg_label1) : strlen(pkg_label2);
278         r = strncasecmp(pkg_label1, pkg_label2, len);
279         if (r >= 0) {
280                 _target_idx++;
281         }
282
283         MGR_APP_END();
284         return r;
285 }
286
287 static void _get_appinfo_from_pkgmgr(const pkgmgrinfo_pkginfo_h handler, mgr_app_app_info_t *app_info)
288 {
289         MGR_APP_BEGIN();
290
291         ret_if(NULL == handler || NULL == app_info);
292
293         int r = 0;
294         char *pkg_name = NULL;
295         char *icon_path = NULL;
296         char *main_appid = NULL;
297         char *pkg_label = NULL;
298         pkgmgrinfo_appinfo_h appinfo_h = NULL;
299
300         r = pkgmgrinfo_pkginfo_get_pkgid(handler, &pkg_name);
301         if (r < 0) {
302                 MGR_APP_DEBUG_ERR("pkgmgrinfo_pkginfo_get_pkgid is failed %d", r);
303                 goto end;
304         }
305         MGR_APP_MEM_STRDUP(app_info->pkg_name, pkg_name);
306         MGR_APP_DEBUG("pkg_name: %s", pkg_name);
307
308         /* get label/icon from mainapp */
309         r = pkgmgrinfo_pkginfo_get_mainappid(handler, &main_appid);
310         if (r < 0) {
311                 MGR_APP_DEBUG_ERR("pkgmgrinfo_pkginfo_get_mainappid is failed %d", r);
312                 goto end;
313         }
314         MGR_APP_DEBUG("main_appid: %s", main_appid);
315         MGR_APP_MEM_STRDUP(app_info->main_appid, main_appid);
316
317         r = pkgmgrinfo_appinfo_get_appinfo(main_appid, &appinfo_h);
318         if (r < 0) {
319                 MGR_APP_DEBUG_ERR("pkgmgrinfo_appinfo_get_appinfo is failed %d", r);
320                 goto end;
321         }
322
323         r = pkgmgrinfo_appinfo_is_nodisplay(appinfo_h, &app_info->nodisplay);
324         if (r < 0) {
325                 MGR_APP_DEBUG_ERR("pkgmgrinfo_appinfo_is_nodisplay failed. %d", r);
326                 goto end;
327         } 
328
329         r = pkgmgrinfo_appinfo_get_icon(appinfo_h, &icon_path);
330         if (r < 0) {
331                 MGR_APP_DEBUG_ERR("pkgmgrinfo_appinfo_get_icon is failed %d", r);
332                 goto end;
333         }
334         MGR_APP_MEM_STRDUP(app_info->icon_path, icon_path);
335         if (app_info->nodisplay) {
336                 mgr_app_set_default_icon(&app_info->icon_path, DEFAULT_ICON_SERVICE);
337         } else {
338                 mgr_app_set_default_icon(&app_info->icon_path, DEFAULT_ICON_APP);
339         }
340         MGR_APP_DEBUG("icon_path: %s", icon_path);
341
342         r = pkgmgrinfo_appinfo_get_label(appinfo_h, &pkg_label);
343         if (r < 0) {
344                 MGR_APP_DEBUG_ERR("pkgmgrinfo_appinfo_get_label is failed %d", r);
345                 goto end;
346         }
347         MGR_APP_MEM_STRDUP(app_info->pkg_label, pkg_label);
348         MGR_APP_DEBUG("pkg_label: %s", pkg_label);
349
350 end:
351         if (appinfo_h) {
352                 pkgmgrinfo_appinfo_destroy_appinfo(appinfo_h);
353         }
354
355         MGR_APP_END();
356 }
357
358 static void _insert_to_app_list(mgr_app_app_info_t *app_info_new, void *user_data)
359 {
360         MGR_APP_BEGIN();
361
362         ret_if(NULL == app_info_new || NULL == user_data);
363         
364         struct ug_data *ugd = (struct ug_data *)user_data;
365         Elm_Object_Item *new_item = NULL;
366         Elm_Object_Item *prev_item = NULL;
367         Elm_Object_Item *next_item = NULL;
368         Elm_Object_Item *index_item = NULL;
369         mgr_app_app_info_t *prev_info = NULL;
370         mgr_app_app_info_t *next_info = NULL;
371         char *letter_new = NULL;
372         char *letter = NULL;
373         char *letter2 = NULL;
374
375         /* insert to genlist */
376         if (_target_idx > 1) {
377                 prev_item = elm_genlist_nth_item_get(_genlist, _target_idx);
378                 if (NULL == prev_item) {
379                         MGR_APP_DEBUG_ERR("prev_item is null");
380                         goto end;
381                 }
382                 new_item = elm_genlist_item_insert_after(_genlist, itc, (void*)app_info_new, NULL, prev_item, ELM_GENLIST_ITEM_NONE, _gl_sel, (void*)ugd);
383                 if (NULL == new_item) {
384                         MGR_APP_DEBUG_ERR("new_item is null");
385                         goto end;
386                 }               
387         } else {
388                 new_item = elm_genlist_item_append(_genlist, itc, (void*)app_info_new, NULL, ELM_GENLIST_ITEM_NONE, _gl_sel, (void*)ugd);
389                 if (NULL == new_item) {
390                         MGR_APP_DEBUG_ERR("new_item is null");
391                         goto end;
392                 }
393         }
394
395         if (NULL == app_info_new->pkg_label) {
396                 MGR_APP_DEBUG_ERR("pkg_name_new is null");
397                 goto end;
398         }
399
400         letter_new = _convert_char_to_string(app_info_new->pkg_label[0]);
401         if (NULL == letter_new) {
402                 MGR_APP_DEBUG_ERR("letter_new is null");
403                 goto end;
404         }
405
406
407         /* A' B' are new one */
408         /* A' */
409         if (_installed_cnt <= 1) {
410                 _register_index_item(_index, letter_new, new_item, EINA_FALSE);
411
412         } else if (_target_idx == 1) {
413                 next_item = elm_genlist_item_next_get(new_item);
414                 if (NULL == next_item) {
415                         MGR_APP_DEBUG_ERR("next_item is null");
416                         goto end;
417                 }
418                 next_info = (mgr_app_app_info_t *)elm_object_item_data_get(next_item);
419                 if (NULL == next_info) {
420                         MGR_APP_DEBUG_ERR("next_info is null");
421                         goto end;
422                 }
423
424                 if (NULL == next_info->pkg_label) {
425                         MGR_APP_DEBUG_ERR("pkg_label is null");
426                         goto end;
427                 }
428
429                 letter = _convert_char_to_string(next_info->pkg_label[0]);
430                 if (NULL == letter) {
431                         MGR_APP_DEBUG_ERR("letter is null");
432                         goto end;
433                 }
434
435                 /* remove next letter and insert new letter */
436                 /* remove and insert operation is executed in index item delete callback */
437                 /* A' - A */
438                 if (letter_new[0] == letter[0]) {
439                         index_item = elm_index_item_find(_index, next_item);
440                         if (index_item) {
441                                 elm_object_item_del(index_item);
442                         }
443                 /* insert new letter */
444                 /* A' - B */
445                 } else {
446                         _register_index_item(_index, letter_new, new_item, EINA_FALSE);
447                 }
448                 
449         } else if (_target_idx > 1 && _target_idx < _installed_cnt) {
450                 prev_item = elm_genlist_item_prev_get(new_item);
451                 if (NULL == prev_item) {
452                         MGR_APP_DEBUG_ERR("prev_item is null");
453                         goto end;
454                 }
455                 next_item = elm_genlist_item_next_get(new_item);
456                 if (NULL == next_item) {
457                         MGR_APP_DEBUG_ERR("next_item is null");
458                         goto end;
459                 }
460
461                 prev_info = (mgr_app_app_info_t *)elm_object_item_data_get(prev_item);
462                 if (NULL == prev_info) {
463                         MGR_APP_DEBUG_ERR("prev_info is null");
464                         goto end;
465                 }
466                 next_info = (mgr_app_app_info_t *)elm_object_item_data_get(next_item);
467                 if (NULL == next_info) {
468                         MGR_APP_DEBUG_ERR("next_info is null");
469                         goto end;
470                 }
471
472                 if (NULL == prev_info->pkg_label) {
473                         MGR_APP_DEBUG_ERR("prev_info->pkg_label is null");
474                         goto end;
475                 }       
476                 if (NULL == next_info->pkg_label) {
477                         MGR_APP_DEBUG_ERR("next_info->pkg_label is null");
478                         goto end;
479                 }       
480
481                 letter = _convert_char_to_string(prev_info->pkg_label[0]);
482                 if (NULL == letter) {
483                         MGR_APP_DEBUG_ERR("letter is null");
484                         goto end;
485                 }
486                 letter2 = _convert_char_to_string(next_info->pkg_label[0]);
487                 if (NULL == letter2) {
488                         MGR_APP_DEBUG_ERR("letter2 is null");
489                         goto end;
490                 }
491
492 #if 0
493                 /* A - A' - A */
494                 if (letter[0] == letter2[0]) {
495                         // Nothing to do
496
497                 /* A - A' - B */
498                 } else if (letter[0] == letter_new[0]) {
499                         // Nothing to do
500                         
501                 } else
502 #endif                  
503                 /* A - B' - C */
504                 if (letter[0] < letter_new[0] && letter_new[0] < letter2[0]) {
505                         _register_index_item(_index, letter_new, new_item, EINA_FALSE);
506
507                 /* A - B' - B */
508                 } else if (letter_new[0] == letter2[0]) {
509                         index_item = elm_index_item_find(_index, next_item);
510                         if (index_item) {
511                                 elm_object_item_del(index_item);
512                                 index_item = NULL;
513                         }
514                 }
515                 
516         } else if (_target_idx == _installed_cnt) {
517                 prev_item = elm_genlist_item_prev_get(new_item);
518                 if (NULL == prev_item) {
519                         MGR_APP_DEBUG_ERR("prev_item is null");
520                         goto end;
521                 }
522                 prev_info = (mgr_app_app_info_t *)elm_object_item_data_get(prev_item);
523                 if (NULL == prev_info) {
524                         MGR_APP_DEBUG_ERR("prev_info is null");
525                         goto end;
526                 }
527                 if (NULL == prev_info->pkg_label) {
528                         MGR_APP_DEBUG_ERR("pkg_label is null");
529                         goto end;
530                 }
531
532                 letter = _convert_char_to_string(prev_info->pkg_label[0]);
533                 if (NULL == letter) {
534                         MGR_APP_DEBUG_ERR("letter is null");
535                         goto end;
536                 }
537
538                 /* insert new letter */
539                 /* A - B' */
540                 if (letter_new[0] > letter[0]) {
541                         _register_index_item(_index, letter_new, new_item, EINA_FALSE);
542                 }
543         }
544         
545
546         elm_genlist_realized_items_update(_genlist);
547
548 end:
549         MGR_APP_MEM_FREE(letter);
550         MGR_APP_MEM_FREE(letter2);
551         MGR_APP_MEM_FREE(letter_new);
552
553         MGR_APP_END();
554 }
555
556 static void _notify_by_uninstall(void *data)
557 {
558         MGR_APP_BEGIN();
559
560         ret_if(data == NULL);
561         struct ug_data *ugd = (struct ug_data*)data;
562
563         Evas_Object *noti = elm_notify_add(ugd->navi_bar);
564         elm_notify_align_set(noti, ELM_NOTIFY_ALIGN_FILL, 1.0);
565
566         Evas_Object *layout = elm_layout_add(noti);
567         elm_layout_theme_set(layout, "standard", "selectioninfo", "center_text");
568
569         elm_object_content_set(noti, layout);
570         elm_notify_timeout_set(noti, 2);
571         edje_object_part_text_set(_EDJ(layout), ELM_TEXT, MGRAPP_STR_UNINSTALLED);
572         evas_object_show(noti);
573
574         MGR_APP_END();
575 }
576
577 static void mgrapp_view_list_update_by_install(const char *pkg_type, const char *pkg_name, void *data)
578 {
579         MGR_APP_BEGIN();
580
581         ret_if(pkg_name == NULL || data == NULL);
582         
583         struct ug_data *ugd = (struct ug_data*)data;
584         pkgmgr_pkginfo_h pkg_handle = NULL;
585         mgr_app_app_info_t *app_info = NULL;
586         int r = 0;
587
588         _initialize = EINA_FALSE;
589
590         r = pkgmgr_pkginfo_get_pkginfo(pkg_name, &pkg_handle);
591         if (r < 0) {
592                 MGR_APP_DEBUG_ERR("pkgmgr_pkginfo_get_pkginfo is failed. %d", r);
593                 goto end;
594         }
595
596         app_info = (mgr_app_app_info_t*)malloc(sizeof(mgr_app_app_info_t));
597         if (NULL == app_info) {
598                 goto end;
599         }
600         memset(app_info, 0, sizeof(mgr_app_app_info_t));
601
602         _get_appinfo_from_pkgmgr(pkg_handle, app_info);
603         
604         _target_idx = 1; // 0: genlist separator item
605         _installed_list = g_list_insert_sorted(_installed_list, (gpointer)app_info, _app_list_qsort_cb);
606         _installed_cnt++;
607
608         _insert_to_app_list(app_info, (void*)ugd);
609
610 end:
611         if (pkg_handle) {
612                 pkgmgr_pkginfo_destroy_pkginfo(pkg_handle);
613         }
614
615         MGR_APP_END();
616 }
617
618 void mgrapp_view_list_update_by_uninstall(const char *pkg_type, const char *pkg_name, void *data)
619 {
620         MGR_APP_BEGIN();
621
622         ret_if(pkg_name == NULL);
623
624         mgr_app_app_info_t *app_info = NULL;
625         Elm_Object_Item *item = NULL;
626         Elm_Object_Item *idx_item = NULL;
627         int i = 0;
628
629         /* header separator */
630         item = elm_genlist_first_item_get(_genlist);
631         ret_if(item == NULL);
632         item = elm_genlist_item_next_get(item);
633         ret_if(item == NULL);
634         
635
636         for (i = 0; i < _installed_cnt; i++) {
637
638                 app_info = (mgr_app_app_info_t *)elm_object_item_data_get(item);
639                 ret_if(app_info == NULL);
640
641                 if (app_info->pkg_name && 0 == strcmp(app_info->pkg_name, pkg_name)) {
642                         MGR_APP_DEBUG_ERR("in");
643                         idx_item = elm_index_item_find(_index, item);
644                         if (idx_item) {
645                                 _index_del_item_cb(item, _index, idx_item);
646                                 elm_object_item_del(idx_item);
647                                 idx_item = NULL;
648                         }
649                         _installed_list = g_list_remove(_installed_list, app_info);
650                         elm_object_item_del(item);
651                         item = NULL;
652                         
653                         MGR_APP_DEBUG("deleted");
654                         _installed_cnt--;
655                 } 
656                 item = elm_genlist_item_next_get(item);
657                 ret_if(item == NULL);
658         }
659
660         elm_genlist_realized_items_update(_genlist);
661
662         MGR_APP_END();
663 }
664
665 static void _response_cb(void *data, Evas_Object *obj, void *event_info)
666 {
667         MGR_APP_BEGIN();
668
669         if (data) {
670                 evas_object_del(data);
671                 data = NULL;
672         }
673
674         MGR_APP_END();
675 }
676
677 int mgrapp_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)
678 {
679         MGR_APP_BEGIN();
680
681         MGR_APP_DEBUG("key:%s val:%s", key, val);
682         MGR_APP_DEBUG("pkg_type:%s pkg_name:%s", pkg_type, pkg_name);
683         retv_if(data == NULL, -1);
684         struct ug_data *ugd = (struct ug_data*)data;
685
686         if (!strncmp(key, STR_START, strlen(key)) && !strncmp(val, STR_UNINSTALL, strlen(val))) {
687                 ugd->uninstall = EINA_TRUE;
688         } else if (!strncmp(key, STR_START, strlen(key)) && !strncmp(val, STR_INSTALL, strlen(val))) {
689                 ugd->uninstall = EINA_FALSE;
690         } else if (!strncmp(key, STR_ERROR, strlen(key))) {
691         } else if (!strncmp(key, STR_END, strlen(key)) && !strncmp(val, STR_FAIL, strlen(val))) {
692                 mgrapp_destroy_popup_progressbar();
693                 mgrapp_create_popup_text_1button(ugd->win_main, MGRAPP_STR_FAILED, STR_POPUP_OK, _response_cb);
694         } else if (!strncmp(key, STR_END, strlen(key)) && !strncmp(val, STR_OK, strlen(val))) {
695                 if (ugd->uninstall) {
696                         mgrapp_destroy_popup_progressbar();
697                         mgrapp_create_popup_text_1button(ugd->win_main, MGRAPP_STR_SUCCESS, STR_POPUP_OK, _response_cb);
698                         mgrapp_view_list_update_by_uninstall(pkg_type, pkg_name, (void*)ugd);
699                 } else {
700                         mgrapp_view_list_update_by_install(pkg_type, pkg_name, (void*)ugd);
701                 }
702
703                 /* check the info view was opened */
704                 if (VIEW_TYPE_APP_INFO == mgrapp_get_view_type()) {
705                         if (ugd->uninstall) {
706                                 mgrapp_view_info_destroy(ugd);
707                                 _notify_by_uninstall((void*)ugd);
708                                 ugd->uninstall = EINA_FALSE;
709                         }
710                 }
711         } else if (!strncmp(key, STR_END, strlen(key)) && !strncmp(val, STR_CANCEL, strlen(val))) {
712         } else {
713         }
714
715         MGR_APP_END();
716         return 0;
717 }
718
719 static char *_convert_char_to_string(char ch)
720 {
721         MGR_APP_BEGIN();
722
723         char *str_buf = NULL;
724         str_buf = (char*)malloc(sizeof(char)*MAX_BUF_SIZE);
725         retv_if(str_buf == NULL, NULL);
726         memset(str_buf, 0, sizeof(char)*MAX_BUF_SIZE);
727
728         if (ch >= 'A' && ch <= 'Z') {
729                 snprintf(str_buf, MAX_BUF_SIZE, "%c", ch);
730         } else if (ch >= 'a' && ch <= 'z') {
731                 snprintf(str_buf, MAX_BUF_SIZE, "%c", ch - 'a' + 'A');
732         } else if (ch >= '0' && ch <= '9') {
733                 snprintf(str_buf, MAX_BUF_SIZE, "%c", ch);
734         } else {
735                 snprintf(str_buf, MAX_BUF_SIZE, "%s", "etc");
736         }
737
738         MGR_APP_END();
739         return str_buf;
740 }
741
742 static int _compare_index_item_letter_cb(const void *a, const void *b)
743 {
744         MGR_APP_BEGIN();
745
746         retv_if(a == NULL, -1);
747         retv_if(b == NULL, -1);
748
749         const Elm_Object_Item *it1 = (const Elm_Object_Item*)a;
750         const Elm_Object_Item *it2 = (const Elm_Object_Item*)b;
751
752         const char *letter1 = elm_index_item_letter_get(it1);
753         const char *letter2 = elm_index_item_letter_get(it2);
754
755         MGR_APP_DEBUG("letter1: %s, letter2: %s", letter1, letter2);
756
757         int len = 0;
758         len = (strlen(letter1) >= strlen(letter2)) ? strlen(letter1) : strlen(letter2);
759
760         MGR_APP_END();
761         return strncasecmp(letter1, letter2, len);
762 }
763
764 /**
765  *  _compare_data_index_item_letter_cb be used when _compare_index_item_letter_cb return 0.
766  */
767 static int _compare_data_index_item_letter_cb(const void *a, const void *b)
768 {
769         MGR_APP_BEGIN();
770
771         retv_if(a == NULL, -1);
772         retv_if(b == NULL, -1);
773
774         const Elm_Object_Item *it1 = (const Elm_Object_Item*)a;
775         const Elm_Object_Item *it2 = (const Elm_Object_Item*)b;
776
777         mgr_app_app_info_t *app_info1 = (mgr_app_app_info_t *)elm_object_item_data_get(it1);
778         mgr_app_app_info_t *app_info2 = (mgr_app_app_info_t *)elm_object_item_data_get(it2);
779         retv_if(app_info1 == NULL, -1);
780         retv_if(app_info2 == NULL, -1);
781
782         MGR_APP_DEBUG("letter1: %s, letter2: %s", app_info1->pkg_label, app_info2->pkg_label);
783
784         MGR_APP_END();
785         return 0;
786 }
787
788 static void _register_index_item(Evas_Object *index, char *letter, Elm_Object_Item *item, Eina_Bool init)
789 {
790         MGR_APP_BEGIN();
791
792         MGR_APP_DEBUG("letter: %s", letter);
793
794         Elm_Object_Item *new_index_item = NULL;
795         Elm_Object_Item *temp_index_item        = NULL;
796         Elm_Object_Item *temp_item              = NULL;
797         char            *temp_letter            = NULL;
798         int i = 0;
799
800         if (!init) {
801                 temp_item = elm_genlist_first_item_get(_genlist);
802                 ret_if(temp_item == NULL);
803
804                 for (i = 0; i < _installed_cnt; i++) {
805                         temp_index_item = elm_index_item_find(index, temp_item);
806
807                         /* indexed genlist item */
808                         if (temp_index_item) {
809                                 temp_letter = elm_index_item_letter_get(temp_index_item);
810                                 ret_if(temp_letter == NULL);
811
812                                 if (letter[0] < temp_letter[0]) {
813                                         elm_index_item_insert_before(index, temp_item, letter, NULL, item);
814                                         break;
815                                 }
816                         }
817                         temp_item = elm_genlist_item_next_get(temp_item);
818                 }
819         } else {
820                 elm_index_item_append(index, letter, NULL, item);
821         }
822
823         new_index_item = elm_index_item_find(index, item);
824         ret_if(new_index_item == NULL);
825         //elm_object_item_del_cb_set(new_index_item, _index_del_item_cb);
826         elm_object_item_data_set(new_index_item, (void*)item);
827
828         _index_cnt++;
829
830         MGR_APP_END();
831 }
832
833 static void _index_del_item_cb(void *data, Evas_Object *obj, void *event_info)
834 {
835         MGR_APP_BEGIN();
836
837         ret_if(data == NULL);
838         Elm_Object_Item *item = (Elm_Object_Item*)data;
839         Elm_Object_Item *next_item = NULL;
840         Elm_Object_Item *prev_item = NULL;
841         Elm_Object_Item *index_item = NULL;
842         mgr_app_app_info_t *next_app_info = NULL;
843         char *next_letter = NULL;
844         char *letter = NULL;
845
846         /* change the index item */
847         next_item = elm_genlist_item_next_get(item);
848         
849         if (next_item) {
850                 next_app_info = (mgr_app_app_info_t *)elm_object_item_data_get(next_item);
851                 ret_if(next_app_info == NULL);
852
853                 index_item = (Elm_Object_Item*)event_info;
854                 ret_if(index_item == NULL);
855
856                 next_letter = _convert_char_to_string(next_app_info->pkg_label[0]);
857                 ret_if(next_letter == NULL);
858
859                 letter = elm_index_item_letter_get(index_item);
860                 if (!letter) {
861                         MGR_APP_DEBUG_ERR("letter is null.");
862                         goto end;
863                 }
864
865                 prev_item = elm_genlist_item_prev_get(item);
866
867                 if (!prev_item) {
868                         /* case: B-B', del:B */
869                         if (letter[0] == next_letter[0]) {
870                                 _register_index_item(_index, next_letter, next_item, EINA_FALSE);
871                         }
872                 } else {
873                         mgr_app_app_info_t *prev_app_info = (mgr_app_app_info_t *)elm_object_item_data_get(prev_item);
874                         if (!prev_app_info) {
875                                 MGR_APP_DEBUG_ERR("prev_app_info is null.");
876                                 goto end;
877                         }
878
879                         char *prev_letter = _convert_char_to_string(prev_app_info->pkg_label[0]);
880                         if (!prev_letter) {
881                                 MGR_APP_DEBUG_ERR("prev_letter is null.");
882                                 goto end;
883                         }
884
885                         /* case: A-B'-B-B'', del:B */
886                         if (letter[0] == prev_letter[0]) {
887                                 _register_index_item(_index, prev_letter, prev_item, EINA_FALSE);
888
889                         /* case: A-B-B'-B'', del:B */
890                         } else if (letter[0] == next_letter[0]) {
891                                 _register_index_item(_index, next_letter, next_item, EINA_FALSE);
892                         }
893
894                         MGR_APP_MEM_FREE(prev_letter);
895                 }
896                 MGR_APP_MEM_FREE(next_letter);
897         } else {
898                 /* A-B, del:B */
899                 MGR_APP_DEBUG("next_item is null");
900         }
901
902         _index_cnt--;
903
904 end:
905         MGR_APP_MEM_FREE(next_letter);
906
907         MGR_APP_END();
908 }
909
910 static void _gl_realized(void *data, Evas_Object *obj, void *event_info)
911 {
912         MGR_APP_BEGIN();
913
914         ret_if(obj == NULL);
915         ret_if(event_info == NULL);
916
917         if (event_info == elm_genlist_item_next_get(elm_genlist_first_item_get(obj))) { // first is a separator
918                 elm_object_item_signal_emit(event_info, "elm,state,top", "");
919         } else if (event_info == elm_genlist_item_prev_get(elm_genlist_last_item_get(obj))) { // last is a separator
920                 elm_object_item_signal_emit(event_info, "elm,state,bottom", "");
921         } else {
922                 elm_object_item_signal_emit(event_info, "elm,state,center", "");
923         }
924
925         MGR_APP_END();
926 }
927
928 static int _pkgmgr_iter_fn(pkgmgr_pkginfo_h handle, void *data)
929 {
930         MGR_APP_BEGIN();
931
932         retv_if(NULL == handle, 0);
933
934         mgr_app_app_info_t *app_info = NULL;
935
936         app_info = (mgr_app_app_info_t*)malloc(sizeof(mgr_app_app_info_t));
937         retv_if(app_info == NULL, -1);
938         memset(app_info, 0, sizeof(mgr_app_app_info_t));
939         
940         _get_appinfo_from_pkgmgr(handle, app_info);
941
942         _installed_list = g_list_append(_installed_list, (gpointer)app_info);
943         _installed_cnt++;
944         MGR_APP_DEBUG("installed cnt %d", _installed_cnt);
945
946         MGR_APP_END();
947         return 0;
948 }
949
950 static void _create_genlist_app_list(seg_type_t seg, void *data)
951 {
952         MGR_APP_BEGIN();
953
954         ret_if(data == NULL);
955         struct ug_data  *ugd = (struct ug_data*)data;
956         Evas_Object             *genlist        = NULL;
957         Evas_Object     *index          = NULL;
958         Elm_Object_Item *item_sep       = NULL;
959         Evas_Object *layout = NULL;
960
961         Elm_Object_Item *item = NULL;
962         char *letter = NULL;
963         char prev_letter[MAX_BUF_SIZE] = {0, };
964         
965         mgr_app_app_info_t *app_info = NULL;
966
967         int r = PKGMGR_R_ERROR;
968         int i = 0;
969         bool is_running = false;
970
971         /* set the genlist item style */
972         itc = elm_genlist_item_class_new();
973         ret_if(itc == NULL);
974         itc_sep = elm_genlist_item_class_new();
975         ret_if(itc_sep == NULL);
976
977         itc->item_style         = ITC_ITEM_STYLE;
978         itc->func.text_get      = _gl_label_get;
979         itc->func.content_get   = _gl_icon_get;
980         itc->func.state_get = NULL;
981         itc->func.del           = _gl_del;
982
983         itc_sep->item_style             = ITC_SEP_ITEM_STYLE;
984         itc_sep->func.text_get  = NULL;
985         itc_sep->func.content_get= NULL;
986         itc_sep->func.state_get = NULL;
987         itc_sep->func.del               = NULL;
988
989         layout = mgr_app_create_layout_file(ugd->navi_bar, EDC_FILE, EDC_GROUPS);
990         ret_if(NULL == layout);
991
992         /* Create index */
993         index = elm_index_add(layout);
994         ret_if(index == NULL);
995         elm_object_part_content_set(layout, "elm.swallow.content.index", index);
996         evas_object_show(index);
997
998
999         /* add a genlist */
1000         genlist = elm_genlist_add(layout);
1001         ret_if(genlist == NULL);
1002         elm_object_part_content_set(layout, "elm.swallow.content.genlist", genlist);
1003         evas_object_size_hint_weight_set(genlist, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
1004         evas_object_size_hint_align_set(genlist, EVAS_HINT_FILL, EVAS_HINT_FILL);
1005         elm_genlist_mode_set(genlist, ELM_LIST_COMPRESS);
1006         elm_genlist_block_count_set(genlist, GENLIST_BLOCK_CNT);
1007         elm_scroller_policy_set(genlist, ELM_SCROLLER_POLICY_OFF, ELM_SCROLLER_POLICY_AUTO);
1008         evas_object_show(genlist);
1009         evas_object_smart_callback_add(genlist, "realized", _gl_realized, NULL);
1010
1011         _genlist = genlist;
1012         _index = index;
1013         _index_cnt = 0;
1014
1015
1016         /* header border */
1017         item_sep = elm_genlist_item_append(genlist, itc_sep, NULL, NULL, ELM_GENLIST_ITEM_NONE, NULL, NULL);
1018         if (item_sep)
1019                 elm_genlist_item_select_mode_set(item_sep, ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY);
1020
1021         for (i = 0; i < _installed_cnt; i++) {
1022
1023                 app_info = (mgr_app_app_info_t *)g_list_nth_data(_installed_list, i);
1024                 if (NULL == app_info) {
1025                         MGR_APP_DEBUG_ERR("app_info is a null");
1026                         continue;
1027                 }
1028                 MGR_APP_DEBUG("genlist %d app_info->pkg_label: %s", i, app_info->pkg_label);
1029
1030                 if (LIST_SEG_TYPE_RUNNING == seg
1031                                 && APP_MANAGER_ERROR_NONE == app_manager_is_running(app_info->main_appid, &is_running)
1032                                 && false == is_running) {
1033                         continue;
1034                 }
1035                 
1036                 item = elm_genlist_item_append(genlist, itc, (void*)app_info, NULL, ELM_GENLIST_ITEM_NONE, _gl_sel, (void*)ugd);
1037
1038                 /* fast scroll insertion */
1039                 letter = _convert_char_to_string(app_info->pkg_label[0]);
1040                 if (item && strncmp(letter, prev_letter, MAX_BUF_SIZE) != 0) {
1041                         _register_index_item(index, letter, item, EINA_TRUE);
1042                         strncpy(prev_letter, letter, MAX_BUF_SIZE);
1043                 }
1044
1045                 MGR_APP_MEM_FREE(letter);
1046
1047         }
1048
1049         /* footer border */
1050         item_sep = elm_genlist_item_append(genlist, itc_sep, NULL, NULL, ELM_GENLIST_ITEM_NONE, NULL, NULL);
1051         if (item_sep)
1052                 elm_genlist_item_select_mode_set(item_sep, ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY);
1053
1054         evas_object_smart_callback_add(index, "delay,changed", _index_delayed_changed, index);
1055         evas_object_smart_callback_add(index, "changed", _index_changed, NULL);
1056         evas_object_smart_callback_add(index, "selected", _index_selected, NULL);
1057
1058         elm_object_item_part_content_set(_navi_it, "elm.swallow.content", layout);
1059
1060         /* register pkg-mgr listener */
1061         ret_if(ugd->pc_listen == NULL);
1062         r = pkgmgr_client_listen_status(ugd->pc_listen, mgrapp_view_listen_cb, (void*)ugd);
1063         if (r < 0) {
1064                 MGR_APP_DEBUG_ERR("status listen failed!\n");
1065                 return ;
1066         }
1067
1068         MGR_APP_END();
1069 }
1070
1071 static void _doubletap_sensor_cb(void *data)
1072 {
1073         MGR_APP_BEGIN();
1074
1075         ret_if(NULL == data);
1076
1077         Evas_Object *genlist = (Evas_Object*)data;
1078         Elm_Object_Item *item = NULL;
1079
1080         item = elm_genlist_first_item_get(genlist);
1081         ret_if(NULL == item);
1082         
1083         elm_genlist_item_show(item, ELM_GENLIST_ITEM_SCROLLTO_TOP);
1084                 
1085         MGR_APP_END();
1086 }
1087
1088 static void _create_genlist_app_cb(void *data, Evas_Object *obj, void *event_info)
1089 {
1090         MGR_APP_BEGIN();
1091
1092         ret_if(NULL == data);
1093                 
1094         _create_genlist_app_list(LIST_SEG_TYPE_APPLICATION, data);
1095
1096         MGR_APP_END();
1097 }
1098
1099 static void _create_genlist_all_cb(void *data, Evas_Object *obj, void *event_info)
1100 {
1101         MGR_APP_BEGIN();
1102
1103         ret_if(NULL == data);
1104         
1105         _create_genlist_app_list(LIST_SEG_TYPE_ALL, data);
1106
1107         MGR_APP_END();
1108 }
1109
1110 static void _create_genlist_running_cb(void *data, Evas_Object *obj, void *event_info)
1111 {
1112         MGR_APP_BEGIN();
1113
1114         ret_if(NULL == data);
1115                 
1116         _create_genlist_app_list(LIST_SEG_TYPE_RUNNING, data);
1117
1118         MGR_APP_END();
1119 }
1120
1121 void mgrapp_view_list_create(void *data)
1122 {
1123         MGR_APP_BEGIN();
1124
1125         ret_if(data == NULL);
1126
1127         struct ug_data *ugd = (struct ug_data *)data;
1128         Evas_Object *layout = NULL;
1129         Evas_Object *back_btn = NULL;
1130         Evas_Object *tabbar = NULL;
1131         Elm_Object_Item *tool_it = NULL;
1132         Elm_Object_Item *navi_it = NULL;
1133         int r = 0;
1134         
1135         mgrapp_set_view_type(VIEW_TYPE_APP_LIST);
1136
1137         Evas_Object *nocontents = NULL;
1138         nocontents = elm_layout_add(ugd->navi_bar);
1139         ret_if(NULL == nocontents);
1140         elm_layout_theme_set(nocontents, "layout", "nocontents", "full");
1141
1142         /* back button */
1143         back_btn = elm_button_add(ugd->navi_bar);
1144         ret_if(NULL == back_btn);
1145         elm_object_style_set(back_btn, "naviframe/end_btn/default");
1146         evas_object_smart_callback_add(back_btn, "clicked", _app_list_back_cb, (void*)ugd);
1147
1148         _navi_it = navi_it = elm_naviframe_item_push(ugd->navi_bar, MGRAPP_STR_MANAGE_APPLICATIONS, back_btn, NULL, nocontents, "tabbar");
1149
1150         r = pkgmgr_pkginfo_get_list(_pkgmgr_iter_fn, data);
1151         if (PKGMGR_R_OK != r) {
1152                 MGR_APP_DEBUG_ERR("pkgmgr_get_pkg_list failed. %d", r);
1153         }
1154
1155         /* sorting by pkg_label */
1156         _installed_list = g_list_sort(_installed_list, _app_list_qsort_cb);
1157
1158         /* create toolbar */
1159         tabbar = elm_toolbar_add(ugd->navi_bar);
1160         ret_if(NULL == tabbar);
1161         elm_toolbar_shrink_mode_set(tabbar, ELM_TOOLBAR_SHRINK_EXPAND);
1162         elm_object_style_set(tabbar, "tabbar");
1163         elm_object_item_part_content_set(navi_it, "tabbar", tabbar);
1164
1165         _tabbar_item[LIST_SEG_TYPE_APPLICATION] = elm_toolbar_item_append(tabbar, NULL, MGRAPP_STR_APPLICATION, _create_genlist_app_cb, (void*)ugd);
1166         _tabbar_item[LIST_SEG_TYPE_RUNNING] = elm_toolbar_item_append(tabbar, NULL, MGRAPP_STR_RUNNING, _create_genlist_running_cb, (void*)ugd);
1167         _tabbar_item[LIST_SEG_TYPE_ALL] = elm_toolbar_item_append(tabbar, NULL, MGRAPP_STR_ALL, _create_genlist_all_cb, (void*)ugd);
1168         elm_toolbar_item_selected_set(_tabbar_item[LIST_SEG_TYPE_APPLICATION], EINA_TRUE);
1169
1170         mgr_app_doubletap_sensor_set_cb(_doubletap_sensor_cb, _genlist);
1171         mgr_app_doubletap_sensor_enable();      
1172
1173         MGR_APP_END();
1174 }
1175
1176 void mgrapp_view_list_update(void *data)
1177 {
1178         MGR_APP_BEGIN();
1179
1180         if (_genlist) {
1181                 mgr_app_doubletap_sensor_set_cb(_doubletap_sensor_cb, _genlist);
1182                 mgr_app_doubletap_sensor_enable();
1183         }
1184
1185         MGR_APP_END();
1186 }