1 /* Copyright (c) 2008, Nokia Corporation
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * * Neither the name of the Nokia Corporation nor the names of its
14 * contributors may be used to endorse or promote products derived from
15 * this software without specific prior written permission.
17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
18 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
19 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
20 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
21 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
22 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
23 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
24 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
25 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
26 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 #include <modest-datetime-formatter.h>
32 #ifdef MODEST_TOOLKIT_HILDON2
33 #include <gconf/gconf-client.h>
34 #include <gtk/gtkmarshal.h>
36 #include <glib/gi18n.h>
37 #include "modest-text-utils.h"
38 #ifdef MODEST_USE_LIBTIME
39 #include <clockd/libtime.h>
41 #include <modest-platform.h>
47 DATETIME_FORMAT_LOCALE,
50 #define HILDON2_GCONF_FORMAT_DIR "/apps/clock"
51 #define HILDON2_GCONF_FORMAT_KEY HILDON2_GCONF_FORMAT_DIR "/time-format"
53 /* 'private'/'protected' functions */
54 static void modest_datetime_formatter_class_init (ModestDatetimeFormatterClass *klass);
55 static void modest_datetime_formatter_finalize (GObject *obj);
56 static void modest_datetime_formatter_instance_init (ModestDatetimeFormatter *obj);
58 typedef struct _ModestDatetimeFormatterPrivate ModestDatetimeFormatterPrivate;
59 struct _ModestDatetimeFormatterPrivate {
60 DatetimeFormat current_format;
61 #ifdef MODEST_TOOLKIT_HILDON2
66 /* We need this very nasty stuff because the call to
67 osso_time_set_notification_cb cannot be reverted and thus the
68 handler will be called always even though we try to set another
70 #ifdef MODEST_USE_LIBTIME
71 static ModestDatetimeFormatter *global_self = NULL;
74 #define MODEST_DATETIME_FORMATTER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), \
75 MODEST_TYPE_DATETIME_FORMATTER, \
76 ModestDatetimeFormatterPrivate))
79 FORMAT_CHANGED_SIGNAL,
84 static GObjectClass *parent_class = NULL;
86 static guint signals[LAST_SIGNAL] = {0};
89 modest_datetime_formatter_get_type (void)
91 static GType my_type = 0;
94 static const GTypeInfo my_info = {
95 sizeof(ModestDatetimeFormatterClass),
97 NULL, /* base finalize */
98 (GClassInitFunc) modest_datetime_formatter_class_init,
99 NULL, /* class finalize */
100 NULL, /* class data */
101 sizeof(ModestDatetimeFormatter),
103 (GInstanceInitFunc) modest_datetime_formatter_instance_init,
107 my_type = g_type_register_static (G_TYPE_OBJECT,
108 "ModestDatetimeFormatter",
115 modest_datetime_formatter_class_init (ModestDatetimeFormatterClass *klass)
117 GObjectClass *gobject_class;
118 gobject_class = (GObjectClass *) klass;
120 parent_class = g_type_class_peek_parent (klass);
121 gobject_class->finalize = modest_datetime_formatter_finalize;
123 g_type_class_add_private (gobject_class,
124 sizeof(ModestDatetimeFormatterPrivate));
126 signals[FORMAT_CHANGED_SIGNAL] =
127 g_signal_new ("format_changed",
128 G_TYPE_FROM_CLASS (gobject_class),
130 G_STRUCT_OFFSET (ModestDatetimeFormatterClass, format_changed),
132 g_cclosure_marshal_VOID__VOID,
136 #ifdef MODEST_TOOLKIT_HILDON2
138 update_format (ModestDatetimeFormatter *obj)
142 gboolean gconf_value;
143 ModestDatetimeFormatterPrivate *priv;
145 priv = MODEST_DATETIME_FORMATTER_GET_PRIVATE (obj);
147 gconf = gconf_client_get_default ();
148 gconf_value = gconf_client_get_bool (gconf, HILDON2_GCONF_FORMAT_KEY,
152 g_warning ("Error reading time format in gconf %s", err->message);
155 priv->current_format = gconf_value?DATETIME_FORMAT_24H:DATETIME_FORMAT_12H;
160 clock_format_changed (GConfClient *gconf,
165 ModestDatetimeFormatter *self = (ModestDatetimeFormatter *) userdata;
167 update_format (self);
168 g_signal_emit (G_OBJECT (self), signals[FORMAT_CHANGED_SIGNAL], 0);
172 #ifdef MODEST_USE_LIBTIME
174 time_changed_cb (gpointer userdata)
178 g_signal_emit (global_self, signals[FORMAT_CHANGED_SIGNAL], 0);
184 init_format (ModestDatetimeFormatter *obj)
186 ModestDatetimeFormatterPrivate *priv;
188 priv = MODEST_DATETIME_FORMATTER_GET_PRIVATE (obj);
190 priv->current_format = DATETIME_FORMAT_LOCALE;
192 #ifdef MODEST_TOOLKIT_HILDON2
196 gconf = gconf_client_get_default ();
197 gconf_client_add_dir (gconf, HILDON2_GCONF_FORMAT_DIR,
198 GCONF_CLIENT_PRELOAD_ONELEVEL,
200 priv->gconf_handler = gconf_client_notify_add (gconf, HILDON2_GCONF_FORMAT_KEY,
201 clock_format_changed, (gpointer) obj,
205 g_warning ("Error listening to time format in gconf %s", err->message);
212 #ifdef MODEST_USE_LIBTIME
213 if (OSSO_OK == osso_time_set_notification_cb (modest_platform_get_osso_context (),
223 modest_datetime_formatter_instance_init (ModestDatetimeFormatter *obj)
229 modest_datetime_formatter_finalize (GObject *obj)
231 #ifdef MODEST_TOOLKIT_HILDON2
232 ModestDatetimeFormatterPrivate *priv;
235 priv = MODEST_DATETIME_FORMATTER_GET_PRIVATE (obj);
236 gconf = gconf_client_get_default ();
237 gconf_client_notify_remove (gconf,
238 priv->gconf_handler);
239 priv->gconf_handler = 0;
240 gconf_client_remove_dir (gconf, HILDON2_GCONF_FORMAT_DIR,
243 /* Disconnect notification */
244 #ifdef MODEST_USE_LIBTIME
245 if (OSSO_OK != osso_time_set_notification_cb (modest_platform_get_osso_context (),
250 G_OBJECT_CLASS (parent_class)->finalize (obj);
253 ModestDatetimeFormatter*
254 modest_datetime_formatter_new (void)
256 return g_object_new (MODEST_TYPE_DATETIME_FORMATTER, NULL);
260 modest_datetime_formatter_format_date (ModestDatetimeFormatter *self,
263 #define DATE_BUF_SIZE 64
265 static gchar date_buf[DATE_BUF_SIZE];
266 ModestDatetimeFormatterPrivate *priv;
267 const gchar *format_string = NULL;
269 g_return_val_if_fail (MODEST_IS_DATETIME_FORMATTER (self), NULL);
270 priv = MODEST_DATETIME_FORMATTER_GET_PRIVATE (self);
272 switch (priv->current_format) {
273 case DATETIME_FORMAT_12H:
274 case DATETIME_FORMAT_24H:
275 format_string = _HL("wdgt_va_date");
277 case DATETIME_FORMAT_LOCALE:
278 format_string = "%x";
281 modest_text_utils_strftime (date_buf, DATE_BUF_SIZE, format_string, date);
287 modest_datetime_formatter_format_time (ModestDatetimeFormatter *self,
290 #define DATE_BUF_SIZE 64
292 static gchar date_buf[DATE_BUF_SIZE];
293 ModestDatetimeFormatterPrivate *priv;
294 const gchar *format_string = NULL;
296 struct tm localtime_tm = {0, };
298 g_return_val_if_fail (MODEST_IS_DATETIME_FORMATTER (self), NULL);
299 priv = MODEST_DATETIME_FORMATTER_GET_PRIVATE (self);
300 #ifdef MODEST_USE_LIBTIME
301 time_get_local_ex (date, &localtime_tm);
305 localtime_r (&date_copy, &localtime_tm);
307 is_pm = (localtime_tm.tm_hour/12) % 2;
309 switch (priv->current_format) {
310 case DATETIME_FORMAT_12H:
311 format_string = is_pm?_HL("wdgt_va_12h_time_pm"):_HL("wdgt_va_12h_time_am");
313 case DATETIME_FORMAT_24H:
314 format_string = _HL("wdgt_va_24h_time");
316 case DATETIME_FORMAT_LOCALE:
317 format_string = "%X";
320 modest_text_utils_strftime (date_buf, DATE_BUF_SIZE, format_string, date);
326 modest_datetime_formatter_display_long_datetime (ModestDatetimeFormatter *self,
330 #define DATE_BUF_DOUBLE_SIZE 128
332 static gchar date_buf[DATE_BUF_DOUBLE_SIZE];
334 snprintf (date_buf, DATE_BUF_DOUBLE_SIZE,
335 "%s %s", modest_datetime_formatter_format_date (self, date),
336 modest_datetime_formatter_format_time (self, date));
342 modest_datetime_formatter_display_datetime (ModestDatetimeFormatter *self,
346 struct tm today_localtime_tm = {0, };
347 struct tm date_localtime_tm = {0, };
351 #ifdef MODEST_USE_LIBTIME
352 time_get_local_ex (today, &today_localtime_tm);
353 time_get_local_ex (date, &date_localtime_tm);
357 localtime_r (&date_copy, &today_localtime_tm);
359 localtime_r (&date_copy, &date_localtime_tm);
362 if (today_localtime_tm.tm_mday == date_localtime_tm.tm_mday &&
363 today_localtime_tm.tm_mon == date_localtime_tm.tm_mon &&
364 today_localtime_tm.tm_year == date_localtime_tm.tm_year)
365 return modest_datetime_formatter_format_time (self, date);
367 return modest_datetime_formatter_format_date (self, date);