54286ad84a8c2a8e662054f8a7571c3aec868a2a
[apps/core/preloaded/calendar.git] / ug / detail / detail-ug.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 #include <ui-gadget-module.h>
19 #include <libintl.h>
20
21 #include "cld.h"
22 #include "dialogue.h"
23
24 #include "reminder.h"
25 #include "external-ug.h"
26 #include "detail-common.h"
27 #include "detail-attendee.h"
28 #include "appcontrol.h"
29
30 typedef struct {
31
32         ui_gadget_h ug;
33
34         Evas_Object *base_layout;
35         Evas_Object *naviframe;
36         Evas_Object *window;
37         Evas_Object *dialogue;
38
39         Elm_Object_Item *navi_item;
40
41         calendar_record_h instance;
42         calendar_record_h record;
43
44         Ecore_Event_Handler *mouse_down_event_handler;
45         Evas_Coord mouse_down_x;
46         Evas_Coord mouse_down_y;
47
48         Evas_Object *title;
49         Evas_Object *from;
50         Evas_Object *to;
51         Evas_Object *due;
52         Evas_Object *reminder;
53         Evas_Object *recurrence;
54         Evas_Object *note;
55         Evas_Object *attendee;
56         Evas_Object *show_me_as;
57         Evas_Object *privacy;
58         Evas_Object *snote;
59         Evas_Object *photo;
60         Evas_Object *save_to;
61 } cal_detail_ug_data;
62 #define CAL_URI_FILE_FORMAT "file://"
63
64 static int __cal_detail_ug_initialize(cal_detail_ug_data *data)
65 {
66         CAL_FN_START;
67
68         calendar_error_e error = CALENDAR_ERROR_NONE;
69
70         error = calendar_connect();
71         c_warn_if(error != CALENDAR_ERROR_NONE, "calendar_connect() is failed(%x)", error);
72
73         _calendar_init_hash();
74
75         const char *path = bindtextdomain(CALENDAR, LOCALEDIR);
76         c_warn_if(!path, "bindtextdomain(%s, %s) is failed.", CALENDAR, LOCALEDIR);
77
78         cal_util_connect_pattern_generator();
79
80         return 0;
81 }
82
83 static void __cal_detail_ug_finish()
84 {
85         CAL_FN_START;
86
87         calendar_error_e error = CALENDAR_ERROR_NONE;
88
89         error = calendar_disconnect();
90         c_warn_if(error != CALENDAR_ERROR_NONE, "calendar_disconnect() is failed(%x)", error);
91
92         elm_theme_extension_del(NULL, EDJDIR "/calendar_theme.edj");
93
94         cal_util_disconnect_pattern_generator();
95 }
96
97 static void __cal_detail_ug_back_button_callback(void *user_data, Evas_Object *obj, void *ei)
98 {
99         CAL_FN_START;
100
101         c_ret_if(!user_data);
102
103         cal_detail_ug_data *data = user_data;
104
105         c_ret_if(!data->ug);
106
107         ug_destroy_me(data->ug);
108 }
109
110 static Evas_Object * __cal_detail_ug_add_back_button(cal_detail_ug_data *data)
111 {
112         CAL_FN_START;
113
114         Evas_Object *back_button = elm_button_add(data->naviframe);
115         c_retv_if(!back_button, NULL);
116
117         evas_object_smart_callback_add(back_button, "clicked", __cal_detail_ug_back_button_callback, data);
118
119         elm_object_style_set(back_button, "naviframe/end_btn/default");
120
121         return back_button;
122 }
123
124 static void __cal_detail_ug_update_title_language(Evas_Object *item, calendar_record_h record)
125 {
126         c_ret_if(!item);
127
128         char *summary = _calendar_get_summary(record);
129
130         elm_object_part_text_set(item, "elm.text.1", summary);
131
132         free(summary);
133 }
134
135 static Evas_Object * __cal_detail_ug_add_title(Evas_Object *box, calendar_record_h record)
136 {
137         CAL_FN_START;
138
139         c_retv_if(!box, NULL);
140         c_retv_if(!record, NULL);
141
142         Evas_Object *item = cal_dialogue_append_item(box, "2text", NULL, NULL);
143
144         __cal_detail_ug_update_title_language(item, record);
145
146         char *location = _calendar_get_location(record);
147
148         elm_object_part_text_set(item, "elm.text.2", location);
149
150         CAL_FREE(location);
151
152         return item;
153 }
154
155 static void __cal_detail_ug_update_from_language(Evas_Object *item)
156 {
157         c_ret_if(!item);
158
159         elm_object_part_text_set(item, "elm.text.1", C_("IDS_CLD_BODY_FROM"));
160 }
161
162 static void __cal_detail_ug_update_from_region(Evas_Object *item, calendar_record_h record)
163 {
164         c_ret_if(!item);
165
166         const char *time_format = NULL;
167
168         if (!_calendar_is_allday_record(record)) {
169                 if (is_hour24)
170                         time_format = CAL_UTIL_TIME_FORMAT_6;
171                 else
172                         time_format = CAL_UTIL_TIME_FORMAT_1;
173         }
174
175         calendar_time_s time = {0};
176
177         _calendar_get_start_time(record, &time);
178
179         char *from_time = _calendar_get_time_str(&time, CAL_UTIL_DATE_FORMAT_1, time_format);
180
181         elm_object_part_text_set(item, "elm.text.2", from_time);
182
183         free(from_time);
184 }
185
186 static Evas_Object * __cal_detail_ug_add_start_time(Evas_Object *box, calendar_record_h record)
187 {
188         CAL_FN_START;
189
190         c_retv_if(!box, NULL);
191         c_retv_if(!record, NULL);
192
193         Evas_Object *item = cal_dialogue_append_item(box, "2text", NULL, NULL);
194
195         __cal_detail_ug_update_from_language(item);
196
197         __cal_detail_ug_update_from_region(item, record);
198
199         return item;
200 }
201
202 static void __cal_detail_ug_update_to_language(Evas_Object *item)
203 {
204         c_ret_if(!item);
205
206         elm_object_part_text_set(item, "elm.text.1", C_("IDS_CLD_BODY_TO"));
207 }
208
209 static void __cal_detail_ug_update_to_region(Evas_Object *item, calendar_record_h record)
210 {
211         c_ret_if(!item);
212
213         const char *time_format = NULL;
214
215         if (!_calendar_is_allday_record(record)) {
216                 if (is_hour24)
217                         time_format = CAL_UTIL_TIME_FORMAT_6;
218                 else
219                         time_format = CAL_UTIL_TIME_FORMAT_1;
220         }
221
222         calendar_time_s time = {0};
223
224         _calendar_get_end_time(record, &time);
225
226         char *to_time = _calendar_get_time_str(&time, CAL_UTIL_DATE_FORMAT_1, time_format);
227
228         elm_object_part_text_set(item, "elm.text.2", to_time);
229
230         free(to_time);
231 }
232
233 static Evas_Object * __cal_detail_ug_add_end_time(Evas_Object *box, calendar_record_h record)
234 {
235         CAL_FN_START;
236
237         c_retv_if(!box, NULL);
238         c_retv_if(!record, NULL);
239
240         Evas_Object *item = cal_dialogue_append_item(box, "2text", NULL, NULL);
241
242         __cal_detail_ug_update_to_language(item);
243
244         __cal_detail_ug_update_to_region(item, record);
245
246         return item;
247 }
248
249 static void __cal_detail_ug_update_due_language(Evas_Object *item)
250 {
251         c_ret_if(!item);
252
253         elm_object_part_text_set(item, "elm.text.1", C_("IDS_CLD_BODY_DUE_DATE"));
254 }
255
256 static void __cal_detail_ug_update_due_region(Evas_Object *item, calendar_record_h record)
257 {
258         c_ret_if(!item);
259
260         const char *time_format = NULL;
261
262         if (!_calendar_is_allday_record(record)) {
263                 if (is_hour24)
264                         time_format = CAL_UTIL_TIME_FORMAT_6;
265                 else
266                         time_format = CAL_UTIL_TIME_FORMAT_1;
267         }
268
269         calendar_time_s due_time = {0};
270
271         _calendar_get_end_time(record, &due_time);
272
273         if (due_time.time.utime == CALENDAR_TODO_NO_DUE_DATE) {
274                 elm_object_part_text_set(item, "elm.text.1", C_("IDS_CLD_BODY_NO_DUE_DATE_M_NOUN"));
275         }
276         else
277         {
278                 char *due_time_text = _calendar_get_time_str(&due_time, CAL_UTIL_DATE_FORMAT_1, time_format);
279
280                 elm_object_part_text_set(item, "elm.text.2", due_time_text);
281                 free(due_time_text);
282         }
283
284 }
285
286 static Evas_Object * __cal_detail_ug_add_due_time(Evas_Object *box, calendar_record_h record)
287 {
288         CAL_FN_START;
289
290         c_retv_if(!box, NULL);
291         c_retv_if(!record, NULL);
292
293         Evas_Object *item = cal_dialogue_append_item(box, "2text", NULL, NULL);
294
295         __cal_detail_ug_update_due_language(item);
296
297         __cal_detail_ug_update_due_region(item, record);
298
299         return item;
300 }
301
302 static char * __cal_detail_ug_get_recurrence_text(calendar_record_h record)
303 {
304         CAL_FN_START;
305
306         c_retv_if(!record, NULL);
307
308         calendar_error_e error = CALENDAR_ERROR_NONE;
309
310         int freq = 0;
311
312         error = calendar_record_get_int(record, _calendar_event.freq, &freq);
313         c_warn_if(error != CALENDAR_ERROR_NONE, "calendar_record_get_int() is failed(%x)", error);
314
315         int interval = 0;
316
317         error = calendar_record_get_int(record, _calendar_event.interval, &interval);
318         c_warn_if(error != CALENDAR_ERROR_NONE, "calendar_record_get_int() is failed(%x)", error);
319
320         if (freq == CALENDAR_RECURRENCE_WEEKLY) {
321                 if (2 == interval)
322                         freq = CAL_REPEAT_EVERY_2_WEEK;
323
324         } else if (freq == CALENDAR_RECURRENCE_DAILY) {
325                 if (3 == interval)
326                         freq = CAL_REPEAT_EVERY_3_DAY;
327         }
328
329         char buf[128] = {0};
330
331         _calendar_get_recurrence_frequency_str(freq, buf, sizeof(buf));
332
333         return strdup(buf);
334 }
335
336 static GList * __cal_detail_ug_get_reminder_list(calendar_record_h record)
337 {
338         CAL_FN_START;
339
340         c_retv_if(!record, NULL);
341
342         GList *reminder_list = NULL;
343
344         int reminder_count = 0;
345         calendar_error_e error = CALENDAR_ERROR_NONE;
346
347         if (_calendar_is_task_record(record))
348                 error = calendar_record_get_child_record_count(record, _calendar_todo.calendar_alarm, (unsigned int *)&reminder_count);
349         else
350                 error = calendar_record_get_child_record_count(record, _calendar_event.calendar_alarm, (unsigned int *)&reminder_count);
351
352         c_warn_if(error != CALENDAR_ERROR_NONE, "calendar_record_get_child_record_count() is failed(%x)", error);
353
354         int i = 0;
355         for (i = 0; i < reminder_count; i++) {
356                 calendar_record_h calendar_alarm = NULL;
357
358                 if (_calendar_is_task_record(record))
359                         error = calendar_record_get_child_record_at_p(record, _calendar_todo.calendar_alarm, i, &calendar_alarm);
360                 else
361                         error = calendar_record_get_child_record_at_p(record, _calendar_event.calendar_alarm, i, &calendar_alarm);
362
363                 c_warn_if(error != CALENDAR_ERROR_NONE, "calendar_record_get_child_record_at_p() is failed(%x)", error);
364
365                 Cal_Reminder* reminder = cal_reminder_create(calendar_alarm);
366                 reminder_list = g_list_append(reminder_list, (void *)reminder);
367         }
368
369         if (reminder_list)
370                 reminder_list = g_list_first(reminder_list);
371
372         return reminder_list;
373 }
374
375 static void __cal_detail_ug_update_reminder_language(Evas_Object *item, calendar_record_h record)
376 {
377         c_ret_if(!item);
378
379         elm_object_part_text_set(item, "elm.text.1", C_("IDS_CLD_BODY_REMINDER"));
380
381         GList *reminder_list = __cal_detail_ug_get_reminder_list(record);
382         if (reminder_list) {
383
384                 char reminder_text[50] = {0};
385
386                 cal_reminder_get_string(reminder_list->data, reminder_text, sizeof(reminder_text));
387
388                 elm_object_part_text_set(item, "elm.text.2", reminder_text);
389
390                 g_list_free(reminder_list);
391         } else
392                 elm_object_part_text_set(item, "elm.text.2", S_("IDS_COM_BODY_OFF"));
393 }
394
395 static Evas_Object * __cal_detail_ug_add_reminder(Evas_Object *box, calendar_record_h record)
396 {
397         CAL_FN_START;
398
399         c_retv_if(!box, NULL);
400         c_retv_if(!record, NULL);
401
402         Evas_Object *item = cal_dialogue_append_item(box, "2text", NULL, NULL);
403
404         __cal_detail_ug_update_reminder_language(item, record);
405
406         return item;
407 }
408
409 static void __cal_detail_ug_update_recurrence_language(Evas_Object *item, calendar_record_h record)
410 {
411         c_ret_if(!item);
412
413         char *recurrence = __cal_detail_ug_get_recurrence_text(record);
414
415         elm_object_part_text_set(item, "elm.text.1", C_("IDS_CLD_BODY_REPEAT"));
416         elm_object_part_text_set(item, "elm.text.2", recurrence);
417
418         free(recurrence);
419 }
420
421 static Evas_Object * __cal_detail_ug_add_recurrence(Evas_Object *box, calendar_record_h record)
422 {
423         CAL_FN_START;
424
425         c_retv_if(!box, NULL);
426         c_retv_if(!record, NULL);
427
428         Evas_Object *item = cal_dialogue_append_item(box, "2text", NULL, NULL);
429
430         __cal_detail_ug_update_recurrence_language(item, record);
431
432         return item;
433 }
434
435 static inline char* __cal_detail_get_note_text(calendar_record_h record)
436 {
437         c_retv_if(!record, NULL);
438
439         char *note = NULL;
440
441         calendar_error_e error = CALENDAR_ERROR_NONE;
442
443         if (_calendar_is_task_record(record))
444                 error = calendar_record_get_str_p(record, _calendar_todo.description, &note);
445         else
446                 error = calendar_record_get_str_p(record, _calendar_event.description, &note);
447
448         c_warn_if(error != CALENDAR_ERROR_NONE, "calendar_record_get_str() is failed(%x)", error);
449
450         return note;
451 }
452
453 static Evas_Object * __cal_detail_ug_add_note(Evas_Object *box, calendar_record_h record)
454 {
455         CAL_FN_START;
456
457         c_retv_if(!box, NULL);
458         c_retv_if(!record, NULL);
459
460         char *note = __cal_detail_get_note_text(record);
461
462         if (!CAL_STRLEN(note))
463                 return NULL;
464
465         Evas_Object *item = cal_dialogue_append_item(box, "1icon", NULL, NULL);
466
467         Evas_Object *edit_field = cal_util_add_edit_field(item, NULL, NULL, EINA_FALSE, EINA_FALSE, EINA_TRUE);
468
469         if (!edit_field) {
470                 ERR("cal_util_add_edit_field() is failed.");
471
472                 evas_object_del(item);
473
474                 return NULL;
475         }
476
477         Evas_Object *entry = elm_object_part_content_get(edit_field, "elm.swallow.content");
478         if (!edit_field) {
479                 ERR("cal_util_add_edit_field() is failed.");
480
481                 evas_object_del(item);
482
483                 return NULL;
484         }
485
486         evas_object_size_hint_weight_set(entry, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
487         evas_object_size_hint_align_set(entry, EVAS_HINT_FILL, EVAS_HINT_EXPAND);
488         elm_entry_input_panel_enabled_set(entry, EINA_FALSE);
489         elm_entry_autocapital_type_set(entry, EINA_TRUE);
490
491         elm_entry_entry_set(entry, note);
492
493         elm_object_part_content_set(item, "elm.icon", edit_field);
494
495         return item;
496 }
497
498 static inline void __cal_detail_append_multibutton_entry_item(Evas_Object *mbe, calendar_record_h record)
499 {
500         cal_participant *part = calloc(1, sizeof(cal_participant));
501         c_ret_if(!part);
502
503         char *name = NULL;
504
505         calendar_error_e error = CALENDAR_ERROR_NONE;
506         error = calendar_record_get_str(record, _calendar_attendee.name, &name);
507         c_warn_if(error != CALENDAR_ERROR_NONE, "calendar_record_get_str() is failed(%x)", error);
508         if (!CAL_STRLEN(name)) {
509                 ERR("Attendee name is NULL!!");
510                 name = S_("IDS_COM_BODY_UNKNOWN");
511         }
512
513         part->name = CAL_STRDUP(name);
514
515         char *email = NULL;
516         error = calendar_record_get_str(record, _calendar_attendee.email, &email);
517         c_warn_if(error != CALENDAR_ERROR_NONE, "calendar_record_get_str() is failed(%x)", error);
518
519         if (CAL_STRLEN(email))
520                 part->email = strdup(email);
521         else
522                 ERR("Attendee email is mandatory data!! There is no email for %s.", part->name);
523
524         error = calendar_record_get_int(record, _calendar_attendee.person_id, &part->person_id);
525         c_warn_if(error != CALENDAR_ERROR_NONE, "calendar_record_get_int() is failed(%x)", error);
526
527         error = calendar_record_get_int(record, _calendar_attendee.status, &part->status);
528         c_warn_if(error != CALENDAR_ERROR_NONE, "calendar_record_get_int() is failed(%x)", error);
529
530         error = calendar_record_get_int(record, _calendar_attendee.role, &part->role);
531         c_warn_if(error != CALENDAR_ERROR_NONE, "calendar_record_get_int() is failed(%x)", error);
532
533         error = calendar_record_get_int(record, _calendar_attendee.rsvp, &part->response);
534         c_warn_if(error != CALENDAR_ERROR_NONE, "calendar_record_get_int() is failed(%x)", error);
535
536         elm_multibuttonentry_item_append(mbe, name, NULL, part);
537 }
538
539 static inline void __cal_detail_set_multibutton_entry_item(Evas_Object *multibutton_entry, calendar_record_h record)
540 {
541         c_ret_if(!multibutton_entry);
542         c_ret_if(!record);
543
544         int attendee_count = 0;
545
546         calendar_error_e error = CALENDAR_ERROR_NONE;
547
548         error = calendar_record_get_child_record_count(record, _calendar_event.calendar_attendee, (unsigned int *)&attendee_count);
549         c_warn_if(error != CALENDAR_ERROR_NONE, "calendar_record_get_child_record_count() is failed(%x)", error);
550
551         int i = 0;
552
553         for (i = 0; i < attendee_count; i++) {
554                 calendar_record_h calendar_attendee = NULL;
555
556                 error = calendar_record_get_child_record_at_p(record, _calendar_event.calendar_attendee, i, &calendar_attendee);
557                 if (error != CALENDAR_ERROR_NONE) {
558                         ERR("calendar_record_get_child_record_at_p() is failed(%x)", error);
559                         continue;
560                 }
561
562                 __cal_detail_append_multibutton_entry_item(multibutton_entry, calendar_attendee);
563         }
564 }
565
566 static void __cal_detail_popup_hide_callback(void *data, Evas_Object *obj, void *ei)
567 {
568         evas_object_del(obj);
569 }
570
571 static void __cal_detail_show_ctx_popup(cal_detail_ug_data *data, cal_participant *part)
572 {
573         c_ret_if(!data);
574         c_ret_if(!part);
575
576         Evas_Object *ctx_popup = elm_ctxpopup_add(data->naviframe);
577         c_ret_if(!ctx_popup);
578
579         int person_id = part->person_id;
580         char *name = part->name;
581
582         if (0 < person_id) {
583                 cal_detail_common_get_person_default_number(person_id, &part->number);
584
585                 char *number = part->number;
586
587                 evas_object_smart_callback_add(ctx_popup, "dismissed", __cal_detail_popup_hide_callback, data);
588
589                 if (CAL_STRLEN(number)) {
590                         elm_ctxpopup_item_append(ctx_popup, S_("IDS_COM_BODY_VOICE_CALL"), NULL, cal_detail_common_ctx_callback_for_voice_call, number);
591
592                         elm_ctxpopup_item_append(ctx_popup, S_("IDS_COM_BODY_MESSAGE"), NULL, cal_detail_common_ctx_callback_for_message, number);
593                 }
594
595                 if (CAL_STRLEN(part->email)) {
596                         elm_ctxpopup_item_append(ctx_popup, S_("IDS_COM_BODY_EMAIL"), NULL, cal_detail_common_ctx_callback_for_email, part->email);
597                 }
598         }
599         else {
600                 evas_object_smart_callback_add(ctx_popup, "dismissed", __cal_detail_popup_hide_callback, NULL);
601
602                 elm_ctxpopup_item_append(ctx_popup, S_("IDS_COM_BODY_EMAIL"), NULL, cal_detail_common_ctx_callback_for_email, name);
603                 elm_ctxpopup_item_append(ctx_popup, S_("IDS_COM_OPT_ADD_TO_CONTACTS"), NULL, cal_detail_common_ctx_callback_for_contact, name);
604         }
605
606         evas_object_data_set(ctx_popup, "record", data->record);
607         evas_object_move(ctx_popup, data->mouse_down_x, data->mouse_down_y);
608         evas_object_show(ctx_popup);
609 }
610
611 static void __cal_detail_multibuttonentry_item_selected_callback(void *user_data, Evas_Object *obj, void *ei)
612 {
613         c_ret_if(!ei);
614         c_ret_if(!user_data);
615
616         Elm_Object_Item *it = ei;
617         cal_detail_ug_data *data = user_data;
618
619         cal_participant *part = elm_object_item_data_get(it);
620         c_ret_if(!part);
621
622         __cal_detail_show_ctx_popup(data, part);
623 }
624
625 static void __cal_detail_multibuttonentry_item_deleted_callback(void *data, Evas_Object *obj, void *ei)
626 {
627         c_ret_if(!ei);
628
629         Elm_Object_Item *item = ei;
630
631         cal_participant *part = elm_object_item_data_get(item);
632         c_ret_if(!part);
633
634         CAL_FREE(part->name);
635
636         free(part);
637 }
638
639 static void __cal_detail_multibuttonentry_unfocused_callback(void *data, Evas_Object *obj, void *ei)
640 {
641         c_ret_if(!obj);
642
643         elm_multibuttonentry_item_selected_set(elm_multibuttonentry_selected_item_get(obj), EINA_FALSE);
644 }
645
646 static Eina_Bool __cal_detail_mouse_down_callback(void *user_data, int type, void *event)
647 {
648         c_retv_if(!user_data, ECORE_CALLBACK_RENEW);
649         c_retv_if(!event, ECORE_CALLBACK_RENEW);
650
651         cal_detail_ug_data *data = user_data;
652
653         Ecore_Event_Mouse_Button *ev= event;
654
655
656         data->mouse_down_x = ev->x;
657         data->mouse_down_y = ev->y;
658
659         return ECORE_CALLBACK_RENEW;
660 }
661
662 static Evas_Object * __cal_detail_add_multibutton_entry(Evas_Object *item, cal_detail_ug_data *data)
663 {
664         c_retv_if(!item, NULL);
665         c_retv_if(!data, NULL);
666
667         Evas_Object *multibutton_entry = elm_multibuttonentry_add(item);
668         c_retv_if(!multibutton_entry, NULL);
669
670         evas_object_size_hint_weight_set(multibutton_entry, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
671         evas_object_size_hint_align_set(multibutton_entry, EVAS_HINT_FILL, EVAS_HINT_FILL);
672
673         evas_object_smart_callback_add(multibutton_entry, "item,selected", __cal_detail_multibuttonentry_item_selected_callback, data);
674         evas_object_smart_callback_add(multibutton_entry, "item,deleted", __cal_detail_multibuttonentry_item_deleted_callback, NULL);
675         evas_object_smart_callback_add(multibutton_entry, "unfocused", __cal_detail_multibuttonentry_unfocused_callback, NULL);
676
677         Evas_Object *entry = elm_multibuttonentry_entry_get(multibutton_entry);
678         if (entry)
679                 elm_entry_editable_set(entry, EINA_FALSE);
680
681         evas_object_show(multibutton_entry);
682
683         if (!data->mouse_down_event_handler)
684                 data->mouse_down_event_handler = ecore_event_handler_add(ECORE_EVENT_MOUSE_BUTTON_DOWN, __cal_detail_mouse_down_callback, data);
685
686         return multibutton_entry;
687 }
688
689 static void __cal_detail_attendee_status_button_callback(void *user_data, Evas_Object *obj, void *event_info)
690 {
691         CAL_FN_START;
692
693         c_ret_if(!user_data);
694
695         cal_detail_ug_data *data = user_data;
696
697         cal_detail_attendee_create_view(data->naviframe, data->record);
698 }
699
700 static Evas_Object * __cal_detail_ug_add_attendee(Evas_Object *box, calendar_record_h record, cal_detail_ug_data *data)
701 {
702         CAL_FN_START;
703
704         c_retv_if(!box, NULL);
705         c_retv_if(!record, NULL);
706         c_retv_if(!data, NULL);
707
708         int attendee_count = 0;
709
710         calendar_error_e error = CALENDAR_ERROR_NONE;
711
712         error = calendar_record_get_child_record_count(record, _calendar_event.calendar_attendee, (unsigned int *)&attendee_count);
713         c_warn_if(error != CALENDAR_ERROR_NONE, "calendar_record_get_child_record_count() is failed(%x)", error);
714
715         if (!attendee_count)
716                 return NULL;
717
718         Evas_Object *item = cal_dialogue_append_item(box, "1icon", NULL, NULL);
719
720         Evas_Object *multibutton_entry = __cal_detail_add_multibutton_entry(item, data);
721
722         __cal_detail_set_multibutton_entry_item(multibutton_entry, record);
723
724         elm_object_part_content_set(item, "elm.icon", multibutton_entry);
725
726         Evas_Object *attendee_status_button = elm_button_add(item);
727         c_retv_if(!attendee_status_button, item);
728
729         cal_util_set_controlbar_button(attendee_status_button, NULL, "reveal/extended", __cal_detail_attendee_status_button_callback, data);
730
731         elm_object_part_content_set(item, "elm.icon.2", attendee_status_button);
732
733         return item;
734 }
735
736 static void __cal_detail_get_save_to_text(int calendar_book_id, char *buf, int sz)
737 {
738         char *str = NULL;
739         calendar_error_e error = CALENDAR_ERROR_NONE;
740         calendar_record_h calendar = NULL;
741
742         error = calendar_db_get_record(_calendar_book._uri, calendar_book_id, &calendar);
743         c_ret_if(error != CALENDAR_ERROR_NONE);
744
745         if (calendar_book_id == DEFAULT_EVENT_CALENDAR_BOOK_ID)
746                 str =  C_("IDS_CLD_BODY_MY_CALENDAR");
747         else if (calendar_book_id == DEFAULT_TODO_CALENDAR_BOOK_ID)
748                 str =  C_("IDS_TASK_BODY_MY_TASK");
749         else {
750                 error = calendar_record_get_str_p(calendar, _calendar_book.name, &str);
751                 c_warn_if(error != CALENDAR_ERROR_NONE, "calendar_record_get_str() is failed(%x)", error);
752         }
753
754         snprintf(buf, sz, "%s", str);
755
756         error = calendar_record_destroy(calendar, true);
757         c_warn_if(error != CALENDAR_ERROR_NONE, "calendar_record_destroy() is failed(%x)", error);
758 }
759
760 static void __cal_detail_ug_update_saveto_language(Evas_Object *item, calendar_record_h record)
761 {
762         c_ret_if(!item);
763
764         elm_object_part_text_set(item, "elm.text.1", C_("IDS_ST_BODY_SAVE_TO"));
765
766         char calendar_name[128] = {0};
767
768         __cal_detail_get_save_to_text(_calendar_get_calendar_index(record), calendar_name, sizeof(calendar_name));
769
770         elm_object_part_text_set(item, "elm.text.2", calendar_name);
771 }
772
773 static Evas_Object * __cal_detail_ug_add_save_to(Evas_Object *box, calendar_record_h record)
774 {
775         CAL_FN_START;
776
777         c_retv_if(!box, NULL);
778         c_retv_if(!record, NULL);
779
780         Evas_Object *item = cal_dialogue_append_item(box, "2text", NULL, NULL);
781
782         __cal_detail_ug_update_saveto_language(item, record);
783
784         return item;
785 }
786
787 static void __cal_detail_ug_add_dialogue_item(cal_detail_ug_data *data)
788 {
789         c_ret_if(!data);
790
791         Evas_Object *dialogue = data->dialogue;
792
793         calendar_record_h record = data->record;
794
795         calendar_record_h instance = data->instance;
796
797         Evas_Object *box = cal_dialogue_get_box(dialogue);
798
799         data->title = __cal_detail_ug_add_title(box, record);
800
801         if (!instance)
802                 instance = record;
803
804         if (!_calendar_is_task_record(instance)) {
805                 data->from = __cal_detail_ug_add_start_time(box, instance);
806
807                 data->to = __cal_detail_ug_add_end_time(box, instance);
808         } else
809                 data->due = __cal_detail_ug_add_due_time(box, instance);
810
811         data->reminder = __cal_detail_ug_add_reminder(box, record);
812
813         if (!_calendar_is_task_record(record))
814                 data->recurrence = __cal_detail_ug_add_recurrence(box, record);
815
816         data->note = __cal_detail_ug_add_note(box, record);
817
818         if (_calendar_is_eas_record(record)) {
819                 if (!_calendar_is_task_record(record))
820                         data->attendee = __cal_detail_ug_add_attendee(box, record, data);
821
822         }
823
824         data->save_to = __cal_detail_ug_add_save_to(box, record);
825 }
826
827 static Evas_Object * __cal_detail_ug_create_dialogue(cal_detail_ug_data *data)
828 {
829         CAL_FN_START;
830
831         c_retv_if(!data, NULL);
832
833         Evas_Object *parent = data->naviframe;
834
835         Evas_Object *dialogue = cal_dialogue_create(parent);
836
837         data->dialogue = dialogue;
838
839         __cal_detail_ug_add_dialogue_item(data);
840
841         return dialogue;
842 }
843
844 static void inline __cal_detail_ug_clone_record(const calendar_record_h source_record, calendar_record_h *target_record)
845 {
846         CAL_FN_START;
847
848         c_ret_if(!source_record);
849         c_ret_if(!target_record);
850
851         calendar_error_e error = CALENDAR_ERROR_NONE;
852
853         error = calendar_record_clone(source_record, target_record);
854         c_warn_if(error != CALENDAR_ERROR_NONE, "calendar_record_clone() is failed(%x)", error);
855 }
856
857 static inline void __cal_detail_ug_update_record(calendar_record_h *record)
858 {
859         calendar_error_e error = CALENDAR_ERROR_NONE;
860
861         int record_index = _calendar_get_record_index(*record);
862         c_ret_if(record_index < 0);
863
864         error = calendar_record_destroy(*record, true);
865         c_warn_if(error != CALENDAR_ERROR_NONE, "calendar_record_destroy() is failed(%x)", error);
866
867         *record = _calendar_get_record_with_index(record_index);
868 }
869
870 static void __cal_detail_update_view(const char* view_uri, void* user_data)
871 {
872         CAL_FN_START;
873
874         c_ret_if(!user_data);
875
876         cal_detail_ug_data *data = user_data;
877
878         __cal_detail_ug_update_record(&data->record);
879
880         Evas_Object *dialogue = data->dialogue;
881
882         cal_dialogue_delete_all_items(dialogue);
883
884         __cal_detail_ug_add_dialogue_item(data);
885 }
886
887 static void __cal_detail_remove_db_changed_callback(cal_detail_ug_data *data)
888 {
889         CAL_FN_START;
890
891         c_ret_if(!data);
892
893         calendar_error_e error = CALENDAR_ERROR_NONE;
894
895         error = calendar_db_remove_changed_cb(_calendar_event._uri, __cal_detail_update_view, data);
896         c_warn_if(error != CALENDAR_ERROR_NONE, "calendar_db_remove_changed_cb() is failed(%x)", error);
897
898         error = calendar_db_remove_changed_cb(_calendar_todo._uri, __cal_detail_update_view, data);
899         c_warn_if(error != CALENDAR_ERROR_NONE, "calendar_db_remove_changed_cb() is failed(%x)", error);
900 }
901
902 static void __cal_detail_add_db_changed_callback(cal_detail_ug_data *data)
903 {
904         CAL_FN_START;
905
906         c_ret_if(!data);
907
908         calendar_error_e error = CALENDAR_ERROR_NONE;
909
910         error = calendar_db_add_changed_cb(_calendar_event._uri, __cal_detail_update_view, data);
911         c_warn_if(error != CALENDAR_ERROR_NONE, "calendar_db_remove_changed_cb() is failed(%x)", error);
912
913         error = calendar_db_add_changed_cb(_calendar_todo._uri, __cal_detail_update_view, data);
914         c_warn_if(error != CALENDAR_ERROR_NONE, "calendar_db_remove_changed_cb() is failed(%x)", error);
915 }
916
917 static void __cal_detail_ug_edit_ug_result_callback(ui_gadget_h ug, service_h result, void *priv)
918 {
919         CAL_FN_START;
920
921         c_ret_if(!result);
922         c_ret_if(!priv);
923
924         int record_index = 0;
925         long long int base_time = 0;
926
927         char *value = NULL;
928
929         int ret = service_get_extra_data(result, "record_index", &value);
930         c_warn_if(ret != SERVICE_ERROR_NONE, "service_get_extra_data() is failed(%x)", ret);
931
932         if (CAL_STRLEN(value))
933                 record_index = atoi(value);
934
935         CAL_FREE(value);
936
937         ret = service_get_extra_data(result, "base_time", &value);
938         c_warn_if(ret != SERVICE_ERROR_NONE, "service_get_extra_data() is failed(%x)", ret);
939
940         base_time = strtoll(value, NULL, 10);
941
942         CAL_FREE(value);
943
944         cal_detail_ug_data *data = priv;
945
946         calendar_error_e error = calendar_record_destroy(data->record, true);
947         c_warn_if(error != CALENDAR_ERROR_NONE, "calendar_record_destroy() is failed(%x)", error);
948
949         data->record = _calendar_get_record_with_index(record_index);
950
951         if (data->instance) {
952                 error = calendar_record_destroy(data->instance, true);
953                 c_warn_if(error != CALENDAR_ERROR_NONE, "calendar_record_destroy() is failed(%x)", error);
954
955                 data->instance = NULL;
956         }
957
958         if(!_calendar_is_task_record(data->record))
959         {
960                 struct tm tm_start = {0};
961
962                 cal_util_convert_lli_to_tm(NULL, base_time, &tm_start);
963
964                 struct tm tm_end = tm_start;
965
966                 cal_util_update_tm_day(&tm_end, 1);
967
968                 data->instance = _calendar_get_instance_from_record(data->record, &tm_start, &tm_end);
969                 c_ret_if(!data->instance);
970         }
971
972         Evas_Object *dialogue = data->dialogue;
973
974         cal_dialogue_delete_all_items(dialogue);
975
976         __cal_detail_ug_add_dialogue_item(data);
977
978         __cal_detail_add_db_changed_callback(data);
979 }
980
981 static void __cal_detail_ug_edit_ug_destroy_callback(ui_gadget_h ug, void *priv)
982 {
983         CAL_FN_START;
984
985         c_ret_if(!priv);
986
987         cal_detail_ug_data *data = priv;
988
989         Evas_Object *edit_button = elm_object_item_part_content_get(data->navi_item, "toolbar_button1");
990         if(elm_object_disabled_get(edit_button))
991                 elm_object_disabled_set(edit_button, EINA_FALSE);
992
993         ug_destroy(ug);
994 }
995
996 static void __cal_detail_launch_edit_ug(cal_detail_ug_data *data, calendar_record_h record)
997 {
998         c_ret_if(!data);
999
1000         calendar_record_h cloned_record = NULL;
1001
1002         __cal_detail_ug_clone_record(record, &cloned_record);
1003
1004         char record_address[16] = {0};
1005
1006         snprintf(record_address, sizeof(record_address), "%p", (void *)cloned_record);
1007
1008         struct ug_cbs cbs = {0};
1009
1010         cbs.result_cb = __cal_detail_ug_edit_ug_result_callback;
1011         cbs.destroy_cb = __cal_detail_ug_edit_ug_destroy_callback;
1012         cbs.priv = data;
1013
1014         cal_launch_ug_with_var(data->ug, "calendar-edit-efl", &cbs, "record", record_address, NULL);
1015
1016         __cal_detail_remove_db_changed_callback(data);
1017 }
1018
1019 static void __cal_detail_event_edit_popup_response_callback(void *user_data, Evas_Object *obj, void *event_info)
1020 {
1021         c_ret_if(!user_data);
1022         c_ret_if(!obj);
1023
1024         Evas_Object *popup = user_data;
1025         Evas_Object *button = obj;
1026
1027         cal_detail_ug_data *data = evas_object_data_get(popup, "data");
1028
1029         if (!strcmp(elm_object_text_get(button), C_("IDS_CLD_BODY_ONLY_THIS_EVENT")))
1030                 __cal_detail_launch_edit_ug(data, data->instance);
1031         else if (!strcmp(elm_object_text_get(button), C_("IDS_CLD_POP_ALL_REPETITIVE_EVENTS"))
1032                 || !strcmp(elm_object_text_get(button), S_("IDS_COM_SK_OK")))
1033                 __cal_detail_launch_edit_ug(data, data->record);
1034
1035         evas_object_del(popup);
1036 }
1037
1038 static void __cal_detail_edit_button_callback(void *user_data, Evas_Object *obj, void *ei)
1039 {
1040         CAL_FN_START;
1041
1042         c_ret_if(!user_data);
1043
1044         cal_detail_ug_data *data = user_data;
1045
1046         calendar_record_h record = data->record;
1047
1048         if (_calendar_is_recurrent_record(record)) {
1049                 cal_util_add_popup(data->window, "verticalbuttonstyle", NULL, C_("IDS_CLD_HEADER_EDIT_EVENT"), __cal_detail_event_edit_popup_response_callback, data,
1050                         C_("IDS_CLD_BODY_ONLY_THIS_EVENT"), C_("IDS_CLD_POP_ALL_REPETITIVE_EVENTS"),
1051                         S_("IDS_COM_SK_CANCEL"), NULL);
1052         } else {
1053                 __cal_detail_launch_edit_ug(data, record);
1054                 elm_object_disabled_set(obj, EINA_TRUE);
1055         }
1056 }
1057
1058 static void __cal_detail_save_button_callback(void *user_data, Evas_Object *obj, void *ei)
1059 {
1060         CAL_FN_START;
1061
1062         c_ret_if(!user_data);
1063
1064         cal_detail_ug_data *data = user_data;
1065
1066         calendar_record_h record = data->record;
1067
1068         calendar_error_e error = CALENDAR_ERROR_NONE;
1069
1070         error = calendar_db_insert_record(record, NULL);
1071         if (error != CALENDAR_ERROR_NONE) {
1072                 ERR("calendar_db_insert_record() is failed(%x)", error);
1073         } else {
1074                 int r = notification_status_message_post(S_("IDS_COM_POP_SAVED"));
1075                 c_warn_if(r != NOTIFICATION_ERROR_NONE, "notification_status_message_post() is failed(%d)", r);
1076         }
1077 }
1078
1079 static void __cal_detail_delete_event(cal_detail_ug_data *data, Eina_Bool is_delete_all)
1080 {
1081         CAL_FN_START;
1082
1083         c_ret_if(!data);
1084
1085         calendar_record_h record = data->record;
1086
1087         if (!is_delete_all)
1088                 _calendar_delete_recurrence_instance(data->instance);
1089         else
1090                 _calendar_delete_record(record);
1091
1092         int r = notification_status_message_post(S_("IDS_COM_POP_DELETED"));
1093         c_warn_if(r != NOTIFICATION_ERROR_NONE, "notification_status_message_post() is failed(%d)", r);
1094
1095         ug_destroy_me(data->ug);
1096 }
1097
1098 static void __cal_detail_delete_popup_response_event_callback(void *user_data, Evas_Object *obj, void *event_info)
1099 {
1100         c_ret_if(!user_data);
1101         c_ret_if(!obj);
1102
1103         Evas_Object *popup = user_data;
1104         Evas_Object *button = obj;
1105
1106         cal_detail_ug_data *data = evas_object_data_get(popup, "data");
1107         c_ret_if(!data);
1108
1109         if (NULL != strstr(elm_object_text_get(button), S_("IDS_COM_BODY_DELETE")))
1110                 __cal_detail_delete_event(data, EINA_TRUE);
1111         else if (!strcmp(elm_object_text_get(button), C_("IDS_CLD_BODY_ONLY_THIS_EVENT")))
1112                 __cal_detail_delete_event(data, EINA_FALSE);
1113         else if (!strcmp(elm_object_text_get(button), C_("IDS_CLD_POP_ALL_REPETITIVE_EVENTS")))
1114                 __cal_detail_delete_event(data, EINA_TRUE);
1115
1116         evas_object_del(popup);
1117 }
1118
1119 static inline void __cal_detail_show_task_delete_popup(cal_detail_ug_data *data, calendar_record_h record)
1120 {
1121         CAL_FN_START;
1122
1123         cal_util_add_popup(data->window, NULL, NULL, S_("IDS_COM_POP_DELETE_Q"), __cal_detail_delete_popup_response_event_callback, data,
1124                                 S_("IDS_COM_BODY_DELETE"), S_("IDS_COM_SK_CANCEL"), NULL);
1125 }
1126
1127 static inline void __cal_detail_show_event_delete_popup(cal_detail_ug_data *data, calendar_record_h record)
1128 {
1129         CAL_FN_START;
1130
1131         if (_calendar_is_recurrent_record(record)) {
1132                 cal_util_add_popup(data->window, "verticalbuttonstyle", NULL, C_("IDS_CLD_OPT_DELETE_EVENT"), __cal_detail_delete_popup_response_event_callback, data,
1133                         C_("IDS_CLD_BODY_ONLY_THIS_EVENT"), C_("IDS_CLD_POP_ALL_REPETITIVE_EVENTS"),S_("IDS_COM_SK_CANCEL"), NULL);
1134         }
1135         else {
1136                 cal_util_add_popup(data->window, NULL, NULL, S_("IDS_COM_POP_DELETE_Q"), __cal_detail_delete_popup_response_event_callback, data,
1137                         S_("IDS_COM_BODY_DELETE"), S_("IDS_COM_SK_CANCEL"), NULL);
1138         }
1139 }
1140
1141 static void __cal_detail_delete_button_callback(void *user_data, Evas_Object *obj, void *ei)
1142 {
1143         CAL_FN_START;
1144
1145         c_ret_if(!user_data);
1146         c_ret_if(!obj);
1147
1148         cal_detail_ug_data *data = user_data;
1149
1150         Evas_Object *ctx_popup = obj;
1151
1152         calendar_record_h record = data->record;
1153         c_ret_if(!record);
1154
1155         evas_object_del(ctx_popup);
1156
1157         if (_calendar_is_task_record(record))
1158                 __cal_detail_show_task_delete_popup(data, record);
1159         else
1160                 __cal_detail_show_event_delete_popup(data, record);
1161 }
1162
1163 static void  __cal_detail_share_popup_hide_callback(void *data, Evas_Object *obj, void *event_info)
1164 {
1165         c_ret_if(!data);
1166
1167         Evas_Object *popup = data;
1168
1169         evas_object_del(popup);
1170 }
1171
1172 static void __cal_detail_via_message_callback(void *user_data, Evas_Object *obj, void *ei)
1173 {
1174         c_ret_if(!user_data);
1175         c_ret_if(!obj);
1176
1177         cal_detail_ug_data *data = user_data;
1178
1179         _calendar_export_record_to_vcs(data->record, CAL_MESSAGE_VCS);
1180
1181         cal_launch_ug_with_var(data->ug, CAL_MESSAGE_COMPOSER_UG, NULL, "ATTACHFILE", CAL_MESSAGE_VCS, NULL);
1182
1183         evas_object_del(obj);
1184 }
1185
1186 static void __cal_detail_via_email_callback(void *user_data, Evas_Object *obj, void *ei)
1187 {
1188         c_ret_if(!user_data);
1189         c_ret_if(!obj);
1190
1191         cal_detail_ug_data *data = user_data;
1192
1193         _calendar_export_record_to_vcs(data->record, CAL_EMAIL_VCS);
1194
1195         cal_launch_ug_with_var(data->ug, CAL_EMAIL_COMPOSER_UG, (struct ug_cbs *)data, "RUN_TYPE", "5", "ATTACHMENT", CAL_EMAIL_VCS, NULL);
1196
1197         evas_object_del(obj);
1198 }
1199
1200 static void __cal_detail_via_bluetooth_callback(void *user_data, Evas_Object *obj, void *ei)
1201 {
1202         c_ret_if(!user_data);
1203         c_ret_if(!obj);
1204
1205         cal_detail_ug_data *data = user_data;
1206
1207         _calendar_export_record_to_vcs(data->record, CAL_BLUETOOTH_VCS);
1208
1209         cal_launch_ug_with_var(data->ug, CAL_BLUETOOTH_UG, NULL, "launch-type", "send", "filecount", "1", "files", CAL_BLUETOOTH_VCS, NULL);
1210
1211         evas_object_del(obj);
1212 }
1213
1214 static void __cal_detail_share_button_callback(void *user_data, Evas_Object *obj, void *ei)
1215 {
1216         c_ret_if(!user_data);
1217         c_ret_if(!obj);
1218
1219         cal_detail_ug_data *data = user_data;
1220
1221         Evas_Object *ctx_popup = obj;
1222
1223         evas_object_del(ctx_popup);
1224
1225         Evas_Object *popup = cal_util_add_popup(data->window, NULL, S_("IDS_COM_BUTTON_SHARE"), NULL, __cal_detail_share_popup_hide_callback, data, S_("IDS_COM_BODY_CLOSE"), NULL);
1226         c_ret_if(!popup);
1227
1228         evas_object_data_set(popup, "priv", data);
1229
1230         Elm_Object_Item *popup_item = elm_popup_item_append(popup, S_("IDS_COM_BODY_MESSAGE"), NULL, __cal_detail_via_message_callback, data);
1231         c_ret_if(!popup_item);
1232
1233         popup_item = elm_popup_item_append(popup, S_("IDS_COM_BODY_EMAIL"), NULL, __cal_detail_via_email_callback, data);
1234         c_ret_if(!popup_item);
1235
1236         popup_item = elm_popup_item_append(popup, S_("IDS_COM_BODY_BLUETOOTH"), NULL, __cal_detail_via_bluetooth_callback, data);
1237         c_ret_if(!popup_item);
1238 }
1239
1240 static void __cal_detail_more_button_callback(void *user_data, Evas_Object *obj, void *event_info)
1241 {
1242         c_ret_if(!user_data);
1243         c_ret_if(!obj);
1244
1245         cal_detail_ug_data *data = user_data;
1246
1247         Evas_Object *ctx_popup = elm_ctxpopup_add(data->naviframe);
1248         c_ret_if(!ctx_popup);
1249
1250         elm_ctxpopup_direction_priority_set(ctx_popup, ELM_CTXPOPUP_DIRECTION_UP, ELM_CTXPOPUP_DIRECTION_UP, ELM_CTXPOPUP_DIRECTION_UP, ELM_CTXPOPUP_DIRECTION_UP);
1251
1252         Elm_Object_Item *item = NULL;
1253
1254         item = elm_ctxpopup_item_append(ctx_popup, S_("IDS_COM_BODY_DELETE"), NULL, __cal_detail_delete_button_callback, data);
1255         c_ret_if(!item);
1256
1257         item = elm_ctxpopup_item_append(ctx_popup, S_("IDS_COM_BUTTON_SHARE"), NULL, __cal_detail_share_button_callback, data);
1258         c_ret_if(!item);
1259
1260         Evas_Coord_Rectangle r = {0};
1261
1262         cal_util_get_geometry(&r, obj);
1263
1264         evas_object_move(ctx_popup, r.x + r.w/2, r.y + r.h/2);
1265
1266         evas_object_show(ctx_popup);
1267 }
1268
1269 static Evas_Object *__cal_detail_ug_create_layout(Evas_Object *parent, cal_detail_ug_data *data)
1270 {
1271         CAL_FN_START;
1272
1273         c_retv_if(!parent, NULL);
1274         c_retv_if(!data, NULL);
1275
1276         Evas_Object *base_layout = cal_util_add_layout(parent, NULL);
1277         c_retv_if(!base_layout, NULL);
1278
1279         Evas_Object *naviframe = elm_naviframe_add(base_layout);
1280         if (!naviframe) {
1281                 ERR("elm_naviframe_add() is failed");
1282
1283                 evas_object_del(base_layout);
1284
1285                 return NULL;
1286         }
1287
1288         evas_object_show(naviframe);
1289
1290         Evas_Object *bg = cal_util_add_bg(base_layout, EINA_FALSE);
1291         if (!bg) {
1292                 ERR("cal_util_add_bg() is failed");
1293
1294                 evas_object_del(base_layout);
1295
1296                 return NULL;
1297         }
1298
1299         data->base_layout = base_layout;
1300         data->naviframe = naviframe;
1301
1302         cal_util_initialize_timezone();
1303
1304         Evas_Object *dialogue = __cal_detail_ug_create_dialogue(data);
1305
1306         Evas_Object *back_button = __cal_detail_ug_add_back_button(data);
1307
1308         Elm_Object_Item *item = NULL;
1309
1310         if (_calendar_is_task_record(data->record))
1311                 item = elm_naviframe_item_push(naviframe, C_("IDS_CLD_BODY_TASK_DETAILS"), back_button, NULL, dialogue, NULL);
1312         else
1313                 item = elm_naviframe_item_push(naviframe, C_("IDS_CLD_BODY_EVENT_DETAILS"), back_button, NULL, dialogue, NULL);
1314         c_warn_if(!item, "elm_naviframe_item_push() is failed");
1315         data->navi_item = item;
1316
1317         cal_util_add_toolbar_button(naviframe, "toolbar_button1", S_("IDS_COM_BODY_EDIT"), __cal_detail_edit_button_callback, data);
1318
1319         if (0 < _calendar_get_record_index(data->record)) {
1320
1321                 Evas_Object *more_button = cal_util_add_toolbar_button(naviframe, "toolbar_more_btn", NULL, __cal_detail_more_button_callback, data);
1322                 elm_object_style_set(more_button, "naviframe/more/default");
1323         } else {
1324                 cal_util_add_toolbar_button(naviframe, "toolbar_button1", S_("IDS_COM_OPT_SAVE"), __cal_detail_save_button_callback, data);
1325         }
1326
1327         elm_object_part_content_set(base_layout, "elm.swallow.content", naviframe);
1328         elm_object_part_content_set(base_layout, "elm.swallow.bg", bg);
1329
1330         return base_layout;
1331
1332 }
1333
1334 static calendar_record_h inline __cal_detail_ug_get_origin_record(const calendar_record_h instance)
1335 {
1336         CAL_FN_START;
1337
1338         c_retv_if(!instance, NULL);
1339
1340         int index = _calendar_get_record_index(instance);
1341
1342         return _calendar_get_record_with_index(index);
1343 }
1344
1345 static void __cal_detail_ug_get_appcontrol_input_data(service_h service, cal_detail_ug_data *data)
1346 {
1347         CAL_FN_START;
1348
1349         int r = 0;
1350         char *index = 0;
1351         char *item_type = NULL;
1352
1353         r = service_get_extra_data(service, CAL_APPCONTROL_ITEM_TYPE, &item_type);
1354         c_ret_if(r != SERVICE_ERROR_NONE);
1355
1356         if (CAL_STRCMP(CAL_APPCONTROL_ITEM_TYPE_EVENT, item_type)
1357                 && CAL_STRCMP(CAL_APPCONTROL_ITEM_TYPE_TODO, item_type)) {
1358                 ERR("Invaild input : %s, %s", CAL_APPCONTROL_ITEM_TYPE, item_type);
1359
1360                 CAL_FREE(item_type);
1361
1362                 return;
1363         }
1364
1365         CAL_FREE(item_type);
1366
1367         r = service_get_extra_data(service, CAL_APPCONTROL_ITEM_ID, &index);
1368         if (r != SERVICE_ERROR_NONE) {
1369                 ERR("service_get_extra_data(%s) is failed(%x)", "eventId", r);
1370
1371                 CAL_FREE(index);
1372
1373                 return;
1374         }
1375
1376         data->record = _calendar_get_record_with_index(atoi(index));
1377 }
1378
1379 static void __cal_detail_ug_get_record_from_vcs(char *vcs, cal_detail_ug_data *data)
1380 {
1381         c_ret_if(!vcs);
1382         c_ret_if(!data);
1383
1384         int r = 0;
1385
1386         FILE * file = fopen(vcs, "r");
1387         if (!file) {
1388                 ERR("fopen(%s) is failed.", vcs);
1389
1390                 return;
1391         }
1392
1393         struct stat st;
1394         r = stat(vcs, &st);
1395         c_warn_if(r == -1, "stat(%s) is failed(%d)", vcs, errno);
1396
1397         int size = st.st_size;
1398         char *raw_data = calloc(size + 1, sizeof(char));
1399         if (!raw_data) {
1400                 ERR("calloc is failed.");
1401
1402                 fclose( file );
1403
1404                 return;
1405         }
1406
1407         r = fread(raw_data, 1, size, file);
1408         fclose( file );
1409         if (r < 0)
1410                 ERR("fread() is failed(%d)", errno);
1411
1412         calendar_list_h list = NULL;
1413
1414         calendar_error_e error = CALENDAR_ERROR_NONE;
1415
1416         error = calendar_vcalendar_parse_to_calendar(raw_data, &list);
1417         c_warn_if(error != CALENDAR_ERROR_NONE, "calendar_vcalendar_parse_to_calendar() is failed(%x)", error);
1418
1419         error = calendar_list_first(list);
1420         c_warn_if(error != CALENDAR_ERROR_NONE, "calendar_list_first() is failed(%x)", error);
1421
1422         calendar_record_h record = NULL;
1423
1424         error = calendar_list_get_current_record_p(list, &record);
1425         c_warn_if(error != CALENDAR_ERROR_NONE, "calendar_list_get_current_record_p() is failed(%x)", error);
1426
1427         while (record) {
1428
1429                 error = calendar_list_get_current_record_p(list, &record);
1430                 c_warn_if(error != CALENDAR_ERROR_NONE, "calendar_list_get_current_record_p() is failed(%x)", error);
1431
1432                 if (_calendar_is_event_or_task(record)) {
1433
1434                         error = calendar_record_clone(record, &data->record);
1435                         c_warn_if(error != CALENDAR_ERROR_NONE, "calendar_record_clone() is failed(%x)", error);
1436
1437                         break;
1438                 }
1439
1440                 error = calendar_list_next(list);
1441
1442                 record = NULL;
1443
1444                 error = calendar_list_get_current_record_p(list, &record);
1445                 c_warn_if(error != CALENDAR_ERROR_NONE, "calendar_list_get_current_record_p() is failed(%x)", error);
1446         }
1447
1448         error = calendar_list_destroy(list, true);
1449
1450         free(raw_data);
1451 }
1452
1453 static char * __cal_detail_ug_filter_uri_format(const char *uri)
1454 {
1455         if (!strstr(uri, CAL_URI_FILE_FORMAT))
1456                 return strdup(uri);
1457         else
1458                 return strdup(uri+strlen(CAL_URI_FILE_FORMAT));
1459 }
1460
1461 /* Only vcs will be supported. */
1462 static void __cal_detail_ug_get_appcontrol_input_data_old(service_h service, cal_detail_ug_data *data)
1463 {
1464         CAL_FN_START;
1465
1466         int r = 0;
1467         char *index = 0;
1468         int cid = 0;
1469
1470         char *uri = NULL;
1471
1472         r = service_get_uri(service, &uri);
1473         if (r == SERVICE_ERROR_NONE && CAL_STRLEN(uri)) {
1474
1475                 char * filtered_uri =  __cal_detail_ug_filter_uri_format(uri);
1476
1477                 free(uri);
1478
1479                 __cal_detail_ug_get_record_from_vcs(filtered_uri, data);
1480
1481                 free(filtered_uri);
1482
1483                 return;
1484         }
1485
1486         r = service_get_extra_data(service, "index", &index);
1487         if (r == SERVICE_ERROR_NONE) {
1488                 calendar_record_h record = _calendar_get_record_with_index(atoi(index));
1489                 if (r != SERVICE_ERROR_NONE) {
1490
1491                         ERR("_calendar_get_record_with_index(%d) is failed", cid);
1492
1493                         CAL_FREE(index);
1494
1495                         return;
1496                 }
1497
1498                 CAL_FREE(index);
1499
1500                 data->record = record;
1501
1502                 return;
1503         }
1504
1505         char *item_type = NULL;
1506
1507         r = service_get_extra_data(service, "itemType", &item_type);
1508         if (r == SERVICE_ERROR_NONE) {
1509
1510                 if (!CAL_STRCMP(item_type, "event")) {
1511
1512                         r = service_get_extra_data(service, "eventId", &index);
1513                         if (r != SERVICE_ERROR_NONE) {
1514                                 ERR("service_get_extra_data(%s) is failed(%x)", "eventid", r);
1515
1516                                 CAL_FREE(index);
1517
1518                                 return;
1519                         }
1520
1521                         calendar_record_h record = _calendar_get_record_with_index(atoi(index));
1522                         if (r != SERVICE_ERROR_NONE) {
1523
1524                                 ERR("_calendar_get_record_with_index(%d) is failed", cid);
1525
1526                                 CAL_FREE(index);
1527
1528                                 return;
1529                         }
1530
1531                         CAL_FREE(index);
1532
1533                         data->record = record;
1534
1535                 } else if (!CAL_STRCMP(item_type, "todo")) {
1536
1537                         r = service_get_extra_data(service, "todoId", &index);
1538                         if (r != SERVICE_ERROR_NONE) {
1539                                 ERR("service_get_extra_data(%s) is failed(%x)", "todoId", r);
1540
1541                                 CAL_FREE(index);
1542
1543                                 return;
1544                         }
1545
1546                         calendar_record_h record = _calendar_get_record_with_index(atoi(index));
1547                         if (r != SERVICE_ERROR_NONE) {
1548
1549                                 ERR("_calendar_get_record_with_index(%d) is failed", cid);
1550
1551                                 CAL_FREE(index);
1552
1553                                 return;
1554                         }
1555
1556                         CAL_FREE(index);
1557
1558                         data->record = record;
1559
1560                 } else if (!CAL_STRCMP(item_type, "vcs")) {
1561
1562                         char *vcs = NULL;
1563
1564                         r = service_get_extra_data(service, "path", &vcs);
1565                         if (r != SERVICE_ERROR_NONE) {
1566                                 ERR("service_get_extra_data(%s) is failed(%x)", "path", r);
1567
1568                                 CAL_FREE(vcs);
1569
1570                                 return;
1571                         }
1572
1573                         __cal_detail_ug_get_record_from_vcs(vcs, data);
1574
1575                         CAL_FREE(vcs);
1576                 }
1577         }
1578
1579         CAL_FREE(item_type);
1580 }
1581
1582 static void *__cal_detail_ug_create_callback(ui_gadget_h ug, enum ug_mode mode, service_h service, void *priv)
1583 {
1584         CAL_FN_START;
1585
1586         c_retv_if(!ug, NULL);
1587         c_retv_if(!service, NULL);
1588         c_retv_if(!priv, NULL);
1589         c_retv_if(mode != UG_MODE_FULLVIEW, NULL);
1590
1591         cal_detail_ug_data *data = priv;
1592
1593         data->ug = ug;
1594
1595         int cid = 0;
1596         char *item_type = NULL;
1597         char *index = NULL;
1598         char *path = NULL;
1599         calendar_error_e error = CALENDAR_ERROR_NONE;
1600
1601         int r = 0;
1602
1603         char *operation = NULL;
1604
1605         r = service_get_operation(service, &operation);
1606         c_retv_if(r != SERVICE_ERROR_NONE, NULL);
1607
1608         if (!CAL_STRCMP(operation, CAL_APPCONTROL_SOCAIL_VIEW))
1609                 __cal_detail_ug_get_appcontrol_input_data(service, data);
1610         else
1611                 __cal_detail_ug_get_appcontrol_input_data_old(service, data);
1612
1613         CAL_FREE(operation);
1614
1615         if (!data->record) {
1616                 char *record_address = NULL;
1617
1618                 r = service_get_extra_data(service, "record", &record_address);
1619                 if (r != SERVICE_ERROR_NONE) {
1620                         ERR("service_get_extra_data(record) is failed(%x)", r);
1621
1622                         return NULL;
1623                 } else {
1624                         data->record = (calendar_record_h)strtoul(record_address, NULL, 16);
1625                         c_warn_if(!data->record, "strtol(%s, NULL, 16) is failed", record_address);
1626                 }
1627
1628                 _calendar_record_type record_type = _calendar_get_record_type(data->record);
1629
1630                 if (record_type != _CALENDAR_RECORD_TYPE_EVENT && record_type != _CALENDAR_RECORD_TYPE_TODO) {
1631                         data->instance = data->record;
1632                         data->record = __cal_detail_ug_get_origin_record(data->instance);
1633                 }
1634
1635                 CAL_FREE(record_address);
1636         }
1637
1638         Evas_Object *parent = ug_get_parent_layout(ug);
1639         c_retv_if(!parent, NULL);
1640
1641         data->window = ug_get_window();
1642         c_retv_if(!data->window, NULL);
1643
1644         elm_theme_extension_add(NULL, "/usr/apps/"CALENDAR_PACKAGE"/res/edje/theme.edj");
1645
1646         Evas_Object *base = __cal_detail_ug_create_layout(parent, data);
1647         c_retv_if(!base, NULL);
1648
1649         __cal_detail_add_db_changed_callback(data);
1650
1651         return base;
1652 }
1653
1654 static void __cal_detail_ug_destroy_callback(ui_gadget_h ug, service_h service, void *priv)
1655 {
1656         CAL_FN_START;
1657
1658         c_ret_if(!priv);
1659
1660         cal_detail_ug_data *data = priv;
1661
1662         __cal_detail_remove_db_changed_callback(data);
1663
1664         if (data->mouse_down_event_handler)
1665                 ecore_event_handler_del(data->mouse_down_event_handler);
1666
1667         cal_util_delete_evas_object(&data->base_layout);
1668 }
1669
1670 static void __cal_detail_ug_key_callback(ui_gadget_h ug, enum ug_key_event evt, service_h data, void *priv)
1671 {
1672         c_ret_if(!ug);
1673
1674         switch (evt) {
1675         case UG_KEY_EVENT_END:
1676                 ug_destroy_me(ug);
1677                 break;
1678         default:
1679                 break;
1680         }
1681 }
1682
1683 static void __cal_detail_ug_update_button_language(Evas_Object *naviframe, calendar_record_h record)
1684 {
1685         c_ret_if(!naviframe);
1686
1687         Elm_Object_Item *item = elm_naviframe_top_item_get(naviframe);
1688         c_ret_if(!item);
1689
1690         Evas_Object *button = elm_object_item_part_content_get(item, "toolbar_button1");
1691         c_ret_if(!button);
1692
1693         elm_object_text_set(button, S_("IDS_COM_BODY_EDIT"));
1694
1695         if (_calendar_get_record_index(record) <= 0)
1696                 elm_object_text_set(button, S_("IDS_COM_OPT_SAVE"));
1697 }
1698
1699 static void __cal_detail_ug_update_language(cal_detail_ug_data *data)
1700 {
1701         c_ret_if(!data);
1702         c_ret_if(!data->record);
1703
1704
1705
1706         calendar_record_h record = data->record;
1707
1708         __cal_detail_ug_update_title_language(data->title, record);
1709
1710         Eina_Bool is_task_record = _calendar_is_task_record(record);
1711
1712         if (!is_task_record) {
1713
1714                 __cal_detail_ug_update_from_language(data->from);
1715
1716                 __cal_detail_ug_update_to_language(data->to);
1717
1718         } else
1719                 __cal_detail_ug_update_due_language(data->due);
1720
1721         __cal_detail_ug_update_reminder_language(data->reminder, record);
1722
1723         if (!is_task_record)
1724                 __cal_detail_ug_update_recurrence_language(data->recurrence, record);
1725
1726         __cal_detail_ug_update_saveto_language(data->save_to, record);
1727
1728 }
1729
1730 static void __cal_detail_ug_update_region(cal_detail_ug_data *data)
1731 {
1732         c_ret_if(!data);
1733         c_ret_if(!data->record);
1734
1735         calendar_record_h record = data->record;
1736
1737         if (!_calendar_is_task_record(data->record)) {
1738
1739                 __cal_detail_ug_update_from_region(data->from, record);
1740
1741                 __cal_detail_ug_update_to_region(data->to, record);
1742
1743         } else
1744                 __cal_detail_ug_update_due_region(data->to, record);
1745 }
1746
1747 static void __cal_detail_ug_event_callback(ui_gadget_h ug, enum ug_event event, service_h service, void *priv)
1748 {
1749         c_ret_if(!ug);
1750         c_ret_if(!priv);
1751
1752         switch (event) {
1753         case UG_EVENT_LANG_CHANGE:
1754                 __cal_detail_ug_update_language((cal_detail_ug_data *)priv);
1755                 break;
1756         case UG_EVENT_REGION_CHANGE:
1757                 __cal_detail_ug_update_region((cal_detail_ug_data *)priv);
1758                 break;
1759
1760         case UG_EVENT_ROTATE_PORTRAIT:
1761         case UG_EVENT_ROTATE_PORTRAIT_UPSIDEDOWN:
1762                 break;
1763         case UG_EVENT_ROTATE_LANDSCAPE:
1764         case UG_EVENT_ROTATE_LANDSCAPE_UPSIDEDOWN:
1765                 break;
1766
1767         default:
1768                 break;
1769         }
1770 }
1771
1772 API int UG_MODULE_INIT(struct ug_module_ops *ops)
1773 {
1774         CAL_FN_START;
1775
1776         c_retv_if(!ops, -1);
1777
1778         cal_detail_ug_data *data = calloc(1, sizeof(cal_detail_ug_data));
1779
1780         ops->create = __cal_detail_ug_create_callback;
1781         ops->destroy = __cal_detail_ug_destroy_callback;
1782         ops->key_event = __cal_detail_ug_key_callback;
1783         ops->event = __cal_detail_ug_event_callback;
1784         ops->priv = data;
1785         ops->opt = UG_OPT_INDICATOR_PORTRAIT_ONLY;
1786
1787         const char *path = bindtextdomain(CALENDAR, LOCALEDIR);
1788         c_warn_if(!path, "bindtextdomain(%s, %s) is failed.", CALENDAR, LOCALEDIR);
1789
1790         __cal_detail_ug_initialize(data);
1791
1792         return 0;
1793 }
1794
1795 API void UG_MODULE_EXIT(struct ug_module_ops *ops)
1796 {
1797         CAL_FN_START;
1798
1799         c_ret_if(!ops);
1800
1801         __cal_detail_ug_finish();
1802
1803         cal_detail_ug_data *data = ops->priv;
1804
1805         free(data);
1806 }