show success/fail popup after uninstalling app
[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 #define STR_ERROR                       "error"
59 #define STR_FAIL                        "fail"
60 #define STR_POPUP_OK            "OK"
61
62 typedef struct _app_list_view_data_t app_list_view_data_t;
63
64 struct _app_list_view_data_t {
65         Evas_Object             *layout;
66         Evas_Object             *genlist;
67         Evas_Object                     *index;
68         int                                     index_cnt;
69         mgr_app_app_info_t      *app_info_list;
70         int                                     app_info_idx;
71         int                                     appinfo_cnt_total;
72         Eina_Bool                       initialize;
73 };
74
75 static Evas_Object *mgr_app_view_app_list_create(void *data);
76 static Evas_Object *mgr_app_view_app_list_set_cbar(void *data);
77 static mgr_app_result_e mgr_app_view_app_list_set_navibar(void *data);
78 static mgr_app_result_e mgr_app_view_app_list_destory(void *data);
79 static mgr_app_result_e mgr_app_view_app_list_update(void *data);
80 static mgr_app_result_e mgr_app_view_app_list_cleanup(void *data);
81
82 static Evas_Object *__create_genlist_app_list(Evas_Object *parent, void *data);
83 static char *__convert_char_to_string(char ch);
84 static void __register_index_item(Evas_Object *index, char *letter, Elm_Object_Item *item, Eina_Bool init);
85 static void _index_del_item_cb(void *data, Evas_Object *obj, void *event_info);
86
87
88 mgr_app_view_t mgr_app_view_app_list = {
89         .create         = mgr_app_view_app_list_create,
90         .setcbar        = mgr_app_view_app_list_set_cbar,
91         .setnavibar     = mgr_app_view_app_list_set_navibar,
92         .destroy        = mgr_app_view_app_list_destory,
93         .update         = mgr_app_view_app_list_update,
94 };
95
96 static Elm_Genlist_Item_Class *itc = NULL;
97 static Elm_Genlist_Item_Class *itc_sep_21 = NULL;
98
99
100 static void _app_list_next_cb(void *data, Evas_Object *obj, void *event_info)
101 {
102         MGR_APP_BEGIN();
103         mgr_app_view_create(&mgr_app_view_app_list, data);
104         MGR_APP_END();
105 }
106
107 static void _app_list_back_cb(void *data, Evas_Object *obj, void *event_info)
108 {
109         MGR_APP_BEGIN();
110         ret_if(data == NULL);
111         struct ug_data *ugd = (struct ug_data*)data;
112         mgr_app_view_common_back_cb(data, EINA_FALSE);
113
114         elm_genlist_item_class_free(itc);
115         elm_genlist_item_class_free(itc_sep_21);
116
117         /* bg must delete before starting on_destroy */
118         evas_object_del(ugd->bg);
119         ugd->bg = NULL;
120         ug_destroy_me(ugd->ug);
121         MGR_APP_END();
122 }
123
124 /* get the state of item */
125 static Eina_Bool _gl_state_get(void *data, Evas_Object *obj, const char *part)
126 {
127         MGR_APP_BEGIN();
128         MGR_APP_END();
129
130         return EINA_FALSE;
131 }
132
133 /* callback for 'deletion' */
134 static void _gl_del(void *data, Evas_Object *obj)
135 {
136         MGR_APP_BEGIN();
137
138         ret_if(data == NULL);
139         mgr_app_app_info_t *app_info = (mgr_app_app_info_t*)data;
140
141         MGR_APP_MEM_FREE(app_info->pkg_name);
142         MGR_APP_MEM_FREE(app_info->app_name);
143         MGR_APP_MEM_FREE(app_info->pkg_type);
144         MGR_APP_MEM_FREE(app_info->icon_path);
145         //MGR_APP_MEM_FREE(app_info);
146         MGR_APP_END();
147
148         return;
149 }
150
151 /* callback for 'selection' */
152 static void _gl_sel(void *data, Evas_Object *obj, void *event_info)
153 {
154         MGR_APP_BEGIN();
155
156         ret_if(data == NULL);
157         ret_if(event_info == NULL);
158
159         struct ug_data *ugd = (struct ug_data*)data;
160         Elm_Object_Item *item = (Elm_Object_Item *)event_info;
161
162         mgr_app_app_info_t *app_info = (mgr_app_app_info_t*)elm_object_item_data_get(item);
163         ret_if(app_info == NULL);
164
165         elm_genlist_item_selected_set(item, 0);
166
167         /* create app info view */
168         ugd->data = (void*)app_info;
169         mgr_app_view_create(&mgr_app_view_app_info, (void*)ugd);
170
171         MGR_APP_END();
172 }
173
174 static char *_gl_label_get(void *data, Evas_Object *obj, const char *part)
175 {
176         MGR_APP_BEGIN();
177
178         retv_if(data == NULL, NULL);
179         mgr_app_app_info_t *app_info = (mgr_app_app_info_t*)data;
180
181         char *label             = NULL;
182         char *package_name = app_info->pkg_name;
183         char *app_name  = app_info->app_name;
184         char *icon_path         = app_info->icon_path;
185         char *pkg_type          = app_info->pkg_type;
186
187         MGR_APP_DEBUG("package_name:[%s], app_name:[%s], x_slp_packagetype:[%s], icon_path:[%s]\n", package_name, app_name, pkg_type, icon_path);
188         MGR_APP_DEBUG("part:%s\n", part);
189
190         /* label for 'elm.text' part */
191         if (app_name && !strncmp(part, ELM_TEXT, strlen(ELM_TEXT))) {
192                 MGR_APP_MEM_STRDUP(label, app_name);
193         } else {
194                 MGR_APP_MEM_STRDUP(label, dgettext("sys_string", "IDS_COM_POP_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_icon_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 int _app_list_qsort_cb(const void *a, const void *b)
256 {
257         MGR_APP_BEGIN();
258
259         if (!a) {
260                 MGR_APP_DEBUG_ERR("a is null");
261                 return 0;
262         } else if (!b) {
263                 MGR_APP_DEBUG_ERR("b is null");
264                 return 0;
265         }
266
267         mgr_app_app_info_t *app_info1 = (mgr_app_app_info_t*)a;
268         mgr_app_app_info_t *app_info2 = (mgr_app_app_info_t*)b;
269
270         if (!app_info1->app_name) {
271                 MGR_APP_DEBUG_ERR("app_info1->app_name is null");
272                 return 0;
273         }
274
275         if (!app_info2->app_name) {
276                 MGR_APP_DEBUG_ERR("app_info2->app_name is null");
277                 return 0;
278         }
279
280         int len = 0;
281         len = (strlen(app_info1->app_name) >= strlen(app_info2->app_name)) ? strlen(app_info1->app_name) : strlen(app_info2->app_name);
282
283         MGR_APP_END();
284         return strncasecmp(app_info1->app_name, app_info2->app_name, len);
285 }
286
287 static ail_cb_ret_e _appinfo_func_cb(const ail_appinfo_h ail_info, void *user_data)
288 {
289         MGR_APP_BEGIN();
290
291         retv_if(mgr_app_view_app_list.view_common_data == NULL, AIL_CB_RET_CONTINUE);
292         mgr_app_view_common_data_t *view_common_data = mgr_app_view_app_list.view_common_data;
293
294         retv_if(view_common_data->user_view_data == NULL, AIL_CB_RET_CONTINUE);
295         app_list_view_data_t *app_list_view_data = view_common_data->user_view_data;
296
297         retv_if(user_data == NULL, AIL_CB_RET_CONTINUE);
298         mgr_app_app_info_t *p_app_info_list = (mgr_app_app_info_t *)user_data;
299
300         if (app_list_view_data->initialize) {
301                 p_app_info_list = p_app_info_list + app_list_view_data->app_info_idx++;
302         }
303
304         char *package_name              = NULL;
305         char *app_name          = NULL;
306         char *icon_path                 = NULL;
307         char *x_slp_packagetype = NULL;
308         bool nodisplay                  = EINA_FALSE;
309         bool removable                  = EINA_FALSE;
310         bool taskmanage                 = EINA_FALSE;
311
312         ail_appinfo_get_str(ail_info, AIL_PROP_PACKAGE_STR, &package_name);
313         if (!package_name) {
314                 MGR_APP_DEBUG_ERR(">>> get package_name failed");
315                 return AIL_CB_RET_CONTINUE;
316         }
317         ail_appinfo_get_str(ail_info, AIL_PROP_NAME_STR, &app_name);
318         if (!app_name) {
319                 MGR_APP_DEBUG_ERR(">>> get app_name failed");
320                 return AIL_CB_RET_CONTINUE;
321         }
322         ail_appinfo_get_str(ail_info, AIL_PROP_ICON_STR, &icon_path);
323         ail_appinfo_get_str(ail_info, AIL_PROP_X_SLP_PACKAGETYPE_STR, &x_slp_packagetype);
324         ail_appinfo_get_bool(ail_info, AIL_PROP_NODISPLAY_BOOL, &nodisplay);
325         ail_appinfo_get_bool(ail_info, AIL_PROP_X_SLP_REMOVABLE_BOOL , &removable);
326         ail_appinfo_get_bool(ail_info, AIL_PROP_X_SLP_TASKMANAGE_BOOL , &taskmanage);
327
328
329         /* setting icon path */
330         FILE *stream = NULL;
331         char *p = NULL;
332         if (icon_path) {
333                 /* TODO - avoid the slow-down change effect due to edj icon */
334                 if (((p = strrchr(icon_path, '.'))) && (!strcasecmp(p, ".edj"))) {
335                         icon_path = DEFAULT_ICON_FILE;
336                 } else if ((stream = fopen(icon_path, "r")) != NULL && strlen(icon_path) > strlen(STR_PNG)) {
337                         fclose(stream);
338                         stream = NULL;
339
340                         char *p_extension = NULL;
341                         p_extension = icon_path + (strlen(icon_path) - strlen(STR_PNG));
342
343                         /* default icon : icon_path's extension is wrong */
344                         if (strncmp(p_extension, STR_PNG, strlen(STR_PNG)) != 0 && strncmp(p_extension, STR_EDJ, strlen(STR_EDJ)) != 0) {
345                                 icon_path = DEFAULT_ICON_FILE;
346                         }
347                 /* default icon : icon_path isn't exist */
348                 } else {
349                         icon_path = DEFAULT_ICON_FILE;
350                         if (stream) {
351                                 fclose(stream);
352                                 stream = NULL;
353                         }
354                 }
355         /* default icon : icon_path == NULL */
356         } else {
357                 icon_path = DEFAULT_ICON_FILE;
358         }
359
360         MGR_APP_MEM_STRDUP(p_app_info_list->pkg_name, package_name);
361         MGR_APP_MEM_STRDUP(p_app_info_list->app_name, app_name);
362         MGR_APP_MEM_STRDUP(p_app_info_list->icon_path, icon_path);
363         MGR_APP_MEM_STRDUP(p_app_info_list->pkg_type, x_slp_packagetype);
364         p_app_info_list->nodisplay = nodisplay;
365         p_app_info_list->removable = removable;
366         p_app_info_list->taskmanage = taskmanage;
367
368         MGR_APP_DEBUG("package_name: %s ", package_name);
369         MGR_APP_DEBUG("app_name: %s", app_name);
370         MGR_APP_DEBUG("icon_path: %s", icon_path);
371         MGR_APP_DEBUG("x_slp_packagetype: %s ", x_slp_packagetype);
372         MGR_APP_DEBUG("nodisplay: %d", nodisplay);
373         MGR_APP_DEBUG("removable: %d", removable);
374         MGR_APP_DEBUG("taskmanage: %d", taskmanage);
375
376         MGR_APP_END();
377         return AIL_CB_RET_CONTINUE;
378 }
379
380 static void _response_cb(void *data, Evas_Object *obj, void *event_info)
381 {
382         MGR_APP_BEGIN();
383
384         evas_object_del(data);
385
386         MGR_APP_END();
387 }
388
389 static void _notify_by_uninstall(void *data)
390 {
391         MGR_APP_BEGIN();
392
393         ret_if(data == NULL);
394         struct ug_data *ugd = (struct ug_data*)data;
395
396         Evas_Object *noti = elm_notify_add(ugd->navi_bar);
397         elm_notify_orient_set(noti, ELM_NOTIFY_ORIENT_BOTTOM);
398
399         Evas_Object *layout = elm_layout_add(noti);
400         elm_layout_theme_set(layout, "standard", "selectioninfo", "vertical/bottom_12");
401
402         elm_object_content_set(noti, layout);
403         elm_notify_timeout_set(noti, 2);
404         edje_object_part_text_set(_EDJ(layout), ELM_TEXT, dgettext(PACKAGE, "IDS_ST_POP_UNINSTALLED"));
405         evas_object_show(noti);
406
407         MGR_APP_END();
408 }
409
410 static void _list_update_by_install(char *pkg_type, const char *pkg_name, void *data)
411 {
412         MGR_APP_BEGIN();
413
414         ret_if(pkg_type == NULL);
415         ret_if(data == NULL);
416         struct ug_data *ugd = (struct ug_data*)data;
417
418         ret_if(mgr_app_view_app_list.view_common_data == NULL);
419         mgr_app_view_common_data_t *view_common_data = mgr_app_view_app_list.view_common_data;
420
421         ret_if(view_common_data->user_view_data == NULL);
422         app_list_view_data_t *app_list_view_data = view_common_data->user_view_data;
423
424
425         /* create app info data */
426         mgr_app_app_info_t *app_info_new = (mgr_app_app_info_t*)malloc(sizeof(mgr_app_app_info_t));
427         ret_if(app_info_new == NULL);
428         memset(app_info_new, 0, sizeof(mgr_app_app_info_t));
429
430
431         /* AIL */
432         ail_filter_h filter = {0};
433         ail_filter_new(&filter);
434         ail_filter_add_str(filter, AIL_PROP_X_SLP_PACKAGETYPE_STR, pkg_type);
435         ail_filter_add_str(filter, AIL_PROP_PACKAGE_STR, pkg_name);
436         app_list_view_data->initialize = EINA_FALSE;
437         ail_filter_list_appinfo_foreach(filter, _appinfo_func_cb, (void*)app_info_new);
438         ail_filter_destroy(filter);
439
440         if (!app_info_new->app_name) {
441                 MGR_APP_DEBUG_ERR("app_info_new->app_name is null");
442                 MGR_APP_MEM_FREE(app_info_new);
443                 return;
444         }
445
446         int i = 0;
447         Elm_Object_Item *item = elm_genlist_first_item_get(app_list_view_data->genlist);
448         if (!item) {
449                 elm_genlist_item_append(app_list_view_data->genlist, itc_sep_21, NULL, NULL, ELM_GENLIST_ITEM_NONE, NULL, NULL);
450         }
451         mgr_app_app_info_t *app_info = NULL;
452
453         for (i = 0; i < app_list_view_data->app_info_idx; i++) {
454
455                 app_info = (mgr_app_app_info_t*)elm_object_item_data_get(item);
456                 if (!app_info) {
457                         MGR_APP_DEBUG_ERR("app_info is null");
458                         MGR_APP_MEM_FREE(app_info_new);
459                         return;
460                 }
461
462                 int len = 0;
463                 len = (strlen(app_info_new->app_name) >= strlen(app_info->app_name)) ? strlen(app_info_new->app_name) : strlen(app_info->app_name);
464
465                 if (strncasecmp(app_info_new->app_name, app_info->app_name, len) < 0) {
466
467                         Elm_Object_Item *prev_item = elm_genlist_item_prev_get(item);
468                         Elm_Object_Item *new_item = elm_genlist_item_insert_before(app_list_view_data->genlist, itc, (void*)app_info_new, NULL, item, ELM_GENLIST_ITEM_NONE, _gl_sel, (void*)ugd);
469                         ret_if(new_item == NULL);
470
471                         char *letter_new = __convert_char_to_string(app_info_new->app_name[0]);
472                         ret_if(letter_new == NULL);
473                         char *letter = __convert_char_to_string(app_info->app_name[0]);
474                         if (!letter) {
475                                 MGR_APP_MEM_FREE(letter_new);
476                                 return;
477                         }
478
479                         /* the top of item */
480                         if (!prev_item) {
481                                 if (letter_new[0] == letter[0]) {
482                                         /* B'-B, index item must be replaced from B to B' */
483                                         elm_object_item_del(item);
484                                 } else {
485                                         /* B'-C, just add the index item */
486                                         __register_index_item(app_list_view_data->index, letter_new, new_item, EINA_FALSE);
487                                 }
488                         } else {
489
490                                 mgr_app_app_info_t *app_info_prev = elm_object_item_data_get(prev_item);
491                                 if (!app_info_prev) {
492                                         MGR_APP_MEM_FREE(letter);
493                                         return;
494                                 }
495
496                                 char *letter_prev = __convert_char_to_string(app_info_prev->app_name[0]);
497                                 if (!letter_prev) {
498                                         MGR_APP_MEM_FREE(letter);
499                                         return;
500                                 }
501
502                                 if (letter_prev[0] == letter_new[0]) {
503                                         /* B-B', nothing to do for index */
504
505                                 } else if (letter_prev[0] < letter_new[0] && letter_new[0] < letter[0]) {
506                                         /* A-B'-C, B' must be inserted to index */
507                                         __register_index_item(app_list_view_data->index, letter_new, new_item, EINA_FALSE);
508
509                                 } else if (letter_prev[0] < letter_new[0] && letter_new[0] == letter[0]) {
510                                         /* A-B'-B, index item must be replaced from B to B' */
511                                         elm_object_item_del(item);
512                                 }
513                                 MGR_APP_MEM_FREE(letter_prev);
514                         }
515
516                         MGR_APP_MEM_FREE(letter_new);
517                         MGR_APP_MEM_FREE(letter);
518                         app_list_view_data->app_info_idx++;
519
520                         break;
521                 } else {
522                         item = elm_genlist_item_next_get(item);
523                         if (!item) {
524                                 MGR_APP_DEBUG_ERR("item is null");
525                                 MGR_APP_MEM_FREE(app_info_new);
526                                 return;
527                         }
528
529                         /* check the item and append after last item */
530                         if (item == elm_genlist_last_item_get(app_list_view_data->genlist)) {
531                                 char *letter_new = __convert_char_to_string(app_info_new->app_name[0]);
532                                 ret_if(letter_new == NULL);
533
534                                 Elm_Object_Item *new_item = elm_genlist_item_append(app_list_view_data->genlist, itc, (void*)app_info_new, NULL, ELM_GENLIST_ITEM_NONE, _gl_sel, (void*)ugd);
535                                 ret_if(new_item == NULL);
536
537                                 __register_index_item(app_list_view_data->index, letter_new, new_item, EINA_FALSE);
538
539                                 MGR_APP_MEM_FREE(letter_new);
540                                 app_list_view_data->app_info_idx++;
541
542                                 break;
543                         }
544                 }
545         }
546
547         elm_genlist_realized_items_update(app_list_view_data->genlist);
548
549         MGR_APP_END();
550 }
551
552 static void _list_update_by_uninstall(char *pkg_type, const char *pkg_name, void *data)
553 {
554         MGR_APP_BEGIN();
555
556         ret_if(pkg_type == NULL);
557
558         ret_if(mgr_app_view_app_list.view_common_data == NULL);
559         mgr_app_view_common_data_t *view_common_data = mgr_app_view_app_list.view_common_data;
560
561         ret_if(view_common_data->user_view_data == NULL);
562         app_list_view_data_t *app_list_view_data = view_common_data->user_view_data;
563
564         int i = 0;
565         Elm_Object_Item *item = elm_genlist_first_item_get(app_list_view_data->genlist);
566         ret_if(item == NULL);
567         item = elm_genlist_item_next_get(item);
568         ret_if(item == NULL);
569         mgr_app_app_info_t *app_info = NULL;
570
571         for (i = 0; i < app_list_view_data->app_info_idx; i++) {
572
573                 app_info = (mgr_app_app_info_t*)elm_object_item_data_get(item);
574                 ret_if(app_info == NULL);
575
576                 MGR_APP_DEBUG("pkg_type: %s, %s", pkg_type, app_info->pkg_type);
577                 MGR_APP_DEBUG("pkg_name: %s, %s", pkg_name, app_info->pkg_name);
578
579                 if (!strncmp(pkg_type, app_info->pkg_type, strlen(pkg_type)) && !strncmp(pkg_name, app_info->pkg_name, strlen(pkg_name))) {
580                         Elm_Object_Item *idx_item = elm_index_item_find(app_list_view_data->index, item);
581                         elm_object_item_del(idx_item);
582                         elm_object_item_del(item);
583                         MGR_APP_DEBUG("deleted");
584                         app_list_view_data->app_info_idx--;
585                         break;
586                 /* temporary code - tpk backend should be passed full pkg name */
587                 } else if (0 == strcmp(pkg_type, TPK_PREFIX) && strstr(app_info->pkg_name, pkg_name)) {
588                                 Elm_Object_Item *idx_item = elm_index_item_find(app_list_view_data->index, item);
589                                 elm_object_item_del(idx_item);
590                                 elm_object_item_del(item);
591                                 MGR_APP_DEBUG("deleted");
592                                 app_list_view_data->app_info_idx--;
593                                 break;
594                 } else {
595                         item = elm_genlist_item_next_get(item);
596                         ret_if(item == NULL);
597                 }
598         }
599
600         elm_genlist_realized_items_update(app_list_view_data->genlist);
601
602         MGR_APP_END();
603 }
604
605 int mgr_app_view_listen_cb(int req_id, const char *pkg_type, const char *pkg_name, const char *key, const char *val, const void *pmsg, void *data)
606 {
607         MGR_APP_BEGIN();
608
609         MGR_APP_DEBUG("key:%s val:%s", key, val);
610         MGR_APP_DEBUG("pkg_type:%s pkg_name:%s", pkg_type, pkg_name);
611         retv_if(data == NULL, -1);
612         struct ug_data *ugd = (struct ug_data*)data;
613
614         if (!strncmp(key, STR_START, strlen(key)) && !strncmp(val, STR_UNINSTALL, strlen(val))) {
615                 ugd->uninstall = EINA_TRUE;
616         } else if (!strncmp(key, STR_START, strlen(key)) && !strncmp(val, STR_INSTALL, strlen(val))) {
617                 ugd->uninstall = EINA_FALSE;
618         } else if (!strncmp(key, STR_ERROR, strlen(key))) {
619         } else if (!strncmp(key, STR_END, strlen(key)) && !strncmp(val, STR_FAIL, strlen(val))) {
620                 mgr_app_destroy_popup_progressbar();
621                 mgr_app_create_popup_text_1button(ugd->win_main, "Uninstall failed", STR_POPUP_OK, _response_cb);
622         } else if (!strncmp(key, STR_END, strlen(key)) && !strncmp(val, STR_OK, strlen(val))) {
623                 if (ugd->uninstall) {
624                         mgr_app_destroy_popup_progressbar();
625                         mgr_app_create_popup_text_1button(ugd->win_main, "Uninstall complete", STR_POPUP_OK, _response_cb);
626                         _list_update_by_uninstall(pkg_type, pkg_name, (void*)ugd);
627                 } else {
628                         _list_update_by_install(pkg_type, pkg_name, (void*)ugd);
629                 }
630
631                 /* check the info view was opened */
632                 GList *view_list = mgr_app_view_get_viewlist(data);
633                 if (!view_list) {
634                         return -1;
635                 }
636
637                 GList *info_view = g_list_find(view_list, &mgr_app_view_app_info);
638                 if (info_view) {
639                         struct ug_data *ugd = (struct ug_data*)data;
640                         if (ugd->uninstall) {
641                                 _app_info_back_cb(data, NULL, NULL);
642                                 _notify_by_uninstall((void*)ugd);
643                                 ugd->uninstall = EINA_FALSE;
644                         }
645                 }
646         } else if (!strncmp(key, STR_END, strlen(key)) && !strncmp(val, STR_CANCEL, strlen(val))) {
647         } else {
648         }
649
650         MGR_APP_END();
651         /* the return value occured infinite loop */
652         /* package manager example has no return value */
653         // return 1;
654 }
655
656 static char *__convert_char_to_string(char ch)
657 {
658         MGR_APP_BEGIN();
659
660         char *str_buf = NULL;
661         str_buf = (char*)malloc(sizeof(char)*MAX_BUF_SIZE);
662         retv_if(str_buf == NULL, NULL);
663         memset(str_buf, 0, sizeof(char)*MAX_BUF_SIZE);
664
665         if (ch >= 'A' && ch <= 'Z') {
666                 snprintf(str_buf, MAX_BUF_SIZE, "%c", ch);
667         } else if (ch >= 'a' && ch <= 'z') {
668                 snprintf(str_buf, MAX_BUF_SIZE, "%c", ch - 'a' + 'A');
669         } else if (ch >= '0' && ch <= '9') {
670                 snprintf(str_buf, MAX_BUF_SIZE, "%c", ch);
671         } else {
672                 snprintf(str_buf, MAX_BUF_SIZE, "%s", "etc");
673         }
674
675         MGR_APP_END();
676         return str_buf;
677 }
678
679 static int _compare_index_item_letter_cb(const void *a, const void *b)
680 {
681         MGR_APP_BEGIN();
682
683         retv_if(a == NULL, -1);
684         retv_if(b == NULL, -1);
685
686         const Elm_Object_Item *it1 = (const Elm_Object_Item*)a;
687         const Elm_Object_Item *it2 = (const Elm_Object_Item*)b;
688
689         const char *letter1 = elm_index_item_letter_get(it1);
690         const char *letter2 = elm_index_item_letter_get(it2);
691
692         MGR_APP_DEBUG("letter1: %s, letter2: %s", letter1, letter2);
693
694         int len = 0;
695         len = (strlen(letter1) >= strlen(letter2)) ? strlen(letter1) : strlen(letter2);
696
697         MGR_APP_END();
698         return strncasecmp(letter1, letter2, len);
699 }
700
701 /**
702  *  _compare_data_index_item_letter_cb be used when _compare_index_item_letter_cb return 0.
703  */
704 static int _compare_data_index_item_letter_cb(const void *a, const void *b)
705 {
706         MGR_APP_BEGIN();
707
708         retv_if(a == NULL, -1);
709         retv_if(b == NULL, -1);
710
711         const Elm_Object_Item *it1 = (const Elm_Object_Item*)a;
712         const Elm_Object_Item *it2 = (const Elm_Object_Item*)b;
713
714         mgr_app_app_info_t *app_info1 = elm_object_item_data_get(it1);
715         mgr_app_app_info_t *app_info2 = elm_object_item_data_get(it2);
716
717         MGR_APP_DEBUG("letter1: %s, letter2: %s", app_info1->app_name, app_info2->app_name);
718
719         MGR_APP_END();
720         return 0;
721 }
722
723 static void __register_index_item(Evas_Object *index, char *letter, Elm_Object_Item *item, Eina_Bool init)
724 {
725         MGR_APP_BEGIN();
726
727         MGR_APP_DEBUG("letter: %s", letter);
728
729         ret_if(mgr_app_view_app_list.view_common_data == NULL);
730         mgr_app_view_common_data_t *view_common_data = mgr_app_view_app_list.view_common_data;
731
732         ret_if(view_common_data->user_view_data == NULL);
733         app_list_view_data_t *app_list_view_data = view_common_data->user_view_data;
734
735         Elm_Object_Item *new_index_item = NULL;
736
737         if (!init) {
738                 Elm_Object_Item *temp_index_item        = NULL;
739                 Elm_Object_Item *temp_item              = NULL;
740                 const char              *temp_letter            = NULL;
741                 int i = 0;
742
743                 temp_item = elm_genlist_first_item_get(app_list_view_data->genlist);
744                 ret_if(temp_item == NULL);
745
746                 for (i = 0; i < app_list_view_data->app_info_idx; i++) {
747                         temp_index_item = elm_index_item_find(index, temp_item);
748
749                         /* indexed genlist item */
750                         if (temp_index_item) {
751                                 temp_letter = elm_index_item_letter_get(temp_index_item);
752                                 ret_if(temp_letter == NULL);
753
754                                 if (letter[0] < temp_letter[0]) {
755                                         elm_index_item_prepend_relative(index, letter, item, temp_item);
756                                         break;
757                                 }
758                         }
759                         temp_item = elm_genlist_item_next_get(temp_item);
760                 }
761         } else {
762                 elm_index_item_append(index, letter, NULL, item);
763         }
764
765         new_index_item = elm_index_item_find(index, item);
766         ret_if(new_index_item == NULL);
767         elm_object_item_del_cb_set(new_index_item, _index_del_item_cb);
768         elm_object_item_data_set(new_index_item, (void*)item);
769
770         app_list_view_data->index_cnt++;
771
772         MGR_APP_END();
773 }
774
775 static void _index_del_item_cb(void *data, Evas_Object *obj, void *event_info)
776 {
777         MGR_APP_BEGIN();
778
779         ret_if(data == NULL);
780         Elm_Object_Item *item = (Elm_Object_Item*)data;
781         Elm_Object_Item *next_item = elm_genlist_item_next_get(item);
782
783         ret_if(mgr_app_view_app_list.view_common_data == NULL);
784         mgr_app_view_common_data_t *view_common_data = mgr_app_view_app_list.view_common_data;
785
786         ret_if(view_common_data->user_view_data == NULL);
787         app_list_view_data_t *app_list_view_data = view_common_data->user_view_data;
788
789         /* change the index item */
790         if (next_item) {
791                 mgr_app_app_info_t *next_app_info = (mgr_app_app_info_t*)elm_object_item_data_get(next_item);
792                 ret_if(next_app_info == NULL);
793
794                 char *next_letter = __convert_char_to_string(next_app_info->app_name[0]);
795                 ret_if(next_letter == NULL);
796
797                 ret_if(event_info == NULL);
798                 Elm_Object_Item *index_item = (Elm_Object_Item*)event_info;
799
800                 const char *letter = elm_index_item_letter_get(index_item);
801                 ret_if(letter == NULL);
802
803                 Elm_Object_Item *prev_item = elm_genlist_item_prev_get(item);
804
805                 if (!prev_item) {
806                         /* case: B-B', del:B */
807                         if (letter[0] == next_letter[0]) {
808                                 __register_index_item(app_list_view_data->index, next_letter, next_item, EINA_FALSE);
809                         }
810                 } else {
811                         mgr_app_app_info_t *prev_app_info = (mgr_app_app_info_t*)elm_object_item_data_get(prev_item);
812                         if (!prev_app_info) {
813                                 MGR_APP_MEM_FREE(next_letter);
814                                 return;
815                         }
816
817                         char *prev_letter = __convert_char_to_string(prev_app_info->app_name[0]);
818                         if (!prev_letter) {
819                                 MGR_APP_MEM_FREE(next_letter);
820                                 return;
821                         }
822
823                         /* case: A-B'-B-B'', del:B */
824                         if (letter[0] == prev_letter[0]) {
825                                 __register_index_item(app_list_view_data->index, prev_letter, prev_item, EINA_FALSE);
826
827                         /* case: A-B-B'-B'', del:B */
828                         } else if (letter[0] == next_letter[0]) {
829                                 __register_index_item(app_list_view_data->index, next_letter, next_item, EINA_FALSE);
830                         }
831
832                         MGR_APP_MEM_FREE(prev_letter);
833                 }
834                 MGR_APP_MEM_FREE(next_letter);
835         } else {
836                 /* A-B, del:B */
837                 MGR_APP_DEBUG("next_item is null");
838         }
839
840         app_list_view_data->index_cnt--;
841         MGR_APP_END();
842 }
843
844 static Evas_Object *__create_genlist_app_list(Evas_Object *parent, void *data)
845 {
846         MGR_APP_BEGIN();
847
848         retv_if(mgr_app_view_app_list.view_common_data == NULL, NULL);
849         mgr_app_view_common_data_t *view_common_data = mgr_app_view_app_list.view_common_data;
850
851         retv_if(view_common_data->user_view_data == NULL, NULL);
852         app_list_view_data_t *app_list_view_data = view_common_data->user_view_data;
853
854         retv_if(data == NULL, NULL);
855         struct ug_data  *ugd = (struct ug_data*)data;
856         Evas_Object             *genlist        = NULL;
857         Evas_Object     *index          = NULL;
858         Elm_Object_Item *item_sep_21    = NULL;
859
860
861         /* set the genlist item style */
862         itc = elm_genlist_item_class_new();
863         retv_if(itc == NULL, NULL);
864 \r       itc_sep_21 = elm_genlist_item_class_new();
865         retv_if(itc_sep_21 == NULL, NULL);
866
867         itc->item_style         = ITC_ITEM_STYLE;
868         itc->func.text_get      = _gl_label_get;
869         itc->func.content_get   = _gl_icon_get;
870         itc->func.state_get = NULL;
871         itc->func.del           = _gl_del;
872
873         itc_sep_21->item_style          = ITC_SEP_21_ITEM_STYLE;
874         itc_sep_21->func.text_get       = NULL;
875         itc_sep_21->func.content_get= NULL;
876         itc_sep_21->func.state_get      = NULL;
877         itc_sep_21->func.del            = NULL;
878
879
880         /* Create index */
881         index = elm_index_add(parent);
882         retv_if(index == NULL, NULL);
883         elm_object_part_content_set(parent, "elm.swallow.content.index", index);
884         evas_object_show(index);
885
886
887         /* add a genlist */
888         genlist = elm_genlist_add(parent);
889         retv_if(genlist == NULL, NULL);
890         elm_object_part_content_set(parent, "elm.swallow.content.genlist", genlist);
891         evas_object_size_hint_weight_set(genlist, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
892         evas_object_size_hint_align_set(genlist, EVAS_HINT_FILL, EVAS_HINT_FILL);
893         elm_genlist_mode_set(genlist, ELM_LIST_COMPRESS);
894         elm_genlist_block_count_set(genlist, GENLIST_BLOCK_CNT);
895         elm_genlist_scroller_policy_set(genlist, ELM_SCROLLER_POLICY_OFF, ELM_SCROLLER_POLICY_OFF);
896         elm_object_style_set(genlist, "dialogue");
897         evas_object_show(genlist);
898
899
900         app_list_view_data->genlist = genlist;
901         app_list_view_data->index = index;
902         app_list_view_data->index_cnt = 0;
903
904
905         /* get app_info from AIL */
906         mgr_app_app_info_t *app_info_list = NULL;
907         mgr_app_app_info_t *p_app_info_list = NULL;
908
909         ail_filter_h filter_rpm = {0};
910         ail_filter_h filter_wrt = {0};
911         ail_filter_h filter_tpk = {0};
912
913         ail_filter_new(&filter_rpm);
914         ail_filter_new(&filter_wrt);
915         ail_filter_new(&filter_tpk);
916
917         ail_filter_add_str(filter_rpm, AIL_PROP_X_SLP_PACKAGETYPE_STR, RPM_PREFIX);
918         ail_filter_add_str(filter_wrt, AIL_PROP_X_SLP_PACKAGETYPE_STR, WRT_PREFIX);
919         ail_filter_add_str(filter_tpk, AIL_PROP_X_SLP_PACKAGETYPE_STR, TPK_PREFIX);
920
921         int appinfo_cnt_rpm = 0;
922         int appinfo_cnt_wrt = 0;
923         int appinfo_cnt_tpk = 0;
924         int appinfo_cnt_total = 0;
925
926         ail_filter_count_appinfo(filter_rpm, &appinfo_cnt_rpm);
927         ail_filter_count_appinfo(filter_wrt, &appinfo_cnt_wrt);
928         ail_filter_count_appinfo(filter_tpk, &appinfo_cnt_tpk);
929
930         appinfo_cnt_total = appinfo_cnt_rpm + appinfo_cnt_wrt + appinfo_cnt_tpk;
931
932         app_info_list = (mgr_app_app_info_t*)malloc(sizeof(mgr_app_app_info_t) * appinfo_cnt_total);
933         if (!app_info_list) {
934                 MGR_APP_DEBUG_ERR("app_info_list allocation failed");
935                 ail_filter_destroy(filter_rpm);
936                 ail_filter_destroy(filter_wrt);
937                 ail_filter_destroy(filter_tpk);
938                 return NULL;
939         }
940         memset(app_info_list, 0, sizeof(mgr_app_app_info_t) * appinfo_cnt_total);
941         p_app_info_list = app_info_list;
942
943         app_list_view_data->app_info_idx = 0;
944         app_list_view_data->app_info_list = app_info_list;
945         app_list_view_data->appinfo_cnt_total = appinfo_cnt_total;
946         app_list_view_data->initialize = EINA_TRUE;
947
948         ail_filter_list_appinfo_foreach(filter_rpm, _appinfo_func_cb, (void*)app_info_list);
949         ail_filter_list_appinfo_foreach(filter_wrt, _appinfo_func_cb, (void*)app_info_list);
950         ail_filter_list_appinfo_foreach(filter_tpk, _appinfo_func_cb, (void*)app_info_list);
951
952         ail_filter_destroy(filter_rpm);
953         ail_filter_destroy(filter_wrt);
954         ail_filter_destroy(filter_tpk);
955
956
957         /* sorting by app_name */
958         app_info_list = p_app_info_list;
959         qsort(app_info_list, appinfo_cnt_total, sizeof(mgr_app_app_info_t), _app_list_qsort_cb);
960
961
962         /* add genlist item order by ASC */
963         Elm_Object_Item *item = NULL;
964         char *letter = NULL;
965         char prev_letter[MAX_BUF_SIZE] = {0, };
966         int j = 0;
967
968         app_info_list = p_app_info_list;
969
970         for (j = 0; j < appinfo_cnt_total; j++) {
971
972                 /* add the space to top of the dialogue */
973                 if (app_list_view_data->initialize && elm_genlist_first_item_get(genlist)) {
974                         app_list_view_data->initialize = EINA_FALSE;
975                         item_sep_21 = elm_genlist_item_prepend(genlist, itc_sep_21, NULL, NULL, ELM_GENLIST_ITEM_NONE, NULL, NULL);
976                         if (item_sep_21)
977                                 elm_genlist_item_select_mode_set(item_sep_21, ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY);
978                 }
979
980                 MGR_APP_DEBUG("%s", app_info_list->app_name);
981
982                 mgr_app_app_info_t *app_info = app_info_list;
983
984                 item = elm_genlist_item_append(genlist, itc, (void*)app_info, NULL, ELM_GENLIST_ITEM_NONE, _gl_sel, (void*)ugd);
985
986                 /* fast scroll insertion */
987                 letter = __convert_char_to_string(app_info_list->app_name[0]);
988                 if (item && strncmp(letter, prev_letter, MAX_BUF_SIZE) != 0) {
989                         __register_index_item(index, letter, item, EINA_TRUE);
990                         strncpy(prev_letter, letter, MAX_BUF_SIZE);
991                 }
992
993                 MGR_APP_MEM_FREE(letter);
994                 app_info_list = app_info_list + 1;
995         }
996
997         evas_object_smart_callback_add(index, "delay,changed", _index_delayed_changed, index);
998         evas_object_smart_callback_add(index, "changed", _index_changed, NULL);
999         evas_object_smart_callback_add(index, "selected", _index_selected, NULL);
1000
1001
1002         /* register pkg-mgr listener */
1003         int result = 0;
1004         retv_if(ugd->pc_listen == NULL, NULL);
1005         result = pkgmgr_client_listen_status(ugd->pc_listen, mgr_app_view_listen_cb, (void*)ugd);
1006         if (result < 0) {
1007                 MGR_APP_DEBUG_ERR("status listen failed!\n");
1008                 MGR_APP_MEM_FREE(genlist);
1009                 return NULL;
1010         }
1011
1012         MGR_APP_END();
1013         return genlist;
1014 }
1015
1016 static Evas_Object *mgr_app_view_app_list_create(void *data)
1017 {
1018         MGR_APP_BEGIN();
1019
1020         retv_if(data == NULL, NULL);
1021
1022         retv_if(mgr_app_view_app_list.view_common_data == NULL, NULL);
1023         mgr_app_view_common_data_t *view_common_data = mgr_app_view_app_list.view_common_data;
1024
1025         MGR_APP_MEM_MALLOC(view_common_data->user_view_data, 1, app_list_view_data_t);
1026         retv_if(view_common_data->user_view_data == NULL, NULL);
1027         app_list_view_data_t *app_list_view_data = view_common_data->user_view_data;
1028
1029         app_list_view_data->layout = mgr_app_create_layout_file(view_common_data->common_navibar, EDC_FILE, EDC_GROUPS);
1030         retv_if(app_list_view_data->layout == NULL, NULL);
1031
1032         app_list_view_data->genlist = __create_genlist_app_list(app_list_view_data->layout, data);
1033
1034         MGR_APP_END();
1035         return app_list_view_data->layout;
1036 }
1037
1038 static Evas_Object *mgr_app_view_app_list_set_cbar(void *data)
1039 {
1040         MGR_APP_BEGIN();
1041         MGR_APP_END();
1042         return NULL;
1043 }
1044
1045 static mgr_app_result_e mgr_app_view_app_list_set_navibar(void *data)
1046 {
1047         MGR_APP_BEGIN();
1048         mgr_app_view_manager_set_navibar(mgr_app_view_app_list.view_common_data, dgettext(PACKAGE, "IDS_ST_BODY_MANAGE_APPLICATIONS"), NULL, _app_list_back_cb, NULL, NULL);
1049         MGR_APP_END();
1050         return MGR_APP_OK;
1051 }
1052
1053 static mgr_app_result_e mgr_app_view_app_list_destory(void *data)
1054 {
1055         MGR_APP_BEGIN();
1056
1057         retv_if(mgr_app_view_app_list.view_common_data == NULL, MGR_APP_ERROR);
1058         mgr_app_view_app_list.view_common_data->view_layout = NULL;
1059
1060         MGR_APP_END();
1061         return MGR_APP_OK;
1062 }
1063 static mgr_app_result_e mgr_app_view_app_list_update(void *data)
1064 {
1065         MGR_APP_BEGIN();
1066
1067         retv_if(mgr_app_view_app_list.view_common_data == NULL, MGR_APP_ERROR);
1068         mgr_app_view_common_data_t *view_common_data = mgr_app_view_app_list.view_common_data;
1069
1070         retv_if(view_common_data->user_view_data == NULL, MGR_APP_ERROR);
1071         app_list_view_data_t *app_list_view_data = view_common_data->user_view_data;
1072
1073         if (app_list_view_data->genlist != NULL) {
1074                 elm_genlist_clear(app_list_view_data->genlist);
1075                 evas_object_del(app_list_view_data->genlist);
1076                 app_list_view_data->genlist = NULL;
1077         }
1078
1079         app_list_view_data->genlist = __create_genlist_app_list(app_list_view_data->layout, data);
1080
1081         MGR_APP_END();
1082         return MGR_APP_OK;
1083 }
1084 static mgr_app_result_e mgr_app_view_app_list_cleanup(void *data)
1085 {
1086         MGR_APP_BEGIN();
1087         MGR_APP_END();
1088         return MGR_APP_OK;
1089 }
1090
1091