From 303fe34730f8c28dda072745b92b3177c6fd11d5 Mon Sep 17 00:00:00 2001 From: Wu Xiaotian Date: Mon, 30 Dec 2019 15:34:00 +0800 Subject: switch to use libgweather --- applets/clock/Makefile.am | 2 +- applets/clock/clock-location-tile.c | 106 ++- applets/clock/clock-location-tile.h | 2 +- applets/clock/clock-location.c | 765 +++++++++----------- applets/clock/clock-location.h | 117 ++-- applets/clock/clock-map.c | 2 +- applets/clock/clock-utils.c | 90 +++ applets/clock/clock-utils.h | 14 +- applets/clock/clock.c | 768 ++++++++++----------- applets/clock/clock.ui | 9 + .../org.mate.panel.applet.clock.gschema.xml.in | 28 +- configure.ac | 4 +- 12 files changed, 906 insertions(+), 1001 deletions(-) diff --git a/applets/clock/Makefile.am b/applets/clock/Makefile.am index 55f94e93..68db4281 100644 --- a/applets/clock/Makefile.am +++ b/applets/clock/Makefile.am @@ -42,7 +42,7 @@ CLOCK_CPPFLAGS = \ -I$(srcdir)/../../libmate-panel-applet \ -I$(top_builddir)/libmate-panel-applet \ -DMATELOCALEDIR=\""$(datadir)/locale"\" \ - -DMATEWEATHER_I_KNOW_THIS_IS_UNSTABLE + -DGWEATHER_I_KNOW_THIS_IS_UNSTABLE CLOCK_LDADD = \ ../../libmate-panel-applet/libmate-panel-applet-4.la \ diff --git a/applets/clock/clock-location-tile.c b/applets/clock/clock-location-tile.c index 82db27c9..58355da2 100644 --- a/applets/clock/clock-location-tile.c +++ b/applets/clock/clock-location-tile.c @@ -52,9 +52,10 @@ typedef struct { G_DEFINE_TYPE_WITH_PRIVATE (ClockLocationTile, clock_location_tile, GTK_TYPE_BIN) static void clock_location_tile_finalize (GObject *); +static void clock_location_tile_dispose (GObject *g_obj); static void clock_location_tile_fill (ClockLocationTile *this); -static void update_weather_icon (ClockLocation *loc, WeatherInfo *info, gpointer data); +static void update_weather_icon (ClockLocation *loc, GWeatherInfo *info, gpointer data); static gboolean weather_tooltip (GtkWidget *widget, gint x, gint y, gboolean keyboard_mode, @@ -77,7 +78,6 @@ clock_location_tile_new (ClockLocation *loc, clock_location_tile_fill (this); - update_weather_icon (loc, clock_location_get_weather_info (loc), this); gtk_widget_set_has_tooltip (priv->weather_icon, TRUE); g_signal_connect (priv->weather_icon, "query-tooltip", @@ -93,7 +93,8 @@ clock_location_tile_class_init (ClockLocationTileClass *this_class) { GObjectClass *g_obj_class = G_OBJECT_CLASS (this_class); - g_obj_class->finalize = clock_location_tile_finalize; + g_obj_class->dispose = clock_location_tile_dispose; + //g_obj_class->finalize = clock_location_tile_finalize; signals[TILE_PRESSED] = g_signal_new ("tile-pressed", G_TYPE_FROM_CLASS (g_obj_class), @@ -130,6 +131,37 @@ clock_location_tile_init (ClockLocationTile *this) priv->time_label = NULL; } +static void +clock_location_tile_dispose (GObject *g_obj) +{ + ClockLocationTile *this; + ClockLocationTilePrivate *priv; + + this = CLOCK_LOCATION_TILE (g_obj); + priv = clock_location_tile_get_instance_private (this); + + if (priv->location) { + if (priv->location_weather_updated_id > 0) + g_signal_handler_disconnect (priv->location, priv->location_weather_updated_id); + priv->location_weather_updated_id = 0; + + g_object_unref (priv->location); + priv->location = NULL; + } + + if (priv->button_group) { + g_object_unref (priv->button_group); + priv->button_group = NULL; + } + + if (priv->current_group) { + g_object_unref (priv->current_group); + priv->current_group = NULL; + } + + G_OBJECT_CLASS (clock_location_tile_parent_class)->dispose (g_obj); +} + static void clock_location_tile_finalize (GObject *g_obj) { @@ -140,7 +172,8 @@ clock_location_tile_finalize (GObject *g_obj) priv = clock_location_tile_get_instance_private (this); if (priv->location) { - g_signal_handler_disconnect (priv->location, priv->location_weather_updated_id); + if (priv->location_weather_updated_id > 0) + g_signal_handler_disconnect (priv->location, priv->location_weather_updated_id); priv->location_weather_updated_id = 0; g_object_unref (priv->location); @@ -415,7 +448,7 @@ copy_tm (struct tm *from, struct tm *to) static char * format_time (struct tm *now, - char *tzname, + const char *tzname, ClockFormat clock_format, long offset) { @@ -425,7 +458,7 @@ format_time (struct tm *now, struct tm local_now; char *utf8; char *tmp; - long hours, minutes; + long hours; time (&local_t); localtime_r (&local_t, &local_now); @@ -469,13 +502,9 @@ format_time (struct tm *now, strcpy (buf, "???"); } - hours = offset / 3600; - minutes = labs (offset % 3600) / 60; + hours = offset / 60; - if (minutes != 0) { - tmp = g_strdup_printf ("%s %s %+ld:%ld", buf, tzname, hours, minutes); - } - else if (hours != 0) { + if (hours != 0) { tmp = g_strdup_printf ("%s %s %+ld", buf, tzname, hours); } else { @@ -521,7 +550,8 @@ void clock_location_tile_refresh (ClockLocationTile *this, gboolean force_refresh) { ClockLocationTilePrivate *priv = clock_location_tile_get_instance_private (this); - gchar *tmp, *tzname; + gchar *tmp; + const gchar *tzname; struct tm now; long offset; int format; @@ -551,10 +581,16 @@ clock_location_tile_refresh (ClockLocationTile *this, gboolean force_refresh) clock_location_localtime (priv->location, &now); tzname = clock_location_get_tzname (priv->location); + if (tzname == NULL) { + tzname = clock_location_get_tzid (priv->location); + } copy_tm (&now, &(priv->last_refresh)); priv->last_offset = clock_location_get_offset (priv->location); + if (priv->location == NULL) { + return; + } tmp = g_strdup_printf ("%s", clock_location_get_display_name (priv->location)); gtk_label_set_markup (GTK_LABEL (priv->city_label), tmp); @@ -562,9 +598,7 @@ clock_location_tile_refresh (ClockLocationTile *this, gboolean force_refresh) g_signal_emit (this, signals[NEED_CLOCK_FORMAT], 0, &format); - offset = - priv->last_offset; - - tmp = format_time (&now, tzname, format, offset); + tmp = format_time (&now, tzname, format, priv->last_offset); gtk_label_set_markup (GTK_LABEL (priv->time_label), tmp); @@ -572,14 +606,14 @@ clock_location_tile_refresh (ClockLocationTile *this, gboolean force_refresh) } void -weather_info_setup_tooltip (WeatherInfo *info, ClockLocation *location, GtkTooltip *tooltip, +weather_info_setup_tooltip (GWeatherInfo *info, ClockLocation *location, GtkTooltip *tooltip, ClockFormat clock_format) { GdkPixbuf *pixbuf = NULL; GtkIconTheme *theme = NULL; const gchar *conditions, *wind; gchar *temp, *apparent; - gchar *line1, *line2, *line3, *line4, *tip; + gchar *line1, *line2, *line3, *line4, *line5, *tip; const gchar *icon_name; const gchar *sys_timezone; time_t sunrise_time, sunset_time; @@ -587,7 +621,7 @@ weather_info_setup_tooltip (WeatherInfo *info, ClockLocation *location, GtkToolt gint icon_scale; theme = gtk_icon_theme_get_default (); - icon_name = weather_info_get_icon_name (info); + icon_name = gweather_info_get_icon_name (info); icon_scale = gdk_window_get_scale_factor (gdk_get_default_root_window ()); pixbuf = gtk_icon_theme_load_icon_for_scale (theme, icon_name, 48, icon_scale, @@ -595,18 +629,18 @@ weather_info_setup_tooltip (WeatherInfo *info, ClockLocation *location, GtkToolt if (pixbuf) gtk_tooltip_set_icon (tooltip, pixbuf); - conditions = weather_info_get_conditions (info); + conditions = gweather_info_get_conditions (info); if (strcmp (conditions, "-") != 0) line1 = g_strdup_printf (_("%s, %s"), conditions, - weather_info_get_sky (info)); + gweather_info_get_sky (info)); else - line1 = g_strdup (weather_info_get_sky (info)); + line1 = g_strdup (gweather_info_get_weather_summary (info)); /* we need to g_strdup() since both functions return the same address * of a static buffer */ - temp = g_strdup (weather_info_get_temp (info)); - apparent = g_strdup (weather_info_get_apparent (info)); + temp = g_strdup (gweather_info_get_temp (info)); + apparent = g_strdup (gweather_info_get_apparent (info)); if (strcmp (apparent, temp) != 0 && /* FMQ: it's broken to read from another module's translations; add some API to libmateweather. */ strcmp (apparent, dgettext ("mate-applets-2.0", "Unknown")) != 0) @@ -617,20 +651,20 @@ weather_info_setup_tooltip (WeatherInfo *info, ClockLocation *location, GtkToolt g_free (temp); g_free (apparent); - wind = weather_info_get_wind (info); + wind = gweather_info_get_wind (info); if (strcmp (wind, dgettext ("mate-applets-2.0", "Unknown")) != 0) line3 = g_strdup_printf ("%s\n", wind); else line3 = g_strdup (""); sys_timezone = getenv ("TZ"); - setenv ("TZ", clock_location_get_timezone (location), 1); + setenv ("TZ", clock_location_get_tzid (location), 1); tzset (); - if (weather_info_get_value_sunrise (info, &sunrise_time)) + if (gweather_info_get_value_sunrise (info, &sunrise_time)) sunrise_str = convert_time_to_str (sunrise_time, clock_format); else sunrise_str = g_strdup ("???"); - if (weather_info_get_value_sunset (info, &sunset_time)) + if (gweather_info_get_value_sunset (info, &sunset_time)) sunset_str = convert_time_to_str (sunset_time, clock_format); else sunset_str = g_strdup ("???"); @@ -639,18 +673,22 @@ weather_info_setup_tooltip (WeatherInfo *info, ClockLocation *location, GtkToolt g_free (sunrise_str); g_free (sunset_str); + line5 = g_strdup_printf ("%s %s", gweather_info_get_visibility(info), + gweather_info_get_pressure(info)); + if (sys_timezone) setenv ("TZ", sys_timezone, 1); else unsetenv ("TZ"); tzset (); - tip = g_strdup_printf ("%s\n%s\n%s%s", line1, line2, line3, line4); + tip = g_strdup_printf ("%s\n%s\n%s\n%s%s", line1, line2, line5, line3, line4); gtk_tooltip_set_markup (tooltip, tip); g_free (line1); g_free (line2); g_free (line3); g_free (line4); + g_free (line5); g_free (tip); } @@ -664,14 +702,14 @@ weather_tooltip (GtkWidget *widget, { ClockLocationTile *tile; ClockLocationTilePrivate *priv; - WeatherInfo *info; + GWeatherInfo *info; int clock_format; tile = CLOCK_LOCATION_TILE (data); priv = clock_location_tile_get_instance_private (tile); info = clock_location_get_weather_info (priv->location); - if (!info || !weather_info_is_valid (info)) + if (!info || !gweather_info_is_valid (info)) return FALSE; g_signal_emit (tile, signals[NEED_CLOCK_FORMAT], 0, &clock_format); @@ -682,7 +720,7 @@ weather_tooltip (GtkWidget *widget, } static void -update_weather_icon (ClockLocation *loc, WeatherInfo *info, gpointer data) +update_weather_icon (ClockLocation *loc, GWeatherInfo *info, gpointer data) { ClockLocationTile *tile; ClockLocationTilePrivate *priv; @@ -691,13 +729,13 @@ update_weather_icon (ClockLocation *loc, WeatherInfo *info, gpointer data) const gchar *icon_name; gint icon_scale; - if (!info || !weather_info_is_valid (info)) + if (!info || !gweather_info_is_valid (info)) return; tile = CLOCK_LOCATION_TILE (data); priv = clock_location_tile_get_instance_private (tile); theme = gtk_icon_theme_get_for_screen (gtk_widget_get_screen (GTK_WIDGET (priv->weather_icon))); - icon_name = weather_info_get_icon_name (info); + icon_name = gweather_info_get_icon_name (info); icon_scale = gtk_widget_get_scale_factor (GTK_WIDGET (priv->weather_icon)); surface = gtk_icon_theme_load_surface (theme, icon_name, 16, icon_scale, diff --git a/applets/clock/clock-location-tile.h b/applets/clock/clock-location-tile.h index a4f75a15..62bc160c 100644 --- a/applets/clock/clock-location-tile.h +++ b/applets/clock/clock-location-tile.h @@ -39,7 +39,7 @@ ClockLocationTile *clock_location_tile_new (ClockLocation *loc, ClockLocation *clock_location_tile_get_location (ClockLocationTile *this); -void weather_info_setup_tooltip (WeatherInfo *info, ClockLocation *location, GtkTooltip *tip, +void weather_info_setup_tooltip (GWeatherInfo *info, ClockLocation *location, GtkTooltip *tip, ClockFormat clock_format); void clock_location_tile_refresh (ClockLocationTile *this, diff --git a/applets/clock/clock-location.c b/applets/clock/clock-location.c index 22ef32be..ce323235 100644 --- a/applets/clock/clock-location.c +++ b/applets/clock/clock-location.c @@ -22,123 +22,226 @@ #include "set-timezone.h" #include "system-timezone.h" +enum { + PROP_0, + PROP_LOCATION, + NUM_PROPERTIES +}; + +enum { + WEATHER_UPDATED, + SET_CURRENT, + LAST_SIGNAL +}; + typedef struct { - gchar *name; - gchar *city; + SystemTimezone *systz; + GWeatherLocation *glocation; + GWeatherInfo *gweather_info; + gulong network_id; + gulong weather_id; +} ClockLocationPrivate; - SystemTimezone *systz; +static ClockLocation *current_location = NULL; - gchar *timezone; +static guint location_signals[LAST_SIGNAL]; - gchar *tzname; +G_DEFINE_TYPE_WITH_PRIVATE (ClockLocation, clock_location, G_TYPE_OBJECT) - gfloat latitude; - gfloat longitude; +static void clock_location_dispose (GObject *object); +static void clock_location_finalize (GObject *); +static void clock_location_set_tz (ClockLocation *this); +static void clock_location_unset_tz (ClockLocation *this); +static void weather_info_updated (GWeatherInfo *info, gpointer data); - gchar *weather_code; - WeatherInfo *weather_info; - guint weather_timeout; - guint weather_retry_time; +static void clock_location_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec); +static void clock_location_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec); - TempUnit temperature_unit; - SpeedUnit speed_unit; -} ClockLocationPrivate; +static gint clock_location_compare (ClockLocation *one, ClockLocation *two) +{ + g_return_val_if_fail (CLOCK_IS_LOCATION(one), FALSE); + g_return_val_if_fail (CLOCK_IS_LOCATION(two), FALSE); + ClockLocationPrivate *priv_one; + ClockLocationPrivate *priv_two; -G_DEFINE_TYPE_WITH_PRIVATE (ClockLocation, clock_location, G_TYPE_OBJECT) + priv_one = clock_location_get_instance_private (one); + priv_two = clock_location_get_instance_private (two); -#define WEATHER_TIMEOUT_BASE 30 -#define WEATHER_TIMEOUT_MAX 1800 -#define WEATHER_EMPTY_CODE "-" + if (gweather_location_equal (priv_one->glocation, priv_two->glocation)) { + return 0; + } + return -1; +} -enum { - WEATHER_UPDATED, - SET_CURRENT, - LAST_SIGNAL -}; +gboolean clock_location_equal (ClockLocation *one, ClockLocation *two) +{ + if (clock_location_compare (one, two) == 0) + return TRUE; + else + return FALSE; +} -static guint location_signals[LAST_SIGNAL] = { 0 }; +gboolean clock_locations_has_location (GList *list, ClockLocation *loc) +{ + GList *found = NULL; + found = g_list_find_custom (list, loc, clock_location_compare); + if (found) { + return TRUE; + } else { + return FALSE; + } +} -static void clock_location_finalize (GObject *); -static void clock_location_set_tz (ClockLocation *this); -static void clock_location_unset_tz (ClockLocation *this); -static gboolean update_weather_info (gpointer data); -static void setup_weather_updates (ClockLocation *loc); - -static gchar *clock_location_get_valid_weather_code (const gchar *code); - -ClockLocation * -clock_location_find_and_ref (GList *locations, - const gchar *name, - const gchar *city, - const gchar *timezone, - gfloat latitude, - gfloat longitude, - const gchar *code) -{ - GList *l; - ClockLocationPrivate *priv; - - for (l = locations; l != NULL; l = l->next) { - priv = clock_location_get_instance_private (l->data); - - if (priv->latitude == latitude && - priv->longitude == longitude && - g_strcmp0 (priv->weather_code, code) == 0 && - g_strcmp0 (priv->timezone, timezone) == 0 && - g_strcmp0 (priv->city, city) == 0 && - g_strcmp0 (priv->name, name) == 0) - break; +GList* clock_locations_append (GList *locations, ClockLocation *loc) +{ + if (!clock_locations_has_location (locations, loc)) { + locations = g_list_append(locations, loc); + } + return locations; +} + +GList* clock_locations_merge (GList *old, GList *new) +{ + GList *l, *result = NULL; + + for (l = old; l != NULL; l = l->next) { + if (clock_locations_has_location (new, l->data)) { + result = g_list_append (result, g_object_ref (l->data)); } + } + g_list_free_full (old, g_object_unref); - if (l != NULL) - return g_object_ref (CLOCK_LOCATION (l->data)); - else - return NULL; + for (l = new; l != NULL; l = l->next) { + result = clock_locations_append (result, l->data); + } + return result; +} + +ClockLocation *clock_location_new (GWeatherLocation *gloc) +{ + return g_object_new (CLOCK_TYPE_LOCATION, "location", gloc, NULL); +} + +GVariant* clock_location_serialize (ClockLocation *loc) +{ + g_return_val_if_fail (CLOCK_IS_LOCATION(loc), NULL); + GVariant *value; + ClockLocationPrivate *priv; + + priv = clock_location_get_instance_private (loc); + + if (clock_location_is_current(loc)) { + value = g_variant_new ("(bv)", TRUE, gweather_location_serialize (priv->glocation)); + } else { + if (priv->glocation != NULL) { + value = g_variant_new ("(bv)", FALSE, gweather_location_serialize (priv->glocation)); + } + } + + return value; } -ClockLocation * -clock_location_new (const gchar *name, const gchar *city, - const gchar *timezone, - gfloat latitude, gfloat longitude, - const gchar *code, WeatherPrefs *prefs) +ClockLocation* clock_location_deserialize (GVariant *serialized) { - ClockLocation *this; - ClockLocationPrivate *priv; + gboolean current; + GVariant *value; + GWeatherLocation *world, *gloc; + ClockLocation *location; - this = g_object_new (CLOCK_LOCATION_TYPE, NULL); - priv = clock_location_get_instance_private (this); + g_variant_get (serialized, "(bv)", ¤t, &value); - priv->name = g_strdup (name); - priv->city = g_strdup (city); - priv->timezone = g_strdup (timezone); + world = gweather_location_get_world (); + gloc = gweather_location_deserialize (world, value); - /* initialize priv->tzname */ - clock_location_set_tz (this); - clock_location_unset_tz (this); + location = clock_location_new(gloc); + return location; +} - priv->latitude = latitude; - priv->longitude = longitude; +static void clock_location_set_gweather (ClockLocation *self, GWeatherLocation *loc) +{ + ClockLocationPrivate *priv; - priv->weather_code = clock_location_get_valid_weather_code (code); + priv = clock_location_get_instance_private (self); - if (prefs) { - priv->temperature_unit = prefs->temperature_unit; - priv->speed_unit = prefs->speed_unit; - } + if (priv->glocation != NULL && gweather_location_equal (priv->glocation, loc)) + return; + + if (priv->weather_id != 0) { + g_signal_handler_disconnect (priv->gweather_info, priv->weather_id); + priv->weather_id = 0; + } - setup_weather_updates (this); + if (priv->glocation != NULL) { + gweather_location_unref (priv->glocation); + priv->glocation = NULL; + } + if (priv->gweather_info != NULL) { + gweather_info_abort (priv->gweather_info); + g_object_unref (priv->gweather_info); + priv->gweather_info = NULL; + } - return this; + priv->glocation = gweather_location_ref (loc); + GWeatherProvider providers = GWEATHER_PROVIDER_METAR + | GWEATHER_PROVIDER_YAHOO + | GWEATHER_PROVIDER_YR_NO; + priv->gweather_info = g_object_new (GWEATHER_TYPE_INFO, "location", priv->glocation, "enabled-providers", providers, NULL); + priv->weather_id = g_signal_connect (priv->gweather_info, "updated", G_CALLBACK (weather_info_updated), self); } -static ClockLocation *current_location = NULL; +static void clock_location_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) +{ + ClockLocation *self; + + self = CLOCK_LOCATION (object); + + switch (prop_id) + { + case PROP_LOCATION: + clock_location_set_gweather (self, g_value_get_boxed (value)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void clock_location_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) +{ + ClockLocation *location; + ClockLocationPrivate *priv; + + location = CLOCK_LOCATION (object); + priv = clock_location_get_instance_private (location); + + switch (prop_id) + { + case PROP_LOCATION: + g_value_set_object (value, priv->glocation); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} static void clock_location_class_init (ClockLocationClass *this_class) { GObjectClass *g_obj_class = G_OBJECT_CLASS (this_class); + g_obj_class->dispose = clock_location_dispose; g_obj_class->finalize = clock_location_finalize; + g_obj_class->set_property = clock_location_set_property; + g_obj_class->get_property = clock_location_get_property; + + g_object_class_install_property (g_obj_class, + PROP_LOCATION, + g_param_spec_boxed ("location", + NULL, + NULL, + GWEATHER_TYPE_LOCATION, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT)); location_signals[WEATHER_UPDATED] = g_signal_new ("weather-updated", @@ -146,8 +249,8 @@ clock_location_class_init (ClockLocationClass *this_class) G_SIGNAL_RUN_FIRST, G_STRUCT_OFFSET (ClockLocationClass, weather_updated), NULL, NULL, - g_cclosure_marshal_VOID__POINTER, - G_TYPE_NONE, 1, G_TYPE_POINTER); + g_cclosure_marshal_VOID__OBJECT, + G_TYPE_NONE, 1, G_TYPE_OBJECT); location_signals[SET_CURRENT] = g_signal_new ("set-current", @@ -159,6 +262,14 @@ clock_location_class_init (ClockLocationClass *this_class) G_TYPE_NONE, 0); } +void clock_location_update_weather (ClockLocation *loc) +{ + ClockLocationPrivate *priv = clock_location_get_instance_private (loc); + + if (priv->gweather_info) + gweather_info_update (priv->gweather_info); +} + static void network_changed (GNetworkMonitor *monitor, gboolean available, @@ -167,35 +278,53 @@ network_changed (GNetworkMonitor *monitor, ClockLocationPrivate *priv = clock_location_get_instance_private (loc); if (available) { - priv->weather_retry_time = WEATHER_TIMEOUT_BASE; - update_weather_info (loc); + gweather_info_update (priv->gweather_info); } } static void clock_location_init (ClockLocation *this) { - ClockLocationPrivate *priv = clock_location_get_instance_private (this); - GNetworkMonitor *monitor; + ClockLocationPrivate *priv = clock_location_get_instance_private (this); + GNetworkMonitor *monitor; - priv->name = NULL; - priv->city = NULL; + priv->systz = system_timezone_new (); + priv->glocation = NULL; + priv->gweather_info = NULL; + priv->weather_id = 0; - priv->systz = system_timezone_new (); + monitor = g_network_monitor_get_default(); + priv->network_id = g_signal_connect (monitor, "network-changed", + G_CALLBACK (network_changed), this); +} - priv->timezone = NULL; +static void clock_location_dispose (GObject *object) +{ + ClockLocation *loc; + ClockLocationPrivate *priv; - priv->tzname = NULL; + loc = CLOCK_LOCATION (object); + priv = clock_location_get_instance_private (loc); - priv->latitude = 0; - priv->longitude = 0; + if (priv->weather_id != 0) { + g_signal_handler_disconnect (priv->gweather_info, priv->weather_id); + priv->weather_id = 0; + } - monitor = g_network_monitor_get_default(); - g_signal_connect (monitor, "network-changed", - G_CALLBACK (network_changed), this); + if (priv->systz != NULL) { + g_object_unref (priv->systz); + priv->systz = NULL; + } + if (priv->glocation != NULL) { + gweather_location_unref (priv->glocation); + priv->glocation = NULL; + } + if (priv->gweather_info != NULL) { + g_object_unref (priv->gweather_info); + priv->gweather_info = NULL; + } - priv->temperature_unit = TEMP_UNIT_CENTIGRADE; - priv->speed_unit = SPEED_UNIT_MS; + G_OBJECT_CLASS (clock_location_parent_class)->dispose (object); } static void @@ -209,46 +338,6 @@ clock_location_finalize (GObject *g_obj) G_CALLBACK (network_changed), CLOCK_LOCATION (g_obj)); - if (priv->name) { - g_free (priv->name); - priv->name = NULL; - } - - if (priv->city) { - g_free (priv->city); - priv->city = NULL; - } - - if (priv->systz) { - g_object_unref (priv->systz); - priv->systz = NULL; - } - - if (priv->timezone) { - g_free (priv->timezone); - priv->timezone = NULL; - } - - if (priv->tzname) { - g_free (priv->tzname); - priv->tzname = NULL; - } - - if (priv->weather_code) { - g_free (priv->weather_code); - priv->weather_code = NULL; - } - - if (priv->weather_info) { - weather_info_free (priv->weather_info); - priv->weather_info = NULL; - } - - if (priv->weather_timeout) { - g_source_remove (priv->weather_timeout); - priv->weather_timeout = 0; - } - G_OBJECT_CLASS (clock_location_parent_class)->finalize (g_obj); } @@ -256,32 +345,20 @@ const gchar * clock_location_get_display_name (ClockLocation *loc) { ClockLocationPrivate *priv = clock_location_get_instance_private (loc); - - if (priv->name && priv->name[0]) - return priv->name; - else - return priv->city; + return gweather_location_get_name (priv->glocation); } const gchar * clock_location_get_name (ClockLocation *loc) { - ClockLocationPrivate *priv = clock_location_get_instance_private (loc); - - return priv->name; + return clock_location_get_display_name (loc); } -void -clock_location_set_name (ClockLocation *loc, const gchar *name) +const gchar * +clock_location_get_sort_name (ClockLocation *loc) { - ClockLocationPrivate *priv = clock_location_get_instance_private (loc); - - if (priv->name) { - g_free (priv->name); - priv->name = NULL; - } - - priv->name = g_strdup (name); + ClockLocationPrivate *priv = clock_location_get_instance_private (loc); + return gweather_location_get_sort_name (priv->glocation); } const gchar * @@ -289,114 +366,65 @@ clock_location_get_city (ClockLocation *loc) { ClockLocationPrivate *priv = clock_location_get_instance_private (loc); - return priv->city; -} - -void -clock_location_set_city (ClockLocation *loc, const gchar *city) -{ - ClockLocationPrivate *priv = clock_location_get_instance_private (loc); - - if (priv->city) { - g_free (priv->city); - priv->city = NULL; - } - - priv->city = g_strdup (city); -} - -gchar * -clock_location_get_timezone (ClockLocation *loc) -{ - ClockLocationPrivate *priv = clock_location_get_instance_private (loc); - - return priv->timezone; + return gweather_location_get_city_name (priv->glocation); } -void -clock_location_set_timezone (ClockLocation *loc, const gchar *timezone) +const gchar * +clock_location_get_tzname (ClockLocation *loc) { - ClockLocationPrivate *priv = clock_location_get_instance_private (loc); + ClockLocationPrivate *priv; + GWeatherTimezone *zone; + const gchar *name; - if (priv->timezone) { - g_free (priv->timezone); - priv->timezone = NULL; - } - - priv->timezone = g_strdup (timezone); + priv = clock_location_get_instance_private (loc); + zone = gweather_location_get_timezone (priv->glocation); + name = gweather_timezone_get_name (zone); + if (name != NULL) { + return name; + } else { + return gweather_timezone_get_tzid (zone); + } } -gchar * -clock_location_get_tzname (ClockLocation *loc) +const gchar * +clock_location_get_tzid (ClockLocation *loc) { - ClockLocationPrivate *priv = clock_location_get_instance_private (loc); + ClockLocationPrivate *priv; + GWeatherTimezone *zone; - return priv->tzname; + priv = clock_location_get_instance_private (loc); + zone = gweather_location_get_timezone (priv->glocation); + return gweather_timezone_get_tzid (zone); } void clock_location_get_coords (ClockLocation *loc, gfloat *latitude, gfloat *longitude) { - ClockLocationPrivate *priv = clock_location_get_instance_private (loc); + double lat, lon; - *latitude = priv->latitude; - *longitude = priv->longitude; -} + ClockLocationPrivate *priv = clock_location_get_instance_private (loc); + gweather_location_get_coords (priv->glocation, &lat, &lon); -void -clock_location_set_coords (ClockLocation *loc, gfloat latitude, - gfloat longitude) -{ - ClockLocationPrivate *priv = clock_location_get_instance_private (loc); - - priv->latitude = latitude; - priv->longitude = longitude; -} - -static void -clock_location_set_tzname (ClockLocation *this, const char *tzname) -{ - ClockLocationPrivate *priv = clock_location_get_instance_private (CLOCK_LOCATION(this)); - - if (priv->tzname) { - if (strcmp (priv->tzname, tzname) == 0) { - return; - } - - g_free (priv->tzname); - priv->tzname = NULL; - } - - if (tzname) { - priv->tzname = g_strdup (tzname); - } else { - priv->tzname = NULL; - } + *latitude = (gfloat)lat; + *longitude = (gfloat)lon; + return; } static void clock_location_set_tz (ClockLocation *this) { - ClockLocationPrivate *priv = clock_location_get_instance_private (this); - + g_return_if_fail (CLOCK_IS_LOCATION(this)); + const gchar* zone; time_t now_t; struct tm now; - if (priv->timezone == NULL) { - return; - } - - setenv ("TZ", priv->timezone, 1); - tzset(); - - now_t = time (NULL); - localtime_r (&now_t, &now); - - if (now.tm_isdst > 0) { - clock_location_set_tzname (this, tzname[1]); - } else { - clock_location_set_tzname (this, tzname[0]); + zone = clock_location_get_tzid (this); + if (zone != NULL) { + setenv ("TZ", zone, 1); + tzset(); + now_t = time (NULL); + localtime_r (&now_t, &now); } } @@ -406,10 +434,6 @@ clock_location_unset_tz (ClockLocation *this) ClockLocationPrivate *priv = clock_location_get_instance_private (this); const char *env_timezone; - if (priv->timezone == NULL) { - return; - } - env_timezone = system_timezone_get_env (priv->systz); if (env_timezone) { @@ -436,24 +460,28 @@ clock_location_localtime (ClockLocation *loc, struct tm *tm) gboolean clock_location_is_current_timezone (ClockLocation *loc) { - ClockLocationPrivate *priv = clock_location_get_instance_private (loc); - const char *zone; + g_return_val_if_fail (CLOCK_IS_LOCATION(loc), FALSE); + ClockLocationPrivate *priv = clock_location_get_instance_private (loc); + const char *zone, *tzid; - zone = system_timezone_get (priv->systz); + zone = system_timezone_get (priv->systz); + tzid = clock_location_get_tzid (loc); - if (zone) - return strcmp (zone, priv->timezone) == 0; - else - return clock_location_get_offset (loc) == 0; + if (zone && tzid != NULL) { + return strcmp (zone, tzid) == 0; + } else { + return clock_location_get_offset (loc) == 0; + } } gboolean clock_location_is_current (ClockLocation *loc) { - if (current_location == loc) + if (current_location == loc) { return TRUE; - else if (current_location != NULL) + } else if (current_location != NULL) { return FALSE; + } if (clock_location_is_current_timezone (loc)) { /* Note that some code in clock.c depends on the fact that @@ -471,39 +499,18 @@ clock_location_is_current (ClockLocation *loc) return FALSE; } - -glong +gint clock_location_get_offset (ClockLocation *loc) { ClockLocationPrivate *priv = clock_location_get_instance_private (loc); - glong sys_timezone, local_timezone; - glong offset; - time_t t; - struct tm *tm; - - t = time (NULL); + GWeatherTimezone *zone; - unsetenv ("TZ"); - tm = localtime (&t); - sys_timezone = timezone; - - if (tm->tm_isdst > 0) { - sys_timezone -= 3600; - } - - setenv ("TZ", priv->timezone, 1); - tm = localtime (&t); - local_timezone = timezone; - - if (tm->tm_isdst > 0) { - local_timezone -= 3600; + zone = gweather_location_get_timezone (priv->glocation); + if (zone != NULL) { + return gweather_timezone_get_offset (zone); + } else { + return 0; } - - offset = local_timezone - sys_timezone; - - clock_location_unset_tz (loc); - - return offset; } typedef struct { @@ -553,7 +560,6 @@ clock_location_make_current (ClockLocation *loc, gpointer data, GDestroyNotify destroy) { - ClockLocationPrivate *priv = clock_location_get_instance_private (loc); gchar *filename; MakeCurrentData *mcdata; @@ -586,7 +592,7 @@ clock_location_make_current (ClockLocation *loc, mcdata->data = data; mcdata->destroy = destroy; - filename = g_build_filename (SYSTEM_ZONEINFODIR, priv->timezone, NULL); + filename = g_build_filename (SYSTEM_ZONEINFODIR, clock_location_get_tzid (loc), NULL); set_system_timezone_async (filename, (GFunc)make_current_cb, mcdata, @@ -594,186 +600,35 @@ clock_location_make_current (ClockLocation *loc, g_free (filename); } -static gchar * -clock_location_get_valid_weather_code (const gchar *code) -{ - if (!code || code[0] == '\0') - return g_strdup (WEATHER_EMPTY_CODE); - else - return g_strdup (code); -} - -const gchar * -clock_location_get_weather_code (ClockLocation *loc) -{ - ClockLocationPrivate *priv = clock_location_get_instance_private (loc); - - return priv->weather_code; -} - -void -clock_location_set_weather_code (ClockLocation *loc, const gchar *code) -{ - ClockLocationPrivate *priv = clock_location_get_instance_private (loc); - - g_free (priv->weather_code); - priv->weather_code = clock_location_get_valid_weather_code (code); - - setup_weather_updates (loc); -} - -WeatherInfo * +GWeatherInfo * clock_location_get_weather_info (ClockLocation *loc) { - ClockLocationPrivate *priv = clock_location_get_instance_private (loc); + g_return_val_if_fail (CLOCK_IS_LOCATION(loc), NULL); + ClockLocationPrivate *priv = clock_location_get_instance_private (loc); - return priv->weather_info; + return g_object_ref (priv->gweather_info); } -static void -set_weather_update_timeout (ClockLocation *loc) +GWeatherLocation* clock_location_get_glocation (ClockLocation *loc) { - ClockLocationPrivate *priv = clock_location_get_instance_private (loc); - guint timeout; - - if (!weather_info_network_error (priv->weather_info)) { - /* The last update succeeded; set the next update to - * happen in half an hour, and reset the retry timer. - */ - timeout = WEATHER_TIMEOUT_MAX; - priv->weather_retry_time = WEATHER_TIMEOUT_BASE; - } else { - /* The last update failed; set the next update - * according to the retry timer, and exponentially - * back off the retry timer. - */ - timeout = priv->weather_retry_time; - priv->weather_retry_time *= 2; - if (priv->weather_retry_time > WEATHER_TIMEOUT_MAX) - priv->weather_retry_time = WEATHER_TIMEOUT_MAX; - } + g_return_val_if_fail (CLOCK_IS_LOCATION(loc), NULL); - if (priv->weather_timeout) - g_source_remove (priv->weather_timeout); - priv->weather_timeout = - g_timeout_add_seconds (timeout, update_weather_info, loc); -} - -static void -weather_info_updated (WeatherInfo *info, gpointer data) -{ - ClockLocation *loc = data; - ClockLocationPrivate *priv = clock_location_get_instance_private (loc); + ClockLocationPrivate *priv = clock_location_get_instance_private (loc); - set_weather_update_timeout (loc); - g_signal_emit (loc, location_signals[WEATHER_UPDATED], - 0, priv->weather_info); -} - -static gboolean -update_weather_info (gpointer data) -{ - ClockLocation *loc = (ClockLocation *) data; - ClockLocationPrivate *priv = clock_location_get_instance_private (loc); - WeatherPrefs prefs = { - FORECAST_STATE, - FALSE, - NULL, - TEMP_UNIT_CENTIGRADE, - SPEED_UNIT_MS, - PRESSURE_UNIT_MB, - DISTANCE_UNIT_KM - }; - - // set temperature and speed units only if different from - // invalid/default - if (priv->temperature_unit > TEMP_UNIT_DEFAULT) - prefs.temperature_unit = priv->temperature_unit; - if (priv->speed_unit > SPEED_UNIT_DEFAULT) - prefs.speed_unit = priv->speed_unit; - - weather_info_abort (priv->weather_info); - weather_info_update (priv->weather_info, - &prefs, weather_info_updated, loc); - - return TRUE; -} - -static gchar * -rad2dms (gfloat lat, gfloat lon) -{ - gchar h, h2; - gfloat d, deg, min, d2, deg2, min2; - - h = lat > 0 ? 'N' : 'S'; - d = fabs (lat); - deg = floor (d); - min = floor (60 * (d - deg)); - h2 = lon > 0 ? 'E' : 'W'; - d2 = fabs (lon); - deg2 = floor (d2); - min2 = floor (60 * (d2 - deg2)); - return g_strdup_printf ("%02d-%02d%c %02d-%02d%c", - (int)deg, (int)min, h, - (int)deg2, (int)min2, h2); + return gweather_location_ref(priv->glocation); } static void -setup_weather_updates (ClockLocation *loc) -{ - ClockLocationPrivate *priv = clock_location_get_instance_private (loc); - WeatherLocation *wl; - WeatherPrefs prefs = { - FORECAST_STATE, - FALSE, - NULL, - TEMP_UNIT_CENTIGRADE, - SPEED_UNIT_MS, - PRESSURE_UNIT_MB, - DISTANCE_UNIT_KM - }; - - gchar *dms; - - prefs.temperature_unit = priv->temperature_unit; - prefs.speed_unit = priv->speed_unit; - - if (priv->weather_info) { - weather_info_free (priv->weather_info); - priv->weather_info = NULL; - } - - if (priv->weather_timeout) { - g_source_remove (priv->weather_timeout); - priv->weather_timeout = 0; - } - - if (!priv->weather_code || - strcmp (priv->weather_code, WEATHER_EMPTY_CODE) == 0) - return; - - dms = rad2dms (priv->latitude, priv->longitude); - wl = weather_location_new (priv->city, priv->weather_code, - NULL, NULL, dms, NULL, NULL); - - priv->weather_info = - weather_info_new (wl, &prefs, weather_info_updated, loc); - - set_weather_update_timeout (loc); - - weather_location_free (wl); - g_free (dms); -} - -void -clock_location_set_weather_prefs (ClockLocation *loc, - WeatherPrefs *prefs) +weather_info_updated (GWeatherInfo *info, gpointer data) { - ClockLocationPrivate *priv = clock_location_get_instance_private (loc); - - priv->temperature_unit = prefs->temperature_unit; - priv->speed_unit = prefs->speed_unit; + g_return_if_fail (GWEATHER_IS_INFO(info)); + ClockLocation *loc = data; + g_return_if_fail (CLOCK_IS_LOCATION(loc)); + ClockLocationPrivate *priv = clock_location_get_instance_private (loc); - update_weather_info (loc); + if (gweather_info_network_error (priv->gweather_info)) + return; + if (priv->gweather_info) { + g_signal_emit (loc, location_signals[WEATHER_UPDATED], 0, priv->gweather_info); + } } - diff --git a/applets/clock/clock-location.h b/applets/clock/clock-location.h index c12072ff..04a506ec 100644 --- a/applets/clock/clock-location.h +++ b/applets/clock/clock-location.h @@ -4,83 +4,52 @@ #include #include #include -#include +#include +#include "clock-utils.h" -#ifdef __cplusplus -extern "C" { -#endif +G_BEGIN_DECLS -#define CLOCK_LOCATION_TYPE (clock_location_get_type ()) -#define CLOCK_LOCATION(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), CLOCK_LOCATION_TYPE, ClockLocation)) -#define CLOCK_LOCATION_CLASS(c) (G_TYPE_CHECK_CLASS_CAST ((c), CLOCK_LOCATION_TYPE, ClockLocationClass)) -#define IS_CLOCK_LOCATION(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), CLOCK_LOCATION_TYPE)) -#define IS_CLOCK_LOCATION_CLASS(c) (G_TYPE_CHECK_CLASS_TYPE ((c), CLOCK_LOCATION_TYPE)) -#define CLOCK_LOCATION_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), CLOCK_LOCATION_TYPE, ClockLocationClass)) +#define CLOCK_TYPE_LOCATION (clock_location_get_type ()) +G_DECLARE_DERIVABLE_TYPE (ClockLocation, clock_location, CLOCK, LOCATION, GObject) -typedef struct +struct _ClockLocationClass { - GObject g_object; -} ClockLocation; + GObjectClass parent_class; + void (* weather_updated) (ClockLocation *location, GWeatherInfo *info); + void (* set_current) (ClockLocation *location); +}; + +GList* clock_locations_append (GList *locations, ClockLocation *loc); +GList* clock_locations_merge (GList *old, GList *new); +gboolean clock_locations_has_location (GList *locations, ClockLocation *loc); + +ClockLocation* clock_location_new (GWeatherLocation *gloc); +GVariant* clock_location_serialize (ClockLocation *loc); +ClockLocation* clock_location_deserialize (GVariant *serialized); +gboolean clock_location_equal (ClockLocation *one, ClockLocation *two); + +const gchar* clock_location_get_tzname (ClockLocation *loc); +const gchar* clock_location_get_tzid (ClockLocation *loc); + +const gchar* clock_location_get_display_name (ClockLocation *loc); +const gchar* clock_location_get_name (ClockLocation *loc); +const gchar* clock_location_get_sort_name (ClockLocation *loc); +const gchar* clock_location_get_city (ClockLocation *loc); +void clock_location_set_timezone (ClockLocation *loc, const gchar *timezone); +void clock_location_get_coords (ClockLocation *loc, gfloat *latitude, gfloat *longitude); +void clock_location_localtime (ClockLocation *loc, struct tm *tm); +gboolean clock_location_is_current (ClockLocation *loc); +void clock_location_make_current (ClockLocation *loc, + GFunc callback, + gpointer data, + GDestroyNotify destroy); +gboolean clock_location_is_current_timezone (ClockLocation *loc); +const gchar* clock_location_get_weather_code (ClockLocation *loc); +GWeatherInfo* clock_location_get_weather_info (ClockLocation *loc); +void clock_location_update_weather (ClockLocation *loc); +GWeatherLocation* clock_location_get_glocation (ClockLocation *loc); +gint clock_location_get_offset (ClockLocation *loc); + +G_END_DECLS -typedef struct -{ - GObjectClass g_object_class; - - void (* weather_updated) (ClockLocation *location, WeatherInfo *info); - - void (* set_current) (ClockLocation *location); -} ClockLocationClass; - -GType clock_location_get_type (void); - -ClockLocation *clock_location_new (const gchar *name, const gchar *city, - const gchar *timezone, - gfloat latitude, gfloat longitude, - const gchar *code, - WeatherPrefs *prefs); - -ClockLocation *clock_location_find_and_ref (GList *locations, - const gchar *name, - const gchar *city, - const gchar *timezone, - gfloat latitude, - gfloat longitude, - const gchar *code); - -gchar *clock_location_get_tzname (ClockLocation *loc); - -const gchar *clock_location_get_display_name (ClockLocation *loc); - -const gchar *clock_location_get_name (ClockLocation *loc); -void clock_location_set_name (ClockLocation *loc, const gchar *name); - -const gchar *clock_location_get_city (ClockLocation *loc); -void clock_location_set_city (ClockLocation *loc, const gchar *city); - -gchar *clock_location_get_timezone (ClockLocation *loc); -void clock_location_set_timezone (ClockLocation *loc, const gchar *timezone); - -void clock_location_get_coords (ClockLocation *loc, gfloat *latitude, gfloat *longitude); -void clock_location_set_coords (ClockLocation *loc, gfloat latitude, gfloat longitude); - -void clock_location_localtime (ClockLocation *loc, struct tm *tm); - -gboolean clock_location_is_current (ClockLocation *loc); -void clock_location_make_current (ClockLocation *loc, - GFunc callback, - gpointer data, - GDestroyNotify destroy); -gboolean clock_location_is_current_timezone (ClockLocation *loc); - -const gchar *clock_location_get_weather_code (ClockLocation *loc); -void clock_location_set_weather_code (ClockLocation *loc, const gchar *code); -WeatherInfo *clock_location_get_weather_info (ClockLocation *loc); -void clock_location_set_weather_prefs (ClockLocation *loc, - WeatherPrefs *weather_prefs); - -glong clock_location_get_offset (ClockLocation *loc); - -#ifdef __cplusplus -} -#endif #endif /* __CLOCK_LOCATION_H__ */ diff --git a/applets/clock/clock-map.c b/applets/clock/clock-map.c index 0c371ca1..4df8623d 100644 --- a/applets/clock/clock-map.c +++ b/applets/clock/clock-map.c @@ -641,7 +641,7 @@ clock_map_blink_location (ClockMap *this, ClockLocation *loc) priv = clock_map_get_instance_private (this); g_return_if_fail (IS_CLOCK_MAP (this)); - g_return_if_fail (IS_CLOCK_LOCATION (loc)); + g_return_if_fail (CLOCK_IS_LOCATION (loc)); data = g_new0 (BlinkData, 1); data->map = this; diff --git a/applets/clock/clock-utils.c b/applets/clock/clock-utils.c index a21c3b86..78f992d1 100644 --- a/applets/clock/clock-utils.c +++ b/applets/clock/clock-utils.c @@ -174,3 +174,93 @@ out: return pixbuf; } +const gchar* clock_utils_get_temp_display_name (GWeatherTemperatureUnit temp) +{ + switch (temp) { + case GWEATHER_TEMP_UNIT_DEFAULT: + return N_("Default"); + case GWEATHER_TEMP_UNIT_KELVIN: + /* translators: Kelvin */ + return N_("K"); + case GWEATHER_TEMP_UNIT_CENTIGRADE: + /* translators: Celsius */ + return N_("C"); + case GWEATHER_TEMP_UNIT_FAHRENHEIT: + /* translators: Fahrenheit */ + return N_("F"); + default: + return N_("Invalid"); + } +} + +const gchar* clock_utils_get_speed_display_name (GWeatherSpeedUnit speed) +{ + switch (speed) { + case GWEATHER_SPEED_UNIT_DEFAULT: + return N_("Default"); + case GWEATHER_SPEED_UNIT_MS: + /* translators: meters per second */ + return N_("m/s"); + case GWEATHER_SPEED_UNIT_KPH: + /* translators: kilometers per hour */ + return N_("km/h"); + case GWEATHER_SPEED_UNIT_MPH: + /* translators: miles per hour */ + return N_("mph"); + case GWEATHER_SPEED_UNIT_KNOTS: + /* translators: knots (speed unit) */ + return N_("knots"); + case GWEATHER_SPEED_UNIT_BFT: + /* translators: wind speed */ + return N_("Beaufort scale"); + default: + return N_("Invalid"); + } +} + +const gchar* clock_utils_get_distance_display_name (GWeatherDistanceUnit distance) +{ + switch (distance) { + case GWEATHER_DISTANCE_UNIT_DEFAULT: + return N_("Default"); + case GWEATHER_DISTANCE_UNIT_METERS: + /* translators: Meters */ + return N_("m"); + case GWEATHER_DISTANCE_UNIT_KM: + /* translators: Km*/ + return N_("km"); + case GWEATHER_DISTANCE_UNIT_MILES: + /* translators: Miles*/ + return N_("miles"); + default: + return N_("Invalid"); + } +} + +const gchar* clock_utils_get_pressure_display_name (GWeatherPressureUnit pressure) +{ + switch (pressure) { + case GWEATHER_PRESSURE_UNIT_DEFAULT: + return N_("Default"); + case GWEATHER_PRESSURE_UNIT_KPA: + /* translators: kiloPascal */ + return N_("kPa"); + case GWEATHER_PRESSURE_UNIT_HPA: + /* translators: hectoPascal */ + return N_("hPa"); + case GWEATHER_PRESSURE_UNIT_MB: + /* translators: millibars */ + return N_("mb"); + case GWEATHER_PRESSURE_UNIT_MM_HG: + /* translators: millimeters of mercury */ + return N_("mmHg"); + case GWEATHER_PRESSURE_UNIT_INCH_HG: + /* translators: inches of mercury */ + return N_("inHg"); + case GWEATHER_PRESSURE_UNIT_ATM: + /* translators: atmospheres */ + return N_("atm"); + default: + return N_("Invalid"); + } +} diff --git a/applets/clock/clock-utils.h b/applets/clock/clock-utils.h index 2ba0ef79..20cffcbe 100644 --- a/applets/clock/clock-utils.h +++ b/applets/clock/clock-utils.h @@ -28,10 +28,9 @@ #define __CLOCK_UTILS_H__ #include +#include -#ifdef __cplusplus -extern "C" { -#endif +G_BEGIN_DECLS /* Needs to match the indices in the combo of the prefs dialog */ typedef enum { @@ -54,8 +53,11 @@ GdkPixbuf *clock_utils_pixbuf_from_svg_resource_at_size (const char *resource, int width, int height); -#ifdef __cplusplus -} -#endif +const gchar* clock_utils_get_temp_display_name (GWeatherTemperatureUnit temp); +const gchar* clock_utils_get_speed_display_name (GWeatherSpeedUnit speed); +const gchar* clock_utils_get_distance_display_name (GWeatherDistanceUnit distance); +const gchar* clock_utils_get_pressure_display_name (GWeatherPressureUnit pressure); + +G_END_DECLS #endif /* __CLOCK_UTILS_H__ */ diff --git a/applets/clock/clock.c b/applets/clock/clock.c index f0f8e16f..56411832 100644 --- a/applets/clock/clock.c +++ b/applets/clock/clock.c @@ -55,9 +55,7 @@ #include #endif -#include -#include -#include +#include #include "clock.h" @@ -81,9 +79,12 @@ #define KEY_SHOW_TEMPERATURE "show-temperature" #define KEY_CUSTOM_FORMAT "custom-format" #define KEY_SHOW_WEEK "show-week-numbers" -#define KEY_CITIES "cities" +#define KEY_LOCATIONS "locations" + #define KEY_TEMPERATURE_UNIT "temperature-unit" -#define KEY_SPEED_UNIT "speed-unit" +#define KEY_SPEED_UNIT "speed-unit" +#define KEY_DISTANCE_UNIT "distance-unit" +#define KEY_PRESSURE_UNIT "pressure-unit" enum { COL_CITY_NAME = 0, @@ -124,8 +125,8 @@ struct _ClockData { GtkWidget *prefs_location_edit_button; GtkWidget *prefs_location_remove_button; - MateWeatherLocationEntry *location_entry; - MateWeatherTimezoneMenu *zone_combo; + GtkWidget *location_entry; + GtkWidget *zone_combo; GtkWidget *time_settings_button; GtkWidget *calendar; @@ -151,10 +152,13 @@ struct _ClockData { gboolean show_weather; gboolean show_temperature; - TempUnit temperature_unit; - SpeedUnit speed_unit; + GWeatherTemperatureUnit temperature_unit; + GWeatherSpeedUnit speed_unit; + GWeatherPressureUnit pressure_unit; + GWeatherDistanceUnit distance_unit; /* Locations */ + GWeatherLocation *world; GList *locations; GList *location_tiles; @@ -182,6 +186,7 @@ struct _ClockData { gboolean can_handle_format_12; GSettings *settings; + GSettings *weather_settings; const gchar *weather_icon_name; }; @@ -219,6 +224,7 @@ static void applet_change_orient (MatePanelApplet *applet, static void edit_hide (GtkWidget *unused, ClockData *cd); static gboolean edit_delete (GtkWidget *unused, GdkEvent *event, ClockData *cd); static void save_cities_store (ClockData *cd); +static void location_tiles_remove (gpointer data, gpointer user_data); /* ClockBox, an instantiable GtkBox */ @@ -528,10 +534,9 @@ static void update_location_tiles (ClockData *cd) { GList *l; + ClockLocationTile *tile; - for (l = cd->location_tiles; l; l = l->next) { - ClockLocationTile *tile; - + for (l = cd->location_tiles; l != NULL; l = l->next) { tile = CLOCK_LOCATION_TILE (l->data); clock_location_tile_refresh (tile, FALSE); } @@ -736,20 +741,6 @@ refresh_click_timeout_time_only (ClockData *cd) clock_timeout_callback (cd); } -static void -free_locations (ClockData *cd) -{ - if (cd->locations != NULL) { - GList *l; - - for (l = cd->locations; l; l = l->next) - g_object_unref (l->data); - - g_list_free (cd->locations); - } - cd->locations = NULL; -} - static void destroy_clock (GtkWidget * widget, ClockData *cd) { @@ -763,6 +754,11 @@ destroy_clock (GtkWidget * widget, ClockData *cd) g_object_unref (cd->settings); cd->settings = NULL; + if (cd->weather_settings) { + g_object_unref (cd->weather_settings); + cd->weather_settings = NULL; + } + if (cd->timeout) g_source_remove (cd->timeout); cd->timeout = 0; @@ -779,11 +775,15 @@ destroy_clock (GtkWidget * widget, ClockData *cd) g_free (cd->custom_format); - free_locations (cd); + if (cd->locations != NULL) { + g_list_free_full (cd->locations, g_object_unref); + cd->locations = NULL; + } - if (cd->location_tiles) - g_list_free (cd->location_tiles); - cd->location_tiles = NULL; + if (cd->location_tiles) { + g_list_free_full (cd->location_tiles, g_object_unref); + cd->location_tiles = NULL; + } if (cd->systz) { g_object_unref (cd->systz); @@ -1010,8 +1010,8 @@ sort_locations_by_name (gconstpointer a, gconstpointer b) ClockLocation *loc_a = (ClockLocation *) a; ClockLocation *loc_b = (ClockLocation *) b; - const char *name_a = clock_location_get_display_name (loc_a); - const char *name_b = clock_location_get_display_name (loc_b); + const char *name_a = clock_location_get_sort_name (loc_a); + const char *name_b = clock_location_get_sort_name (loc_b); return strcmp (name_a, name_b); } @@ -1032,7 +1032,7 @@ create_cities_store (ClockData *cd) cd->cities_store = g_object_ref (gtk_list_store_new (COL_CITY_LAST, G_TYPE_STRING, /* COL_CITY_NAME */ G_TYPE_STRING, /* COL_CITY_TZ */ - CLOCK_LOCATION_TYPE)); /* COL_CITY_LOC */ + CLOCK_TYPE_LOCATION)); /* COL_CITY_LOC */ list = g_list_copy (cities); list = g_list_sort (list, sort_locations_by_name); @@ -1041,10 +1041,14 @@ create_cities_store (ClockData *cd) ClockLocation *loc = CLOCK_LOCATION (list->data); gtk_list_store_append (cd->cities_store, &iter); + const gchar *tzname = clock_location_get_tzname (loc); + if (tzname == NULL) { + tzname = clock_location_get_tzid (loc); + } gtk_list_store_set (cd->cities_store, &iter, COL_CITY_NAME, clock_location_get_display_name (loc), /* FIXME: translate the timezone */ - COL_CITY_TZ, clock_location_get_timezone (loc), + COL_CITY_TZ, tzname, COL_CITY_LOC, loc, -1); @@ -1126,6 +1130,72 @@ location_tile_need_clock_format_cb(ClockLocationTile *tile, gpointer data) return cd->format; } +static void location_tiles_remove (gpointer data, gpointer user_data) +{ + ClockData *cd; + ClockLocationTile *city; + + city = data; + cd = user_data; + g_signal_handlers_disconnect_by_func(city, location_tile_pressed_cb, cd); + g_signal_handlers_disconnect_by_func(city, location_tile_need_clock_format_cb, cd); + gtk_container_remove (GTK_CONTAINER (cd->cities_section), GTK_WIDGET(city)); +} + +static void +cities_section_sync (ClockData *cd) +{ + GList *l, *m, *n; + GList *node; + ClockLocationTile *city; + ClockLocation *loc; + gboolean found; + + l = cd->location_tiles; + node = g_list_copy (cd->locations); + node = g_list_sort (node, sort_locations_by_time); + node = g_list_reverse (node); + while (l != NULL) { + GList *next = l->next; + found = FALSE; + loc = clock_location_tile_get_location (l->data); + for (n = node; n != NULL; n = n->next) { + if (clock_location_equal (loc, n->data)) { + found = TRUE; + break; + } + } + if (found) { + /* Remove existing elements from the new list */ + node = g_list_delete_link (node, n); + } else { + /* Remove non-existing elements from the old list */ + gtk_container_remove (GTK_CONTAINER (cd->cities_section), l->data); + cd->location_tiles = g_list_delete_link (cd->location_tiles, l); + } + l = next; + } + + /* Append the remaining elements to the new list */ + for (m = node; m != NULL; m = m->next) { + loc = m->data; + city = clock_location_tile_new (loc, CLOCK_FACE_SMALL); + g_signal_connect (city, "tile-pressed", + G_CALLBACK (location_tile_pressed_cb), cd); + g_signal_connect (city, "need-clock-format", + G_CALLBACK (location_tile_need_clock_format_cb), cd); + + gtk_box_pack_start (GTK_BOX (cd->cities_section), + GTK_WIDGET (city), + FALSE, FALSE, 0); + + gtk_widget_show_all(GTK_WIDGET (city)); + cd->location_tiles = g_list_append(cd->location_tiles, city); + clock_location_tile_refresh (city, TRUE); + } + g_list_free (node); +} + static void create_cities_section (ClockData *cd) { @@ -1171,10 +1241,9 @@ create_cities_section (ClockData *cd) GTK_WIDGET (city), FALSE, FALSE, 0); + clock_location_update_weather (loc); cd->location_tiles = g_list_prepend (cd->location_tiles, city); - clock_location_tile_refresh (city, TRUE); - node = g_list_next (node); } @@ -1376,7 +1445,7 @@ weather_tooltip (GtkWidget *widget, ClockData *cd) { GList *locations, *l; - WeatherInfo *info; + GWeatherInfo *info; locations = cd->locations; @@ -1384,11 +1453,9 @@ weather_tooltip (GtkWidget *widget, ClockLocation *location = l->data; if (clock_location_is_current (location)) { info = clock_location_get_weather_info (location); - if (!info || !weather_info_is_valid (info)) + if (!info || !gweather_info_is_valid (info)) continue; - weather_info_setup_tooltip (info, location, tooltip, cd->format); - return TRUE; } } @@ -2045,7 +2112,7 @@ weather_icon_updated_cb (MatePanelApplet *applet, static void location_weather_updated_cb (ClockLocation *location, - WeatherInfo *info, + GWeatherInfo *info, gpointer data) { ClockData *cd = data; @@ -2054,13 +2121,13 @@ location_weather_updated_cb (ClockLocation *location, cairo_surface_t *surface; gint icon_size, icon_scale; - if (!info || !weather_info_is_valid (info)) + if (!info || !gweather_info_is_valid (info)) return; if (!clock_location_is_current (location)) return; - cd->weather_icon_name = weather_info_get_icon_name (info); + cd->weather_icon_name = gweather_info_get_icon_name (info); if (cd->weather_icon_name == NULL) return; @@ -2086,7 +2153,7 @@ location_weather_updated_cb (ClockLocation *location, GTK_ICON_LOOKUP_FORCE_SIZE, NULL); - temp = weather_info_get_temp_summary (info); + temp = gweather_info_get_temp_summary (info); gtk_image_set_from_surface (GTK_IMAGE (cd->panel_weather_icon), surface); gtk_label_set_text (GTK_LABEL (cd->panel_temperature_label), temp); @@ -2099,7 +2166,7 @@ location_set_current_cb (ClockLocation *loc, gpointer data) { ClockData *cd = data; - WeatherInfo *info; + GWeatherInfo *info; info = clock_location_get_weather_info (loc); location_weather_updated_cb (loc, info, cd); @@ -2111,11 +2178,12 @@ location_set_current_cb (ClockLocation *loc, } static void -locations_changed (ClockData *cd) +locations_reset (ClockData *cd) { GList *l; ClockLocation *loc; - glong id; + gulong id; + gpointer idp; if (!cd->locations) { if (cd->weather_obox) @@ -2133,12 +2201,12 @@ locations_changed (ClockData *cd) for (l = cd->locations; l; l = l->next) { loc = l->data; - - id = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (loc), "weather-updated")); + idp = g_object_get_data (G_OBJECT (loc), "weather-updated-id"); + id = GPOINTER_TO_UINT (idp); if (id == 0) { id = g_signal_connect (loc, "weather-updated", G_CALLBACK (location_weather_updated_cb), cd); - g_object_set_data (G_OBJECT (loc), "weather-updated", GINT_TO_POINTER (id)); + g_object_set_data (G_OBJECT (loc), "weather-updated-id", GUINT_TO_POINTER (id)); g_signal_connect (loc, "set-current", G_CALLBACK (location_set_current_cb), cd); } @@ -2148,158 +2216,32 @@ locations_changed (ClockData *cd) clock_map_refresh (CLOCK_MAP (cd->map_widget)); if (cd->clock_vbox) - create_cities_section (cd); + cities_section_sync (cd); } - static void -set_locations (ClockData *cd, GList *locations) -{ - free_locations (cd); - cd->locations = locations; - locations_changed (cd); -} - -typedef struct { - GList *cities; - ClockData *cd; -} LocationParserData; - -/* Parser for our serialized locations in gsettings */ -static void -location_start_element (GMarkupParseContext *context, - const gchar *element_name, - const gchar **attribute_names, - const gchar **attribute_values, - gpointer user_data, - GError **error) -{ - ClockLocation *loc; - LocationParserData *data = user_data; - ClockData *cd = data->cd; - WeatherPrefs prefs; - const gchar *att_name; - - gchar *name = NULL; - gchar *city = NULL; - gchar *timezone = NULL; - gfloat latitude = 0.0; - gfloat longitude = 0.0; - gchar *code = NULL; - gboolean current = FALSE; - - int index = 0; - - prefs.temperature_unit = cd->temperature_unit; - prefs.speed_unit = cd->speed_unit; - - if (strcmp (element_name, "location") != 0) { - return; - } - - setlocale (LC_NUMERIC, "POSIX"); - - for (att_name = attribute_names[index]; att_name != NULL; - att_name = attribute_names[++index]) { - if (strcmp (att_name, "name") == 0) { - name = (gchar *)attribute_values[index]; - } else if (strcmp (att_name, "city") == 0) { - city = (gchar *)attribute_values[index]; - } else if (strcmp (att_name, "timezone") == 0) { - timezone = (gchar *)attribute_values[index]; - } else if (strcmp (att_name, "latitude") == 0) { - sscanf (attribute_values[index], "%f", &latitude); - } else if (strcmp (att_name, "longitude") == 0) { - sscanf (attribute_values[index], "%f", &longitude); - } else if (strcmp (att_name, "code") == 0) { - code = (gchar *)attribute_values[index]; - } - else if (strcmp (att_name, "current") == 0) { - if (strcmp (attribute_values[index], "true") == 0) { - current = TRUE; - } - } - } - - setlocale (LC_NUMERIC, ""); - - if ((!name && !city) || !timezone) { - return; - } - - /* migration from the old configuration, when name == city */ - if (!city) - city = name; - - loc = clock_location_find_and_ref (cd->locations, name, city, - timezone, latitude, longitude, code); - if (!loc) - loc = clock_location_new (name, city, timezone, - latitude, longitude, code, &prefs); - - if (current && clock_location_is_current_timezone (loc)) - clock_location_make_current (loc, NULL, NULL, NULL); - - data->cities = g_list_append (data->cities, loc); -} - -static GMarkupParser location_parser = { - location_start_element, NULL, NULL, NULL, NULL -}; - -static void -cities_changed (GSettings *settings, - gchar *key, - ClockData *cd) +locations_changed (GSettings *settings, + gchar *key, + ClockData *cd) { - LocationParserData data; - GSList *cur = NULL; - - GMarkupParseContext *context; - - data.cities = NULL; - data.cd = cd; - - context = g_markup_parse_context_new (&location_parser, 0, &data, NULL); - - cur = mate_panel_applet_settings_get_gslist (settings, key); + GList *cities = NULL; + GVariant *value, *item; + GVariantIter *iter; + ClockLocation* loc; - while (cur) { - const char *str = cur->data; - g_markup_parse_context_parse (context, str, strlen (str), NULL); - cur = cur->next; + value = g_settings_get_value (settings, key); + g_variant_get (value, "av", &iter); + while (g_variant_iter_loop (iter, "v", &item)) { + loc = clock_location_deserialize (item); + cities = g_list_append(cities, loc); } + g_variant_iter_free (iter); + cd->locations = clock_locations_merge (cd->locations, cities); - g_markup_parse_context_free (context); - - set_locations (cd, data.cities); + locations_reset (cd); create_cities_store (cd); } -static void -update_weather_locations (ClockData *cd) -{ - GList *locations, *l; - WeatherPrefs prefs = { - FORECAST_STATE, - FALSE, - NULL, - TEMP_UNIT_CENTIGRADE, - SPEED_UNIT_MS, - PRESSURE_UNIT_MB, - DISTANCE_UNIT_KM - }; - - prefs.temperature_unit = cd->temperature_unit; - prefs.speed_unit = cd->speed_unit; - - locations = cd->locations; - - for (l = locations; l; l = l->next) { - clock_location_set_weather_prefs (l->data, &prefs); - } -} - static void clock_timezone_changed (SystemTimezone *systz, const char *new_tz, @@ -2322,11 +2264,10 @@ temperature_unit_changed (GSettings *settings, GtkWidget *widget; gint oldvalue; widget = _clock_get_widget (cd, "temperature_combo"); - oldvalue = gtk_combo_box_get_active (GTK_COMBO_BOX (widget)) + 2; + oldvalue = gtk_combo_box_get_active (GTK_COMBO_BOX (widget)) + 1; if (oldvalue != cd->speed_unit) - gtk_combo_box_set_active (GTK_COMBO_BOX (widget), cd->temperature_unit - 2); + gtk_combo_box_set_active (GTK_COMBO_BOX (widget), cd->temperature_unit - 1); } - update_weather_locations (cd); } static void @@ -2340,11 +2281,44 @@ speed_unit_changed (GSettings *settings, GtkWidget *widget; gint oldvalue; widget = _clock_get_widget (cd, "wind_speed_combo"); - oldvalue = gtk_combo_box_get_active (GTK_COMBO_BOX (widget)) + 2; + oldvalue = gtk_combo_box_get_active (GTK_COMBO_BOX (widget)) + 1; if (oldvalue != cd->speed_unit) - gtk_combo_box_set_active (GTK_COMBO_BOX (widget), cd->speed_unit - 2); + gtk_combo_box_set_active (GTK_COMBO_BOX (widget), cd->speed_unit - 1); + } +} + +static void +distance_unit_changed (GSettings *settings, + gchar *key, + ClockData *cd) +{ + cd->distance_unit = g_settings_get_enum (settings, key); + if (cd->distance_unit > 0) + { + GtkWidget *widget; + gint oldvalue; + widget = _clock_get_widget (cd, "visibility_combo"); + oldvalue = gtk_combo_box_get_active (GTK_COMBO_BOX (widget)) + 1; + if (oldvalue != cd->distance_unit) + gtk_combo_box_set_active (GTK_COMBO_BOX (widget), cd->distance_unit - 1); + } +} + +static void +pressure_unit_changed (GSettings *settings, + gchar *key, + ClockData *cd) +{ + cd->pressure_unit = g_settings_get_enum (settings, key); + if (cd->pressure_unit > 0) + { + GtkWidget *widget; + gint oldvalue; + widget = _clock_get_widget (cd, "pressure_combo"); + oldvalue = gtk_combo_box_get_active (GTK_COMBO_BOX (widget)) + 1; + if (oldvalue != cd->pressure_unit) + gtk_combo_box_set_active (GTK_COMBO_BOX (widget), cd->pressure_unit - 1); } - update_weather_locations (cd); } static void @@ -2387,6 +2361,7 @@ static void setup_gsettings (ClockData *cd) { cd->settings = mate_panel_applet_settings_new (MATE_PANEL_APPLET (cd->applet), CLOCK_SCHEMA); + cd->weather_settings = g_settings_new ("org.gnome.GWeather"); /* hack to allow users to set custom format in dconf-editor */ gint format; @@ -2405,39 +2380,19 @@ setup_gsettings (ClockData *cd) g_signal_connect (cd->settings, "changed::" KEY_SHOW_TEMPERATURE, G_CALLBACK (show_temperature_changed), cd); g_signal_connect (cd->settings, "changed::" KEY_CUSTOM_FORMAT, G_CALLBACK (custom_format_changed), cd); g_signal_connect (cd->settings, "changed::" KEY_SHOW_WEEK, G_CALLBACK (show_week_changed), cd); - g_signal_connect (cd->settings, "changed::" KEY_CITIES, G_CALLBACK (cities_changed), cd); - g_signal_connect (cd->settings, "changed::" KEY_TEMPERATURE_UNIT, G_CALLBACK (temperature_unit_changed), cd); - g_signal_connect (cd->settings, "changed::" KEY_SPEED_UNIT, G_CALLBACK (speed_unit_changed), cd); -} - -static GList * -parse_gsettings_cities (ClockData *cd, gchar **values) -{ - gint i; - LocationParserData data; - GMarkupParseContext *context; - - data.cities = NULL; - data.cd = cd; - - context = g_markup_parse_context_new (&location_parser, 0, &data, NULL); - - if (values) { - for (i = 0; values[i]; i++) { - g_markup_parse_context_parse (context, values[i], strlen(values[i]), NULL); - } - } - - g_markup_parse_context_free (context); - - return data.cities; + g_signal_connect (cd->settings, "changed::" KEY_LOCATIONS, G_CALLBACK (locations_changed), cd); + g_signal_connect (cd->weather_settings, "changed::" KEY_DISTANCE_UNIT, G_CALLBACK (distance_unit_changed), cd); + g_signal_connect (cd->weather_settings, "changed::" KEY_PRESSURE_UNIT, G_CALLBACK (pressure_unit_changed), cd); + g_signal_connect (cd->weather_settings, "changed::" KEY_SPEED_UNIT, G_CALLBACK (speed_unit_changed), cd); + g_signal_connect (cd->weather_settings, "changed::" KEY_TEMPERATURE_UNIT, G_CALLBACK (temperature_unit_changed), cd); } static void load_gsettings (ClockData *cd) { - gchar **values; - GList *cities = NULL; + GVariant *value, *item; + GVariantIter iter; + ClockLocation *loc; cd->format = g_settings_get_enum (cd->settings, KEY_FORMAT); @@ -2456,18 +2411,18 @@ load_gsettings (ClockData *cd) if (!cd->can_handle_format_12 && cd->format == CLOCK_FORMAT_12) cd->format = CLOCK_FORMAT_24; - cd->temperature_unit = g_settings_get_enum (cd->settings, KEY_TEMPERATURE_UNIT); - cd->speed_unit = g_settings_get_enum (cd->settings, KEY_SPEED_UNIT); - - values = g_settings_get_strv (cd->settings, KEY_CITIES); + cd->distance_unit = g_settings_get_enum (cd->weather_settings, KEY_DISTANCE_UNIT); + cd->pressure_unit = g_settings_get_enum (cd->weather_settings, KEY_PRESSURE_UNIT); + cd->speed_unit = g_settings_get_enum (cd->weather_settings, KEY_SPEED_UNIT); + cd->temperature_unit = g_settings_get_enum (cd->weather_settings, KEY_TEMPERATURE_UNIT); - if (!values || (g_strv_length (values) == 0)) { - cities = NULL; - } else { - cities = parse_gsettings_cities (cd, values); + value = g_settings_get_value (cd->settings, KEY_LOCATIONS); + g_variant_iter_init (&iter, value); + while (g_variant_iter_loop (&iter, "v", &item)) { + loc = clock_location_deserialize (item); + cd->locations = clock_locations_append(cd->locations, loc); } - - set_locations (cd, cities); + locations_reset(cd); } static gboolean @@ -2484,6 +2439,7 @@ fill_clock_applet (MatePanelApplet *applet) cd->fixed_height = -1; cd->applet = GTK_WIDGET (applet); + cd->world = gweather_location_get_world (); setup_gsettings (cd); load_gsettings (cd); @@ -2561,120 +2517,42 @@ prefs_locations_changed (GtkTreeSelection *selection, ClockData *cd) gtk_widget_set_sensitive (cd->prefs_location_remove_button, n > 0); } -static gchar * -loc_to_string (ClockLocation *loc) -{ - const gchar *name, *city; - gfloat latitude, longitude; - gchar *ret; - - name = clock_location_get_name (loc); - city = clock_location_get_city (loc); - clock_location_get_coords (loc, &latitude, &longitude); - - setlocale (LC_NUMERIC, "POSIX"); - - ret = g_markup_printf_escaped - ("", - name ? name : "", - city ? city : "", - clock_location_get_timezone (loc), - latitude, longitude, - clock_location_get_weather_code (loc), - clock_location_is_current (loc) ? "true" : "false"); - - setlocale (LC_NUMERIC, ""); - - return ret; -} - static void save_cities_store (ClockData *cd) { - GList *locs = NULL; - GList *node; + GList *node; + GVariant *value; + GVariantBuilder *builder; + ClockLocation *loc; - for (node = cd->locations; node != NULL; node = node->next) { - locs = g_list_prepend (locs, loc_to_string (CLOCK_LOCATION (node->data))); - } + builder = g_variant_builder_new (G_VARIANT_TYPE ("av")); + for (node = cd->locations; node != NULL; node = node->next) { + loc = node->data; + g_variant_builder_add (builder, "v", clock_location_serialize (loc)); + } + value = g_variant_builder_end (builder); + g_variant_builder_unref (builder); - locs = g_list_reverse (locs); - mate_panel_applet_settings_set_glist (cd->settings, KEY_CITIES, locs); - g_list_free_full (locs, g_free); + g_settings_set_value (cd->settings, KEY_LOCATIONS, value); } static void run_prefs_edit_save (GtkButton *button, ClockData *cd) { + ClockLocation *loc; + GWeatherLocation *gloc; + const gchar *timezone; GtkWidget *edit_window = _clock_get_widget (cd, "edit-location-window"); - ClockLocation *loc = g_object_get_data (G_OBJECT (edit_window), "clock-location"); - - GtkWidget *lat_entry = _clock_get_widget (cd, "edit-location-latitude-entry"); - GtkWidget *lon_entry = _clock_get_widget (cd, "edit-location-longitude-entry"); - GtkWidget *lat_combo = _clock_get_widget (cd, "edit-location-latitude-combo"); - GtkWidget *lon_combo = _clock_get_widget (cd, "edit-location-longitude-combo"); - - const gchar *timezone, *weather_code; - gchar *city, *name; - - MateWeatherLocation *gloc; - gfloat lat = 0; - gfloat lon = 0; - - timezone = mateweather_timezone_menu_get_tzid (cd->zone_combo); + timezone = gweather_timezone_menu_get_tzid (GWEATHER_TIMEZONE_MENU(cd->zone_combo)); if (!timezone) { edit_hide (NULL, cd); return; } - city = NULL; - weather_code = NULL; - name = NULL; - - gloc = mateweather_location_entry_get_location (cd->location_entry); - if (gloc) { - city = mateweather_location_get_city_name (gloc); - weather_code = mateweather_location_get_code (gloc); - } - - if (mateweather_location_entry_has_custom_text (cd->location_entry)) { - name = gtk_editable_get_chars (GTK_EDITABLE (cd->location_entry), 0, -1); - } - - sscanf (gtk_entry_get_text (GTK_ENTRY (lat_entry)), "%f", &lat); - sscanf (gtk_entry_get_text (GTK_ENTRY (lon_entry)), "%f", &lon); - - if (gtk_combo_box_get_active (GTK_COMBO_BOX (lat_combo)) != 0) { - lat = -lat; - } - - if (gtk_combo_box_get_active (GTK_COMBO_BOX (lon_combo)) != 0) { - lon = -lon; - } - - if (loc) { - clock_location_set_timezone (loc, timezone); - clock_location_set_name (loc, name); - clock_location_set_city (loc, city); - clock_location_set_coords (loc, lat, lon); - clock_location_set_weather_code (loc, weather_code); - } else { - WeatherPrefs prefs; - - prefs.temperature_unit = cd->temperature_unit; - prefs.speed_unit = cd->speed_unit; - - loc = clock_location_new (name, city, timezone, lat, lon, weather_code, &prefs); - /* has the side-effect of setting the current location if - * there's none and this one can be considered as a current one - */ - clock_location_is_current (loc); - - cd->locations = g_list_append (cd->locations, loc); - } - g_free (name); - g_free (city); + gloc = gweather_location_entry_get_location (GWEATHER_LOCATION_ENTRY(cd->location_entry)); + loc = clock_location_new (gloc); + cd->locations = clock_locations_append(cd->locations, loc); /* This will update everything related to locations to take into * account the new location (via the gsettings changed signal) */ @@ -2708,6 +2586,10 @@ update_coords (ClockData *cd, gboolean valid, gfloat lat, gfloat lon) GtkWidget *lon_combo = _clock_get_widget (cd, "edit-location-longitude-combo"); if (!valid) { + gtk_widget_set_sensitive(lat_entry, TRUE); + gtk_widget_set_sensitive(lon_entry, TRUE); + gtk_widget_set_sensitive(lat_combo, TRUE); + gtk_widget_set_sensitive(lon_combo, TRUE); gtk_entry_set_text (GTK_ENTRY (lat_entry), ""); gtk_entry_set_text (GTK_ENTRY (lon_entry), ""); gtk_combo_box_set_active (GTK_COMBO_BOX (lat_combo), -1); @@ -2718,16 +2600,20 @@ update_coords (ClockData *cd, gboolean valid, gfloat lat, gfloat lon) update_coords_helper (lat, lat_entry, lat_combo); update_coords_helper (lon, lon_entry, lon_combo); + gtk_widget_set_sensitive(lat_entry, FALSE); + gtk_widget_set_sensitive(lon_entry, FALSE); + gtk_widget_set_sensitive(lat_combo, FALSE); + gtk_widget_set_sensitive(lon_combo, FALSE); } static void fill_timezone_combo_from_location (ClockData *cd, ClockLocation *loc) { if (loc != NULL) { - mateweather_timezone_menu_set_tzid (cd->zone_combo, - clock_location_get_timezone (loc)); + gweather_timezone_menu_set_tzid (GWEATHER_TIMEZONE_MENU(cd->zone_combo), + clock_location_get_tzid (loc)); } else { - mateweather_timezone_menu_set_tzid (cd->zone_combo, NULL); + gweather_timezone_menu_set_tzid (GWEATHER_TIMEZONE_MENU(cd->zone_combo), NULL); } } @@ -2740,7 +2626,7 @@ location_update_ok_sensitivity (ClockData *cd) ok_button = _clock_get_widget (cd, "edit-location-ok-button"); - timezone = mateweather_timezone_menu_get_tzid (cd->zone_combo); + timezone = gweather_timezone_menu_get_tzid (GWEATHER_TIMEZONE_MENU(cd->zone_combo)); name = gtk_editable_get_chars (GTK_EDITABLE (cd->location_entry), 0, -1); if (timezone && name && name[0] != '\0') { @@ -2753,39 +2639,44 @@ location_update_ok_sensitivity (ClockData *cd) } static void -location_changed (GObject *object, GParamSpec *param, ClockData *cd) +location_entry_changed (GObject *object, GParamSpec *param, ClockData *cd) { - MateWeatherLocationEntry *entry = MATEWEATHER_LOCATION_ENTRY (object); - MateWeatherLocation *gloc; - MateWeatherTimezone *zone; + GWeatherLocationEntry *entry = GWEATHER_LOCATION_ENTRY (object); + GWeatherLocation *gloc; + GWeatherTimezone *zone; gboolean latlon_valid; - double latitude = 0.0, longitude = 0.0; + gdouble latitude = 0.0, longitude = 0.0; - gloc = mateweather_location_entry_get_location (entry); + gloc = gweather_location_entry_get_location (entry); - latlon_valid = gloc && mateweather_location_has_coords (gloc); + if (gloc == NULL) + return; + + latlon_valid = gweather_location_has_coords (gloc); if (latlon_valid) - mateweather_location_get_coords (gloc, &latitude, &longitude); + gweather_location_get_coords (gloc, &latitude, &longitude); update_coords (cd, latlon_valid, latitude, longitude); - zone = gloc ? mateweather_location_get_timezone (gloc) : NULL; - if (zone) - mateweather_timezone_menu_set_tzid (cd->zone_combo, mateweather_timezone_get_tzid (zone)); - else - mateweather_timezone_menu_set_tzid (cd->zone_combo, NULL); - - if (gloc) - mateweather_location_unref (gloc); -} + zone = gweather_location_get_timezone (gloc); + if (zone != NULL) { + const gchar* tzid = gweather_timezone_get_tzid (zone); + if (tzid != NULL) { + gweather_timezone_menu_set_tzid (GWEATHER_TIMEZONE_MENU(cd->zone_combo), tzid); + } + } else { + gweather_timezone_menu_set_tzid (GWEATHER_TIMEZONE_MENU(cd->zone_combo), NULL); + } -static void -location_name_changed (GObject *object, ClockData *cd) -{ - location_update_ok_sensitivity (cd); + if (zone) { + gweather_timezone_unref (zone); + } + if (gloc) { + gweather_location_unref (gloc); + } } static void -location_timezone_changed (GObject *object, GParamSpec *param, ClockData *cd) +location_timezone_changed (GObject *object, G_GNUC_UNUSED GParamSpec *param, ClockData *cd) { location_update_ok_sensitivity (cd); } @@ -2799,8 +2690,8 @@ edit_clear (ClockData *cd) GtkWidget *lon_combo = _clock_get_widget (cd, "edit-location-longitude-combo"); /* clear out the old data */ - mateweather_location_entry_set_location (cd->location_entry, NULL); - mateweather_timezone_menu_set_tzid (cd->zone_combo, NULL); + gweather_location_entry_set_location (GWEATHER_LOCATION_ENTRY(cd->location_entry), NULL); + gweather_timezone_menu_set_tzid (GWEATHER_TIMEZONE_MENU(cd->zone_combo), NULL); gtk_entry_set_text (GTK_ENTRY (lat_entry), ""); gtk_entry_set_text (GTK_ENTRY (lon_entry), ""); @@ -2917,7 +2808,6 @@ edit_tree_row (GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, gpoint { ClockData *cd = data; ClockLocation *loc; - const char *name; gchar *tmp; gfloat lat, lon; @@ -2936,13 +2826,9 @@ edit_tree_row (GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, gpoint gtk_tree_model_get (model, iter, COL_CITY_LOC, &loc, -1); - mateweather_location_entry_set_city (cd->location_entry, - clock_location_get_city (loc), - clock_location_get_weather_code (loc)); - name = clock_location_get_name (loc); - if (name && name[0]) { - gtk_entry_set_text (GTK_ENTRY (cd->location_entry), name); - } + GWeatherLocation*gloc; + gloc = clock_location_get_glocation (loc); + gweather_location_entry_set_location (GWEATHER_LOCATION_ENTRY(cd->location_entry), gloc); clock_location_get_coords (loc, &lat, &lon); @@ -3006,13 +2892,13 @@ temperature_combo_changed (GtkComboBox *combo, ClockData *cd) int value; int old_value; - value = gtk_combo_box_get_active (combo) + 2; + value = gtk_combo_box_get_active (combo) + 1; old_value = cd->temperature_unit; if (value == old_value) return; - g_settings_set_enum (cd->settings, KEY_TEMPERATURE_UNIT, value); + g_settings_set_enum (cd->weather_settings, KEY_TEMPERATURE_UNIT, value); } static void @@ -3021,35 +2907,85 @@ speed_combo_changed (GtkComboBox *combo, ClockData *cd) int value; int old_value; - value = gtk_combo_box_get_active (combo) + 2; + value = gtk_combo_box_get_active (combo) + 1; old_value = cd->speed_unit; if (value == old_value) return; - g_settings_set_enum (cd->settings, KEY_SPEED_UNIT, value); + g_settings_set_enum (cd->weather_settings, KEY_SPEED_UNIT, value); } +static void +visibility_combo_changed (GtkComboBox *combo, ClockData *cd) +{ + int value; + int old_value; + + value = gtk_combo_box_get_active (combo) + 1; + old_value = cd->distance_unit; + + if (value == old_value) + return; + + g_settings_set_enum (cd->weather_settings, KEY_DISTANCE_UNIT, value); +} + +static void +pressure_combo_changed (GtkComboBox *combo, ClockData *cd) +{ + int value; + int old_value; + + value = gtk_combo_box_get_active (combo) + 1; + old_value = cd->pressure_unit; + + if (value == old_value) + return; + + g_settings_set_enum (cd->weather_settings, KEY_PRESSURE_UNIT, value); +} static void fill_prefs_window (ClockData *cd) { static const int temperatures[] = { - TEMP_UNIT_KELVIN, - TEMP_UNIT_CENTIGRADE, - TEMP_UNIT_FAHRENHEIT, + GWEATHER_TEMP_UNIT_DEFAULT, + GWEATHER_TEMP_UNIT_KELVIN, + GWEATHER_TEMP_UNIT_CENTIGRADE, + GWEATHER_TEMP_UNIT_FAHRENHEIT, -1 }; static const int speeds[] = { - SPEED_UNIT_MS, - SPEED_UNIT_KPH, - SPEED_UNIT_MPH, - SPEED_UNIT_KNOTS, - SPEED_UNIT_BFT, + GWEATHER_SPEED_UNIT_DEFAULT, + GWEATHER_SPEED_UNIT_MS, /* metres per second */ + GWEATHER_SPEED_UNIT_KPH, /* kilometres per hour */ + GWEATHER_SPEED_UNIT_MPH, /* miles per hour */ + GWEATHER_SPEED_UNIT_KNOTS, /* Knots */ + GWEATHER_SPEED_UNIT_BFT, /* Beaufort scale */ -1 }; + static const int distances [] = { + GWEATHER_DISTANCE_UNIT_DEFAULT, + GWEATHER_DISTANCE_UNIT_METERS, + GWEATHER_DISTANCE_UNIT_KM, + GWEATHER_DISTANCE_UNIT_MILES, + -1 + }; + + static const int pressures[] = { + GWEATHER_PRESSURE_UNIT_DEFAULT, + GWEATHER_PRESSURE_UNIT_KPA, /* kiloPascal */ + GWEATHER_PRESSURE_UNIT_HPA, /* hectoPascal */ + GWEATHER_PRESSURE_UNIT_MB, /* 1 millibars = 1 hectoPascal */ + GWEATHER_PRESSURE_UNIT_MM_HG, /* millimeters of mercury */ + GWEATHER_PRESSURE_UNIT_INCH_HG, /* inches of mercury */ + GWEATHER_PRESSURE_UNIT_ATM, /* atmosphere */ + -1 + }; + GtkWidget *radio_12hr; GtkWidget *radio_24hr; GtkWidget *widget; @@ -3123,14 +3059,14 @@ fill_prefs_window (ClockData *cd) gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (widget), renderer, TRUE); gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (widget), renderer, "text", 0, NULL); - for (i = 0; temperatures[i] != -1; i++) + for (i = 0; temperatures[i] > 0; i++) gtk_list_store_insert_with_values (store, &iter, -1, - 0, mateweather_prefs_get_temp_display_name (temperatures[i]), + 0, clock_utils_get_temp_display_name (temperatures[i]), -1); if (cd->temperature_unit > 0) gtk_combo_box_set_active (GTK_COMBO_BOX (widget), - cd->temperature_unit - 2); + cd->temperature_unit - 1); g_signal_connect (widget, "changed", G_CALLBACK (temperature_combo_changed), cd); @@ -3142,16 +3078,54 @@ fill_prefs_window (ClockData *cd) gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (widget), renderer, TRUE); gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (widget), renderer, "text", 0, NULL); - for (i = 0; speeds[i] != -1; i++) + for (i = 0; speeds[i] > 0; i++) gtk_list_store_insert_with_values (store, &iter, -1, - 0, mateweather_prefs_get_speed_display_name (speeds[i]), + 0, clock_utils_get_speed_display_name (speeds[i]), -1); if (cd->speed_unit > 0) gtk_combo_box_set_active (GTK_COMBO_BOX (widget), - cd->speed_unit - 2); + cd->speed_unit - 1); g_signal_connect (widget, "changed", G_CALLBACK (speed_combo_changed), cd); + + /* Visibility speed combo */ + widget = _clock_get_widget (cd, "visibility_combo"); + store = gtk_list_store_new (1, G_TYPE_STRING); + gtk_combo_box_set_model (GTK_COMBO_BOX (widget), GTK_TREE_MODEL (store)); + renderer = gtk_cell_renderer_text_new (); + gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (widget), renderer, TRUE); + gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (widget), renderer, "text", 0, NULL); + + for (i = 0; distances[i] > 0; i++) + gtk_list_store_insert_with_values (store, &iter, -1, + 0, clock_utils_get_distance_display_name (distances[i]), + -1); + + if (cd->distance_unit > 0) + gtk_combo_box_set_active (GTK_COMBO_BOX (widget), + cd->distance_unit - 1); + g_signal_connect (widget, "changed", + G_CALLBACK (visibility_combo_changed), cd); + + /* Pressure speed combo */ + widget = _clock_get_widget (cd, "pressure_combo"); + store = gtk_list_store_new (1, G_TYPE_STRING); + gtk_combo_box_set_model (GTK_COMBO_BOX (widget), GTK_TREE_MODEL (store)); + renderer = gtk_cell_renderer_text_new (); + gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (widget), renderer, TRUE); + gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (widget), renderer, "text", 0, NULL); + + for (i = 0; pressures[i] > 0; i++) + gtk_list_store_insert_with_values (store, &iter, -1, + 0, clock_utils_get_pressure_display_name (pressures[i]), + -1); + + if (cd->distance_unit > 0) + gtk_combo_box_set_active (GTK_COMBO_BOX (widget), + cd->pressure_unit - 1); + g_signal_connect (widget, "changed", + G_CALLBACK (pressure_combo_changed), cd); } static void @@ -3168,7 +3142,6 @@ ensure_prefs_window_is_created (ClockData *cd) GtkWidget *location_name_label; GtkWidget *timezone_label; GtkTreeSelection *selection; - MateWeatherLocation *world; if (cd->prefs_window) return; @@ -3228,31 +3201,27 @@ ensure_prefs_window_is_created (ClockData *cd) edit_ok_button = _clock_get_widget (cd, "edit-location-ok-button"); - world = mateweather_location_new_world (FALSE); location_box = _clock_get_widget (cd, "edit-location-name-box"); - cd->location_entry = MATEWEATHER_LOCATION_ENTRY (mateweather_location_entry_new (world)); + cd->location_entry = gweather_location_entry_new (cd->world); gtk_widget_show (GTK_WIDGET (cd->location_entry)); gtk_container_add (GTK_CONTAINER (location_box), GTK_WIDGET (cd->location_entry)); gtk_label_set_mnemonic_widget (GTK_LABEL (location_name_label), GTK_WIDGET (cd->location_entry)); g_signal_connect (G_OBJECT (cd->location_entry), "notify::location", - G_CALLBACK (location_changed), cd); - g_signal_connect (G_OBJECT (cd->location_entry), "changed", - G_CALLBACK (location_name_changed), cd); + G_CALLBACK (location_entry_changed), cd); zone_box = _clock_get_widget (cd, "edit-location-timezone-box"); - cd->zone_combo = MATEWEATHER_TIMEZONE_MENU (mateweather_timezone_menu_new (world)); + cd->zone_combo = gweather_timezone_menu_new (cd->world); + gtk_widget_set_sensitive (GTK_WIDGET(cd->zone_combo), FALSE); gtk_widget_show (GTK_WIDGET (cd->zone_combo)); - gtk_container_add (GTK_CONTAINER (zone_box), GTK_WIDGET (cd->zone_combo)); - gtk_label_set_mnemonic_widget (GTK_LABEL (timezone_label), - GTK_WIDGET (cd->zone_combo)); + gtk_container_add (GTK_CONTAINER (zone_box), cd->zone_combo); + gtk_label_set_mnemonic_widget (GTK_LABEL (timezone_label), cd->zone_combo); g_signal_connect (G_OBJECT (cd->zone_combo), "notify::tzid", G_CALLBACK (location_timezone_changed), cd); - mateweather_location_unref (world); g_signal_connect (G_OBJECT (edit_cancel_button), "clicked", G_CALLBACK (edit_hide), cd); @@ -3343,7 +3312,6 @@ display_properties_dialog (ClockData *cd, gboolean start_in_locations_page) gtk_widget_add_events (notebook, GDK_SCROLL_MASK); g_signal_connect (GTK_NOTEBOOK (notebook), "scroll-event", G_CALLBACK (dialog_page_scroll_event_cb), GTK_WINDOW (cd->prefs_window)); - if (start_in_locations_page) { gtk_notebook_set_current_page (GTK_NOTEBOOK (notebook), 1); @@ -3372,7 +3340,7 @@ display_help_dialog (GtkAction *action, clock_utils_display_help (cd->applet, "mate-clock", NULL); } -static void display_about_dialog(GtkAction* action, ClockData* cd) +static void display_about_dialog(GtkAction* action, G_GNUC_UNUSED ClockData* cd) { static const gchar* authors[] = { "George Lebl ", diff --git a/applets/clock/clock.ui b/applets/clock/clock.ui index 822aca0b..e6d2cb69 100644 --- a/applets/clock/clock.ui +++ b/applets/clock/clock.ui @@ -736,6 +736,7 @@ True + True False @@ -745,6 +746,7 @@ + True False _Visibility unit: True @@ -758,6 +760,7 @@ + True False @@ -767,6 +770,7 @@ + True False _Pressure unit: True @@ -1082,6 +1086,8 @@ True center True + False + False @@ -1157,6 +1163,9 @@ True center True + False + False + diff --git a/applets/clock/org.mate.panel.applet.clock.gschema.xml.in b/applets/clock/org.mate.panel.applet.clock.gschema.xml.in index ee1b6902..e441171b 100644 --- a/applets/clock/org.mate.panel.applet.clock.gschema.xml.in +++ b/applets/clock/org.mate.panel.applet.clock.gschema.xml.in @@ -7,22 +7,6 @@ - - - - - - - - - - - - - - - - '24-hour' @@ -69,20 +53,10 @@ Expand list of locations If true, expand the list of locations in the calendar window. - + [] List of locations A list of locations to display in the calendar window. - - 'Centigrade' - Temperature unit - The unit to use when showing temperatures. - - - 'm/s' - Speed unit - The unit to use when showing wind speed. - diff --git a/configure.ac b/configure.ac index ba401049..8a44307d 100644 --- a/configure.ac +++ b/configure.ac @@ -64,7 +64,7 @@ LIBRSVG_REQUIRED=2.36.2 GTK_REQUIRED=3.22.0 LIBWNCK_REQUIRED=3.4.6 LIBWNCK_PREVIEWS_OPTIONAL=3.32.0 -WEATHER_REQUIRED=1.17.0 +GWEATHER_REQUIRED=3.32.0 dnl pkg-config dependency checks @@ -107,7 +107,7 @@ PKG_CHECK_MODULES(TZ, gio-2.0 >= $GLIB_REQUIRED) AC_SUBST(TZ_CFLAGS) AC_SUBST(TZ_LIBS) -PKG_CHECK_MODULES(CLOCK, pango >= $PANGO_REQUIRED gtk+-3.0 >= $GTK_REQUIRED glib-2.0 >= $GLIB_REQUIRED gio-2.0 >= $GLIB_REQUIRED librsvg-2.0 >= $LIBRSVG_REQUIRED mateweather >= $WEATHER_REQUIRED mate-desktop-2.0 >= $LIBMATE_DESKTOP_REQUIRED) +PKG_CHECK_MODULES(CLOCK, pango >= $PANGO_REQUIRED gtk+-3.0 >= $GTK_REQUIRED glib-2.0 >= $GLIB_REQUIRED gio-2.0 >= $GLIB_REQUIRED librsvg-2.0 >= $LIBRSVG_REQUIRED gweather-3.0 >= $GWEATHER_REQUIRED mate-desktop-2.0 >= $LIBMATE_DESKTOP_REQUIRED) AC_SUBST(CLOCK_CFLAGS) AC_SUBST(CLOCK_LIBS) -- cgit v1.2.1