dc1736e9e481ba13e0996576119c6a7113d29a4c
[apps/core/preloaded/calendar.git] / src / view-ring.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 <Ecore_X.h>
27 #include <utilX.h>
28 #include <mm_error.h>
29 #include <pmapi.h>
30 #include <wav_player.h>
31
32 #include "view.h"
33 #include "alm-mgr.h"
34 #include "view-ring.h"
35
36 #define DEFAULT_TONE RESDIR "/sounds/On_time.wav"
37 #define CAL_ALARM_RING_TIMER 60.0
38
39 static const char *_name = "ring";
40
41 typedef struct {
42         const char *name;
43         struct appdata *ad;
44         Evas_Object *win;
45         Evas_Object *ly;
46
47         Eina_List *cslist;
48
49         Ecore_Timer *tmr;
50         int mm_id;
51
52         char *ring_path;
53
54         int is_stop;
55 }cal_ring_data;
56
57 static void __cal_ring_set_window_property(Evas_Object *win)
58 {
59         Ecore_X_Window w;
60
61         w = elm_win_xwindow_get(win);
62
63         ecore_x_netwm_window_type_set(w, ECORE_X_WINDOW_TYPE_NOTIFICATION);
64         utilx_set_system_notification_level(ecore_x_display_get(), w, UTILX_NOTIFICATION_LEVEL_NORMAL);
65 }
66
67 static void __cal_ring_stop_alarm(cal_ring_data *p)
68 {
69         CAL_FN_START;
70
71         if (p->mm_id != -1) {
72                 wav_player_stop(p->mm_id);
73                 p->mm_id = -1;
74         }
75
76         if (p->ring_path) {
77                 free(p->ring_path);
78                 p->ring_path = NULL;
79         }
80 }
81
82 static void __cal_ring_window_delete_callback(void *data, Evas *e, Evas_Object *obj, void *event)
83 {
84         CAL_FN_START;
85
86         c_retm_if(!data, "data is null");
87
88         cal_ring_data *p = data;
89
90         __cal_ring_stop_alarm(p);
91
92         if (p->tmr)
93                 ecore_timer_del(p->tmr);
94
95         if (p->cslist)
96                 CALENDAR_SVC_FREE_CS_LIST(&p->cslist);
97
98         struct appdata *ad = p->ad;
99         if (ad)
100                 ad->alarm_window = NULL;
101
102         free(p);
103 }
104
105 static void __cal_ring_fill_cs(cal_struct *cs, Evas_Object *ly)
106 {
107         c_retm_if(!cs, "cs is null");
108         c_retm_if(!ly, "ly is null");
109
110         const char *str = CALENDAR_SVC_STRUCT_GET_STR(cs, CAL_VALUE_TXT_SUMMARY);
111         if (!CAL_STRLEN(str))
112                 str = C_("IDS_CLD_BODY_NO_TITLE");
113
114         const char *prev_title = edje_object_part_text_get(CAL_UTIL_GET_EDJ_DATA(ly), "text/title");
115         if (CAL_STRLEN(prev_title)) {
116                 char buffer[512] = {0};
117                 snprintf(buffer, sizeof(buffer), "%s, %s", prev_title, str);
118
119                 edje_object_part_text_set(CAL_UTIL_GET_EDJ_DATA(ly), "text/title", buffer);
120         } else
121                 edje_object_part_text_set(CAL_UTIL_GET_EDJ_DATA(ly), "text/title", str);
122
123         struct tm tm;
124         time_t now = time(NULL);
125         localtime_r(&now, &tm);
126
127         cal_util_set_time_text(CAL_UTIL_GET_EDJ_DATA(ly), "text/currenttime", NULL, CAL_UTIL_TIME_FORMAT_1, &tm);
128
129         cal_util_emit_signal(CAL_UTIL_GET_EDJ_DATA(ly), "min,%02d", tm.tm_min);
130
131         int hour = 0;
132         const char *ampm = NULL;
133
134         if (tm.tm_hour < 12) {
135                 ampm = "go,am";
136                 hour = tm.tm_hour;
137         } else {
138                 ampm = "go,pm";
139                 hour = tm.tm_hour - 12;
140         }
141
142         cal_util_emit_signal(CAL_UTIL_GET_EDJ_DATA(ly), "hour,%02d", hour * 5 + (tm.tm_min / 12));
143         edje_object_signal_emit(CAL_UTIL_GET_EDJ_DATA(ly), ampm, "prog");
144 }
145
146
147 static void __cal_ring_play_alarm_completed_cb(int id, void *user_data)
148 {
149         CAL_FN_START;
150
151         c_retm_if(!user_data, "user_data is NULL");
152
153         cal_ring_data *p = user_data;
154
155         if (id != p->mm_id)
156                 return;
157
158         int mm_id = 0;
159
160         wav_player_start(p->ring_path, SOUND_TYPE_RINGTONE, __cal_ring_play_alarm_completed_cb, p, &mm_id);
161
162         p->mm_id = mm_id;
163 }
164
165 static void __cal_ring_play_alarm(cal_ring_data *p, const char *path)
166 {
167         c_retm_if(!p, "p is NULL.");
168         c_retm_if(!path, "path is NULL.");
169
170         __cal_ring_stop_alarm(p);
171
172         p->ring_path = strdup(path);
173
174         int mm_id = 0;
175         int r = wav_player_start(path, SOUND_TYPE_RINGTONE, __cal_ring_play_alarm_completed_cb, p, &mm_id);
176         c_retm_if(r!= WAV_PLAYER_ERROR_NONE, "wav_player_start is failed.");
177
178         p->mm_id = mm_id;
179 }
180
181 static void __cal_ring_fill(cal_ring_data *p)
182 {
183         c_retm_if(!p, "p is null");
184         c_retm_if(!p->cslist, "p->cslist is null");
185
186         Eina_List *l = NULL;
187         cal_struct *cs = NULL;
188
189         EINA_LIST_FOREACH (p->cslist, l, cs) {
190
191                 if (!cs) {
192                         ERR("cs is null");
193                         continue;
194                 }
195
196                 __cal_ring_fill_cs(cs, p->ly);
197
198                 GList *al = NULL;
199
200                 int r = CALENDAR_SVC_STRUCT_GET_LIST(cs, CAL_VALUE_LST_ALARM, &al);
201                 if (r != CAL_SUCCESS) {
202                         ERR("CALENDAR_SVC_STRUCT_GET_LIST() is failed(%d)", r);
203                         continue;
204                 }
205
206                 if (al) {
207                         int count = g_list_length(al);
208                         c_retm_if(!count, "length of alarm list is 0");
209
210                         cal_value *val = al->data;
211                         c_retm_if(!val, "data of alarm list is null");
212
213                         const char *tone = CALENDAR_SVC_VALUE_GET_STR(val, CAL_VALUE_TXT_ALARMS_TONE);
214
215                         if (!CAL_STRLEN(tone))
216                                 tone = DEFAULT_TONE;
217
218                         __cal_ring_play_alarm(p, tone);
219                 }
220
221                 CALENDAR_SVC_STRUCT_FREE(&cs);
222         }
223
224         CALENDAR_SVC_FREE_CS_LIST(&p->cslist);
225 }
226
227 static void __cal_ring_stop_button_callback(void *data, Evas_Object *eo, const char *e, const char *s)
228 {
229         CAL_FN_START;
230
231         c_retm_if(!data, "data is null");
232
233         cal_ring_data *p = data;
234
235         if (p->cslist) {
236                 __cal_ring_fill(p);
237                 return;
238         }
239
240         evas_object_del(p->win);
241 }
242
243 static Evas_Object* __cal_ring_create_view(struct appdata *ad)
244 {
245         c_retvm_if(!ad, NULL, "ad is null");
246
247         cal_ring_data *p = NULL;
248
249         if (ad->alarm_window) {
250                 p = CAL_UTIL_GET_PRIV_DATA (ad->alarm_window);
251                 c_retvm_if(!p, NULL, "p is null");
252
253                 return ad->alarm_window;
254         }
255
256         p = calloc(1, sizeof(cal_ring_data));
257         c_retvm_if(!p, NULL, "p is null");
258
259         p->name = _name;
260         p->ad = ad;
261         p->mm_id = -1;
262
263         p->win = cal_util_add_window(CALENDAR_RING , NULL, NULL);
264         if (!p->win)
265         {
266                 ERR("cal_util_add_window(CALENDAR_RING, NULL, NULL) is failed");
267                 free(p);
268                 return NULL;
269         }
270
271         ad->alarm_window = p->win;
272
273         __cal_ring_set_window_property(p->win);
274         evas_object_data_set(p->win, "priv", p);
275
276         p->ly = cal_util_add_layout(p->win, p->name);
277         if (!p->ly)
278         {
279                 ERR("cal_util_add_layout() is failed");
280                 evas_object_del(p->win);
281                 free(p);
282                 return NULL;
283         }
284
285         elm_win_resize_object_add(p->win, p->ly);
286
287         edje_object_part_text_set(CAL_UTIL_GET_EDJ_DATA(p->ly), "text/stop", _("Stop"));
288         edje_object_signal_callback_add(CAL_UTIL_GET_EDJ_DATA(p->ly), "stop", "edj", __cal_ring_stop_button_callback, p);
289
290         evas_object_event_callback_add(p->win, EVAS_CALLBACK_DEL, __cal_ring_window_delete_callback, p);
291
292         pm_change_state(LCD_NORMAL);
293
294         evas_object_show(p->win);
295
296         return p->win;
297 }
298
299 static Eina_Bool __cal_ring_timer_callback(void *data)
300 {
301         CAL_FN_START;
302
303         c_retvm_if(!data, ECORE_CALLBACK_CANCEL, "data is null");
304
305         cal_ring_data *p = data;
306
307         __cal_ring_stop_alarm(p);
308
309         evas_object_del(p->win);
310
311         p->tmr = NULL;
312
313         return ECORE_CALLBACK_CANCEL;
314 }
315
316 static int __cal_ring_append_alarm(Evas_Object *win, Eina_List *cslist)
317 {
318         c_retvm_if(!win, -1, "win is null");
319         c_retvm_if(!cslist, -1, "cslist is null");
320
321         cal_ring_data *p = CAL_UTIL_GET_PRIV_DATA(win);
322         c_retvm_if(!p, -1, "p is null");
323
324         p->cslist = eina_list_merge(p->cslist, cslist);
325
326         __cal_ring_fill(p);
327
328         if (p->tmr)
329                 ecore_timer_del(p->tmr);
330
331         p->tmr = ecore_timer_add(CAL_ALARM_RING_TIMER, __cal_ring_timer_callback, p);
332         c_retvm_if(!p->tmr, -1, "p->tmr is null");
333
334         return 0;
335 }
336
337 int cal_ring_add_alarm(struct appdata *ad, Eina_List *cslist)
338 {
339         c_retvm_if(!ad, -1, "ad is null");
340         c_retvm_if(!cslist, -1, "csl is null");
341
342         Evas_Object *win = __cal_ring_create_view(ad);
343         c_retvm_if(!win, -1, "__cal_ring_create_view returned null");
344
345         return __cal_ring_append_alarm(win, cslist);
346 }
347