[libgweather/ebassi/issue-161] location: Add getter for time zone name
- From: Emmanuele Bassi <ebassi src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [libgweather/ebassi/issue-161] location: Add getter for time zone name
- Date: Tue, 1 Mar 2022 00:44:45 +0000 (UTC)
commit 5adbc470187e58f090b39f32a57d00925cde181c
Author: Emmanuele Bassi <ebassi gnome org>
Date: Thu Jan 13 02:41:02 2022 +0000
location: Add getter for time zone name
When I removed GWeatherTimezone I inadvertedly missed the only
functionality that the type provided on top of GTimeZone, and that
is: the ability to retrieve the human readable, localised name of the
time zone bound to a location. That information does not exist in the
time zone database as parsed by GLib, but it is available in GWeather's
location database. This means we need to retrieve the time zone reference
from the location's database, just like we do for
gweather_location_get_timezone(), and from that reference we retrieve the
localised string with the time zone name.
The old GWeather-3 API allowed retrieving the name for any given
GWeatherTimezone, but since all time zones are bound to a location, we can
skip that particular aspect of the API.
Fixes: #161
libgweather/gweather-location.c | 92 +++++++++++++++++++++++++++++++++++++++++
libgweather/gweather-location.h | 3 ++
libgweather/tests/timezones.c | 13 ++++++
3 files changed, 108 insertions(+)
---
diff --git a/libgweather/gweather-location.c b/libgweather/gweather-location.c
index 0ad5adcf..9d8a62cb 100644
--- a/libgweather/gweather-location.c
+++ b/libgweather/gweather-location.c
@@ -1063,6 +1063,98 @@ gweather_location_get_timezone_str (GWeatherLocation *loc)
return NULL;
}
+static const char *
+timezone_ref_get_name (GWeatherDb *db,
+ guint16 idx)
+{
+ DbWorldTimezonesEntryRef entry_ref = db_world_timezones_get_at (db->timezones_ref, idx);
+
+ DbTimezoneRef tz_ref = db_world_timezones_entry_get_value (entry_ref);
+ DbI18nRef tz_name = db_timezone_get_name (tz_ref);
+
+ const char *name = EMPTY_TO_NULL (db_i18n_get_str (tz_name));
+ const char *msgctxt = EMPTY_TO_NULL (db_i18n_get_msgctxt (tz_name));
+
+ if (name != NULL) {
+ if (msgctxt != NULL) {
+ return g_dpgettext2 (LOCATIONS_GETTEXT_PACKAGE, msgctxt, name);
+ } else {
+ return g_dgettext (LOCATIONS_GETTEXT_PACKAGE, name);
+ }
+ }
+
+ return NULL;
+}
+
+/**
+ * gweather_location_get_timezone_name:
+ * @loc: the location to query
+ * @tzid: (nullable): the identifier of a timezone
+ *
+ * Retrieves the human readable, localized name of the timezone available
+ * at the given location, if any.
+ *
+ * If @tzid is omitted then the returned name will be the one of the first
+ * available timezone.
+ *
+ * Returns: (transfer none) (nullable): the human readable name of the
+ * location's timezone
+ */
+const char *
+gweather_location_get_timezone_name (GWeatherLocation *loc,
+ const char *tzid)
+{
+ g_autoptr (GWeatherLocation) s = NULL;
+
+ g_return_val_if_fail (GWEATHER_IS_LOCATION (loc), NULL);
+
+ ITER_UP (loc, s) {
+ /* NOTE: Only DB backed locations can have timezones */
+ if (s->db && IDX_VALID (s->db_idx)) {
+ if (tzid == NULL && IDX_VALID (s->tz_hint_idx)) {
+ return timezone_ref_get_name (s->db, s->tz_hint_idx);
+ }
+
+ DbArrayofuint16Ref ref;
+ gsize len;
+
+ ref = db_location_get_timezones (loc->ref);
+ len = db_arrayofuint16_get_length (ref);
+
+ if (len == 0) {
+ continue;
+ }
+
+ guint16 tz_idx;
+ if (tzid == NULL) {
+ tz_idx = 0;
+ } else {
+ gboolean found = FALSE;
+
+ for (gsize i = 0; i < len; i++) {
+ tz_idx = db_arrayofuint16_get_at (ref, i);
+
+ DbWorldTimezonesEntryRef entry_ref =
+ db_world_timezones_get_at (s->db->timezones_ref, tz_idx);
+
+ const char *id = db_world_timezones_entry_get_key (entry_ref);
+ if (strcmp (id, tzid) == 0) {
+ found = TRUE;
+ break;
+ }
+ }
+
+ if (!found)
+ continue;
+ }
+
+ return timezone_ref_get_name (s->db, tz_idx);
+ }
+ }
+
+ return NULL;
+}
+
static void
add_timezones (GWeatherLocation *loc,
GPtrArray *zones)
diff --git a/libgweather/gweather-location.h b/libgweather/gweather-location.h
index 4e33a108..bddfd9bf 100644
--- a/libgweather/gweather-location.h
+++ b/libgweather/gweather-location.h
@@ -147,6 +147,9 @@ GTimeZone * gweather_location_get_timezone (GWeatherLocatio
GWEATHER_AVAILABLE_IN_ALL
const char * gweather_location_get_timezone_str (GWeatherLocation *loc);
GWEATHER_AVAILABLE_IN_ALL
+const char * gweather_location_get_timezone_name (GWeatherLocation *loc,
+ const char *tzid);
+GWEATHER_AVAILABLE_IN_ALL
GTimeZone ** gweather_location_get_timezones (GWeatherLocation *loc);
GWEATHER_AVAILABLE_IN_ALL
void gweather_location_free_timezones (GWeatherLocation *loc,
diff --git a/libgweather/tests/timezones.c b/libgweather/tests/timezones.c
index 5475c223..312b80da 100644
--- a/libgweather/tests/timezones.c
+++ b/libgweather/tests/timezones.c
@@ -147,6 +147,19 @@ test_timezone (GWeatherLocation *location)
tzs = gweather_location_get_timezones (location);
g_assert_nonnull (tzs);
+ for (int i = 0; tzs[i] != NULL; i++) {
+ GTimeZone *tz = tzs[i];
+
+ const char *tz_id = g_time_zone_get_identifier (tz);
+ const char *tz_name = gweather_location_get_timezone_name (location, tz_id);
+ g_test_message ("Location '%s': timezone (%s) = '%s'",
+ gweather_location_get_name (location),
+ tz_id,
+ tz_name);
+
+ g_assert_nonnull (tz_name);
+ }
+
/* Only countries should have multiple timezones associated */
if ((tzs[0] == NULL && gweather_location_get_level (location) < GWEATHER_LOCATION_WEATHER_STATION) &&
gweather_location_get_level (location) >= GWEATHER_LOCATION_COUNTRY) {
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]