e5d02a5b56ee11786d7e70330f6635ebcf7d8822
[apps/core/preloaded/calendar.git] / ug / list / ug-list.c
1 /*
2
3 Copyright (c) 2000-2012 Samsung Electronics Co., Ltd All Rights Reserved
4
5 This file is part of org.tizen.efl-calendar
6 Written by Taeho Kang <taeho84.kang@samsung.com>
7
8 PROPRIETARY/CONFIDENTIAL
9
10 This software is the confidential and proprietary information of
11 SAMSUNG ELECTRONICS ("Confidential Information"). You shall not
12 disclose such Confidential Information and shall use it only in
13 accordance with the terms of the license agreement you entered
14 into with SAMSUNG ELECTRONICS.
15
16 SAMSUNG make no representations or warranties about the suitability
17 of the software, either express or implied, including but not limited
18 to the implied warranties of merchantability, fitness for a particular
19 purpose, or non-infringement. SAMSUNG shall not be liable for any
20 damages suffered by licensee as a result of using, modifying or
21 distributing this software or its derivatives.
22
23 */
24
25
26 #include "cld.h"
27 #include "ug.h"
28 #include <glib.h>
29
30 static const char *_name = "list/base";
31
32 ///TODO: get full path from caller
33 #define VFILE_PATH "/opt/data/ug-calendar"
34
35 static Elm_Entry_Filter_Limit_Size _limit_20char = {
36        .max_char_count = 20,
37 };
38
39 #define MAX_FETCH_COUNT 10
40
41 #define ACCOUNT_LABLE_STRING_LENGTH 128
42
43 typedef struct {
44         const char *name;
45         struct ug_data *ugd;
46         Evas_Object *parent;
47         Evas_Object *ly;
48         Evas_Object *no_contents;
49         Evas_Object *bg;
50
51         Elm_Object_Item *bt;
52
53         Evas_Object *conformant;
54         Evas_Object *genlist;
55
56         Eina_List *event_list;
57
58         Evas_Object *select_all_layout;
59         Evas_Object *select_all_check;
60         Evas_Object *box;
61
62         int totalcnt;
63         int offset;
64         Ecore_Idler* idler;
65
66         int num_check;
67         int genlist_count;
68         Evas_Object* searchbar;
69         const char * searchtext;
70         Elm_Object_Item *navi_item;
71         Evas_Object * notify;
72         Evas_Object * notify_layout;
73 }cal_list_ug_data;
74
75 typedef struct {
76         Elm_Object_Item *it;  // Genlist Item pointer
77         Eina_Bool checked;     // Check status
78         char *label;
79         cal_struct *cs;
80         struct tm* tm;
81         Elm_Genlist_Item_Type it_flag;
82 }cal_list_ug_item_data;
83
84 static Eina_Bool is_ug_list_view_destory;
85
86 static int is_hour24;
87
88 static void __cal_list_ug_genlist_item_select_callback(void *data, Evas_Object *obj, void *event_info);
89 static void __cal_list_ug_update(cal_list_ug_data *p);
90 static void __cal_list_ug_searchbar_entry_changed_callback(void *data, Evas_Object *obj, void *event_info);
91 static void __cal_list_ug_cancel_button_callback(void *data, Evas_Object *obj, void *event_info);
92 static void __cal_list_ug_searchbar_entry_unfocused_callback(void *data, Evas_Object *obj, void *event_info);
93 static void __cal_list_ug_searchbar_clicked_callback(void *data, Evas_Object *obj, void *event_info);
94 static void __cal_list_ug_create_searchbar(cal_list_ug_data *p);
95 static char* __cal_list_ug_get_genlist_item_label(void *data, Evas_Object *obj, const char *part);
96 static Evas_Object *__cal_list_ug_get_genlist_item_icon(void *data, Evas_Object *obj, const char *part);
97 static void __cal_list_ug_update_all_check(cal_list_ug_data* p);
98 static void __cal_list_ug_create_searchbar(cal_list_ug_data *p);
99 static void __cal_list_ug_append_with_idler(void* data);
100
101 static Elm_Genlist_Item_Class itc = {
102         .item_style = "3text.5icon",
103         .func.text_get = __cal_list_ug_get_genlist_item_label,
104         .func.content_get = __cal_list_ug_get_genlist_item_icon,
105         .decorate_all_item_style = "edit_default",
106 };
107
108 static Calendar_color calendar_color;
109
110 //TODO
111 #define ELM_GENLIST_ITEM_GROUP (1<<1)
112
113 static void __cal_list_ug_add_small_info(cal_list_ug_data *p, int count)
114 {
115         c_retm_if(!p, "p is null");
116         struct ug_data *ad = p->ugd;
117         c_retm_if(!ad, "ug data is null");
118
119         Evas_Object *nv = ad->nv;
120         c_retm_if(!nv, "nv is null");
121
122         Evas_Object *notify = NULL;
123         Evas_Object *notify_layout = NULL;
124         char lable_str[ACCOUNT_LABLE_STRING_LENGTH] = { '\0'};
125
126         c_ret_if(count < 0);
127
128         if (!p->notify) {
129                 notify = elm_notify_add(nv);
130
131                 c_retm_if(!notify, "notify is null");
132
133                 elm_notify_orient_set(notify, ELM_NOTIFY_ORIENT_BOTTOM);
134
135                 p->notify = notify;
136
137                 notify_layout = elm_layout_add(notify);
138                 if (!notify_layout) {
139                         evas_object_del(p->notify);
140                         p->notify = NULL;
141                         return;
142                 }
143
144                 p->notify_layout = notify_layout;
145                 elm_layout_theme_set(notify_layout, "standard", "selectioninfo", "vertical/bottom_64");
146                 elm_object_content_set(notify, notify_layout);
147         }
148
149         snprintf(lable_str, sizeof(lable_str), "%s (%d)", S_("IDS_COM_POP_SELECTED"), count);
150         edje_object_part_text_set(CAL_UTIL_GET_EDJ_DATA(p->notify_layout), "elm.text", lable_str);
151
152         if (0 < count) {
153                 evas_object_show(p->notify);
154         } else {
155                 evas_object_hide(p->notify);
156         }
157 }
158
159 static void __cal_list_ug_genlist_item_check_changed_callback(void *data, Evas_Object *obj, void *event_info)
160 {
161         c_retm_if(!data, "data is null");
162
163         cal_list_ug_item_data *item_data = data;
164         Elm_Object_Item *it;
165         Eina_List* realized_list, *l;
166
167         cal_list_ug_data* p = CAL_UTIL_GET_PRIV_DATA(obj);
168         c_retm_if(!p, "p is null");
169
170         if (p->genlist_count <= 0) {
171                 return;
172         }
173
174         item_data->checked = elm_check_state_get(obj);
175         if (item_data->checked)
176                 p->num_check++;
177         else
178                 p->num_check--;
179
180         if (item_data->checked || 0 < p->num_check)
181                 elm_object_item_disabled_set(p->bt, EINA_FALSE);
182         else
183                 elm_object_item_disabled_set(p->bt, EINA_TRUE);
184
185         realized_list = elm_genlist_realized_items_get(p->genlist);
186         EINA_LIST_FOREACH(realized_list, l, it) {
187                 if (it)
188                         elm_genlist_item_update(it);
189         }
190
191         if (p->num_check == p->genlist_count) {
192                 elm_check_state_set(p->select_all_check,EINA_TRUE);
193                 __cal_list_ug_update_all_check(p);
194         } else {
195                 elm_check_state_set(p->select_all_check,EINA_FALSE);
196                 __cal_list_ug_add_small_info(p, p->num_check);
197         }
198 }
199
200 static Evas_Object *__cal_list_ug_get_genlist_item_icon(void *data, Evas_Object *obj, const char *part)
201 {
202         c_retvm_if(!part, NULL, "part is null");
203         c_retvm_if(!obj, NULL, "obj is null");
204         c_retvm_if(!data, NULL, "data is null");
205
206         Evas_Object *icon = NULL;
207         cal_struct *calendar = NULL;
208         cal_list_ug_data* p = CAL_UTIL_GET_PRIV_DATA(obj);
209         c_retvm_if(!p, NULL, "p is null");
210
211         cal_list_ug_item_data *item_data = data;
212         int r;
213         cal_struct *cs = item_data->cs;
214         c_retvm_if(!cs, NULL, "cs is null");
215
216         if (!CAL_STRCMP(part, "elm.edit.icon.1") )      {
217                 icon = elm_check_add(obj);
218                 c_retvm_if(!icon, NULL, "elm_check_add returned null");
219
220                 elm_check_state_pointer_set(icon, &item_data->checked);
221                 evas_object_smart_callback_add(icon, "changed", __cal_list_ug_genlist_item_check_changed_callback, item_data);
222                 evas_object_propagate_events_set(icon, EINA_FALSE);
223                 evas_object_data_set(icon, "priv", p);
224
225                 return icon;
226         }
227         else if (!CAL_STRCMP(part, "elm.swallow.colorbar"))
228         {
229                 r = CALENDAR_SVC_GET(CAL_STRUCT_CALENDAR, CALENDAR_SVC_STRUCT_GET_INT(cs,CAL_VALUE_INT_CALENDAR_ID), NULL, &calendar);
230                 c_retvm_if(r != CAL_SUCCESS, NULL, "calendar_svc_get is failed(%d)", r);
231
232                 icon = evas_object_rectangle_add(evas_object_evas_get(obj));
233                 c_retvm_if(!icon, NULL, "evas_object_rectangle_add returned null");
234                 evas_object_size_hint_align_set(icon, EVAS_HINT_FILL, EVAS_HINT_FILL);
235
236                 CALENDAR_SVC_GET_CALENDAR_COLOR(calendar, &calendar_color);
237
238                 evas_object_color_set(icon, calendar_color.red, calendar_color.green, calendar_color.blue, calendar_color.alpha);
239
240                 CALENDAR_SVC_STRUCT_FREE(&calendar);
241
242                 return icon;
243         }
244
245         return NULL;
246 }
247
248 static void __cal_list_ug_clear_event_list(cal_list_ug_data *p)
249 {
250         CAL_FN_START;
251
252         c_retm_if(!p, "p is null");
253
254         cal_list_ug_item_data *item;
255         Eina_List *l = NULL;
256
257         EINA_LIST_FOREACH(p->event_list, l, item) {
258                 if (item) {
259                         calendar_svc_struct_free(&item->cs);
260                         item->cs = NULL;
261                         free(item);
262                         item=NULL;
263                 }
264         }
265
266         if (p->event_list) {
267                 eina_list_free(p->event_list);
268                 p->event_list = NULL;
269         }
270 }
271
272 static void __cal_list_ug_delete_layout(void *data, Evas *e, Evas_Object *obj, void *ei)
273 {
274         CAL_FN_START;
275
276         c_retm_if(!data, "data is null");
277
278         cal_list_ug_data *p = data;
279
280         is_ug_list_view_destory = TRUE;
281         if (p->idler) {
282                 ecore_idler_del(p->idler);
283                 p->idler = NULL;
284         }
285
286         __cal_list_ug_clear_event_list(p);
287
288         if (p->no_contents) {
289                 evas_object_del(p->no_contents);
290         }
291
292         if (p->searchbar) {
293                 evas_object_smart_callback_del(elm_object_part_content_get(p->searchbar, "elm.swallow.content"), "changed", __cal_list_ug_searchbar_entry_changed_callback);
294                 evas_object_smart_callback_del(p->searchbar, "cancel,clicked", __cal_list_ug_cancel_button_callback);
295                 evas_object_del(p->searchbar);
296                 p->searchbar = NULL;
297         }
298
299         CALENDAR_SVC_DEL_EVENT_CHANGED_CALLBACK((void(*)(void*))__cal_list_ug_update);
300
301         if (p->notify) {
302                 evas_object_del(p->notify);
303         }
304
305         if (p->box) {
306                 elm_box_clear(p->box);
307         }
308
309         free(p);
310 }
311
312 static char* __cal_list_ug_get_cs(cal_struct *cs)
313 {
314         char buf[512];
315         char stime[512];
316         time_t st;
317         struct tm tm;
318         int repeat;
319         const char* time;
320
321         if (is_hour24)
322                 time = CAL_UTIL_TIME_FORMAT_6;
323         else
324                 time = CAL_UTIL_TIME_FORMAT_1;
325
326         st = CALENDAR_SVC_STRUCT_GET_TIME(cs, CAL_VALUE_GMT_START_DATE_TIME, CAL_TZ_FLAG_GMT);
327         localtime_r(&st, &tm);
328
329         repeat = CALENDAR_SVC_STRUCT_GET_INT(cs, CAL_VALUE_INT_REPEAT_TERM);
330         if (repeat == CAL_REPEAT_NONE)
331         {
332                 cal_util_get_time_text(stime, sizeof(stime), NULL, time, &tm);
333                 snprintf(buf, sizeof(buf), "%s", stime);
334         } else {
335                 cal_util_get_time_text(stime, sizeof(stime), NULL, time, &tm);
336                 snprintf(buf, sizeof(buf), "%s", stime);
337         }
338
339         return strdup(buf);
340 }
341
342 static char* __cal_list_ug_get_genlist_item_label(void *data, Evas_Object *obj, const char *part)
343 {
344         c_retvm_if(!part, NULL, "part is null");
345         c_retvm_if(!data, NULL, "data is null");
346
347         const char *str = NULL;
348         cal_list_ug_item_data *item = data;
349         cal_struct *cs = item->cs;
350         c_retvm_if(!cs, NULL, "cs is null");
351
352         if (!CAL_STRCMP(part, "elm.text.1"))
353         {
354                 str = CALENDAR_SVC_STRUCT_GET_STR(cs, CAL_VALUE_TXT_SUMMARY);
355                 if (str)
356                         return strdup(str);
357
358                 return strdup(C_("IDS_CLD_BODY_NO_TITLE"));
359         }
360
361         if (!CAL_STRCMP(part, "elm.text.2"))
362         {
363                 str = CALENDAR_SVC_STRUCT_GET_STR(cs, CAL_VALUE_TXT_LOCATION);
364                 if (str)
365                         return strdup(str);
366
367                 return strdup(C_("IDS_CLD_BODY_NO_LOCATION_SELECTED"));
368         }
369
370         if (!CAL_STRCMP(part, "elm.text.3"))
371                 return __cal_list_ug_get_cs(cs);
372
373         return NULL;
374 }
375
376 static void __cal_list_ug_genlist_item_select_callback(void *data, Evas_Object *obj, void *event_info)
377 {
378         c_retm_if(!data, "data is null");
379         c_retm_if(!obj, "obj is null");
380
381         Eina_List* realized_list, *l;
382         Elm_Object_Item* it;
383         cal_list_ug_item_data* item = data;
384         cal_list_ug_data *p = CAL_UTIL_GET_PRIV_DATA(obj);
385         c_retm_if(!p, "p is null");
386
387         if (p->genlist_count <= 0) {
388                 return;
389         }
390
391         item->checked = !(item->checked);
392         if (item->checked) {
393                 p->num_check++;
394         } else {
395                 p->num_check--;
396         }
397
398         if (item->checked || 0 < p->num_check) {
399                 elm_object_item_disabled_set(p->bt, EINA_FALSE);
400         } else if (p->num_check <= 0) {
401                 elm_object_item_disabled_set(p->bt, EINA_TRUE);
402         }
403
404         it = elm_genlist_selected_item_get(obj);
405         if (it) {
406                 elm_genlist_item_selected_set(it, EINA_FALSE);
407         }
408
409         realized_list = elm_genlist_realized_items_get(obj);
410         EINA_LIST_FOREACH(realized_list, l, it) {
411                 if (it) {
412                         elm_genlist_item_update(it);
413                 }
414         }
415
416         if (p->num_check == p->genlist_count) {
417                 elm_check_state_set(p->select_all_check,EINA_TRUE);
418                 __cal_list_ug_update_all_check(p);
419         } else {
420                 elm_check_state_set(p->select_all_check,EINA_FALSE);
421                 __cal_list_ug_add_small_info(p, p->num_check);
422         }
423
424 }
425
426 Eina_Bool __cal_list_ug_update_fetch_list_idler(void* data)
427 {
428         CAL_FN_START;
429
430         cal_list_ug_data *p = data;
431
432         c_retvm_if(!p, ECORE_CALLBACK_CANCEL, "priv is null.");
433
434         int r;
435         cal_iter *it=NULL;
436         int cal_id;
437         cal_id = 0;
438         it = NULL;
439         cal_list_ug_item_data *item;
440         Eina_Bool is_finished = EINA_FALSE;
441
442         if(is_ug_list_view_destory == EINA_TRUE)
443                 return ECORE_CALLBACK_CANCEL;
444
445         if(p->idler == NULL)
446                 return ECORE_CALLBACK_CANCEL;
447
448         r = CALENDAR_SVC_GET_LIST(ALL_VISIBILITY_ACCOUNT, ALL_CALENDAR_ID, CAL_STRUCT_SCHEDULE, CAL_VALUE_LIST_FILED, p->offset, MAX_FETCH_COUNT, &it);
449         if (r != CAL_SUCCESS)
450                 return ECORE_CALLBACK_CANCEL;
451
452         while (CALENDAR_SVC_ITER_NEXT(it) == CAL_SUCCESS) {
453
454                 item = calloc(1, sizeof(cal_list_ug_item_data));
455                 c_retvm_if(!item, ECORE_CALLBACK_CANCEL, "item is null");
456
457                 r = CALENDAR_SVC_ITER_GET_INFO(it, &item->cs);
458                 if (r != CAL_SUCCESS)
459                         break;
460
461                 p->event_list = eina_list_append(p->event_list, item);
462         }
463
464         CALENDAR_SVC_ITER_REMOVE(&it);
465
466         if(eina_list_count(p->event_list) < MAX_FETCH_COUNT)
467                 is_finished = EINA_TRUE;
468
469         __cal_list_ug_append_with_idler(p);
470
471         if(is_finished || (p->offset == p->totalcnt))
472         {
473                 if (p->idler)
474                 {
475                         ecore_idler_del(p->idler);
476                         p->idler = NULL;
477                 }
478
479                 p->offset= 0;
480
481                 return ECORE_CALLBACK_CANCEL;
482         }
483         else
484         {
485                 return ECORE_CALLBACK_RENEW;
486         }
487
488         return ECORE_CALLBACK_CANCEL;
489 }
490
491 static void __cal_list_ug_get_event_list(cal_list_ug_data *p)
492 {
493         CAL_FN_START;
494
495         c_retm_if(!p, "p is null");
496
497         int r;
498         cal_iter *it = NULL;
499         cal_list_ug_item_data *item;
500
501         p->totalcnt = CALENDAR_SVC_GET_COUNT(ALL_ACCOUNT_ID,ALL_CALENDAR_ID,CAL_STRUCT_SCHEDULE);
502
503         p->offset = 0;
504
505         r = CALENDAR_SVC_GET_LIST(ALL_ACCOUNT_ID, ALL_CALENDAR_ID, CAL_STRUCT_SCHEDULE, CAL_VALUE_LIST_FILED, 0, MAX_FETCH_COUNT, &it);
506
507         if (r != CAL_SUCCESS)
508                 return;
509
510         while (CALENDAR_SVC_ITER_NEXT(it) == CAL_SUCCESS)       {
511
512                 item = calloc(1, sizeof(cal_list_ug_item_data));
513                 c_retm_if(!item, "item is null");
514
515                 r = CALENDAR_SVC_ITER_GET_INFO(it, &item->cs);
516                 if (r != CAL_SUCCESS)
517                         break;
518
519                 p->event_list = eina_list_append(p->event_list, item);
520         }
521
522         CALENDAR_SVC_ITER_REMOVE(&it);
523         if (eina_list_count(p->event_list) < p->totalcnt) {
524                 if (!p->idler) {
525                         p->idler = ecore_idler_add(__cal_list_ug_update_fetch_list_idler,p);
526                 }
527         }
528 }
529 static bool __cal_list_ug_strstr(const char *pszParent, const char * pszChild)
530 {
531         bool bRst = false;
532         if (!pszParent || !pszChild) {
533                 return false;
534         }
535
536         GString * gSrc = g_string_new(pszParent);
537         if (!gSrc) {
538                 return false;
539         }
540
541         GString * gDes = g_string_new(pszChild);
542         if (!gDes) {
543                 g_string_free(gSrc,true);
544                 return false;
545         }
546
547         gSrc = g_string_ascii_up(gSrc);
548         if (!gSrc) {
549                 g_string_free(gDes,true);
550                 return false;
551         }
552
553         gDes = g_string_ascii_up(gDes);
554         if (!gDes) {
555                 g_string_free(gSrc,true);
556                 return false;
557         }
558
559         if (g_strrstr(gSrc->str,gDes->str)) {
560                 bRst = true;
561         } else {
562                 bRst = false;
563         }
564
565         g_string_free(gSrc,true);
566         g_string_free(gDes,true);
567         return bRst;
568 }
569 static void __cal_list_ug_append_with_idler(void* data)
570 {
571         c_retm_if(!data, "data is null");
572
573         cal_list_ug_data* p = data;
574         Eina_List *event_list, *l = NULL;
575         cal_list_ug_item_data *item = NULL;
576         Elm_Object_Item *it = NULL;
577         const char* summary = NULL;
578
579         event_list = eina_list_nth_list(p->event_list, p->offset-1);
580         if (event_list) {
581                 event_list = eina_list_next(event_list);
582                 c_retm_if(NULL == event_list, "eina_list_nth_list(append_list, 1) is null");
583         }
584         c_retm_if(!event_list, "eina_list_nth(list, %d) returned null", p->offset);
585
586         EINA_LIST_FOREACH(event_list, l, item) {
587                 if (item && item->cs) {
588                         if (p->searchtext && 0 < strlen(p->searchtext)) {
589                                 summary = CALENDAR_SVC_STRUCT_GET_STR(item->cs, CAL_VALUE_TXT_SUMMARY);
590
591                                 if (summary && __cal_list_ug_strstr(summary, p->searchtext)) {
592                                         it = elm_genlist_item_append(p->genlist, &itc, item, NULL, ELM_GENLIST_ITEM_NONE, __cal_list_ug_genlist_item_select_callback, item);
593                                         c_retm_if(!it, "elm_genlist_item_append is failed");
594
595                                         if (item && item->checked)
596                                                 p->num_check++;
597
598                                         p->genlist_count++;
599                                 }
600
601                         } else {
602
603                                 if (item && item->checked)
604                                         p->num_check++;
605
606                                 it = elm_genlist_item_append(p->genlist, &itc, item, NULL, ELM_GENLIST_ITEM_NONE, __cal_list_ug_genlist_item_select_callback, item);
607                                 c_retm_if(!it, "elm_genlist_item_append is failed");
608
609                                 p->genlist_count++;
610                         }
611                 }
612
613                 p->offset++;
614         }
615 }
616
617 static void __cal_list_ug_append_genlist(cal_list_ug_data *p)
618 {
619         CAL_FN_START;
620
621         c_retm_if(!p, "p is null");
622         c_ret_if(p->event_list <= 0);
623
624         Eina_List *l = NULL;
625         cal_list_ug_item_data *item = NULL;
626         Elm_Object_Item *it = NULL;
627         const char* summary = NULL;
628         p->genlist_count = 0;
629
630         EINA_LIST_FOREACH(p->event_list, l, item) {
631                 if (item && item->cs) {
632                         if (p->searchtext && 0 < strlen(p->searchtext)) {
633                                 summary = CALENDAR_SVC_STRUCT_GET_STR(item->cs, CAL_VALUE_TXT_SUMMARY);
634
635                                 if (summary && __cal_list_ug_strstr(summary, p->searchtext)) {
636                                         it = elm_genlist_item_append(p->genlist, &itc, item, NULL, ELM_GENLIST_ITEM_NONE, __cal_list_ug_genlist_item_select_callback, item);
637                                         c_retm_if(!it, "elm_genlist_item_append is failed");
638                                         if (item && item->checked)
639                                                 p->num_check++;
640
641                                         p->genlist_count++;
642                                 }
643
644                         } else {
645
646                                 if (item && item->checked)
647                                         p->num_check++;
648
649                                 it = elm_genlist_item_append(p->genlist, &itc, item, NULL, ELM_GENLIST_ITEM_NONE, __cal_list_ug_genlist_item_select_callback, item);
650                                 c_retm_if(!it, "elm_genlist_item_append is failed");
651
652                                 p->genlist_count++;
653                         }
654
655                 }
656
657                 p->offset++;
658
659         }
660
661         if (p->genlist_count == p->num_check)
662                 elm_check_state_set(p->select_all_check, EINA_TRUE);
663         else
664                 elm_check_state_set(p->select_all_check, EINA_FALSE);
665
666         if (p->num_check <= 0) {
667                 evas_object_hide(p->notify);
668                 elm_object_item_disabled_set(p->bt, EINA_TRUE);
669         } else
670                 elm_object_item_disabled_set(p->bt, EINA_FALSE);
671 }
672
673 static void __cal_list_ug_create_searchbar(cal_list_ug_data *p)
674 {
675         c_retm_if(!p, "priv is null.");
676         c_retm_if(!p->ly, "p->ly is null.");
677
678         Evas_Object *searchbar = cal_util_add_searchbar(p->ly, NULL, NULL, EINA_TRUE);
679         c_retm_if(!searchbar, "cal_util_add_searchbar() returned null.");
680
681         Evas_Object *en = elm_object_part_content_get(searchbar, "elm.swallow.content");
682         c_retm_if(!en, "elm_object_part_content_get returned null.");
683
684         elm_entry_input_panel_layout_set(en, ELM_INPUT_PANEL_LAYOUT_NORMAL);
685         elm_entry_markup_filter_append(en, elm_entry_filter_limit_size, &_limit_20char);
686
687         evas_object_size_hint_weight_set(searchbar, EVAS_HINT_EXPAND, 0.1);
688         evas_object_size_hint_align_set(searchbar, EVAS_HINT_FILL, 0.6);
689
690         evas_object_smart_callback_add(en, "changed", __cal_list_ug_searchbar_entry_changed_callback, p);
691         evas_object_smart_callback_add(en, "unfocused", __cal_list_ug_searchbar_entry_unfocused_callback, p);
692         evas_object_smart_callback_add(searchbar, "clicked", __cal_list_ug_searchbar_clicked_callback, p);
693         evas_object_smart_callback_add(searchbar, "cancel,clicked", __cal_list_ug_cancel_button_callback, p);
694
695         evas_object_show(searchbar);
696
697         elm_object_part_content_set(p->ly, "searchbar", searchbar);
698         p->searchbar = searchbar;
699 }
700
701 static void __cal_list_ug_select_all_mouse_up_callback(void *data, Evas *e, Evas_Object *obj, void *event_info)
702 {
703         c_retm_if(!data, "data is null");
704         cal_list_ug_data *p = data;
705
706         Evas_Event_Mouse_Up *ev = event_info;
707         if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD)
708                 return;
709
710         if (p->genlist_count <= 0) {
711                 return;
712         }
713         elm_check_state_set(p->select_all_check, !elm_check_state_get(p->select_all_check));
714
715         __cal_list_ug_update_all_check(p);
716 }
717
718 static void __cal_list_ug_select_all_changed_callback(void *data, Evas_Object *obj, void *event_info)
719 {
720         c_retm_if(!obj, "obj is null");
721
722         cal_list_ug_data* p = data;
723         c_retm_if(!p, "p is null");
724         if (p->genlist_count <= 0) {
725                 return;
726         }
727
728         __cal_list_ug_update_all_check(p);
729 }
730
731 static void __cal_list_ug_create_select_all(cal_list_ug_data* p)
732 {
733         CAL_FN_START;
734
735         c_retm_if(!p, "p is null");
736         c_retm_if(!p->ly, "p->lu is null");
737         c_retm_if(!p->box, "p->box is null");
738
739         Evas_Object* layout = p->select_all_layout = elm_layout_add(p->box);
740         c_retm_if(!layout, "elm_layout_add returned null");
741
742         elm_layout_theme_set(layout, "genlist", "item", "select_all/default");
743         evas_object_size_hint_weight_set(layout, EVAS_HINT_EXPAND, EVAS_HINT_FILL);
744         evas_object_size_hint_align_set(layout, EVAS_HINT_FILL, EVAS_HINT_FILL);
745         evas_object_event_callback_add(layout, EVAS_CALLBACK_MOUSE_UP, __cal_list_ug_select_all_mouse_up_callback, p);
746
747         Evas_Object* check = p->select_all_check = elm_check_add(p->select_all_layout);
748
749         c_retm_if(!check, "elm_check_add returned null");
750         evas_object_smart_callback_add(check, "changed", __cal_list_ug_select_all_changed_callback, p);
751         evas_object_propagate_events_set(check, EINA_FALSE);
752
753         elm_object_part_content_set(layout, "elm.icon", check);
754         evas_object_data_set(p->select_all_check, "layout", p->select_all_layout);
755         elm_object_part_text_set(p->select_all_layout, "elm.text", S_("IDS_COM_BODY_SELECT_ALL"));
756         elm_box_pack_start(p->box, p->select_all_layout);
757         evas_object_show(p->select_all_layout);
758 }
759
760 static void __cal_list_ug_update_event_list(cal_list_ug_data *p)
761 {
762         __cal_list_ug_clear_event_list(p);
763
764         p->num_check = 0;
765         p->offset = 0;
766
767         __cal_list_ug_get_event_list(p);
768 }
769
770 static void __cal_list_ug_update(cal_list_ug_data *p)
771 {
772         CAL_FN_START;
773
774         c_retm_if(!p, "p is null");
775
776         if (p->idler) {
777                 ecore_idler_del(p->idler);
778                 p->idler = NULL;
779         }
780
781         __cal_list_ug_update_event_list(p);
782
783         if (p->event_list && 0 < eina_list_count(p->event_list)) {
784                 p->no_contents = NULL;
785
786                 edje_object_signal_emit(CAL_UTIL_GET_EDJ_DATA(p->ly), "searchbar,show", "prog");
787
788                 if (!p->conformant) {
789                         Evas_Object *conformant = elm_conformant_add(p->ly);
790                         c_retm_if(!conformant, "conformant is null");
791
792                         elm_object_style_set(conformant, "internal_layout");
793                         evas_object_size_hint_weight_set(conformant, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
794
795                         elm_object_part_content_set(p->ly, "sw", conformant);
796
797                         p->conformant = conformant;
798                 }
799
800                 __cal_list_ug_create_searchbar(p);
801
802                 if (!p->box) {
803                         Evas_Object *box = elm_box_add(p->conformant);
804                         c_retm_if(!box, "box is null");
805
806                         evas_object_size_hint_weight_set(box, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
807
808                         elm_object_content_set(p->conformant, box);
809
810                         p->box = box;
811                 }
812
813                 __cal_list_ug_create_select_all(p);
814
815                 if (!p->genlist)
816                 {
817                         Evas_Object *genlist = elm_genlist_add(p->ly);
818                         c_retm_if(!genlist, "genlist is null");
819
820                         elm_genlist_decorate_mode_set(genlist, EINA_TRUE);
821                         evas_object_data_set(genlist, "priv", p);
822                         elm_genlist_scroller_policy_set(genlist, ELM_SCROLLER_POLICY_OFF,ELM_SCROLLER_POLICY_OFF);
823                         elm_genlist_block_count_set(genlist, 20);
824                         elm_genlist_homogeneous_set(genlist, EINA_TRUE);
825                         evas_object_size_hint_weight_set(genlist, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
826                         evas_object_size_hint_align_set(genlist, EVAS_HINT_FILL, EVAS_HINT_FILL);
827                         evas_object_show(genlist);
828                         elm_box_pack_end(p->box, genlist);
829
830                         p->genlist = genlist;
831                 }
832                 else
833                         elm_genlist_clear(p->genlist);
834
835                 __cal_list_ug_append_genlist(p);
836         }
837         else {
838                 p->conformant = NULL;
839                 p->box = NULL;
840                 p->select_all_layout = NULL;
841                 p->genlist = NULL;
842
843                 if (p->notify)
844                         evas_object_hide(p->notify);
845
846                 edje_object_signal_emit(CAL_UTIL_GET_EDJ_DATA(p->ly), "searchbar,hide", "prog");
847
848                 if (!p->no_contents) {
849                         Evas_Object *no_contents = cal_util_add_nocontents(p->ly, C_("IDS_CLD_BODY_NO_EVENTS"));
850                         c_retm_if(!no_contents, "no_contents is null.");
851
852                         elm_object_part_content_set(p->ly, "sw", no_contents);
853
854                         p->no_contents = no_contents;
855                 }
856
857                 elm_object_item_disabled_set(p->bt, EINA_TRUE);
858
859         }
860
861         CAL_FN_END;
862 }
863
864 static void __cal_list_ug_update_all_check(cal_list_ug_data* p)
865 {
866         c_retm_if(!p, "p is null");
867         c_retm_if(!p->genlist, "p is null");
868
869         Elm_Object_Item *it;
870         Eina_List *realized_list, *l;
871         cal_list_ug_item_data* item_data;
872
873         if (elm_check_state_get(p->select_all_check)) {
874                 p->num_check = p->genlist_count;
875                 elm_object_item_disabled_set(p->bt, EINA_FALSE);
876                 __cal_list_ug_add_small_info(p, p->genlist_count);
877         } else {
878                 p->num_check = 0;
879                 elm_object_item_disabled_set(p->bt, EINA_TRUE);
880                 evas_object_hide(p->notify);
881         }
882
883         it = elm_genlist_first_item_get(p->genlist);
884         while (it) {
885                 item_data = elm_object_item_data_get(it);
886                 if (item_data) {
887                         item_data->checked = elm_check_state_get(p->select_all_check);
888                 }
889                 it = elm_genlist_item_next_get(it);
890         }
891
892         realized_list = elm_genlist_realized_items_get(p->genlist);
893         EINA_LIST_FOREACH(realized_list, l, it)
894         {
895                 if (it) {
896                         elm_genlist_item_update(it);
897                 }
898         }
899 }
900
901 static Evas_Object* __cal_list_ug_create_layout(Evas_Object *parent, struct ug_data *ugd)
902 {
903         CAL_FN_START;
904
905         c_retvm_if(!parent, NULL, "parent is null");
906         c_retvm_if(!ugd, NULL, "ugd is null");
907
908         cal_list_ug_data *p = calloc(1, sizeof(cal_list_ug_data));
909         c_retvm_if(!p, NULL, "p is null");
910
911         p->name = _name;
912         p->ugd = ugd;
913         p->parent = parent;
914         p->searchtext = NULL;
915         p->notify_layout = NULL;
916         p->notify = NULL;
917         p->navi_item = NULL;
918         p->genlist_count = 0;
919         p->bg = NULL;
920
921         is_ug_list_view_destory = EINA_FALSE;
922
923         Evas_Object *ly = cal_util_add_layout(parent, p->name);
924         if (!ly)
925         {
926                 ERR("cal_util_add_layout returned null");
927                 free(p);
928                 return NULL;
929         }
930         p->ly = ly;
931         evas_object_data_set(ly, "priv", p);
932
933         p->bg = cal_util_add_bg(ly,EINA_FALSE);
934         if (!p->bg) {
935                 ERR("cal_util_add_bg returned null");
936                 evas_object_del(ly);
937                 free(p);
938                 ERR("bg is null");
939                 return NULL;
940         }
941         elm_object_part_content_set(ly, "base", p->bg);
942
943         __cal_list_ug_update(p);
944
945         evas_object_show(ly);
946         evas_object_event_callback_add(ly, EVAS_CALLBACK_DEL, __cal_list_ug_delete_layout, p);
947         CALENDAR_SVC_ADD_EVENT_CHANGED_CALLBACK((void(*)(void*))__cal_list_ug_update, p);
948
949         return ly;
950 }
951
952
953 static void __cal_list_ug_get_time_text(time_t t, int allday, char *buf, int sz)
954 {
955         struct tm tm;
956         const char* time;
957
958         localtime_r(&t, &tm);
959
960         if (is_hour24)
961                 time = CAL_UTIL_TIME_FORMAT_6;
962         else
963                 time = CAL_UTIL_TIME_FORMAT_1;
964
965         if (allday)
966                 cal_util_get_time_text(buf, sz, CAL_UTIL_DATE_FORMAT_1, NULL, &tm);
967         else
968                 cal_util_get_time_text(buf, sz, CAL_UTIL_DATE_FORMAT_1, time, &tm);
969 }
970
971 static void __cal_list_ug_get_start_time_text(cal_struct *cs, char *buf, int sz)
972 {
973         int allday;
974         time_t t;
975
976         allday = CALENDAR_SVC_STRUCT_GET_INT(cs, CAL_VALUE_INT_ALL_DAY_EVENT);
977
978         t = mktime(CALENDAR_SVC_STRUCT_GET_TM(cs, CAL_VALUE_GMT_START_DATE_TIME, CAL_TZ_FLAG_LOCAL));
979
980         __cal_list_ug_get_time_text(t, allday, buf, sz);
981 }
982
983 static void __cal_list_ug_get_end_time_text(cal_struct *cs, char *buf, int sz)
984 {
985         int allday;
986         time_t t;
987
988         allday = CALENDAR_SVC_STRUCT_GET_INT(cs, CAL_VALUE_INT_ALL_DAY_EVENT);
989
990         t = mktime(CALENDAR_SVC_STRUCT_GET_TM(cs, CAL_VALUE_GMT_END_DATE_TIME, CAL_TZ_FLAG_LOCAL));
991
992         __cal_list_ug_get_time_text(t, allday, buf, sz);
993 }
994
995
996 static void __cal_list_ug_get_message_content(cal_struct *cs, char *body , int nsize)
997 {
998         c_retm_if(!cs, "cs is null");
999
1000         char *content = NULL;
1001         char *title = NULL;
1002         char *location = NULL;
1003         char start[1024] = "Start\n";
1004         char end[1024] = "End\n";
1005         char buf[1024] = {0};
1006
1007         content = _("Check this schedule,please");
1008
1009         title = CALENDAR_SVC_STRUCT_GET_STR(cs, CAL_VALUE_TXT_SUMMARY);
1010         if (!title)
1011                 title = C_("IDS_CLD_BODY_NO_TITLE");
1012
1013         location = CALENDAR_SVC_STRUCT_GET_STR(cs, CAL_VALUE_TXT_LOCATION);
1014         if (!location)
1015                 location = _("No location");
1016
1017         __cal_list_ug_get_start_time_text(cs, buf, sizeof(buf));
1018         CAL_STRNCAT(start,buf,sizeof start)
1019
1020                 __cal_list_ug_get_end_time_text(cs, buf, sizeof(buf));
1021         CAL_STRNCAT(end,buf,sizeof end)
1022
1023         snprintf(body, nsize, "%s\n%s\n%s\n%s\n%s",content, title, location, start, end);
1024 }
1025
1026
1027 static void __cal_list_ug_add_bundle_event(bundle *b, cal_struct *cs, int idx)
1028 {
1029         char txt_content[1024*5] = {0};
1030
1031         __cal_list_ug_get_message_content(cs, txt_content,sizeof txt_content);
1032
1033         bundle_add(b, "BODY", txt_content);
1034 }
1035
1036 static void __cal_list_ug_add_bundle_vcs(bundle *b, cal_struct *cs, int idx, const char *caller)
1037 {
1038         int cid;
1039         int r;
1040         char buf[FILENAME_MAX];
1041         char path[FILENAME_MAX];
1042
1043         cid = CALENDAR_SVC_STRUCT_GET_INT(cs, CAL_VALUE_INT_INDEX);
1044
1045         snprintf(buf, sizeof(buf), "vfile%d", idx);
1046         snprintf(path, sizeof(path), "%s/Calendar_%d.vcs", VFILE_PATH, cid);
1047
1048         r = CALENDAR_SVC_UTIL_SAVE_VCS_BY_INDEX(cid, path);
1049         if (r == CAL_SUCCESS)
1050                 bundle_add(b, buf, path);
1051 }
1052
1053 static void __cal_list_ug_add_bundle(bundle *b, cal_struct *cs, int idx, struct ug_data *ugd)
1054 {
1055         switch (ugd->mode) {
1056         case _MODE_GET_EVT:
1057                 __cal_list_ug_add_bundle_event(b, cs, idx);
1058                 break;
1059         case _MODE_GET_VCS:
1060                 __cal_list_ug_add_bundle_vcs(b, cs, idx, ugd->caller);
1061                 break;
1062         default:
1063                 // do nothing
1064                 break;
1065         }
1066 }
1067
1068 static bundle* __cal_list_ug_make_bundle(cal_list_ug_data *p, struct ug_data *ugd)
1069 {
1070         c_retvm_if(!p, NULL, "p is null");
1071         c_retvm_if(!ugd, NULL, "ugd is null");
1072
1073         bundle *b = NULL;
1074         Eina_List *l;
1075         cal_list_ug_item_data* item_data;
1076         int count = 0;
1077         char buf[32] = {'\0'};
1078
1079         b = bundle_create();
1080         c_retvm_if(!b, NULL, "bundle_create returned null");
1081
1082         EINA_LIST_FOREACH(p->event_list, l, item_data)
1083         {
1084                 if (item_data && item_data->checked)
1085                 {
1086                         count++;
1087                         __cal_list_ug_add_bundle(b, item_data->cs, count, ugd);
1088                 }
1089         }
1090
1091         snprintf(buf, sizeof(buf), "%d", count);
1092         bundle_add(b, "count", buf);
1093
1094         return b;
1095 }
1096
1097 static void __cal_list_ug_attach(void *data, Evas_Object *obj, void *ei)
1098 {
1099         c_retm_if(!data, "data is null");
1100
1101         Evas_Object *ly = data;
1102         cal_list_ug_data *p;
1103         struct ug_data *ugd;
1104         bundle *b;
1105
1106         p = CAL_UTIL_GET_PRIV_DATA(ly);
1107         c_retm_if(!p, "p is null");
1108
1109         ugd = p->ugd;
1110         c_retm_if(!ugd, "ugd is null");
1111
1112         switch (ugd->mode)
1113         {
1114         case _MODE_GET_EVT:
1115         case _MODE_GET_VCS:
1116                 b = __cal_list_ug_make_bundle(p, ugd);
1117                 c_retm_if(!b, "b is null");
1118                 break;
1119         default:
1120                 b = NULL;
1121                 break;
1122         }
1123
1124         if (b)
1125         {
1126                 ug_send_result(ugd->ug, b);
1127                 bundle_free(b);
1128         }
1129
1130         ug_destroy_me(ugd->ug);
1131 }
1132
1133 static void __cal_list_ug_add_controlbar( struct ug_data *ugd, Evas_Object *ly, const char* title)
1134 {
1135         Evas_Object *cbar = NULL;
1136         Elm_Object_Item* navi_item = NULL;
1137         Elm_Object_Item * attach_button = NULL;
1138         cal_list_ug_data* p = evas_object_data_get(ly,"priv");
1139         c_retm_if(!p, "p is null");
1140
1141         cbar = cal_util_add_controlbar(ugd->nv);
1142         c_retm_if(!cbar, "cal_util_add_controlbar returned null");
1143
1144         elm_toolbar_item_append(cbar, NULL, NULL, NULL, NULL);
1145
1146         attach_button = elm_toolbar_item_append(cbar, NULL, S_("IDS_COM_POP_ATTACH"), __cal_list_ug_attach, ly);
1147         c_retm_if(!attach_button, "elm_toolbar_item_append returned null");
1148         p->bt = attach_button;
1149
1150         elm_object_item_disabled_set(p->bt, EINA_TRUE);
1151
1152         is_hour24 = ugd->is_hour24;
1153
1154         navi_item = elm_naviframe_item_push(ugd->nv, title, NULL, NULL, ly, NULL);
1155         if (!navi_item)
1156         {
1157                 ERR("elm_naviframe_item_push returned null");
1158                 evas_object_del(cbar);
1159                 return;
1160         }
1161
1162         elm_object_item_part_content_set(navi_item, "controlbar", cbar);
1163 }
1164
1165 void cal_list_ug_create(const char *title, struct ug_data *ugd)
1166 {
1167         Evas_Object *ly = __cal_list_ug_create_layout(ugd->nv, ugd);
1168         if (!ly)
1169                 return;
1170
1171         ugd->cont = ly;
1172
1173         __cal_list_ug_add_controlbar(ugd, ly, title);
1174 }
1175
1176 static void __cal_list_ug_searchbar_entry_changed_callback(void *data, Evas_Object *obj, void *event_info)
1177 {
1178         CAL_FN_START;
1179
1180         cal_list_ug_data *p = data;
1181         c_retm_if(!p, "priv is null.");
1182
1183         p->searchtext = elm_object_text_get(elm_object_part_content_get(p->searchbar, "elm.swallow.content"));
1184
1185         elm_genlist_clear(p->genlist);
1186
1187         if (!p->genlist) {
1188                 p->genlist = elm_genlist_add(p->parent);
1189                 c_retm_if(!p->genlist, "p->genlist is null");
1190                 elm_genlist_decorate_mode_set(p->genlist, EINA_TRUE);
1191                 evas_object_data_set(p->genlist, "priv", p);
1192         }
1193
1194         p->num_check = 0;
1195         p->offset = 0;
1196         __cal_list_ug_append_genlist(p);
1197         if (p->genlist_count == p->num_check) {
1198                 if (p->num_check == 0) {
1199                         elm_check_state_set(p->select_all_check,EINA_FALSE);
1200                         elm_object_disabled_set(p->select_all_check,EINA_TRUE);
1201                 } else {
1202                         elm_check_state_set(p->select_all_check,EINA_TRUE);
1203                 }
1204         } else {
1205                 elm_check_state_set(p->select_all_check,EINA_FALSE);
1206         }
1207
1208         if (p->genlist_count > 0) {
1209                 elm_object_disabled_set(p->select_all_check,EINA_FALSE);
1210         }
1211
1212         if (0 < p->num_check)
1213                 elm_object_item_disabled_set(p->bt, EINA_FALSE);
1214         else
1215                 elm_object_item_disabled_set(p->bt, EINA_TRUE);
1216
1217         __cal_list_ug_add_small_info(p,p->num_check);
1218 }
1219
1220 static void __cal_list_ug_cancel_button_callback(void *data, Evas_Object *obj, void *event_info)
1221 {
1222         CAL_FN_START;
1223
1224         c_retm_if(!data, "data is null");
1225         cal_list_ug_data *p = data;
1226         Eina_List *l = NULL;
1227         cal_list_ug_item_data *item =NULL;
1228
1229         Evas_Object *en = elm_object_part_content_get(p->searchbar, "elm.swallow.content");
1230         c_retm_if(!en, "elm_object_part_content_get returned null");
1231
1232         Ecore_IMF_Context *imf_context = elm_entry_imf_context_get(en);
1233         c_retm_if(!imf_context, "elm_entry_imf_context_get returned null");
1234
1235         if (imf_context)
1236                 ecore_imf_context_input_panel_hide(imf_context);
1237
1238         if (0 < p->num_check)
1239                 elm_object_item_disabled_set(p->bt, EINA_FALSE);
1240         else
1241                 elm_object_item_disabled_set(p->bt, EINA_TRUE);
1242
1243         p->num_check = 0;
1244
1245         EINA_LIST_FOREACH(p->event_list, l, item) {
1246                 if (item != NULL && item->checked) {
1247                         p->num_check++;
1248                 }
1249         }
1250
1251         if (p->genlist_count == p->num_check && p->num_check != 0) {
1252                 elm_check_state_set(p->select_all_check, EINA_TRUE);
1253         } else {
1254                 elm_check_state_set(p->select_all_check, EINA_FALSE);
1255         }
1256         elm_object_disabled_set(p->select_all_check,EINA_FALSE);
1257
1258         __cal_list_ug_add_small_info(p,p->num_check);
1259 }
1260
1261 static void __cal_list_ug_searchbar_entry_unfocused_callback(void *data, Evas_Object *obj, void *event_info)
1262 {
1263         c_retm_if(!data, "data is null.");
1264         cal_list_ug_data *p = data;
1265
1266         if (p->num_check <= 0) {
1267                 elm_object_item_disabled_set(p->bt, EINA_TRUE);
1268         } else {
1269                 elm_object_item_disabled_set(p->bt, EINA_FALSE);
1270         }
1271
1272         __cal_list_ug_add_small_info(p,p->num_check);
1273 }
1274
1275 static void __cal_list_ug_searchbar_clicked_callback(void *data, Evas_Object *obj, void *event_info)
1276 {
1277         c_retm_if(!data, "data is null.");
1278         cal_list_ug_data *p = data;
1279
1280         elm_object_item_disabled_set(p->bt, EINA_TRUE);
1281 }