3f88dfc148fde90505b7012262956f503179aee8
[apps/core/preloaded/calendar.git] / viewer / viewer.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 <stdio.h>
20 #include <aul.h>
21 #include <Ecore_X.h>
22 #include <ui-gadget.h>
23 #include <app.h>
24
25 #include "detail-view.h"
26
27 #define SERVICE_CALENDAR_VIEWER_CAL_ID_NAME "cal_id"
28 #define SERVICE_CALENDAR_VIEWER_MIME_NAME AUL_K_MIME_CONTENT
29 #define VCALENDAR_LABLE_STRING_LENGTH 128
30
31 #if !defined(CV_PACKAGE)
32 #  define CV_PACKAGE "calendar-viewer"
33 #endif
34
35 typedef struct {
36         struct appdata *ad;
37         Evas_Object *layout;
38         Evas_Object *genlist;
39         Evas_Object *save_to_calendar;
40         int selected_item_count;
41 }cal_viewer_data;
42
43 typedef struct {
44         calendar_record_h record;
45         Eina_Bool checked;
46 }vcs_item_data;
47
48 static char *__cal_viewer_get_vcs_genlist_item_label(void *data, Evas_Object *obj, const char *part);
49 static Evas_Object* __cal_viewer_get_vcs_genlist_icon(void *item_data, Evas_Object *obj, const char *part);
50 static void __cal_viewer_create_view(struct appdata *ad, Evas_Object *parent, calendar_list_h list);
51 static void __cal_viewer_update_small_info(cal_viewer_data *p, int count);
52
53 static Elm_Genlist_Item_Class itc_3text_1icon_2 = {
54         .item_style = "3text.1icon.2",
55         .func.text_get = __cal_viewer_get_vcs_genlist_item_label,
56         .func.content_get = __cal_viewer_get_vcs_genlist_icon,
57         .func.del = NULL,
58         .decorate_all_item_style = "edit_default",
59 };
60
61 static char* __cal_viewer_vcs_get_time_str(calendar_record_h record)
62 {
63         c_retv_if(!record, NULL);
64
65         char stime[512] = {0};
66
67         struct tm tm = {0};
68         const char* time = CAL_UTIL_TIME_FORMAT_1;
69
70         calendar_time_s start_time = {0};
71
72         _calendar_get_start_time(record, &start_time);
73
74         cal_util_convert_lli_to_tm(NULL, start_time.time.utime, &tm);
75
76         cal_util_get_time_text(stime, sizeof(stime), NULL, time, &tm);
77
78         return g_strdup_printf("%s", stime);
79 }
80
81 static char *__cal_viewer_get_vcs_genlist_item_label(void *data, Evas_Object *obj, const char *part)
82 {
83         c_retvm_if(!data, NULL, "data is null");
84         c_retvm_if(!part, NULL, "part is null");
85
86         vcs_item_data *item_data = (vcs_item_data*)data;
87         c_retv_if(!item_data->record, NULL);
88
89         if (!CAL_STRCMP(part,"elm.text.1")) {
90                 return _calendar_get_summary(item_data->record);
91
92         } else if (!CAL_STRCMP(part,"elm.text.2")) {
93                 return _calendar_get_location(item_data->record);
94
95         } else if (!CAL_STRCMP(part, "elm.text.3")) {
96
97                 return __cal_viewer_vcs_get_time_str(item_data->record);
98         }
99
100         return NULL;
101 }
102
103 static void __cal_viewer_update_small_info(cal_viewer_data *p, int count)
104 {
105         c_retm_if(!p, "p is null");
106
107         if (count <= 0) {
108                 cal_util_hide_small_information(p->layout);
109                 return;
110         }
111
112         struct appdata *ad = p->ad;
113         c_retm_if(!ad, "ad is null");
114
115         Evas_Object *nv = ad->naviframe;
116         c_retm_if(!nv, "nv is null");
117
118         char lable_str[VCALENDAR_LABLE_STRING_LENGTH] = { '\0'};
119
120         snprintf(lable_str, sizeof(lable_str), "%s (%d)", S_("IDS_COM_POP_SELECTED"), count);
121
122         cal_util_show_small_information(p->layout, lable_str, 0.0);
123 }
124
125 static void __cal_viewer_vcs_check_changed_callback(void *data, Evas_Object *obj, void *event_info)
126 {
127         c_retm_if(!data, "data is null");
128
129         vcs_item_data *item_data= data;
130
131         Evas_Object *genlist = elm_object_parent_widget_get(obj);
132         c_retm_if(!genlist, "genlist is null");
133
134         cal_viewer_data *p = evas_object_data_get(genlist, "priv");
135         c_retm_if(!p, "p is null");
136
137         Eina_Bool checked = elm_check_state_get(obj);
138         if (checked) {
139                 p->selected_item_count++;
140                 item_data->checked = EINA_TRUE;
141         } else {
142                 p->selected_item_count--;
143                 item_data->checked = EINA_FALSE;
144         }
145
146         if (0 < p->selected_item_count)
147                 elm_object_disabled_set(p->save_to_calendar, EINA_FALSE);
148         else
149                 elm_object_disabled_set(p->save_to_calendar, EINA_TRUE);
150
151         __cal_viewer_update_small_info(p, p->selected_item_count);
152 }
153
154 static Evas_Object* __cal_viewer_get_vcs_genlist_icon(void *item_data, Evas_Object *obj, const char *part)
155 {
156         c_retvm_if(!part, NULL, "part is null");
157         c_retvm_if(!obj, NULL, "obj is null");
158         c_retvm_if(!item_data, NULL, "data is null");
159
160         Evas_Object *icon = NULL;
161         vcs_item_data *item = item_data;
162         c_retvm_if(!item->record, NULL, "item->record is null");
163
164         if (!CAL_STRCMP(part, "elm.icon") ) {
165                 icon = elm_check_add(obj);
166                 c_retvm_if(!icon, NULL, "elm_check_add returned null");
167
168                 elm_check_state_pointer_set(icon, &item->checked);
169                 evas_object_smart_callback_add(icon, "changed", __cal_viewer_vcs_check_changed_callback, item);
170                 evas_object_propagate_events_set(icon, EINA_FALSE);
171                 return icon;
172         }
173
174         return NULL;
175 }
176
177 static bool viewer_create(void *data)
178 {
179         struct appdata *ad = data;
180         Evas_Object *win;
181         Evas_Object *bg;
182         Evas_Object *nv;
183
184         calendar_error_e error = CALENDAR_ERROR_NONE;
185
186         error = calendar_connect();
187         c_warn_if(error != CALENDAR_ERROR_NONE, "calendar_connect() is failed(%x)", error);
188
189         _calendar_init_hash();
190
191         elm_theme_extension_add(NULL, "/usr/apps/"CALENDAR_PACKAGE"/res/edje/theme.edj");
192
193         /* create window */
194         win = cal_util_add_window(CV_PACKAGE, NULL, NULL);
195         c_retvm_if(!win, false, "cal_util_add_window() Failed");
196         ad->win = win;
197
198         bg = cal_util_add_bg(win, EINA_TRUE);
199         c_retvm_if(NULL == bg, false, "cal_util_add_bg() Failed");
200
201         Evas_Object *conformant = elm_conformant_add(win);
202         c_retv_if(!conformant, false);
203
204         evas_object_size_hint_weight_set(conformant, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
205         elm_win_resize_object_add(win, conformant);
206         evas_object_show(conformant);
207
208         Evas_Object *base_layout = elm_layout_add(conformant);
209         c_retv_if(!base_layout, false);
210
211         Eina_Bool r = elm_layout_theme_set(base_layout, "layout", "application", "default");
212         c_warn_if(!r, "elm_layout_theme_set is failed");
213
214         evas_object_size_hint_weight_set(base_layout, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
215
216         elm_object_content_set(conformant, base_layout);
217
218         ad->base = base_layout;
219
220         nv = elm_naviframe_add(ad->base);
221         c_retvm_if(NULL == win, false, "elm_naviframe_add() Failed");
222         ad->naviframe = nv;
223         elm_object_part_content_set(ad->base, "elm.swallow.content", ad->naviframe);
224
225         const char *path = bindtextdomain(CALENDAR, LOCALEDIR);
226         c_warn_if(!path, "bindtextdomain(%s, %s) is failed.", CALENDAR, LOCALEDIR);
227
228         cal_util_connect_pattern_generator();
229
230         evas_object_show(win);
231
232         UG_INIT_EFL(ad->win, UG_OPT_INDICATOR_PORTRAIT_ONLY);
233
234         return true;
235 }
236
237 static void viewer_terminate(void *data)
238 {
239         struct appdata *ad = data;
240
241         cal_util_disconnect_pattern_generator();
242
243         ug_destroy_all();
244
245         if (ad->win)
246                 evas_object_del(ad->win);
247
248         calendar_error_e error = CALENDAR_ERROR_NONE;
249
250         error = calendar_disconnect();
251         c_warn_if(error != CALENDAR_ERROR_NONE, "calendar_disconnect() is failed(%x)", error);
252
253         return;
254 }
255
256 static void viewer_pause(void *data)
257 {
258         ug_pause();
259
260         return;
261 }
262
263 static void viewer_resume(void *data)
264 {
265         ug_resume();
266
267         return;
268 }
269
270 static void viewer_service(service_h service, void *data)
271 {
272         c_retm_if(!service, "service is null.");
273         c_retm_if(!data, "data is null.");
274
275         int cal_id;
276         int r;
277         char *operation = NULL;
278         char *val_cal_id = NULL;
279         char *val_ical = NULL;
280         struct appdata *ad = data;
281
282         if (NULL == ad->win) {
283                 ERR("win is NULL");
284                 elm_exit();
285                 return;
286         }
287
288         r = service_get_extra_data(service, SERVICE_CALENDAR_VIEWER_CAL_ID_NAME, &val_cal_id);
289         c_warn_if(SERVICE_ERROR_NONE != r, "service_get_extra_data is failed(%d).", r);
290
291         if (val_cal_id && *val_cal_id) {
292                 cal_id = atoi(val_cal_id);
293                 if (cal_id <= 0) {
294                         ERR("bundle value(cal_id) is wrong(%d)", cal_id);
295                 }
296                 else {
297                         ad->cid= cal_id;
298
299                         calendar_record_h record = _calendar_get_record_with_index(cal_id);
300
301                         cal_detail_create_view(ad, record, NULL, NULL);
302                 }
303
304                 free(val_cal_id);
305                 val_cal_id = NULL;
306         } else {
307                 r = service_get_operation(service, &operation);
308                 c_retm_if(SERVICE_ERROR_NONE != r, "service_get_operation is failed.");
309
310                 r = service_get_uri(service, &val_ical);
311                 c_retm_if(SERVICE_ERROR_NONE != r, "service_get_uri is failed.");
312
313                 /*MIME CONTENT FOR VCS*/
314                 if (val_ical) {
315                         char *raw_data = NULL;
316                         int size = 0;
317                         struct stat st;
318
319                         FILE * file = fopen(val_ical, "r");
320                         if(!file) {
321                                 free(raw_data);
322                                 ERR("Failed to open file!");
323                                 return;
324                         }
325
326                         if(stat(val_ical, &st) != 0) {
327                                 free(raw_data);
328                                 ERR("stat() is failed!");
329                                 fclose( file );
330                                 return;
331                         }
332
333                         size = st.st_size;
334                         CAL_CALLOC(raw_data, (size+1), char);
335                         CAL_ASSERT(raw_data);
336                         memset(raw_data,0,(size+1));
337
338                         r = fread(raw_data, 1, size, file);
339                         if (r < 0) {
340                                 free(raw_data);
341                                 ERR("Failed to read file!");
342                                 return;
343                         }
344
345                         fclose( file );
346
347                         ad->is_aul = EINA_TRUE;
348                         ad->request_view = CV_DETAIL;
349
350                         calendar_error_e error = CALENDAR_ERROR_NONE;
351
352                         calendar_list_h list = NULL;
353
354                         error = calendar_vcalendar_parse_to_calendar(raw_data, &list);
355                         c_warn_if(error != CALENDAR_ERROR_NONE, "calendar_vcalendar_parse_to_calendar() is failed(%x)", error);
356
357                         __cal_viewer_create_view(ad, ad->naviframe, list);
358
359                         free(raw_data);
360                         free(val_ical);
361                         val_ical = NULL;
362                 }
363                 else {
364                         ERR("bundle value is NULL");
365                         elm_exit();
366                         return;
367                 }
368         }
369
370         elm_win_activate(ad->win);
371         return;
372 }
373
374 static void __cal_viewer_genlist_select_callback(void *data, Evas_Object *obj, void *event_info)
375 {
376         c_retm_if(!data, "data is null");
377
378         vcs_item_data *item = data;
379         c_retm_if(!item->record, "__cal_viewer_genlist_sel param error");
380
381         cal_viewer_data *p = evas_object_data_get(obj, "priv");
382         c_retm_if(!p || !p->ad, "p is null");
383
384         elm_genlist_item_selected_set((Elm_Object_Item *)event_info, EINA_FALSE);
385
386         cal_detail_create_view(p->ad, item->record, NULL, NULL);
387 }
388
389 static void __cal_viewer_save_to_calendar_button_callback(void *data, Evas_Object *obj, void *ei)
390 {
391         CAL_FN_START;
392
393         cal_viewer_data *p = data;
394         c_retm_if(!p, "p is null");
395
396         Elm_Object_Item *it = NULL;
397         Elm_Object_Item *temp = NULL;
398         vcs_item_data *item = NULL;
399         it = elm_genlist_first_item_get(p->genlist);
400
401         int saved_item_count = 0;
402
403         while (it) {
404                 item = elm_object_item_data_get(it);
405                 temp = elm_genlist_item_next_get(it);
406                 if (NULL == item) {
407                         it = temp;
408                         continue;
409                 }
410
411                 if (item && item->record && EINA_TRUE == item->checked) {
412                         calendar_error_e error = CALENDAR_ERROR_NONE;
413
414                         error = calendar_db_insert_record(item->record, NULL);
415                         if (error == CALENDAR_ERROR_NONE)
416                                 saved_item_count++;
417                         else
418                                 ERR("calendar_db_insert_record() is failed(%x)", error);
419                 }
420                 it = temp;
421         }
422
423         if (saved_item_count) {
424
425                 int r = status_message_post(S_("IDS_COM_POP_SAVED"));
426                 c_warn_if(r != STATUS_ERROR_NONE, "status_message_post() is failed(%d)", r);
427         }
428 }
429
430 static void __cal_viewer_back_button_callback(void *data, Evas_Object *obj, void *ei)
431 {
432         CAL_FN_START;
433
434         cal_viewer_data *p = data;
435         c_retm_if(!p || !p->genlist,  "p is null");
436
437         elm_genlist_clear(p->genlist);
438         elm_exit();
439 }
440
441 static void __cal_viewer_create_view(struct appdata *ad, Evas_Object *parent, calendar_list_h list)
442 {
443         CAL_FN_START;
444
445         c_retm_if(!ad || !parent || !list, "Input parameter is null");
446
447         cal_viewer_data *p = calloc(1, sizeof(cal_viewer_data));
448         c_retm_if(!p, "calloc is null");
449
450         p->ad = ad;
451
452         Evas_Object *layout = cal_util_add_layout(parent, "selectioninfo");
453         if (!layout){
454                 ERR("layout is NULL!");
455                 free(p);
456                 return;
457         }
458
459         p->layout = layout;
460
461         Evas_Object *genlist = elm_genlist_add(layout);
462         if(!genlist){
463                 ERR("genlist is NULL!");
464                 evas_object_del(p->layout);
465                 free(p);
466                 return;
467         }
468
469         elm_object_part_content_set(layout, "gen.swallow.contents", genlist);
470
471         Evas_Object *back_button;
472         Elm_Object_Item* navi_item;
473
474         int i = 0;
475         int count = 0;
476
477         calendar_error_e error = CALENDAR_ERROR_NONE;
478
479         error = calendar_list_get_count(list, &count);
480         c_warn_if(error != CALENDAR_ERROR_NONE, "calendar_list_get_count() is failed(%x)", error);
481
482         error = calendar_list_first(list);
483         c_warn_if(error != CALENDAR_ERROR_NONE, "calendar_list_first() is failed(%x)", error);
484
485         calendar_record_h record = NULL;
486
487         error = calendar_list_get_current_record_p(list, &record);
488         c_warn_if(error != CALENDAR_ERROR_NONE, "calendar_list_get_current_record_p() is failed(%x)", error);
489
490         while (record) {
491
492                 if (!_calendar_is_event_or_task(record)) {
493
494                         calendar_list_next(list);
495
496                         record = NULL;
497
498                         error = calendar_list_get_current_record_p(list, &record);
499                         c_warn_if(error != CALENDAR_ERROR_NONE, "calendar_list_get_current_record_p() is failed(%x)", error);
500
501                         continue;
502                 }
503
504                 vcs_item_data *item_data = calloc(1, sizeof(vcs_item_data));
505                 if(!item_data)
506                 {
507                         ERR("calloc is null!");
508                         free(p);
509                         return;
510                 }
511
512                 item_data->checked = EINA_FALSE;
513
514                 error = calendar_record_clone(record, &item_data->record);
515                 c_warn_if(error != CALENDAR_ERROR_NONE, "calendar_record_clone() is failed(%x)", error);
516
517                 elm_genlist_item_append(genlist, &itc_3text_1icon_2, item_data, NULL, ELM_GENLIST_ITEM_NONE, __cal_viewer_genlist_select_callback, item_data);
518
519                 calendar_list_next(list);
520
521                 record = NULL;
522
523                 error = calendar_list_get_current_record_p(list, &record);
524                 c_warn_if(error != CALENDAR_ERROR_NONE, "calendar_list_get_current_record_p() is failed(%x)", error);
525         }
526
527         error = calendar_list_destroy(list, true);
528         c_warn_if(error != CALENDAR_ERROR_NONE, "calendar_list_destroy() is failed(%x)", error);
529
530         evas_object_data_set(genlist, "priv", p);
531         p->genlist = genlist;
532
533         //TODO: i18n
534         navi_item = elm_naviframe_item_push(ad->naviframe, _("VCS Viewer"), NULL, NULL, layout, NULL);
535         if (!navi_item) {
536                 ERR("elm_naviframe_item_push is failed");
537                 evas_object_del(genlist);
538                 return;
539         }
540
541         p->save_to_calendar = cal_util_add_toolbar_button(ad->naviframe, "toolbar_button1", S_("IDS_COM_OPT_SAVE"), __cal_viewer_save_to_calendar_button_callback, p);
542         elm_object_disabled_set(p->save_to_calendar, EINA_TRUE);
543
544         back_button = elm_object_item_part_content_get(navi_item, "prev_btn");
545         if (!back_button) {
546                 back_button = elm_button_add(ad->naviframe);
547                 c_retm_if(!back_button, "elm_button_add is failed.");
548
549                 elm_object_style_set(back_button, "naviframe/back_btn/default");
550                 elm_object_item_part_content_set(navi_item, "prev_btn", back_button);
551         }
552         elm_object_style_set(back_button, "naviframe/back_btn/default");
553         evas_object_smart_callback_add(back_button, "clicked",  __cal_viewer_back_button_callback, p);
554 }
555
556 API int main(int argc, char *argv[])
557 {
558         struct appdata ad;
559
560         app_event_callback_s event_callback;
561
562         event_callback.create = viewer_create;
563         event_callback.terminate = viewer_terminate;
564         event_callback.pause = viewer_pause;
565         event_callback.resume = viewer_resume;
566         event_callback.service = viewer_service;
567         event_callback.low_memory = NULL;
568         event_callback.low_battery = NULL;
569         event_callback.device_orientation = NULL;
570         event_callback.language_changed = NULL;
571         event_callback.region_format_changed = NULL;
572
573         memset(&ad, 0x0, sizeof(struct appdata));
574
575         return app_efl_main(&argc, &argv, &event_callback, &ad);
576 }