tizen_2.0_build
[apps/home/draglock.git] / src / draglock-time.c
1 /*
2  * Copyright 2012  Samsung Electronics Co., Ltd
3  *
4  * Licensed under the Flora License, Version 1.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *  http://www.tizenopensource.org/license
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #include <time.h>
18 #include <runtime_info.h>
19 #include <unicode/uloc.h>
20 #include <unicode/udat.h>
21 #include <unicode/udatpg.h>
22 #include <unicode/ustring.h>
23
24 #include "draglock.h"
25 #include "draglock-util.h"
26
27 #define DRAGLOCK_SUPPORT_ICU
28
29 static Eina_Bool _draglock_get_time(struct tm *st, char *data, int len,
30                 int *is_24hour) {
31
32         int r = -1, hour = 0;
33         char temp[32] = { 0, };
34         bool is_24hour_enabled = 0;
35
36         if (st == NULL) {
37                 DRAGLOCK_ERR("st is NULL");
38                 return EINA_FALSE;
39         }
40         if (data == NULL || len <= 0) {
41                 DRAGLOCK_ERR("data is NULL");
42                 return EINA_FALSE;
43         }
44         if (is_24hour == NULL) {
45                 DRAGLOCK_ERR("is_24hour is NULL");
46                 return EINA_FALSE;
47         }
48
49         r = runtime_info_get_value_bool(
50                         RUNTIME_INFO_KEY_24HOUR_CLOCK_FORMAT_ENABLED, &is_24hour_enabled);
51
52         DRAGLOCK_DBG("r:%d, is_24hour_enabled:%d bufSize:%d",
53                         r, is_24hour_enabled, sizeof(data));
54
55         if (r == RUNTIME_INFO_ERROR_NONE && is_24hour_enabled == 1) {
56                 strftime(data, len, "%H:%M", st);
57         } else {
58                 /* if %l is 1 ~9, it has blank space in front. Trim it using atoi function */
59                 strftime(temp, sizeof(temp), "%l", st);
60                 hour = atoi(temp);
61                 strftime(temp, sizeof(temp), ":%M", st);
62
63                 snprintf(data, len, "%d%s", hour, temp);
64         }
65
66         *is_24hour = is_24hour_enabled;
67         DRAGLOCK_DBG("data = %s", data);
68
69         return EINA_TRUE;
70 }
71
72 static Eina_Bool _draglock_get_date(time_t tt, char *data) {
73         UErrorCode status = U_ZERO_ERROR;
74         UDateTimePatternGenerator *generator;
75         UDateFormat *formatter;
76         UChar skeleton[40] = { 0 }, pattern[40] = { 0 }, formatted[40] = { 0 };
77         int32_t patternCapacity, formattedCapacity;
78         int32_t skeletonLength, patternLength, formattedLength;
79         UDate date;
80         const char *locale;
81         const char customSkeleton[] = UDAT_MONTH_WEEKDAY_DAY;
82
83         /* set UDate  from time_t */
84         date = (UDate) tt * 1000;
85
86         /* get default locale  */
87         uloc_setDefault(__secure_getenv("LC_TIME"), &status); /* for thread saftey  */
88         locale = uloc_getDefault();
89
90         /* open datetime pattern generator */
91         generator = udatpg_open(locale, &status);
92         if (generator == NULL)
93                 return EINA_FALSE;
94
95         /* calculate pattern string capacity */
96         patternCapacity = (int32_t)(sizeof(pattern) / sizeof((pattern)[0]));
97
98         /* ascii to unicode for input skeleton */
99         u_uastrcpy(skeleton, customSkeleton);
100
101         /* get skeleton length */
102         skeletonLength = strlen(customSkeleton);
103
104         /* get best pattern using skeleton */
105         patternLength = udatpg_getBestPattern(generator, skeleton, skeletonLength,
106                         pattern, patternCapacity, &status);
107
108         /* open datetime formatter using best pattern */
109         formatter = udat_open(UDAT_IGNORE, UDAT_DEFAULT, locale, NULL, -1, pattern,
110                         patternLength, &status);
111         if (formatter == NULL) {
112                 udatpg_close(generator);
113                 return EINA_FALSE;
114         }
115
116         /* calculate formatted string capacity */
117         formattedCapacity = (int32_t)(sizeof(formatted) / sizeof((formatted)[0]));
118
119         /* formatting date using formatter by best pattern */
120         formattedLength = udat_format(formatter, date, formatted, formattedCapacity,
121                         NULL, &status);
122
123         /* unicode to ascii to display */
124         u_austrcpy(data, formatted);
125         DRAGLOCK_DBG("formatted string=%s", data);
126
127         /* close datetime pattern generator */
128         udatpg_close(generator);
129
130         /* close datetime formatter */
131         udat_close(formatter);
132
133         return EINA_TRUE;
134 }
135
136 static Eina_Bool _draglock_time_set_date(void *data) {
137         struct appdata *ad = (struct appdata *) data;
138
139         if (ad == NULL || ad->time_layout == NULL) {
140                 return ECORE_CALLBACK_CANCEL;
141         }
142
143         int is_24hour = 0;
144         struct tm st;
145         time_t tt;
146         char buf[128] = { 0, };
147
148         tt = time(NULL);
149         localtime_r(&tt, &st);
150
151         if (ad->clock_timer != NULL) {
152                 ecore_timer_del(ad->clock_timer);
153                 ad->clock_timer = NULL;
154         }
155
156         ad->clock_timer = ecore_timer_add(60 - st.tm_sec, _draglock_time_set_date,
157                         ad);
158
159 #ifdef DRAGLOCK_SUPPORT_ICU
160         if (_draglock_get_date(tt, buf) == EINA_TRUE)
161                 elm_object_part_text_set(ad->time_layout, "text.date", buf);
162 #else
163         strftime(buf, sizeof(buf), "%b %d, %A", &st);
164         elm_object_part_text_set(ad->time_layout, "text.date", buf);
165 #endif
166
167         if (_draglock_get_time(&st, buf, sizeof(buf), &is_24hour) == EINA_TRUE) {
168
169                 if (is_24hour == 0) {
170                         if ((st.tm_hour >= 22 && st.tm_hour <= 23)
171                                         || (st.tm_hour >= 10 && st.tm_hour <= 12)
172                                         || (st.tm_hour == 0)) {
173                                 edje_object_signal_emit(_EDJ(ad->time_layout), "period.stretch",
174                                                 "rect.time.period");
175                         } else {
176                                 edje_object_signal_emit(_EDJ(ad->time_layout), "period.default",
177                                                 "rect.time.period");
178                         }
179
180                         if (st.tm_hour >= 0 && st.tm_hour < 12) {
181                                 elm_object_part_text_set(ad->time_layout, "text.time.period",
182                                                 "AM");
183                         } else {
184                                 elm_object_part_text_set(ad->time_layout, "text.time.period",
185                                                 "PM");
186                         }
187                 } else {
188                         elm_object_part_text_set(ad->time_layout, "text.time.period", "");
189                 }
190                 elm_object_part_text_set(ad->time_layout, "text.time", buf);
191         }
192
193         return ECORE_CALLBACK_CANCEL;
194 }
195
196 static void _draglock_power_changed_cb(power_state_e state, void *user_data) {
197         power_state_e current_power_state;
198         struct appdata *ad = (struct appdata *) user_data;
199
200         if (ad == NULL) {
201                 DRAGLOCK_DBG("ad or ad->ui_layout is null");
202                 return;
203         }
204
205         current_power_state = power_get_state();
206
207         DRAGLOCK_DBG("prev p-state:%d cur p-state:%d",
208                         ad->power_state, current_power_state);
209
210         if (ad->power_state == POWER_STATE_SCREEN_OFF
211                         && (current_power_state == POWER_STATE_SCREEN_DIM
212                                         || current_power_state == POWER_STATE_NORMAL)) {
213                 _draglock_time_set_date(user_data);
214                 DRAGLOCK_DBG("(after sleep)time updated");
215         }
216
217         ad->power_state = current_power_state;
218 }
219
220 Evas_Object *draglock_time_get_time(void *data) {
221         struct appdata *ad = (struct appdata *) data;
222         Evas_Object *layout = NULL;
223
224         if (ad == NULL || ad->ui_layout == NULL) {
225                 DRAGLOCK_DBG("ad or ad->ui_layout is null");
226                 return NULL;
227         }
228
229         layout = draglock_util_add_layout(ad->ui_layout, EDJEFILE, "draglock-time");
230         ad->time_layout = layout;
231
232         if (layout == NULL) {
233                 return NULL;
234         }
235
236         _draglock_time_set_date(ad);
237
238         ad->power_state = power_get_state();
239         power_set_changed_cb(_draglock_power_changed_cb, ad);
240
241         return layout;
242 }