[dates] Copy function from Jana to determine local timezone (#3503)



commit dc082a6bec098df537f9fb31c464fdc83dccfbfd
Author: Long Bu <long bu intel com>
Date:   Wed Jul 29 16:29:24 2009 +0100

    Copy function from Jana to determine local timezone (#3503)
    
    Signed-off-by: Ross Burton <ross linux intel com>

 src/dates_view.c |  159 +++++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 157 insertions(+), 2 deletions(-)
---
diff --git a/src/dates_view.c b/src/dates_view.c
index e0a4e6d..5cf2207 100644
--- a/src/dates_view.c
+++ b/src/dates_view.c
@@ -39,6 +39,7 @@
 #include <libical/icalperiod.h>
 #include <libical/icalcomponent.h>
 #include <gconf/gconf-client.h>
+#include <time.h>
 #include "dates_view.h"
 
 #define CALENDAR_GCONF_PREFIX   "/apps/evolution/calendar"
@@ -750,14 +751,168 @@ dates_view_get_property (GObject *object, guint prop_id,
 	}
 }
 
+
+#define JANA_ECAL_LOCATION_KEY "/apps/evolution/calendar/display/timezone"
+/**
+ * jana_utils_get_local_tzname:
+ *        
+ * Retrieves the local timezone name using system functions.
+ *      
+ * Returns: A newly allocated string with the local tzname.
+ */          
+static gchar *
+jana_utils_get_local_tzname ()
+{   
+  static gboolean tzset_called = FALSE;
+    
+  if (!tzset_called) {
+    tzset ();
+  } 
+    
+  return g_strdup_printf ("%s%s%s", tzname[0],
+    (tzname[1]&&(tzname[1][0]!='\0')) ? "/" : "",
+    (tzname[1]&&(tzname[1][0]!='\0')) ? tzname[1] : "");
+}
+
+/**
+ * jana_ecal_utils_guess_location:
+ *
+ * Tries to guess the location by checking for common system settings and 
+ * files, and finally falling back on the first location that matches the
+ * current system timezone. See also #JANA_ECAL_LOCATION_KEY.
+ *
+ * Returns: A newly allocated string with the guessed location.
+ */
+static gchar *
+jana_ecal_utils_guess_location ()
+{
+	gint i;
+	FILE *file;
+	gchar *tzname;
+	gchar string[128];
+	icaltimetype today;
+	icalarray *builtin;
+	time_t now_t = time (NULL);
+	struct tm *now = localtime (&now_t);
+
+	/* Check the Evolution timezone key first */
+	tzname = gconf_client_get_string (gconf_client_get_default (),
+			JANA_ECAL_LOCATION_KEY, NULL);
+	if (tzname && icaltimezone_get_builtin_timezone (tzname)) return tzname;
+	g_free (tzname);
+
+	/* Debian systems have /etc/timezone */
+	if ((file = fopen ("/etc/timezone", "r"))) {
+		if ((fgets (string, 128, file)) && (string[0] != '\0')) {
+			gint c;
+			for (c = 0; (string[c] != '\0') &&
+					(string[c] != '\n'); c++);
+			string[c] = '\0';
+			if (icaltimezone_get_builtin_timezone (string)) {
+				fclose (file);
+				return g_strdup (string);
+			}
+		}
+		fclose (file);
+	}
+
+#if GLIB_CHECK_VERSION(2,14,0)
+	/* OpenSuSE (and RH?) systems have /etc/sysconfig/clock */
+	if ((file = fopen ("/etc/sysconfig/clock", "r"))) {
+		GRegex *regex;
+		GError *error = NULL;
+
+		regex = g_regex_new ("ZONE *= *\".*\"",
+				G_REGEX_OPTIMIZE, 0, &error);
+		if (!regex) {
+			g_warning ("Failed to create regex: %s",
+					error->message);
+			g_error_free (error);
+		} else while (fgets (string, 128, file)) {
+			GMatchInfo *match_info;
+			if (g_regex_match (regex, string, 0, &match_info)) {
+				gchar *zone;
+				gchar *match = g_match_info_fetch (
+						match_info, 0);
+
+				g_match_info_free (match_info);
+				g_regex_unref (regex);
+				regex = NULL;
+
+				if (match[strlen (match) - 2] == '\n')
+					match[strlen (match)-2] = '\0';
+				else
+					match[strlen (match)-1] = '\0';
+				zone = g_strdup (strchr (match, '\"') + 1);
+				g_free (match);
+
+				if (icaltimezone_get_builtin_timezone (zone)) {
+					fclose (file);
+					return zone;
+				} else {
+					g_free (zone);
+					break;
+				}
+			}
+			g_match_info_free (match_info);
+		}
+		if (regex) g_regex_unref (regex);
+		fclose (file);
+	}
+#endif
+
+	/* Check to see if the /etc/localtime symlink exists */
+	if (g_file_test ("/etc/localtime", G_FILE_TEST_IS_SYMLINK)) {
+		gchar *link;
+		if ((link = g_file_read_link ("/etc/localtime", NULL))) {
+			tzname = g_strrstr (link, "zoneinfo/");
+			if (tzname &&
+					icaltimezone_get_builtin_timezone (tzname + 9)) {
+				tzname = g_strdup (tzname + 9);
+				g_free (link);
+				return tzname;
+			}
+			g_free (link);
+		}
+	}
+
+	/* Fallback to first location that matches libc timezone and the
+	 * offset for the current time.
+	 */
+	today = icaltime_today ();
+	tzname = jana_utils_get_local_tzname ();
+	if (strcmp (tzname, "UTC") == 0) return tzname;
+
+	builtin = icaltimezone_get_builtin_timezones ();
+	for (i = 0; i < builtin->num_elements; i++) {
+		icaltimezone *zone = (icaltimezone *)icalarray_element_at (
+				builtin, i);
+		gchar *zone_tz;
+		int offset;
+
+		offset = icaltimezone_get_utc_offset (zone, &today, NULL);
+		zone_tz = icaltimezone_get_tznames (zone);
+
+		if (zone_tz && (strcasecmp (tzname, zone_tz) == 0) &&
+				(offset == now->tm_gmtoff)) {
+			g_free (tzname);
+			return g_strdup (icaltimezone_get_display_name (zone));
+		}
+	}
+	g_free (tzname);
+
+	/* No matching timezone found, fall back to UTC */
+	return g_strdup ("UTC");
+}
+
+
 static gchar *
 dates_view_config_get_tzid (GConfClient *gconf_client)
 {
 	gchar *location;
 	GError *error = NULL;
 	
-	location = gconf_client_get_string (gconf_client,
-		CALENDAR_GCONF_TIMEZONE, &error);
+	location = jana_ecal_utils_guess_location ();
 	if (!location) {
 		g_warning ("Error retrieving local time zone");
 		if (error) {



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]