b32736bef522021cfb19f48362762507f372069a
[apps/home/ug-setting-manage-applications-efl.git] / view / 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://www.tizenopensource.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-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"
25 #include <ail.h>
26 #include <stdbool.h>
27 #include <package-manager.h>
28
29
30 #define WRT_PREFIX                      "wgt"
31 #define TPK_PREFIX                      "tpk"
32 #define RPM_PREFIX                      "rpm"
33
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"
38
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"
41
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
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
59
60 typedef struct _app_list_view_data_t app_list_view_data_t;
61
62 struct _app_list_view_data_t {
63         Evas_Object             *layout;
64         Evas_Object             *genlist;
65         Evas_Object                     *index;
66         int                                     index_cnt;
67         mgr_app_app_info_t      *app_info_list;
68         int                                     app_info_idx;
69         int                                     appinfo_cnt_total;
70         Eina_Bool                       initialize;
71 };
72
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);
79
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);
84
85
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,
92 };
93
94 static Elm_Genlist_Item_Class *itc = NULL;
95 static Elm_Genlist_Item_Class *itc_sep_21 = NULL;
96
97
98 static void _app_list_next_cb(void *data, Evas_Object *obj, void *event_info)
99 {
100         MGR_APP_BEGIN();
101         mgr_app_view_create(&mgr_app_view_app_list, data);
102         MGR_APP_END();
103 }
104
105 static void _app_list_back_cb(void *data, Evas_Object *obj, void *event_info)
106 {
107         MGR_APP_BEGIN();
108         ret_if(data == NULL);
109         struct ug_data *ugd = (struct ug_data*)data;
110         mgr_app_view_common_back_cb(data, EINA_FALSE);
111
112         elm_genlist_item_class_free(itc);
113         elm_genlist_item_class_free(itc_sep_21);
114
115         /* bg must delete before starting on_destroy */
116         evas_object_del(ugd->bg);
117         ugd->bg = NULL;
118         ug_destroy_me(ugd->ug);
119         MGR_APP_END();
120 }
121
122 /* get the state of item */
123 static Eina_Bool _gl_state_get(void *data, Evas_Object *obj, const char *part)
124 {
125         MGR_APP_BEGIN();
126         MGR_APP_END();
127
128         return EINA_FALSE;
129 }
130
131 /* callback for 'deletion' */
132 static void _gl_del(void *data, Evas_Object *obj)
133 {
134         MGR_APP_BEGIN();
135
136         ret_if(data == NULL);
137         mgr_app_app_info_t *app_info = (mgr_app_app_info_t*)data;
138
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);
144         MGR_APP_END();
145
146         return;
147 }
148
149 /* callback for 'selection' */
150 static void _gl_sel(void *data, Evas_Object *obj, void *event_info)
151 {
152         MGR_APP_BEGIN();
153
154         ret_if(data == NULL);
155         ret_if(event_info == NULL);
156
157         struct ug_data *ugd = (struct ug_data*)data;
158         Elm_Object_Item *item = (Elm_Object_Item *)event_info;
159
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);
162
163         elm_genlist_item_selected_set(item, 0);
164
165         /* create app info view */
166         ugd->data = (void*)app_info;
167         mgr_app_view_create(&mgr_app_view_app_info, (void*)ugd);
168
169         MGR_APP_END();
170 }
171
172 static char *_gl_label_get(void *data, Evas_Object *obj, const char *part)
173 {
174         MGR_APP_BEGIN();
175
176         retv_if(data == NULL, NULL);
177         mgr_app_app_info_t *app_info = (mgr_app_app_info_t*)data;
178
179         char *label             = NULL;
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;
184
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);
187
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);
191         } else {
192                 MGR_APP_MEM_STRDUP(label, dgettext("sys_string", "IDS_COM_POP_ERROR"));
193         }
194
195         MGR_APP_END();
196         return label;
197 }
198
199 static Evas_Object *_gl_icon_get(void *data, Evas_Object *obj, const char *part)
200 {
201         MGR_APP_BEGIN();
202
203         retv_if(data == NULL, NULL);
204         mgr_app_app_info_t *app_info = (mgr_app_app_info_t*)data;
205
206         retv_if(app_info->icon_path == NULL, NULL);
207         char *icon_path = NULL;
208         icon_path = app_info->icon_path;
209
210         Evas_Object *icon = NULL;
211
212         MGR_APP_DEBUG("icon_path:[%s]\n", icon_path);
213         MGR_APP_DEBUG("part:%s\n", part);
214
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);
221
222         elm_icon_file_set(icon, icon_path, STR_ICON);
223         evas_object_show(icon);
224
225         MGR_APP_END();
226         return icon;
227 }
228
229 static void _index_delayed_changed(void *data, Evas_Object *obj, void *event_info)
230 {
231         MGR_APP_BEGIN();
232         // called on a change but delayed in case multiple changes happen in a
233         // short timespan
234         elm_genlist_item_bring_in(elm_object_item_data_get(event_info), ELM_GENLIST_ITEM_SCROLLTO_TOP);
235         MGR_APP_END();
236 }
237
238 static void _index_changed(void *data, Evas_Object *obj, void *event_info)
239 {
240         MGR_APP_BEGIN();
241         // this is calld on every change, no matter how often
242         MGR_APP_END();
243 }
244
245 static void _index_selected(void *data, Evas_Object *obj, void *event_info)
246 {
247         MGR_APP_BEGIN();
248         // called on final select
249         elm_genlist_item_bring_in(elm_object_item_data_get(event_info), ELM_GENLIST_ITEM_SCROLLTO_TOP);
250         MGR_APP_END();
251 }
252
253 static int _app_list_qsort_cb(const void *a, const void *b)
254 {
255         MGR_APP_BEGIN();
256
257         if (!a) {
258                 MGR_APP_DEBUG_ERR("a is null");
259                 return 0;
260         } else if (!b) {
261                 MGR_APP_DEBUG_ERR("b is null");
262                 return 0;
263         }
264
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;
267
268         if (!app_info1->app_name) {
269                 MGR_APP_DEBUG_ERR("app_info1->app_name is null");
270                 return 0;
271         }
272
273         if (!app_info2->app_name) {
274                 MGR_APP_DEBUG_ERR("app_info2->app_name is null");
275                 return 0;
276         }
277
278         int len = 0;
279         len = (strlen(app_info1->app_name) >= strlen(app_info2->app_name)) ? strlen(app_info1->app_name) : strlen(app_info2->app_name);
280
281         MGR_APP_END();
282         return strncasecmp(app_info1->app_name, app_info2->app_name, len);
283 }
284
285 static ail_cb_ret_e _appinfo_func_cb(const ail_appinfo_h ail_info, void *user_data)
286 {
287         MGR_APP_BEGIN();
288
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;
291
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;
294
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;
297
298         if (app_list_view_data->initialize) {
299                 p_app_info_list = p_app_info_list + app_list_view_data->app_info_idx++;
300         }
301
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;
309
310         ail_appinfo_get_str(ail_info, AIL_PROP_PACKAGE_STR, &package_name);
311         if (!package_name) {
312                 MGR_APP_DEBUG_ERR(">>> get package_name failed");
313                 return AIL_CB_RET_CONTINUE;
314         }
315         ail_appinfo_get_str(ail_info, AIL_PROP_NAME_STR, &app_name);
316         if (!app_name) {
317                 MGR_APP_DEBUG_ERR(">>> get app_name failed");
318                 return AIL_CB_RET_CONTINUE;
319         }
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);
325
326
327         /* setting icon path */
328         FILE *stream = NULL;
329         char *p = NULL;
330         if (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)) {
335                         fclose(stream);
336                         stream = NULL;
337
338                         char *p_extension = NULL;
339                         p_extension = icon_path + (strlen(icon_path) - strlen(STR_PNG));
340
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;
344                         }
345                 /* default icon : icon_path isn't exist */
346                 } else {
347                         icon_path = DEFAULT_ICON_FILE;
348                         if (stream) {
349                                 fclose(stream);
350                                 stream = NULL;
351                         }
352                 }
353         /* default icon : icon_path == NULL */
354         } else {
355                 icon_path = DEFAULT_ICON_FILE;
356         }
357
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;
365
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);
373
374         MGR_APP_END();
375         return AIL_CB_RET_CONTINUE;
376 }
377
378 static void _popup_progressbar_by_uninstall(void *data)
379 {
380         MGR_APP_BEGIN();
381
382         ret_if(data == NULL);
383         struct ug_data *ugd = (struct ug_data*)data;
384
385         Evas_Object *popup = NULL;
386         Evas_Object *layout = NULL;
387         Evas_Object *progressbar = NULL;
388
389         popup = elm_popup_add(ugd->win_main);\r
390         ret_if(popup == NULL);
391
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);
399
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);
404
405         MGR_APP_END();
406 }
407
408 static void _notify_by_uninstall(void *data)
409 {
410         MGR_APP_BEGIN();
411
412         ret_if(data == NULL);
413         struct ug_data *ugd = (struct ug_data*)data;
414
415         Evas_Object *noti = elm_notify_add(ugd->navi_bar);
416         elm_notify_orient_set(noti, ELM_NOTIFY_ORIENT_BOTTOM);
417
418         Evas_Object *layout = elm_layout_add(noti);
419         elm_layout_theme_set(layout, "standard", "selectioninfo", "vertical/bottom_12");
420
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);
425
426         MGR_APP_END();
427 }
428
429 static void _list_update_by_install(char *pkg_type, const char *pkg_name, void *data)
430 {
431         MGR_APP_BEGIN();
432
433         ret_if(pkg_type == NULL);
434         ret_if(data == NULL);
435         struct ug_data *ugd = (struct ug_data*)data;
436
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;
439
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;
442
443
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));
448
449
450         /* AIL */
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);
458
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);
462                 return;
463         }
464
465         int i = 0;
466         Elm_Object_Item *item = elm_genlist_first_item_get(app_list_view_data->genlist);
467         if (!item) {
468                 elm_genlist_item_append(app_list_view_data->genlist, itc_sep_21, NULL, NULL, ELM_GENLIST_ITEM_NONE, NULL, NULL);
469         }
470         mgr_app_app_info_t *app_info = NULL;
471
472         for (i = 0; i < app_list_view_data->app_info_idx; i++) {
473
474                 app_info = (mgr_app_app_info_t*)elm_object_item_data_get(item);
475                 if (!app_info) {
476                         MGR_APP_DEBUG_ERR("app_info is null");
477                         MGR_APP_MEM_FREE(app_info_new);
478                         return;
479                 }
480
481                 int len = 0;
482                 len = (strlen(app_info_new->app_name) >= strlen(app_info->app_name)) ? strlen(app_info_new->app_name) : strlen(app_info->app_name);
483
484                 if (strncasecmp(app_info_new->app_name, app_info->app_name, len) < 0) {
485
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);
489
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]);
493                         if (!letter) {
494                                 MGR_APP_MEM_FREE(letter_new);
495                                 return;
496                         }
497
498                         /* the top of item */
499                         if (!prev_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);
503                                 } else {
504                                         /* B'-C, just add the index item */
505                                         __register_index_item(app_list_view_data->index, letter_new, new_item, EINA_FALSE);
506                                 }
507                         } else {
508
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);
512                                         return;
513                                 }
514
515                                 char *letter_prev = __convert_char_to_string(app_info_prev->app_name[0]);
516                                 if (!letter_prev) {
517                                         MGR_APP_MEM_FREE(letter);
518                                         return;
519                                 }
520
521                                 if (letter_prev[0] == letter_new[0]) {
522                                         /* B-B', nothing to do for index */
523
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);
527
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);
531                                 }
532                                 MGR_APP_MEM_FREE(letter_prev);
533                         }
534
535                         MGR_APP_MEM_FREE(letter_new);
536                         MGR_APP_MEM_FREE(letter);
537                         app_list_view_data->app_info_idx++;
538
539                         break;
540                 } else {
541                         item = elm_genlist_item_next_get(item);
542                         if (!item) {
543                                 MGR_APP_DEBUG_ERR("item is null");
544                                 MGR_APP_MEM_FREE(app_info_new);
545                                 return;
546                         }
547
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);
552
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);
555
556                                 __register_index_item(app_list_view_data->index, letter_new, new_item, EINA_FALSE);
557
558                                 MGR_APP_MEM_FREE(letter_new);
559                                 app_list_view_data->app_info_idx++;
560
561                                 break;
562                         }
563                 }
564         }
565
566         elm_genlist_realized_items_update(app_list_view_data->genlist);
567
568         MGR_APP_END();
569 }
570
571 static void _list_update_by_uninstall(char *pkg_type, const char *pkg_name, void *data)
572 {
573         MGR_APP_BEGIN();
574
575         ret_if(pkg_type == NULL);
576
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;
579
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;
582
583         int i = 0;
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;
589
590         for (i = 0; i < app_list_view_data->app_info_idx; i++) {
591
592                 app_info = (mgr_app_app_info_t*)elm_object_item_data_get(item);
593                 ret_if(app_info == NULL);
594
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);
597
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--;
604                         break;
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--;
612                                 break;
613                 } else {
614                         item = elm_genlist_item_next_get(item);
615                         ret_if(item == NULL);
616                 }
617         }
618
619         elm_genlist_realized_items_update(app_list_view_data->genlist);
620
621         MGR_APP_END();
622 }
623
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)
625 {
626         MGR_APP_BEGIN();
627
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;
632
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);
641                 } else {
642                         _list_update_by_install(pkg_type, pkg_name, (void*)ugd);
643                 }
644
645                 /* check the info view was opened */
646                 GList *view_list = mgr_app_view_get_viewlist(data);
647                 if (!view_list) {
648                         return -1;
649                 }
650
651                 GList *info_view = g_list_find(view_list, &mgr_app_view_app_info);
652                 if (info_view) {
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;
658                         }
659                 }
660         } else if (!strncmp(key, STR_END, strlen(key)) && !strncmp(val, STR_CANCEL, strlen(val))) {
661         } else {
662         }
663
664         MGR_APP_END();
665         /* the return value occured infinite loop */
666         /* package manager example has no return value */
667         // return 1;
668 }
669
670 static char *__convert_char_to_string(char ch)
671 {
672         MGR_APP_BEGIN();
673
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);
678
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);
685         } else {
686                 snprintf(str_buf, MAX_BUF_SIZE, "%s", "etc");
687         }
688
689         MGR_APP_END();
690         return str_buf;
691 }
692
693 static int _compare_index_item_letter_cb(const void *a, const void *b)
694 {
695         MGR_APP_BEGIN();
696
697         retv_if(a == NULL, -1);
698         retv_if(b == NULL, -1);
699
700         const Elm_Object_Item *it1 = (const Elm_Object_Item*)a;
701         const Elm_Object_Item *it2 = (const Elm_Object_Item*)b;
702
703         const char *letter1 = elm_index_item_letter_get(it1);
704         const char *letter2 = elm_index_item_letter_get(it2);
705
706         MGR_APP_DEBUG("letter1: %s, letter2: %s", letter1, letter2);
707
708         int len = 0;
709         len = (strlen(letter1) >= strlen(letter2)) ? strlen(letter1) : strlen(letter2);
710
711         MGR_APP_END();
712         return strncasecmp(letter1, letter2, len);
713 }
714
715 /**
716  *  _compare_data_index_item_letter_cb be used when _compare_index_item_letter_cb return 0.
717  */
718 static int _compare_data_index_item_letter_cb(const void *a, const void *b)
719 {
720         MGR_APP_BEGIN();
721
722         retv_if(a == NULL, -1);
723         retv_if(b == NULL, -1);
724
725         const Elm_Object_Item *it1 = (const Elm_Object_Item*)a;
726         const Elm_Object_Item *it2 = (const Elm_Object_Item*)b;
727
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);
730
731         MGR_APP_DEBUG("letter1: %s, letter2: %s", app_info1->app_name, app_info2->app_name);
732
733         MGR_APP_END();
734         return 0;
735 }
736
737 static void __register_index_item(Evas_Object *index, char *letter, Elm_Object_Item *item, Eina_Bool init)
738 {
739         MGR_APP_BEGIN();
740
741         MGR_APP_DEBUG("letter: %s", letter);
742
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;
745
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;
748
749         Elm_Object_Item *new_index_item = NULL;
750
751         if (!init) {
752                 Elm_Object_Item *temp_index_item        = NULL;
753                 Elm_Object_Item *temp_item              = NULL;
754                 const char              *temp_letter            = NULL;
755                 int i = 0;
756
757                 temp_item = elm_genlist_first_item_get(app_list_view_data->genlist);
758                 ret_if(temp_item == NULL);
759
760                 for (i = 0; i < app_list_view_data->app_info_idx; i++) {
761                         temp_index_item = elm_index_item_find(index, temp_item);
762
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);
767
768                                 if (letter[0] < temp_letter[0]) {
769                                         elm_index_item_prepend_relative(index, letter, item, temp_item);
770                                         break;
771                                 }
772                         }
773                         temp_item = elm_genlist_item_next_get(temp_item);
774                 }
775         } else {
776                 elm_index_item_append(index, letter, NULL, item);
777         }
778
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);
783
784         app_list_view_data->index_cnt++;
785
786         MGR_APP_END();
787 }
788
789 static void _index_del_item_cb(void *data, Evas_Object *obj, void *event_info)
790 {
791         MGR_APP_BEGIN();
792
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);
796
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;
799
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;
802
803         /* change the index item */
804         if (next_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);
807
808                 char *next_letter = __convert_char_to_string(next_app_info->app_name[0]);
809                 ret_if(next_letter == NULL);
810
811                 ret_if(event_info == NULL);
812                 Elm_Object_Item *index_item = (Elm_Object_Item*)event_info;
813
814                 const char *letter = elm_index_item_letter_get(index_item);
815                 ret_if(letter == NULL);
816
817                 Elm_Object_Item *prev_item = elm_genlist_item_prev_get(item);
818
819                 if (!prev_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);
823                         }
824                 } else {
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);
828                                 return;
829                         }
830
831                         char *prev_letter = __convert_char_to_string(prev_app_info->app_name[0]);
832                         if (!prev_letter) {
833                                 MGR_APP_MEM_FREE(next_letter);
834                                 return;
835                         }
836
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);
840
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);
844                         }
845
846                         MGR_APP_MEM_FREE(prev_letter);
847                 }
848                 MGR_APP_MEM_FREE(next_letter);
849         } else {
850                 /* A-B, del:B */
851                 MGR_APP_DEBUG("next_item is null");
852         }
853
854         app_list_view_data->index_cnt--;
855         MGR_APP_END();
856 }
857
858 static Evas_Object *__create_genlist_app_list(Evas_Object *parent, void *data)
859 {
860         MGR_APP_BEGIN();
861
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;
864
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;
867
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;
873
874
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);
880
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;
886
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;
892
893
894         /* Create index */
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);
899
900
901         /* add a genlist */
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);
912
913
914         app_list_view_data->genlist = genlist;
915         app_list_view_data->index = index;
916         app_list_view_data->index_cnt = 0;
917
918
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;
922
923         ail_filter_h filter_rpm = {0};
924         ail_filter_h filter_wrt = {0};
925         ail_filter_h filter_tpk = {0};
926
927         ail_filter_new(&filter_rpm);
928         ail_filter_new(&filter_wrt);
929         ail_filter_new(&filter_tpk);
930
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);
934
935         int appinfo_cnt_rpm = 0;
936         int appinfo_cnt_wrt = 0;
937         int appinfo_cnt_tpk = 0;
938         int appinfo_cnt_total = 0;
939
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);
943
944         appinfo_cnt_total = appinfo_cnt_rpm + appinfo_cnt_wrt + appinfo_cnt_tpk;
945
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);
952                 return NULL;
953         }
954         memset(app_info_list, 0, sizeof(mgr_app_app_info_t) * appinfo_cnt_total);
955         p_app_info_list = app_info_list;
956
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;
961
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);
965
966         ail_filter_destroy(filter_rpm);
967         ail_filter_destroy(filter_wrt);
968         ail_filter_destroy(filter_tpk);
969
970
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);
974
975
976         /* add genlist item order by ASC */
977         Elm_Object_Item *item = NULL;
978         char *letter = NULL;
979         char prev_letter[MAX_BUF_SIZE] = {0, };
980         int j = 0;
981
982         app_info_list = p_app_info_list;
983
984         for (j = 0; j < appinfo_cnt_total; j++) {
985
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);
990                         if (item_sep_21)
991                                 elm_genlist_item_select_mode_set(item_sep_21, ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY);
992                 }
993
994                 MGR_APP_DEBUG("%s", app_info_list->app_name);
995
996                 mgr_app_app_info_t *app_info = app_info_list;
997
998                 item = elm_genlist_item_append(genlist, itc, (void*)app_info, NULL, ELM_GENLIST_ITEM_NONE, _gl_sel, (void*)ugd);
999
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);
1005                 }
1006
1007                 MGR_APP_MEM_FREE(letter);
1008                 app_info_list = app_info_list + 1;
1009         }
1010
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);
1014
1015
1016         /* register pkg-mgr listener */
1017         int result = 0;
1018         retv_if(ugd->pc_listen == NULL, NULL);
1019         result = pkgmgr_client_listen_status(ugd->pc_listen, mgr_app_view_listen_cb, (void*)ugd);
1020         if (result < 0) {
1021                 MGR_APP_DEBUG_ERR("status listen failed!\n");
1022                 MGR_APP_MEM_FREE(genlist);
1023                 return NULL;
1024         }
1025
1026         MGR_APP_END();
1027         return genlist;
1028 }
1029
1030 static Evas_Object *mgr_app_view_app_list_create(void *data)
1031 {
1032         MGR_APP_BEGIN();
1033
1034         retv_if(data == NULL, NULL);
1035
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;
1038
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;
1042
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);
1045
1046         app_list_view_data->genlist = __create_genlist_app_list(app_list_view_data->layout, data);
1047
1048         MGR_APP_END();
1049         return app_list_view_data->layout;
1050 }
1051
1052 static Evas_Object *mgr_app_view_app_list_set_cbar(void *data)
1053 {
1054         MGR_APP_BEGIN();
1055         MGR_APP_END();
1056         return NULL;
1057 }
1058
1059 static mgr_app_result_e mgr_app_view_app_list_set_navibar(void *data)
1060 {
1061         MGR_APP_BEGIN();
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);
1063         MGR_APP_END();
1064         return MGR_APP_OK;
1065 }
1066
1067 static mgr_app_result_e mgr_app_view_app_list_destory(void *data)
1068 {
1069         MGR_APP_BEGIN();
1070
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;
1073
1074         MGR_APP_END();
1075         return MGR_APP_OK;
1076 }
1077 static mgr_app_result_e mgr_app_view_app_list_update(void *data)
1078 {
1079         MGR_APP_BEGIN();
1080
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;
1083
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;
1086
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;
1091         }
1092
1093         app_list_view_data->genlist = __create_genlist_app_list(app_list_view_data->layout, data);
1094
1095         MGR_APP_END();
1096         return MGR_APP_OK;
1097 }
1098 static mgr_app_result_e mgr_app_view_app_list_cleanup(void *data)
1099 {
1100         MGR_APP_BEGIN();
1101         MGR_APP_END();
1102         return MGR_APP_OK;
1103 }
1104
1105