Upload Tizen2.0 beta source
[apps/home/app-selector.git] / app-selector-view.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
19 #include <ail.h>
20 #include <aul.h>
21 #include <appsvc.h>
22 #include <libsoup/soup.h>
23
24 #include "app-selector.h"
25 #include "app-selector-view.h"
26
27 #define TBL_NAME "menu"
28 #define MIME_FIELD_NAME "mimetype"
29 #define PATH_LEN        256
30 #define NAME_LEN        256
31 #define MAX_MIME_STR_SIZE 256
32 #define MAX_SCHEME_STR_SIZE 256
33 #define MAX_HOST_STR_SIZE 256
34 #define EDJ_NAME        "/usr/share/edje/app-selector/app-selector.edj"
35
36 extern int aul_forward_app(const char* pkgname, bundle *kb);
37
38 static Eina_Bool __unload_info_popup(void *data);
39 static void __default_app_set_cb(void *data, Evas_Object * obj, 
40                                         void *event_info);
41 static void __launch_set_default_app_popup(struct _select_app_info *info);
42 static void __response_cb(void *data, Evas_Object * obj, void *event_info);
43 static void __clear_app_list(void *data);
44 static int __app_list_get_with_mimetype(void *data);
45 static Eina_Bool __gl_state_get(const void *data, Evas_Object * obj,
46                                const char *part);
47 static void __gl_del(const void *data, Evas_Object * obj);
48 static void __gl_sel(void *data, Evas_Object * obj, void *event_info);
49 static Evas_Object *__gl_content_get(const void *data, Evas_Object * obj,
50                                  const char *part);
51 static char *__gl_text_get(const void *data, Evas_Object * obj,
52                            const char *part);
53 static void __app_genlist_item_append(struct appdata *ad);
54 static Evas_Object *__app_genlist_add(struct appdata *ad);
55
56 static Eina_Bool __unload_info_popup(void *data)
57 {
58 /*      Evas_Object *eo = (Evas_Object *) data;
59         if (eo) {
60                 evas_object_hide(eo);
61                 evas_object_del(eo);
62         }
63 */      elm_exit();
64
65         return ECORE_CALLBACK_CANCEL;
66 }
67
68 void load_info_popup(struct appdata *ad, char *str)
69 {
70         Evas_Object *eo = NULL;
71         eo = elm_popup_add(ad->win);
72         evas_object_size_hint_weight_set(eo, EVAS_HINT_EXPAND,
73                                          EVAS_HINT_EXPAND);
74         elm_object_text_set(eo, str);
75
76         ecore_timer_add(2.0, __unload_info_popup, eo);
77         evas_object_show(eo);
78 }
79
80 static void __default_app_set_ok_cb(void *data, Evas_Object * obj,
81                                         void *event_info)
82 {
83         char *scheme = NULL;
84         char *host = NULL;
85         char *uri_r_info = NULL;
86         bundle *outb;
87         int ret;
88         SoupURI *s_uri;
89         char *val = NULL;
90         
91         if (!data)
92                 return;
93
94         struct _select_app_info *info = (struct _select_app_info *)data;
95
96
97         //printf("MIME :: %s, PKGNAME : %s\n", info->ad->mime_type, info->pkg_name);
98
99         if(info->ad->mime_type){
100                 if (aul_set_defapp_with_mime(info->ad->mime_type, info->pkg_name) == AUL_R_OK){
101                         //printf("[Select Application] Insert Complete!!! %d\n", __LINE__);
102                 }
103                 else{
104                         //printf("[Select Application] Insert Error!!! %d\n", __LINE__);
105                 }
106         } else if(info->ad->control_op) {
107
108                 if(info->ad->control_uri) {
109                         if(strncmp(info->ad->control_uri,"/",1) == 0){
110                                 if(!info->ad->control_mime) {
111                                         info->ad->control_mime = malloc(MAX_MIME_STR_SIZE);
112                                         aul_get_mime_from_file(info->ad->control_uri, info->ad->control_mime, MAX_MIME_STR_SIZE);
113                                 }
114                                 info->ad->control_uri = NULL;
115                         } else if(strncmp(info->ad->control_uri,"file:/",6)==0){
116                                 if(!info->ad->control_mime) {
117                                         info->ad->control_mime = malloc(MAX_MIME_STR_SIZE);
118                                         aul_get_mime_from_file(&info->ad->control_uri[5], info->ad->control_mime, MAX_MIME_STR_SIZE);
119                                 }
120                                 info->ad->control_uri = NULL;
121                         } else if(strncmp(info->ad->control_uri,"file:///",8) == 0){
122                                 if(!info->ad->control_mime) {
123                                         info->ad->control_mime = malloc(MAX_MIME_STR_SIZE);
124                                         aul_get_mime_from_file(&info->ad->control_uri[7], info->ad->control_mime, MAX_MIME_STR_SIZE);
125                                 }
126                                 info->ad->control_uri = NULL;
127                         }
128                 }
129
130                 s_uri = soup_uri_new(info->ad->control_uri);
131                 if(s_uri->scheme) {
132                         scheme = malloc(MAX_SCHEME_STR_SIZE);
133                         strncpy(scheme, s_uri->scheme, MAX_SCHEME_STR_SIZE-1);
134                 }
135                 if(s_uri->host) {
136                         host = malloc(MAX_HOST_STR_SIZE);
137                         strncpy(host, s_uri->host, MAX_HOST_STR_SIZE-1);
138                 }
139                 if(scheme && host) {
140                         uri_r_info = malloc(MAX_SCHEME_STR_SIZE+MAX_HOST_STR_SIZE+2);
141                         snprintf(uri_r_info, MAX_SCHEME_STR_SIZE+MAX_HOST_STR_SIZE+1,
142                                 "%s://%s", scheme, host);
143                 }
144                 soup_uri_free(s_uri);
145
146                 val = bundle_get_val(info->ad->kb, APP_SVC_K_URI_R_INFO);
147
148                 if(val == NULL) {
149                         appsvc_set_defapp(info->ad->control_op,info->ad->control_mime,scheme,info->pkg_name);
150                 } else {
151                         if(strncmp(val, APP_SVC_V_SCHEME_AND_HOST, strlen(APP_SVC_V_SCHEME_AND_HOST)) == 0) {
152                                 appsvc_set_defapp(info->ad->control_op,info->ad->control_mime,uri_r_info,info->pkg_name);
153                         } else {
154                                 appsvc_set_defapp(info->ad->control_op,info->ad->control_mime,scheme,info->pkg_name);
155                         }
156                          bundle_del(info->ad->kb, APP_SVC_K_URI_R_INFO);
157                 }
158         }
159
160         ret = aul_forward_app(info->pkg_name, info->ad->kb);
161         _D("ok : aul_forward_app() pkg_name:%s ret:%d", info->pkg_name, ret);
162         
163         elm_exit();
164 }
165
166 static void __default_app_set_calcel_cb(void *data, Evas_Object * obj,
167                                         void *event_info)
168 {
169         int ret;
170
171         if (!data)
172                 return;
173
174         struct _select_app_info *info = (struct _select_app_info *)data;
175
176         ret = aul_forward_app(info->pkg_name, info->ad->kb);
177         _D("cancel : aul_forward_app() pkg_name:%s ret:%d", info->pkg_name, ret);
178
179         elm_exit();
180 }
181
182
183 static void __launch_set_default_app_popup(struct _select_app_info *info)
184 {
185         Evas_Object *popup = NULL;
186         Evas_Object *btn1 = NULL;
187         Evas_Object *btn2 = NULL;
188
189         if (!info)
190                 return;
191
192         struct appdata *ad = info->ad;
193
194         popup = elm_popup_add(ad->win);
195         evas_object_size_hint_weight_set(popup, EVAS_HINT_EXPAND,
196                                          EVAS_HINT_EXPAND);
197         elm_object_text_set(popup, _("Set this application as default?"));
198         elm_object_part_text_set(popup, "title,text", _("Default app setting"));
199
200         btn1 = elm_button_add(popup);
201         elm_object_text_set(btn1, dgettext("sys_string", "IDS_COM_SK_OK"));
202         elm_object_part_content_set(popup, "button1", btn1);
203         evas_object_smart_callback_add(btn1, "clicked", __default_app_set_ok_cb, info);
204         btn2 = elm_button_add(popup);
205         elm_object_text_set(btn2, _("Cancel"));
206         elm_object_part_content_set(popup, "button2", btn2);
207         evas_object_smart_callback_add(btn2, "clicked", __default_app_set_calcel_cb, info);
208
209         ad->def_set_popup = popup;
210
211         evas_object_show(popup);
212
213 }
214
215 static void __response_cb(void *data, Evas_Object * obj, void *event_info)
216 {
217         elm_exit();
218 }
219
220 static void __clear_app_list(void *data)
221 {
222         struct appdata *ad = data;
223         Eina_List *l;
224         struct _select_app_info *info;
225
226         if (ad->app_list) {
227                 EINA_LIST_FOREACH(ad->app_list, l, info) {
228                         if (info != NULL) {
229                                 free(info->pkg_name);
230                                 free(info->app_name);
231                                 free(info->app_path);
232                                 free(info->app_icon_path);
233                                 free(info);
234                                 info = NULL;
235                         }
236                 }
237
238                 eina_list_free(ad->app_list);
239                 ad->app_list = NULL;
240         }
241
242         if (ad->app_genlist) {
243                 elm_genlist_clear(ad->app_genlist);
244         }
245 }
246
247 static ail_cb_ret_e __iter_func(
248                         const ail_appinfo_h appinfo, void *user_data)
249 {
250         struct appdata *ad = (struct appdata *)user_data;
251         struct _select_app_info *info;
252         char *str = NULL;
253
254         info = calloc(1, sizeof(struct _select_app_info));
255
256         ail_appinfo_get_str(appinfo, AIL_PROP_PACKAGE_STR, &str);
257         info->pkg_name = strdup(str);
258
259         ail_appinfo_get_str(appinfo, AIL_PROP_NAME_STR, &str);
260         info->app_name = strdup(str);
261
262         ail_appinfo_get_str(appinfo, AIL_PROP_EXEC_STR, &str);
263         info->app_path = strdup(str);
264
265         ail_appinfo_get_str(appinfo, AIL_PROP_ICON_STR, &str);
266         info->app_icon_path = strdup(str);
267         
268         printf("PKGNAME : %s, ICONPATH : %s\n", info->pkg_name,
269                        info->app_icon_path);
270
271         info->ad = ad;
272
273         ad->app_list = eina_list_append(ad->app_list, info);
274         
275         return AIL_CB_RET_CONTINUE;     
276 }
277
278
279 static int __app_list_get_with_mimetype(void *data)
280 {
281
282         struct appdata *ad = data;
283
284         ail_filter_h filter;
285         ail_error_e ret;
286
287         ret = ail_filter_new(&filter);
288         if (ret != AIL_ERROR_OK) 
289                 return -1;
290
291         ret = ail_filter_add_str(filter, AIL_PROP_MIMETYPE_STR, ad->mime_type);
292         if (ret != AIL_ERROR_OK) {
293                 ail_filter_destroy(filter);
294                 return -1;
295         }
296
297         ail_filter_list_appinfo_foreach(filter, __iter_func, (void *)ad);
298
299         if (eina_list_count(ad->app_list) < 1) {
300                 load_info_popup(ad, dgettext("sys_string", "IDS_COM_BODY_NO_APPLICATIONS_CAN_PERFORM_THIS_ACTION"));
301                 ail_filter_destroy(filter);
302                 return -1;
303         }
304         
305         ail_filter_destroy(filter);
306
307         return 0;
308 }
309
310 static int __iterate(const char* pkg_name, void *data)
311 {
312         struct appdata *ad = data;
313         struct _select_app_info *info;
314         ail_appinfo_h handle;
315         ail_error_e ret;
316         char *str = NULL;
317
318         ret = ail_get_appinfo(pkg_name, &handle);
319         if (ret != AIL_ERROR_OK) {
320                 return -1;
321         }
322
323         info = calloc(1, sizeof(struct _select_app_info));
324
325         ail_appinfo_get_str(handle, AIL_PROP_PACKAGE_STR, &str);
326         info->pkg_name = strdup(str);
327
328         ail_appinfo_get_str(handle, AIL_PROP_NAME_STR, &str);
329         info->app_name = strdup(str);
330
331         ail_appinfo_get_str(handle, AIL_PROP_EXEC_STR, &str);
332         info->app_path = strdup(str);
333
334         ail_appinfo_get_str(handle, AIL_PROP_ICON_STR, &str);
335         info->app_icon_path = strdup(str);
336         
337         printf("PKGNAME : %s, ICONPATH : %s\n", info->pkg_name,
338                        info->app_icon_path);
339
340         info->ad = data;
341
342         ad->app_list = eina_list_append(ad->app_list, info);
343
344         ret = ail_package_destroy_appinfo(handle);
345         if (ret != AIL_ERROR_OK) {
346                 return -1;
347         }
348         
349         return 0;
350 }
351
352
353 static int __app_list_get_with_control(void *data)
354 {
355         struct appdata *ad = data;
356         struct _select_app_info *info;
357         bundle *kb;
358
359         char *scheme = NULL;
360         char *tmp = NULL;
361         char op_mime[1024] = {0,};
362         char op_scheme[1024] = {0,};
363
364         kb = bundle_create();
365         if(kb == NULL)
366         {
367                 _E("bundle creation fail\n");
368                 return -1;
369         }
370
371         if(ad->control_op){
372                 appsvc_set_operation(kb, ad->control_op);
373         }
374
375         if(ad->control_uri){
376                 appsvc_set_uri(kb, ad->control_uri);
377         }
378
379         if(ad->control_mime){
380                 appsvc_set_mime(kb, ad->control_mime);
381         }
382
383         if( appsvc_get_list(kb, __iterate, ad) != 0 ){
384                 load_info_popup(ad, _("Cannot find associated application"));
385                 bundle_free(kb);
386                 return -1;
387         }
388
389         bundle_free(kb);
390
391         return 0;
392 }
393
394 static Eina_Bool __gl_state_get(const void *data, Evas_Object * obj,
395                                const char *part)
396 {
397         return EINA_FALSE;
398 }
399
400 static void __gl_del(const void *data, Evas_Object * obj)
401 {
402         return;
403 }
404
405 static void __gl_sel(void *data, Evas_Object * obj, void *event_info)
406 {
407         Elm_Object_Item *item = (Elm_Object_Item *) event_info;
408
409         static int flag = 0;
410
411         if (flag == 1)
412                 return;
413
414         flag = 1;
415
416         if (item != NULL) {
417                 struct _select_app_info *info =
418                     (struct _select_app_info *)elm_object_item_data_get(item);
419
420                 __launch_set_default_app_popup(info);
421
422         }
423 }
424
425 Evas_Object *_add_layout(Evas_Object *parent, const char *file,
426                               const char *group)
427 {
428         Evas_Object *eo = NULL;
429         int r;
430
431         eo = elm_layout_add(parent);
432         if (eo == NULL) {
433                 printf("[Error] Cannot add layout\n");
434                 return NULL;
435         }
436
437         r = elm_layout_file_set(eo, file, group);
438         if (!r) {
439                 printf("[Error] Cannot set file layout\n");
440                 evas_object_del(eo);
441                 return NULL;
442         }
443
444         evas_object_size_hint_weight_set(eo, EVAS_HINT_EXPAND,
445                                          EVAS_HINT_EXPAND);
446
447         return eo;
448 }
449
450 static Evas_Object *__gl_content_get(const void *data, Evas_Object * obj,
451                                  const char *part)
452 {
453         struct _select_app_info *info = (struct _select_app_info *)data;
454         char buf[PATH_LEN] = { 0, };
455
456         Evas_Object *icon;
457         Evas_Object *rt, *icon_ly = NULL;
458         double scale = elm_config_scale_get();
459
460         if (!strcmp(part, "elm.icon")) {
461                 snprintf(buf, (size_t) PATH_LEN, "%s", info->app_icon_path);
462                 if (!ecore_file_exists(buf))
463                         snprintf((char *)buf, PATH_LEN,
464                                  (const char *)ICON_PATH
465                                  "/icon_app-selector.png");
466
467                 
468                 if (!strncmp(&buf[strlen(buf) - 3], "edj", 3)) {
469                         icon_ly = _add_layout(obj, buf, "icon");
470                         icon = _add_layout(obj, EDJ_NAME, "icon");
471                         rt = evas_object_rectangle_add(evas_object_evas_get(obj));
472                         
473                         evas_object_color_set(rt, 0, 0, 0, 0);
474                         evas_object_size_hint_min_set(rt, (int)(50.0 * scale),
475                                                       (int)(50.0 * scale));
476                         evas_object_size_hint_max_set(rt, (int)(50.0 * scale),
477                                               (int)(50.0 * scale));
478                         elm_object_part_content_set(icon, "icon_ly", rt);
479
480                         elm_object_part_content_set(icon, "icon", icon_ly);
481                 
482                 } else {
483                         icon = elm_icon_add(obj);
484                         elm_icon_file_set(icon, buf, NULL);
485                         evas_object_size_hint_aspect_set(icon,
486                                                  EVAS_ASPECT_CONTROL_VERTICAL,
487                                                  1, 1);
488                 }               
489                 
490                 return icon;
491         }
492         return NULL;
493 }
494
495 static char *__gl_text_get(const void *data, Evas_Object * obj,
496                            const char *part)
497 {
498         struct _select_app_info *info = (struct _select_app_info *)data;
499         char buf[NAME_LEN] = { 0, };
500
501         if (!strcmp(part, "elm.text")) {
502                 snprintf(buf, NAME_LEN, "%s", info->app_name);
503                 return strdup(buf);
504         }
505         return NULL;
506 }
507
508 static void __app_genlist_item_append(struct appdata *ad)
509 {
510         Eina_List *l;
511         struct _select_app_info *info;
512         Elm_Genlist_Item_Class *itc;
513
514         if (!ad)
515                 return;
516
517         itc = elm_genlist_item_class_new();
518
519         itc->item_style = "1text.1icon.2";
520         itc->func.text_get = __gl_text_get;
521         itc->func.content_get = __gl_content_get;
522         itc->func.state_get = __gl_state_get;
523         itc->func.del = __gl_del;
524
525         EINA_LIST_FOREACH(ad->app_list, l, info) {
526
527                 info->it =
528                     elm_genlist_item_append(ad->app_genlist, itc, (void *)info,
529                                             NULL, ELM_GENLIST_ITEM_NONE,
530                                             __gl_sel, ad);
531
532         }
533
534         elm_genlist_item_class_free(itc);
535 }
536
537 static Evas_Object *__app_genlist_add(struct appdata *ad)
538 {
539         Evas_Object *genlist;
540         if (!ad)
541                 return NULL;
542
543         if (ad->app_genlist)
544                 return NULL;
545
546         genlist = elm_genlist_add(ad->popup);
547
548         evas_object_size_hint_weight_set(genlist, EVAS_HINT_EXPAND,
549                                          EVAS_HINT_EXPAND);
550         evas_object_size_hint_align_set(genlist, EVAS_HINT_FILL,
551                                         EVAS_HINT_FILL);
552
553         return genlist;
554 }
555
556 void load_app_list(struct appdata *ad)
557 {
558         Evas_Object *popup;
559         Evas_Object *btn1;
560
561         popup = elm_popup_add(ad->win);
562         elm_object_style_set(popup, "menustyle");
563         ad->popup = popup;
564
565         evas_object_size_hint_weight_set(popup, EVAS_HINT_EXPAND,
566                                          EVAS_HINT_EXPAND);
567         elm_object_part_text_set(popup, "title,text", _("Select application"));
568
569         btn1 = elm_button_add(popup);
570         elm_object_text_set(btn1, _("Cancel"));
571         elm_object_part_content_set(popup, "button1", btn1);
572
573         ad->app_genlist = __app_genlist_add(ad);
574         if (!ad->app_genlist)
575                 return;
576
577         __app_genlist_item_append(ad);
578
579         elm_object_content_set(popup, ad->app_genlist);
580         evas_object_smart_callback_add(btn1, "clicked", __response_cb, NULL);
581
582         evas_object_show(popup);
583 }
584
585 void update_app_list(struct appdata *ad)
586 {
587         __clear_app_list(ad);
588         if (__app_list_get_with_mimetype(ad) == -1)
589                 return;
590
591         __app_genlist_item_append(ad);
592 }
593
594 void load_app_select_popup(struct appdata *ad)
595 {
596         int ret = -1;
597         
598         if(ad->mime_type)
599                 ret = __app_list_get_with_mimetype(ad); 
600         else if(ad->control_op)
601                 ret = __app_list_get_with_control(ad);
602         
603         if (ret == -1)
604                 {
605                 printf("fail fail fail\n");
606                 return;
607                 }
608         else
609                 load_app_list(ad);
610
611 }