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