Merge "custom eail widget implementation" into tizen
[platform/core/uifw/eail.git] / eail / eail_calendar.c
1 /*
2  * Copyright (c) 2013 Samsung Electronics Co., Ltd.
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public License
15  * along with this library; see the file COPYING.LIB.  If not, write to
16  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17  * Boston, MA 02110-1301, USA.
18  */
19
20 /**
21  * @file eail_calendar.c
22  * @brief EailCalendar implementation
23  */
24
25 #include <Elementary.h>
26
27 #include "eail_calendar.h"
28 #include "eail_utils.h"
29
30 static void atk_value_interface_init(AtkValueIface *iface);
31
32 /**
33  * @brief Define EailCalendar GObject type
34  */
35 G_DEFINE_TYPE_WITH_CODE(EailCalendar,
36                         eail_calendar,
37                         EAIL_TYPE_WIDGET,
38                         G_IMPLEMENT_INTERFACE(ATK_TYPE_VALUE,
39                                               atk_value_interface_init));
40
41 /**
42  * @brief handler for changed event
43  *
44  * @param data passed to callback
45  * @param obj object that raised event
46  * @param event_info additional event info
47  */
48
49 void
50 _eail_calendar_handle_changed_event(void *data,
51                                         Evas_Object *obj,
52                                         void *event_info)
53 {
54    eail_emit_atk_signal
55                   (ATK_OBJECT(data), "visible-data-changed", ATK_TYPE_OBJECT);
56 }
57 /**
58  * @brief EailCalendar object initialization
59  *
60  * Sets role of AtkObject.
61  *
62  * @param  obj AtkObject instance
63  * @param  data initialization data
64  */
65 static void eail_calendar_initialize(AtkObject *obj, gpointer data)
66 {
67    Evas_Object *nested_widget = NULL;
68    ATK_OBJECT_CLASS(eail_calendar_parent_class)->initialize(obj, data);
69
70    obj->role = ATK_ROLE_CALENDAR;
71    g_return_if_fail(EAIL_IS_WIDGET(obj));
72
73    nested_widget = eail_widget_get_widget(EAIL_WIDGET(obj));
74    evas_object_smart_callback_add(nested_widget, "changed",
75                                   _eail_calendar_handle_changed_event, obj);
76 }
77
78 /**
79  * @brief EailCalendar instance initialization
80  *
81  * EailCalendar does not have any fields to initialize in struct EailCalendar
82  * thus this function is empty but still it has to be defined.
83  *
84  * @param calendar EailCalendar instance
85  */
86 static void
87 eail_calendar_init(EailCalendar *calendar)
88 {
89 }
90
91 /**
92  * @brief EailCalendar class initialization function
93  *
94  * Unitializes AtkObjectClass method pointers
95  * with class's implementations.
96  *
97  * @param klass EailCalendarClass instance
98  */
99 static void
100 eail_calendar_class_init(EailCalendarClass *klass)
101 {
102    AtkObjectClass *atk_class;
103
104    atk_class = ATK_OBJECT_CLASS(klass);
105    atk_class->initialize = eail_calendar_initialize;
106 }
107
108 /**
109  * @brief Gets the current value of obj
110  *
111  * Gets calendar date.
112  *
113  * Example:
114  * @code
115  * AtkObject *obj; // AtkObject representing EailCalendar
116  * GValue value = G_VALUE_INIT;
117  * eail_calendar_get_current_value(ATK_VALUE(obj), &value);
118  * @endcode
119  *
120  * @param obj AtkValue instance
121  * @param [out] value obj's current value for date
122  */
123 static void
124 eail_calendar_get_current_value(AtkValue *obj,
125                                 GValue   *value)
126 {
127    Evas_Object *widget;
128    struct tm current;
129
130    widget = eail_widget_get_widget(EAIL_WIDGET(obj));
131    if (!widget) return;
132
133    elm_calendar_selected_time_get(widget, &current);
134
135    memset(value, 0, sizeof(GValue));
136    g_value_init(value, G_TYPE_INT);
137    g_value_set_int(value, mktime(&current));
138 }
139
140 /**
141  * @brief Gets the maxiumum value of obj
142  *
143  * Gets the maximum date that can be set for calendar.
144  *
145  * Example:
146  * @code
147  * AtkObject *obj; //AtkObject representing EailCalendar
148  * GValue value = G_VALUE_INIT;
149  * eail_calendar_get_maximum_value(ATK_VALUE(obj), &value);
150  * @endcode
151  *
152  * @param  obj AtkValue instance
153  * @param [out] value obj's maxiumum value
154  */
155 static void
156 eail_calendar_get_maximum_value(AtkValue *obj,
157                                 GValue   *value)
158 {
159    Evas_Object *widget;
160    struct tm maximum;
161    int min, max;
162
163    widget = eail_widget_get_widget(EAIL_WIDGET(obj));
164    if (!widget) return;
165
166    elm_calendar_min_max_year_get(widget, &min, &max);
167
168    memset(&maximum, 0, sizeof(maximum));
169
170    if (min < max)
171      {
172         maximum.tm_year = max - 1900;
173         maximum.tm_mon = 11;
174         maximum.tm_mday = 31;
175         maximum.tm_hour = 23;
176         maximum.tm_min = 59;
177         maximum.tm_sec = 59;
178      }
179
180    memset(value, 0, sizeof(GValue));
181    g_value_init(value, G_TYPE_INT);
182    g_value_set_int(value, mktime(&maximum));
183 }
184
185 /**
186  * @brief Gets the minimum value of obj
187  *
188  * Gets the minimum date than can be set for calendar.
189  *
190  * Example:
191  * @code
192  * AtkObject *obj; //AtkObject representing EailCalendar
193  * GValue value = G_VALUE_INIT;
194  * eail_calendar_get_minimum_value(ATK_VALUE(obj), &value);
195  * @endcode
196  *
197  * @param obj AtkObject instance
198  * @param [out] value obj's minimum value
199  */
200 static void
201 eail_calendar_get_minimum_value(AtkValue *obj,
202                                 GValue   *value)
203 {
204    Evas_Object *widget;
205    struct tm minimum;
206    int min, max;
207
208    widget = eail_widget_get_widget(EAIL_WIDGET(obj));
209    if (!widget) return;
210
211    elm_calendar_min_max_year_get(widget, &min, &max);
212
213    memset(&minimum, 0, sizeof(minimum));
214
215    if (min < max)
216      {
217         minimum.tm_year = min - 1900;
218         minimum.tm_mon = 0;
219         minimum.tm_mday = 1;
220         minimum.tm_hour = 0;
221         minimum.tm_min = 0;
222         minimum.tm_sec = 0;
223      }
224
225    memset(value, 0, sizeof(GValue));
226    g_value_init(value, G_TYPE_INT);
227    g_value_set_int(value, mktime(&minimum));
228 }
229
230 /**
231  * @brief Sets the value of obj
232  *
233  * Sets calendar date.
234  *
235  * Example:
236  * @code
237  * AtkObject *obj; // AtkObject representing EailCalendar
238  * GValue value = G_VALUE_INIT;
239  * struct tm time;
240  *
241  * memset(&tm, 0, sizeof(time));
242  * time.tm_year = 120;  // years since 1900
243  * time.tm_mon = 2;
244  * time.tm_mday = 15;
245  * time.tm_hour = 7;
246  * time.tm_min = 21;
247  * time.tm_sec = 33;
248  *
249  * g_value_set_int(&value, mktime(&time));
250  *
251  * eail_calendar_set_current_value(ATK_VALUE(obj), &value);
252  * @endcode
253  *
254  * @param  obj AtkValue instance
255  * @param  value obj's new value
256  * @return TRUE if new value was set successfully, FALSE otherwise
257  */
258 static gboolean
259 eail_calendar_set_current_value(AtkValue     *obj,
260                                 const GValue *value)
261 {
262    Evas_Object *widget;
263    struct tm minimum, maximum, current_set;
264    int min, max;
265    time_t time;
266
267    widget = eail_widget_get_widget(EAIL_WIDGET(obj));
268    if (!widget) return FALSE;
269
270    elm_calendar_min_max_year_get(widget, &min, &max);
271
272    memset(&minimum, 0, sizeof(minimum));
273    minimum.tm_year = min - 1900;
274    minimum.tm_mon = 0;
275    minimum.tm_mday = 1;
276    minimum.tm_hour = 0;
277    minimum.tm_min = 0;
278    minimum.tm_sec = 0;
279
280    memset(&maximum, 0, sizeof(maximum));
281    maximum.tm_year = max - 1900;
282    maximum.tm_mon = 11;
283    maximum.tm_mday = 31;
284    maximum.tm_hour = 23;
285    maximum.tm_min = 59;
286    maximum.tm_sec = 59;
287
288    time = g_value_get_int(value);
289
290    if ((min < max) && (mktime(&minimum) > time || mktime(&maximum) < time))
291      return FALSE;
292
293    localtime_r(&time, &current_set);
294    elm_calendar_selected_time_set(widget, &current_set);
295
296    return TRUE;
297 }
298
299 /**
300  * @brief Gets the minimum increment of obj
301  *
302  * Gets the minimum calendar increment i.e one second.
303  *
304  * Example:
305  *
306  * @code
307  * AtkObject *obj;
308  * GValue value = G_VALUE_INIT;
309  * eail_calendar_get_minimum_increment(ATK_VALUE(obj), &value);
310  * @endcode
311  *
312  * @param obj AtkValue instance
313  * @param [out] value obj's minimum increment
314  */
315 static void
316 eail_calendar_get_minimum_increment(AtkValue *obj,
317                                     GValue   *value)
318 {
319    Evas_Object *widget;
320
321    widget = eail_widget_get_widget(EAIL_WIDGET(obj));
322    if (!widget) return;
323
324    memset(value, 0, sizeof(GValue));
325    g_value_init(value, G_TYPE_INT);
326    g_value_set_int(value, 1);
327 }
328
329 /**
330  * @brief Initialization of AtkValue interface
331  *
332  * Function called upon instance creation. It initializes AtkValue interface
333  * implementation i.e hooks method pointers in the interface structure
334  * to the implementing class's implementation.
335  *
336  * @param iface AtkObject instance than implements AtkValueInterface
337  */
338 static void
339 atk_value_interface_init(AtkValueIface *iface)
340 {
341    iface->get_current_value     = eail_calendar_get_current_value;
342    iface->get_maximum_value     = eail_calendar_get_maximum_value;
343    iface->get_minimum_value     = eail_calendar_get_minimum_value;
344    iface->set_current_value     = eail_calendar_set_current_value;
345    iface->get_minimum_increment = eail_calendar_get_minimum_increment;
346 }