86445ee54695ad02408a16abd3da7bb52f0219f1
[apps/core/preloaded/calendar.git] / ug / list / ug-list.c
1 /*
2   *
3   *  Copyright 2012  Samsung Electronics Co., Ltd
4   *
5   *  Licensed under the Flora License, Version 1.0 (the "License");
6   *  you may not use this file except in compliance with the License.
7   *  You may obtain a copy of the License at
8   *
9   *       http://floralicense.org/license/
10   *
11   *  Unless required by applicable law or agreed to in writing, software
12   *  distributed under the License is distributed on an "AS IS" BASIS,
13   *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   *  See the License for the specific language governing permissions and
15   *  limitations under the License.
16   */
17
18
19 #include <fcntl.h>
20 #include <vconf.h>
21 #include "cld.h"
22 #include "ug.h"
23
24 static const char *_name = "list/base";
25
26 ///TODO: get full path from caller
27 #define VFILE_PATH "/opt/usr/media/Others"
28
29 static Elm_Entry_Filter_Limit_Size _limit_20char = {
30        .max_char_count = 20,
31 };
32
33 #define MAX_FETCH_COUNT 10
34
35 #define ACCOUNT_LABLE_STRING_LENGTH 128
36
37 typedef struct {
38         const char *name;
39         struct ug_data *ugd;
40         Evas_Object *parent;
41         Evas_Object *ly;
42         Evas_Object *no_contents;
43         Evas_Object *bg;
44
45         Evas_Object *bt;
46
47         Evas_Object *genlist;
48
49         Eina_List *event_list;
50         Eina_List *search_list;
51
52         Evas_Object *box;
53
54         Ecore_Idler* idler;
55
56         int checked_event_count;
57         int added_event_count;
58         Evas_Object* searchbar;
59         const char * searchtext;
60         Elm_Object_Item *navi_item;
61 }cal_list_ug_data;
62
63 typedef struct {
64         Elm_Object_Item *it;  // Genlist Item pointer
65         Eina_Bool checked;     // Check status
66         char *label;
67         calendar_record_h record;
68         struct tm* tm;
69         Elm_Genlist_Item_Type it_flag;
70 }cal_list_ug_item_data;
71
72 static void __cal_list_ug_genlist_item_select_callback(void *data, Evas_Object *obj, void *event_info);
73 static void __cal_list_ug_update_callback(const char* view_uri, void *data);
74 static void __cal_list_ug_searchbar_entry_changed_callback(void *data, Evas_Object *obj, void *event_info);
75 static void __cal_list_ug_cancel_button_callback(void *data, Evas_Object *obj, void *event_info);
76 static void __cal_list_ug_searchbar_entry_unfocused_callback(void *data, Evas_Object *obj, void *event_info);
77 static void __cal_list_ug_searchbar_clicked_callback(void *data, Evas_Object *obj, void *event_info);
78 static void __cal_list_ug_create_searchbar(cal_list_ug_data *p);
79 static char* __cal_list_ug_get_genlist_item_label(void *data, Evas_Object *obj, const char *part);
80 static Evas_Object *__cal_list_ug_get_genlist_item_icon(void *data, Evas_Object *obj, const char *part);
81
82 static Elm_Genlist_Item_Class itc = {
83         .item_style = "3text.5icon",
84         .func.text_get = __cal_list_ug_get_genlist_item_label,
85         .func.content_get = __cal_list_ug_get_genlist_item_icon,
86         .decorate_all_item_style = "edit_default",
87 };
88
89 static _calendar_book_color calendar_color;
90
91 //TODO
92 #define ELM_GENLIST_ITEM_GROUP (1<<1)
93
94 static void __cal_list_ug_update_selection_info(cal_list_ug_data *p)
95 {
96         CAL_FN_START;
97
98         c_ret_if(!p);
99
100         if (!p->checked_event_count) {
101                 cal_util_hide_small_information(p->ly);
102                 return;
103         }
104
105         char lable_str[128] = { '\0'};
106
107         snprintf(lable_str, sizeof(lable_str), "%s (%d)", S_("IDS_COM_POP_SELECTED"), p->checked_event_count);
108
109         cal_util_show_small_information(p->ly, lable_str, 0.0);
110 }
111
112 static inline void __cal_list_ug_update_button_state(cal_list_ug_data *p)
113 {
114         if (0 < p->checked_event_count)
115                 elm_object_disabled_set(p->bt, EINA_FALSE);
116         else
117                 elm_object_disabled_set(p->bt, EINA_TRUE);
118 }
119
120 static inline void __cal_list_ug_update_realized_genlist_item(cal_list_ug_data *p)
121 {
122         Eina_List *realized_list = elm_genlist_realized_items_get(p->genlist);
123         c_ret_if(!realized_list);
124
125         Eina_List *l = NULL;
126         Elm_Object_Item *it = NULL;
127
128         EINA_LIST_FOREACH(realized_list, l, it) {
129                 if (it)
130                         elm_genlist_item_update(it);
131         }
132 }
133
134 static void __cal_list_ug_genlist_item_check_changed_callback(void *data, Evas_Object *obj, void *event_info)
135 {
136         c_ret_if(!data);
137         c_ret_if(!obj);
138
139         cal_list_ug_item_data *item_data = data;
140
141         cal_list_ug_data* p = CAL_UTIL_GET_PRIV_DATA(obj);
142         c_ret_if(!p);
143
144         item_data->checked = elm_check_state_get(obj);
145
146         if (item_data->checked)
147                 p->checked_event_count++;
148         else
149                 p->checked_event_count--;
150
151         __cal_list_ug_update_button_state(p);
152
153         __cal_list_ug_update_realized_genlist_item(p);
154
155         __cal_list_ug_update_selection_info(p);
156 }
157
158 static Evas_Object *__cal_list_ug_get_genlist_item_icon(void *data, Evas_Object *obj, const char *part)
159 {
160         c_retv_if(!part, NULL);
161         c_retv_if(!obj, NULL);
162         c_retv_if(!data, NULL);
163
164         cal_list_ug_item_data *item_data = data;
165
166         if (!CAL_STRCMP(part, "elm.edit.icon.1")) {
167
168                 cal_list_ug_data* p = CAL_UTIL_GET_PRIV_DATA(obj);
169                 c_retv_if(!p, NULL);
170
171                 Evas_Object *checkbox = elm_check_add(obj);
172                 c_retv_if(!checkbox, NULL);
173
174                 elm_check_state_pointer_set(checkbox, &item_data->checked);
175                 evas_object_smart_callback_add(checkbox, "changed", __cal_list_ug_genlist_item_check_changed_callback, item_data);
176                 evas_object_propagate_events_set(checkbox, EINA_FALSE);
177                 evas_object_data_set(checkbox, "priv", p);
178
179                 return checkbox;
180
181         } else if (!CAL_STRCMP(part, "elm.swallow.colorbar")) {
182
183                 Evas_Object *rect = evas_object_rectangle_add(evas_object_evas_get(obj));
184                 c_retv_if(!rect, NULL);
185
186                 evas_object_size_hint_align_set(rect, EVAS_HINT_FILL, EVAS_HINT_FILL);
187
188                 _calendar_get_calendar_color(item_data->record, &calendar_color);
189
190                 evas_object_color_set(rect, calendar_color.red, calendar_color.green, calendar_color.blue, calendar_color.alpha);
191
192                 return rect;
193         }
194
195         return NULL;
196 }
197
198 static void __cal_list_ug_delete_idler(cal_list_ug_data *p)
199 {
200         CAL_FN_START;
201
202         c_ret_if(!p);
203
204         if (!p->idler)
205                 return;
206
207         ecore_idler_del(p->idler);
208         p->idler = NULL;
209 }
210
211 static void __cal_list_ug_delete_no_contents(cal_list_ug_data *p)
212 {
213         CAL_FN_START;
214
215         c_ret_if(!p);
216         c_ret_if(!p->ly);
217
218         if (!p->no_contents)
219                 return;
220
221         elm_object_part_content_unset(p->ly, "sw");
222
223         evas_object_del(p->no_contents);
224
225         p->no_contents = NULL;
226 }
227
228 static void __cal_list_ug_delete_layout(void *data, Evas *e, Evas_Object *obj, void *ei)
229 {
230         CAL_FN_START;
231
232         c_retm_if(!data, "data is null");
233
234         cal_list_ug_data *p = data;
235
236         calendar_error_e error = CALENDAR_ERROR_NONE;
237
238         error = calendar_db_remove_changed_cb(_calendar_event._uri, __cal_list_ug_update_callback, p);
239         c_warn_if(error != CALENDAR_ERROR_NONE, "calendar_db_remove_changed_cb() is failed(%x)", error);
240
241         __cal_list_ug_delete_idler(p);
242
243         _calendar_free_record_list(&p->event_list);
244
245         free(p);
246 }
247
248 static char* __cal_list_ug_get_genlist_item_label(void *data, Evas_Object *obj, const char *part)
249 {
250         c_retv_if(!part, NULL);
251         c_retv_if(!data, NULL);
252
253         cal_list_ug_item_data *item = data;
254         calendar_record_h record = item->record;
255         c_retv_if(!record, NULL);
256
257         if (!CAL_STRCMP(part, "elm.text.1")) {
258
259                 return _calendar_get_summary(record);
260         }
261
262         if (!CAL_STRCMP(part, "elm.text.2")) {
263
264                 return _calendar_get_location(record);
265         }
266
267         if (!CAL_STRCMP(part, "elm.text.3"))
268                 return _calendar_get_time_str_for_genlist(record);
269
270         return NULL;
271 }
272
273 static void __cal_list_ug_genlist_item_select_callback(void *data, Evas_Object *obj, void *event_info)
274 {
275         c_retm_if(!data, "data is null");
276         c_retm_if(!obj, "obj is null");
277
278         Elm_Object_Item* it;
279         cal_list_ug_item_data* item = data;
280         cal_list_ug_data *p = CAL_UTIL_GET_PRIV_DATA(obj);
281         c_retm_if(!p, "p is null");
282
283         if (p->ugd->selection_mode == SELECTION_MODE_SINGLE) {
284
285                 int cid = _calendar_get_record_index(item->record);
286                 c_retm_if(cid < 0, "CALENDAR_SVC_STRUCT_GET_INT return error!");
287
288                 service_h service;
289
290                 service_create(&service);
291
292                 char ** value = calloc(1, sizeof(char *));
293                 if(!value)      {
294                         ERR("value is NULL!");
295                         service_destroy(service);
296                         return;
297                 }
298
299
300                 char path[FILENAME_MAX] = {0};
301                 char *vcs_data = NULL;
302
303                 snprintf(path, sizeof(path), "%s/Calendar_%d.vcs", VFILE_PATH, cid);
304
305                 calendar_list_h list = NULL;
306
307                 calendar_error_e error = CALENDAR_ERROR_NONE;
308
309                 error = calendar_list_create(&list);
310                 c_warn_if(error != CALENDAR_ERROR_NONE, "calendar_list_create() is failed(%x)");
311
312                 error = calendar_list_add(list, item->record);
313                 c_warn_if(error != CALENDAR_ERROR_NONE, "calendar_list_add() is failed(%x)");
314
315                 error = calendar_vcalendar_make_from_records(list, &vcs_data);
316                 c_warn_if(error != CALENDAR_ERROR_NONE, "calendar_vcalendar_make_from_records() is failed(%x)");
317
318
319                 int fd = open(path, O_WRONLY|O_CREAT|O_TRUNC, 0644);
320                 if(fd < 0)
321                 {
322                         ERR("Failed to open file %s.", path);
323
324                         free(value);
325                         service_destroy(service);
326                         error = calendar_list_destroy(list, false);
327                         c_warn_if(error != CALENDAR_ERROR_NONE, "calendar_list_destroy() is failed(%x)");
328
329                         return;
330                 }
331
332                 if (vcs_data) {
333                         int ret = write(fd, vcs_data, strlen(vcs_data));
334                         if (ret == -1)
335                                 ERR("write() is failed.");
336                         else
337                                 cal_util_update_media_db(path);
338
339                         free(vcs_data);
340                 }
341
342                 fsync(fd);
343                 close(fd);
344
345                 error = calendar_list_destroy(list, false);
346                 c_warn_if(error != CALENDAR_ERROR_NONE, "calendar_list_destroy() is failed(%x)");
347
348                 value[0] = strdup(path);
349
350                 service_add_extra_data_array(service, CAL_APPCONTROL_PATH, (const char **)value, 1);
351
352                 free(value[0]);
353                 free(value);
354
355                 service_add_extra_data(service, CAL_APPCONTROL_RESULT, CAL_APPCONTROL_RESULT_SUCCESS);
356
357                 if (p->ugd->item_type == ITEM_TYPE_EVENT)
358                         service_add_extra_data(service, CAL_APPCONTROL_ITEM_TYPE, CAL_APPCONTROL_ITEM_TYPE_EVENT);
359                 else
360                         service_add_extra_data(service, CAL_APPCONTROL_ITEM_TYPE, CAL_APPCONTROL_ITEM_TYPE_TODO);
361
362                 ug_send_result(p->ugd->ug, service);
363                 service_destroy(service);
364
365                 ug_destroy_me(p->ugd->ug);
366
367                 return;
368         }
369
370         if (p->added_event_count <= 0) {
371                 return;
372         }
373
374         item->checked = !(item->checked);
375         if (item->checked) {
376                 p->checked_event_count++;
377         } else {
378                 p->checked_event_count--;
379         }
380
381         if (item->checked || 0 < p->checked_event_count) {
382                 elm_object_disabled_set(p->bt, EINA_FALSE);
383         } else if (p->checked_event_count <= 0) {
384                 elm_object_disabled_set(p->bt, EINA_TRUE);
385         }
386
387         it = elm_genlist_selected_item_get(obj);
388         if (it) {
389                 elm_genlist_item_selected_set(it, EINA_FALSE);
390         }
391
392         __cal_list_ug_update_realized_genlist_item(p);
393
394         __cal_list_ug_update_selection_info(p);
395 }
396
397 static void __cal_list_ug_get_event_list(cal_list_ug_data *p)
398 {
399         CAL_FN_START;
400
401         c_ret_if(!p);
402
403         struct tm tm_start = {0};
404         struct tm tm_end = {0};
405
406         tm_start.tm_year = 70;
407         tm_end.tm_year = 137;
408
409         if (p->ugd->item_type == ITEM_TYPE_EVENT)
410                 p->event_list = _calendar_get_all_instance_list(&tm_start,&tm_end);
411         else
412                 p->event_list = _calendar_get_all_task_list2(&tm_start, &tm_end, EINA_TRUE, _CALENDAR_TASK_SORT_TYPE_DUEDATE_ASC);
413 }
414
415 static void __cal_list_ug_add_event_to_genlist(cal_list_ug_data *p)
416 {
417         CAL_FN_START;
418
419         c_ret_if(!p);
420         c_ret_if(!p->event_list);
421
422         Eina_List *l = NULL;
423         calendar_record_h record = NULL;
424
425         int added_event_count = 0;
426
427         Eina_List *event_list = eina_list_nth_list(p->event_list, p->added_event_count);
428         c_ret_if(!event_list);
429
430         EINA_LIST_FOREACH(event_list, l, record) {
431                 if (record) {
432                         cal_list_ug_item_data *item_data = calloc(1, sizeof(cal_list_ug_item_data));
433                         c_ret_if(!item_data);
434
435                         item_data->record = record;
436
437                         item_data->it = elm_genlist_item_append(p->genlist, &itc, item_data, NULL, ELM_GENLIST_ITEM_NONE, __cal_list_ug_genlist_item_select_callback, item_data);
438
439                         added_event_count++;
440
441                         if (10 < added_event_count)
442                                 break;
443                 }
444         }
445
446         p->added_event_count += added_event_count;
447 }
448
449 static Eina_Bool __cal_list_ug_check_idler_condition(cal_list_ug_data *p)
450 {
451         c_retv_if(!p, ECORE_CALLBACK_CANCEL);
452
453         if (p->added_event_count < eina_list_count(p->event_list)) {
454
455                 return ECORE_CALLBACK_RENEW;
456         }
457
458         if (p->idler) {
459                 ecore_idler_del(p->idler);
460                 p->idler = NULL;
461         }
462
463         return ECORE_CALLBACK_CANCEL;
464 }
465
466 Eina_Bool __cal_list_ug_idler_callback(void* data)
467 {
468         CAL_FN_START;
469
470         c_retvm_if(!data, ECORE_CALLBACK_CANCEL, "data is null.");
471
472         cal_list_ug_data *p = data;
473
474         c_retv_if(!p->idler, ECORE_CALLBACK_CANCEL);
475
476         __cal_list_ug_add_event_to_genlist(p);
477
478         CAL_FN_END;
479
480         return __cal_list_ug_check_idler_condition(p);
481 }
482
483 static void __cal_list_ug_add_idler(cal_list_ug_data *p)
484 {
485         c_ret_if(!p);
486
487         if (p->added_event_count < eina_list_count(p->event_list)) {
488
489                 if (p->idler)
490                         ecore_idler_del(p->idler);
491
492                 p->idler = ecore_idler_add(__cal_list_ug_idler_callback, p);
493                 c_ret_if(!p->idler);
494         }
495 }
496
497 static void __cal_list_ug_create_searchbar(cal_list_ug_data *p)
498 {
499         c_ret_if(!p);
500         c_ret_if(!p->ly);
501
502         if (p->searchbar)
503                 return;
504
505         Evas_Object *searchbar = cal_util_add_searchbar(p->ly, NULL, NULL, EINA_TRUE, NULL, NULL);
506         c_ret_if(!searchbar);
507
508         Evas_Object *entry = elm_object_part_content_get(searchbar, "elm.swallow.content");
509         c_ret_if(!entry);
510
511         elm_entry_input_panel_layout_set(entry, ELM_INPUT_PANEL_LAYOUT_NORMAL);
512         elm_entry_markup_filter_append(entry, elm_entry_filter_limit_size, &_limit_20char);
513
514         evas_object_size_hint_weight_set(searchbar, EVAS_HINT_EXPAND, 0.1);
515         evas_object_size_hint_align_set(searchbar, EVAS_HINT_FILL, 0.6);
516
517         evas_object_smart_callback_add(entry, "changed", __cal_list_ug_searchbar_entry_changed_callback, p);
518         evas_object_smart_callback_add(entry, "unfocused", __cal_list_ug_searchbar_entry_unfocused_callback, p);
519         evas_object_smart_callback_add(searchbar, "clicked", __cal_list_ug_searchbar_clicked_callback, p);
520         evas_object_smart_callback_add(searchbar, "cancel,clicked", __cal_list_ug_cancel_button_callback, p);
521
522         evas_object_show(searchbar);
523
524         edje_object_signal_emit(CAL_UTIL_GET_EDJ_DATA(p->ly), "searchbar,show", "prog");
525
526         elm_object_part_content_set(p->ly, "searchbar", searchbar);
527
528         p->searchbar = searchbar;
529 }
530
531 static void __cal_list_ug_create_box(cal_list_ug_data *p)
532 {
533         CAL_FN_START;
534
535         c_ret_if(!p);
536         c_ret_if(!p->ly);
537
538         if (p->box)
539                 return;
540
541         Evas_Object *box = elm_box_add(p->ly);
542         c_ret_if(!box);
543
544         evas_object_size_hint_weight_set(box, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
545         elm_object_part_content_set(p->ly, "sw", box);
546         p->box = box;
547 }
548
549 static void __cal_list_ug_append_list_with_iter(Eina_List **event_list, calendar_list_h list)
550 {
551         c_ret_if(!event_list);
552         c_ret_if(!list);
553
554         calendar_record_h record = NULL;
555
556         int i = 0;
557
558         int count = 0;
559
560         calendar_error_e error = CALENDAR_ERROR_NONE;
561
562         error = calendar_list_get_count(list, &count);
563         c_warn_if(error != CALENDAR_ERROR_NONE, "calendar_list_get_count() is failed(%x)", error);
564
565         error = calendar_list_first(list);
566         c_warn_if(error != CALENDAR_ERROR_NONE, "calendar_list_first() is failed(%x)", error);
567
568         for (i = 0; i < count; i++) {
569                 error = calendar_list_get_current_record_p(list, &record);
570                 c_warn_if(error != CALENDAR_ERROR_NONE, "calendar_list_get_current_record_p() is failed(%x)", error);
571
572                 *event_list = eina_list_append(*event_list, record);
573
574                 calendar_list_next(list);
575         }
576 }
577
578
579 static void __cal_list_ug_update_event_list_with_keyword(cal_list_ug_data *p)
580 {
581         c_ret_if(!p);
582
583         calendar_list_h list = NULL;
584         if (p->ugd->item_type == ITEM_TYPE_EVENT) {
585                 list = _calendar_search_event(p->searchtext);
586                 c_ret_if(!list);
587         }
588         else {
589                 list = _calendar_search_task(p->searchtext);
590                 c_ret_if(!list);
591         }
592
593         __cal_list_ug_append_list_with_iter(&p->search_list, list);
594
595         calendar_error_e error = CALENDAR_ERROR_NONE;
596
597         error = calendar_list_destroy(list, false);
598         c_warn_if(error != CALENDAR_ERROR_NONE, "calendar_list_destroy() is failed(%x)", error);
599
600 }
601
602 static void __cal_list_ug_update_event_list(cal_list_ug_data *p)
603 {
604         c_ret_if(!p);
605
606         p->checked_event_count = 0;
607
608         p->added_event_count = 0;
609
610         _calendar_free_record_list(&p->event_list);
611
612         if (CAL_STRLEN(p->searchtext))
613                 __cal_list_ug_update_event_list_with_keyword(p);
614         else
615                 __cal_list_ug_get_event_list(p);
616 }
617
618 static void __cal_list_ug_create_genlist(cal_list_ug_data *p)
619 {
620         CAL_FN_START;
621
622         c_ret_if(!p);
623         c_ret_if(!p->box);
624
625         if (p->genlist) {
626
627                 elm_genlist_clear(p->genlist);
628
629                 return;
630         }
631
632         Evas_Object *genlist = elm_genlist_add(p->box);
633         c_ret_if(!genlist);
634
635         if (p->ugd->selection_mode == SELECTION_MODE_SINGLE)
636                 itc.decorate_all_item_style = NULL;
637         else
638                 elm_genlist_decorate_mode_set(genlist, EINA_TRUE);
639
640         evas_object_data_set(genlist, "priv", p);
641         elm_genlist_scroller_policy_set(genlist, ELM_SCROLLER_POLICY_OFF,ELM_SCROLLER_POLICY_OFF);
642         elm_genlist_block_count_set(genlist, 20);
643         elm_genlist_homogeneous_set(genlist, EINA_TRUE);
644         evas_object_size_hint_weight_set(genlist, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
645         evas_object_size_hint_align_set(genlist, EVAS_HINT_FILL, EVAS_HINT_FILL);
646         evas_object_show(genlist);
647         elm_box_pack_end(p->box, genlist);
648
649         p->genlist = genlist;
650 }
651
652 static void __cal_list_ug_create_no_contents(cal_list_ug_data *p)
653 {
654         CAL_FN_START;
655
656         c_ret_if(!p);
657         c_ret_if(!p->ly);
658
659         p->no_contents = cal_util_add_nocontents(p->ly, C_("IDS_CLD_BODY_NO_EVENTS"));
660         c_ret_if(!p->no_contents);
661
662         elm_object_part_content_set(p->ly, "sw", p->no_contents);
663
664         evas_object_show(p->no_contents);
665 }
666
667 static void __cal_list_ug_update_callback(const char* view_uri, void *data)
668 {
669         CAL_FN_START;
670
671         c_ret_if(!data);
672         cal_list_ug_data *p = data;
673
674         __cal_list_ug_delete_idler(p);
675
676         __cal_list_ug_update_event_list(p);
677
678         if (p->event_list && eina_list_count(p->event_list)) {
679
680                 __cal_list_ug_delete_no_contents(p);
681
682                 __cal_list_ug_create_searchbar(p);
683
684                 __cal_list_ug_create_box(p);
685
686                 __cal_list_ug_create_genlist(p);
687
688                 __cal_list_ug_add_event_to_genlist(p);
689
690                 __cal_list_ug_add_idler(p);
691
692         } else {
693
694                 p->searchbar = NULL;
695
696                 p->box = NULL;
697
698                 p->genlist = NULL;
699
700                 __cal_list_ug_create_no_contents(p);
701
702                 elm_object_disabled_set(p->bt, EINA_TRUE);
703
704         }
705 }
706
707 static Evas_Object* __cal_list_ug_create_layout(Evas_Object *parent, struct ug_data *ugd)
708 {
709         CAL_FN_START;
710
711         c_retvm_if(!parent, NULL, "parent is null");
712         c_retvm_if(!ugd, NULL, "ugd is null");
713
714         cal_list_ug_data *p = calloc(1, sizeof(cal_list_ug_data));
715         c_retvm_if(!p, NULL, "p is null");
716
717         p->name = _name;
718         p->ugd = ugd;
719         p->parent = parent;
720
721         Evas_Object *ly = cal_util_add_layout(parent, p->name);
722         if (!ly)
723         {
724                 ERR("cal_util_add_layout returned null");
725                 free(p);
726                 return NULL;
727         }
728         p->ly = ly;
729         evas_object_data_set(ly, "priv", p);
730
731         p->bg = cal_util_add_bg(ly,EINA_FALSE);
732         if (!p->bg) {
733                 ERR("cal_util_add_bg returned null");
734                 evas_object_del(ly);
735                 free(p);
736                 ERR("bg is null");
737                 return NULL;
738         }
739         elm_object_part_content_set(ly, "base", p->bg);
740
741         __cal_list_ug_update_callback(_calendar_event._uri, p);
742
743         evas_object_show(ly);
744         evas_object_event_callback_add(ly, EVAS_CALLBACK_DEL, __cal_list_ug_delete_layout, p);
745
746         calendar_error_e error = CALENDAR_ERROR_NONE;
747         error = calendar_db_add_changed_cb(_calendar_event._uri, __cal_list_ug_update_callback, p);
748         c_warn_if(error != CALENDAR_ERROR_NONE, "calendar_db_add_changed_cb() is failed(%x)", error);
749
750         return ly;
751 }
752
753 static void __cal_list_ug_get_message_content(calendar_record_h record, char *body , int nsize)
754 {
755         c_ret_if(!record);
756         c_ret_if(!body);
757
758         char *title = _calendar_get_summary(record);
759
760         strncat(body, title, nsize - CAL_STRLEN(body));
761         strncat(body, "\n", nsize - CAL_STRLEN(body));
762
763         char *location = _calendar_get_location(record);
764
765         if (CAL_STRLEN(location)) {
766                 strncat(body, location, nsize - CAL_STRLEN(body));
767                 strncat(body, "\n", nsize - CAL_STRLEN(body));
768         }
769
770         char text[64] = {0};
771
772         const char *time_format = NULL;
773         if (is_hour24)
774                 time_format = CAL_UTIL_TIME_FORMAT_6;
775         else
776                 time_format = CAL_UTIL_TIME_FORMAT_1;
777
778         struct tm tm_start, tm_end;
779         calendar_time_s start_time = {0};
780         calendar_time_s end_time = {0};
781         _calendar_get_start_time(record, &start_time);
782         _calendar_get_end_time(record, &end_time);
783
784         if (_calendar_is_allday_record(record)) {
785                 long long int lli_time = time(NULL);
786
787                 cal_util_convert_lli_to_tm(NULL, lli_time, &tm_start);
788
789                 tm_end = tm_start;
790
791                 tm_start.tm_year = start_time.time.date.year - 1900;
792                 tm_start.tm_mon = start_time.time.date.month - 1;
793                 tm_start.tm_mday = start_time.time.date.mday;
794
795                 tm_end.tm_year = end_time.time.date.year - 1900;
796                 tm_end.tm_mon = end_time.time.date.month - 1;
797                 tm_end.tm_mday = end_time.time.date.mday;
798
799                 if (tm_start.tm_year == tm_end.tm_year
800                         && tm_start.tm_mon == tm_end.tm_mon
801                         && tm_start.tm_mday == tm_end.tm_mday) {
802                         cal_util_get_time_text(text, sizeof(text), CAL_UTIL_DATE_FORMAT_1, NULL, &tm_start);
803                         strncat(body, text, nsize - CAL_STRLEN(body));
804                 } else {
805                         cal_util_get_time_text(text, sizeof(text), CAL_UTIL_DATE_FORMAT_1, NULL, &tm_start);
806                         strncat(body, text, nsize - CAL_STRLEN(body));
807
808                         strncat(body, " ~ ", nsize - CAL_STRLEN(body));
809
810                         cal_util_get_time_text(text, sizeof(text), CAL_UTIL_DATE_FORMAT_1, NULL, &tm_end);
811                         strncat(body, text, nsize - CAL_STRLEN(body));
812                 }
813
814         } else {
815
816                 cal_util_convert_lli_to_tm(NULL, start_time.time.utime, &tm_start);
817                 cal_util_convert_lli_to_tm(NULL, end_time.time.utime, &tm_end);
818
819                 cal_util_get_time_text(text, sizeof(text), CAL_UTIL_DATE_FORMAT_1, time_format, &tm_start);
820                 strncat(body, text, nsize - CAL_STRLEN(body));
821
822                 strncat(body, " ~ " , nsize - CAL_STRLEN(body));
823
824                 cal_util_get_time_text(text, sizeof(text), CAL_UTIL_DATE_FORMAT_1, time_format, &tm_end);
825                 strncat(body, text, nsize - CAL_STRLEN(body));
826         }
827
828         free(title);
829         CAL_FREE(location);
830 }
831
832
833 static void __cal_list_ug_add_bundle_event_content(service_h service, int record_index, int result_index)
834 {
835         c_ret_if(!service);
836         c_ret_if(record_index <= 0);
837
838         char key[16] = {0};
839         char value[1024*5] = {0};
840
841         calendar_record_h record = NULL;
842
843         record = _calendar_get_record_with_index(record_index);
844         c_ret_if(!record);
845
846         __cal_list_ug_get_message_content(record, value, sizeof(value));
847
848         snprintf(key, sizeof(key), "text%d", result_index);
849
850         calendar_error_e error = CALENDAR_ERROR_NONE;
851
852         error = calendar_record_destroy(record, true);
853         c_retm_if(error != CALENDAR_ERROR_NONE, "calendar_record_destroy() is failed(%x)", error);
854
855         int r = service_add_extra_data(service, key, value);
856         c_ret_if(r != SERVICE_ERROR_NONE);
857 }
858
859 static void __cal_list_ug_add_bundle_vcs(service_h service, int record_index, int result_index)
860 {
861         c_ret_if(!service);
862         c_ret_if(record_index <= 0);
863
864         calendar_record_h record = NULL;
865
866         record = _calendar_get_record_with_index(record_index);
867         c_ret_if(!record);
868
869         calendar_error_e error = CALENDAR_ERROR_NONE;
870
871         calendar_list_h list = NULL;
872
873         error = calendar_list_create(&list);
874         if (error != CALENDAR_ERROR_NONE) {
875                 ERR("calendar_list_create() is failed(%x)", error);
876
877                 calendar_record_destroy(record, true);
878
879                 return;
880         }
881
882         error = calendar_list_add(list, record);
883         if (error != CALENDAR_ERROR_NONE) {
884                 ERR("calendar_list_add() is failed(%x)", error);
885
886                 calendar_list_destroy(list, false);
887
888                 calendar_record_destroy(record, true);
889
890                 return;
891         }
892
893         char *vcs_data = NULL;
894
895         error = calendar_vcalendar_make_from_records(list, &vcs_data);
896         if (error != CALENDAR_ERROR_NONE) {
897                 ERR("calendar_vcalendar_make_from_records() is failed(%x)", error);
898
899                 calendar_list_destroy(list, true);
900
901                 return;
902         }
903
904         if (!CAL_STRLEN(vcs_data)) {
905                 ERR("vcs_data is empty");
906
907                 calendar_list_destroy(list, true);
908
909                 return;
910         }
911
912         char key[128] = {0};
913         char value[FILENAME_MAX] = {0};
914
915         snprintf(key, sizeof(key), "vfile%d", result_index);
916         snprintf(value, sizeof(value), "%s/Calendar_%d.vcs", VFILE_PATH, record_index);
917
918         int fd = open(value, O_WRONLY|O_CREAT|O_TRUNC, 0644);
919         if (fd < 0) {
920                 ERR("open() is failed.");
921
922                 calendar_list_destroy(list, true);
923
924                 CAL_FREE(vcs_data);
925
926                 return;
927         }
928
929         int r = write(fd, vcs_data, strlen(vcs_data));
930         if (r == -1) {
931                 ERR("write() is failed.");
932         } else
933                 cal_util_update_media_db(value);
934
935         free(vcs_data);
936
937         fsync(fd);
938         close(fd);
939
940         error = calendar_list_destroy(list, true);
941         c_warn_if(error != CALENDAR_ERROR_NONE, "calendar_list_destroy() is failed(%x)");
942
943         r = service_add_extra_data(service, key, value);
944         c_ret_if(r != SERVICE_ERROR_NONE);
945 }
946
947 static void __cal_list_ug_add_bundle(service_h service, GList *record_index_list, struct ug_data *ugd)
948 {
949         c_ret_if(!service);
950         c_ret_if(!record_index_list);
951         c_ret_if(!ugd);
952
953         record_index_list = g_list_first(record_index_list);
954
955         int result_index = 0;
956
957         while (record_index_list && record_index_list->data) {
958
959                 int record_index = (int)record_index_list->data;
960
961                 switch (ugd->mode) {
962                 case _MODE_GET_EVT:
963                         __cal_list_ug_add_bundle_event_content(service, record_index, ++result_index);
964                         break;
965                 case _MODE_GET_VCS:
966                         __cal_list_ug_add_bundle_vcs(service, record_index, ++result_index);
967                         break;
968                 default:
969                         // do nothing
970                         break;
971                 }
972
973                 record_index_list = g_list_next(record_index_list);
974         }
975 }
976
977 static service_h __cal_list_ug_make_bundle(cal_list_ug_data *p, struct ug_data *ugd)
978 {
979         c_retv_if(!p, NULL);
980         c_retv_if(!ugd, NULL);
981
982         char buf[32] = {'\0'};
983
984         service_h service;
985         int r = service_create(&service);
986         c_retv_if(r != SERVICE_ERROR_NONE, NULL);
987
988         Elm_Object_Item* item = elm_genlist_first_item_get(p->genlist);
989         if (!item) {
990                 ERR("item is null");
991                 service_destroy(service);
992                 return NULL;
993         }
994
995         GList *record_index_list = NULL;
996
997         while (item) {
998
999                 cal_list_ug_item_data* item_data = elm_object_item_data_get(item);
1000                 if(!item_data)
1001                 {
1002                         ERR("elm_object_item_data_get() is failed!");
1003                         service_destroy(service);
1004                         return NULL;
1005                 }
1006
1007                 if (item_data->checked)
1008                         record_index_list = g_list_append(record_index_list, (void *)_calendar_get_record_index(item_data->record));
1009
1010                 item = elm_genlist_item_next_get(item);
1011         }
1012
1013         int count = 0;
1014
1015         if (record_index_list) {
1016                 __cal_list_ug_add_bundle(service, record_index_list, ugd);
1017
1018                 count = g_list_length(record_index_list);
1019
1020                 g_list_free(record_index_list);
1021         }
1022
1023         snprintf(buf, sizeof(buf), "%d", count);
1024
1025         r = service_add_extra_data(service, "count", buf);
1026         if(r != SERVICE_ERROR_NONE)
1027         {
1028                 ERR("service_add_extra_data_array() is failed(%d)", r);
1029                 service_destroy(service);
1030                 return NULL;
1031         }
1032
1033         char **value = calloc(count, sizeof(char *));
1034         if(!value)      {
1035                 ERR("value is NULL!");
1036                 service_destroy(service);
1037                 return NULL;
1038         }
1039
1040         int i = 0;
1041         char key[32] = {0};
1042
1043         for (i = 0; i < count; i++) {
1044                 snprintf(key, sizeof(key), "vfile%d", i + 1);
1045                 service_get_extra_data(service, key, &value[i]);
1046         }
1047
1048         r = service_add_extra_data_array(service, CAL_APPCONTROL_PATH, (const char **)value, count);
1049         if(r != SERVICE_ERROR_NONE)
1050         {
1051                 ERR("service_add_extra_data_array() is failed(%d)", r);
1052                 free(value);
1053                 service_destroy(service);
1054                 return NULL;
1055         }
1056
1057         if (ugd->item_type == ITEM_TYPE_EVENT)
1058                 r = service_add_extra_data(service, CAL_APPCONTROL_ITEM_TYPE, CAL_APPCONTROL_ITEM_TYPE_EVENT);
1059         else
1060                 r = service_add_extra_data(service, CAL_APPCONTROL_ITEM_TYPE, CAL_APPCONTROL_ITEM_TYPE_TODO);
1061
1062         c_warn_if(r != SERVICE_ERROR_NONE, "service_add_extra_data() is failed(%d)", r);
1063
1064         r = service_add_extra_data(service, "result", "success");
1065         c_warn_if(r != SERVICE_ERROR_NONE, "service_add_extra_data() is failed(%d)", r);
1066
1067         if(value)
1068                 free(value);
1069
1070         return service;
1071 }
1072
1073 static void __cal_list_ug_attach(void *data, Evas_Object *obj, void *ei)
1074 {
1075         c_retm_if(!data, "data is null");
1076
1077         Evas_Object *ly = data;
1078         cal_list_ug_data *p;
1079         struct ug_data *ugd;
1080         service_h service = NULL;
1081
1082         p = CAL_UTIL_GET_PRIV_DATA(ly);
1083         c_retm_if(!p, "p is null");
1084
1085         ugd = p->ugd;
1086         c_retm_if(!ugd, "ugd is null");
1087
1088         cal_util_hide_small_information(p->ly);
1089
1090         switch (ugd->mode) {
1091         case _MODE_GET_EVT:
1092         case _MODE_GET_VCS:
1093                 service = __cal_list_ug_make_bundle(p, ugd);
1094                 c_ret_if(!service);
1095                 break;
1096         default:
1097                 break;
1098         }
1099
1100         if (service) {
1101
1102                 ug_send_result(ugd->ug, service);
1103                 service_destroy(service);
1104         }
1105
1106         ug_destroy_me(ugd->ug);
1107 }
1108
1109 static void __cal_list_ug_add_controlbar( struct ug_data *ugd, Evas_Object *ly, const char* title)
1110 {
1111         Elm_Object_Item* navi_item = NULL;
1112
1113         cal_list_ug_data* p = evas_object_data_get(ly,"priv");
1114         c_retm_if(!p, "p is null");
1115
1116         navi_item = elm_naviframe_item_push(ugd->naviframe, title, NULL, NULL, ly, NULL);
1117         if (!navi_item)
1118         {
1119                 ERR("elm_naviframe_item_push returned null");
1120                 return;
1121         }
1122
1123         if (ugd->selection_mode == SELECTION_MODE_MULTIPLE) {
1124                 Evas_Object * attach_button = cal_util_add_toolbar_button(ugd->naviframe, "toolbar_button1", S_("IDS_COM_POP_ATTACH"), __cal_list_ug_attach, ly);
1125                 c_retm_if(!attach_button, "elm_toolbar_item_append returned null");
1126
1127                 p->bt = attach_button;
1128
1129                 elm_object_disabled_set(p->bt, EINA_TRUE);
1130         }
1131 }
1132
1133 void cal_list_ug_create(const char *title, struct ug_data *ugd)
1134 {
1135         Evas_Object *ly = __cal_list_ug_create_layout(ugd->naviframe, ugd);
1136         if (!ly)
1137                 return;
1138
1139         ugd->cont = ly;
1140
1141         __cal_list_ug_add_controlbar(ugd, ly, title);
1142 }
1143
1144 static void __cal_list_ug_searchbar_entry_changed_callback(void *data, Evas_Object *obj, void *event_info)
1145 {
1146         CAL_FN_START;
1147
1148         cal_list_ug_data *p = data;
1149         c_ret_if(!p);
1150
1151         p->searchtext = elm_object_text_get(elm_object_part_content_get(p->searchbar, "elm.swallow.content"));
1152
1153 // TODO: Show search result
1154         __cal_list_ug_update_callback(_calendar_event._uri, p);
1155
1156         if (0 < p->checked_event_count)
1157                 elm_object_disabled_set(p->bt, EINA_FALSE);
1158         else
1159                 elm_object_disabled_set(p->bt, EINA_TRUE);
1160
1161         __cal_list_ug_update_selection_info(p);
1162 }
1163
1164 static void __cal_list_ug_cancel_button_callback(void *data, Evas_Object *obj, void *event_info)
1165 {
1166         CAL_FN_START;
1167
1168         c_retm_if(!data, "data is null");
1169         cal_list_ug_data *p = data;
1170         Eina_List *l = NULL;
1171         cal_list_ug_item_data *item =NULL;
1172
1173         Evas_Object *en = elm_object_part_content_get(p->searchbar, "elm.swallow.content");
1174         c_retm_if(!en, "elm_object_part_content_get returned null");
1175
1176         Ecore_IMF_Context *imf_context = elm_entry_imf_context_get(en);
1177         c_retm_if(!imf_context, "elm_entry_imf_context_get returned null");
1178
1179         if (imf_context)
1180                 ecore_imf_context_input_panel_hide(imf_context);
1181
1182         if (0 < p->checked_event_count)
1183                 elm_object_disabled_set(p->bt, EINA_FALSE);
1184         else
1185                 elm_object_disabled_set(p->bt, EINA_TRUE);
1186
1187         p->checked_event_count = 0;
1188
1189         EINA_LIST_FOREACH(p->event_list, l, item) {
1190                 if (item != NULL && item->checked) {
1191                         p->checked_event_count++;
1192                 }
1193         }
1194
1195         __cal_list_ug_update_selection_info(p);
1196 }
1197
1198 static void __cal_list_ug_searchbar_entry_unfocused_callback(void *data, Evas_Object *obj, void *event_info)
1199 {
1200         c_retm_if(!data, "data is null.");
1201         cal_list_ug_data *p = data;
1202
1203         if (p->checked_event_count <= 0) {
1204                 elm_object_disabled_set(p->bt, EINA_TRUE);
1205         } else {
1206                 elm_object_disabled_set(p->bt, EINA_FALSE);
1207         }
1208
1209         __cal_list_ug_update_selection_info(p);
1210 }
1211
1212 static void __cal_list_ug_searchbar_clicked_callback(void *data, Evas_Object *obj, void *event_info)
1213 {
1214         c_retm_if(!data, "data is null.");
1215         cal_list_ug_data *p = data;
1216
1217         elm_object_disabled_set(p->bt, EINA_TRUE);
1218 }