diff --git a/panel-plugin/weather-config.c b/panel-plugin/weather-config.c index eb00f22..3716ff8 100644 --- a/panel-plugin/weather-config.c +++ b/panel-plugin/weather-config.c @@ -30,7 +30,7 @@ #include "weather-search.h" #include "weather-scrollbox.h" -#define OPTIONS_N 12 +#define OPTIONS_N 13 #define BORDER 8 static const labeloption labeloptions[OPTIONS_N] = { @@ -44,6 +44,7 @@ static const labeloption labeloptions[OPTIONS_N] = { {N_("Low cloudiness (CL)"), CLOUDINESS_LOW}, {N_("Medium cloudiness (CM)"), CLOUDINESS_MED}, {N_("High cloudiness (CH)"), CLOUDINESS_HIGH}, + {N_("Overall Cloudiness (CO)"), CLOUDINESS_OVERALL}, {N_("Fog (F)"), FOG}, {N_("Precipitations (R)"), PRECIPITATIONS}, }; @@ -139,7 +140,7 @@ make_label (void) menu = gtk_menu_new (); widget = gtk_option_menu_new (); - for (i = 0; i < 11; i++) + for (i = 0; i < OPTIONS_N; i++) { labeloption opt = labeloptions[i]; @@ -160,7 +161,7 @@ apply_options (xfceweather_dialog *dialog) gint history = 0; gboolean hasiter = FALSE; GtkTreeIter iter; - gchar *text; + gchar *text, *pos; gint option; GValue value = { 0, }; GtkWidget *widget; @@ -183,6 +184,9 @@ apply_options (xfceweather_dialog *dialog) if (data->location_name) g_free (data->location_name); + if (data->location_name_short) + g_free (data->location_name_short); + data->lat = g_strdup (gtk_entry_get_text (GTK_ENTRY (dialog->txt_lat))); @@ -192,6 +196,14 @@ apply_options (xfceweather_dialog *dialog) data->location_name = g_strdup (gtk_label_get_text (GTK_LABEL (dialog->txt_loc_name))); + pos = g_utf8_strchr(data->location_name, -1, ','); + if (pos != NULL) + data->location_name_short = + g_utf8_substring (data->location_name, 0, + g_utf8_pointer_to_offset (data->location_name, pos)); + else + data->location_name_short = g_strdup (data->location_name); + /* call labels_clear() here */ if (data->labels && data->labels->len > 0) g_array_free (data->labels, TRUE); diff --git a/panel-plugin/weather-data.c b/panel-plugin/weather-data.c index 5c17a8d..b9290cb 100644 --- a/panel-plugin/weather-data.c +++ b/panel-plugin/weather-data.c @@ -27,27 +27,34 @@ #define CHK_NULL(s) ((s) ? (s):"") -static gboolean need_interval(datas type) +gboolean has_timeslice(xml_weather *data, time_t start, time_t end) { - return type == PRECIPITATIONS || type == SYMBOL; + int i = 0; + for (i = 0; i < data->num_timeslices; i++) { + if (data->timeslice[i]->start == start + && data->timeslice[i]->end == end) + return TRUE; + } + return FALSE; } const gchar * -get_data (xml_weather *data, datas type) +get_data (xml_time *timeslice, datas type) { - const xml_time *timeslice = NULL; const xml_location *loc = NULL; - if (data == NULL) - return ""; - - timeslice = get_current_timeslice(data, need_interval(type)); if (timeslice == NULL) return ""; loc = timeslice->location; switch(type) { + case ALTITUDE: + return CHK_NULL(loc->altitude); + case LATITUDE: + return CHK_NULL(loc->latitude); + case LONGITUDE: + return CHK_NULL(loc->longitude); case TEMPERATURE: return CHK_NULL(loc->temperature_value); case PRESSURE: @@ -68,6 +75,8 @@ get_data (xml_weather *data, datas type) return CHK_NULL(loc->cloudiness_percent[CLOUD_MED]); case CLOUDINESS_HIGH: return CHK_NULL(loc->cloudiness_percent[CLOUD_HIGH]); + case CLOUDINESS_OVERALL: + return CHK_NULL(loc->cloudiness_percent[CLOUD_OVERALL]); case FOG: return CHK_NULL(loc->fog_percent); case PRECIPITATIONS: @@ -79,21 +88,18 @@ get_data (xml_weather *data, datas type) } const gchar * -get_unit (xml_weather *data, units unit, datas type) +get_unit (xml_time *timeslice, units unit, datas type) { - const xml_time *timeslice = NULL; const xml_location *loc = NULL; - if (data == NULL) - return ""; - - timeslice = get_current_timeslice(data, need_interval(type)); if (timeslice == NULL) return ""; loc = timeslice->location; switch(type) { + case ALTITUDE: + return "m"; case TEMPERATURE: return strcmp(loc->temperature_unit, "celcius") ? "°F":"°C"; case PRESSURE: @@ -101,11 +107,14 @@ get_unit (xml_weather *data, units unit, datas type) case WIND_SPEED: return "m/s"; case WIND_DIRECTION_DEG: + case LATITUDE: + case LONGITUDE: return "°"; case HUMIDITY: case CLOUDINESS_LOW: case CLOUDINESS_MED: case CLOUDINESS_HIGH: + case CLOUDINESS_OVERALL: case FOG: return "%"; case PRECIPITATIONS: @@ -118,3 +127,219 @@ get_unit (xml_weather *data, units unit, datas type) return ""; } +/* + * Calculate start and end of a daytime interval using given dates. + * We ought to take one of the intervals supplied by the XML feed, + * which gives the most consistent data and does not force too many + * searches to find something that fits. The following chosen + * intervals were pretty reliable for several tested locations at the + * time of this writing and gave reasonable results: + * Morning: 08:00-14:00 + * Afternoon: 14:00-20:00 + * Evening: 20:00-02:00 + * Night: 02:00-08:00 + */ +void +get_daytime_interval(struct tm *start_t, struct tm *end_t, daytime dt) +{ + start_t->tm_min = end_t->tm_min = 0; + start_t->tm_sec = end_t->tm_sec = 0; + start_t->tm_isdst = end_t->tm_isdst = -1; + switch(dt) { + case MORNING: + start_t->tm_hour = 8; + end_t->tm_hour = 14; + break; + case AFTERNOON: + start_t->tm_hour = 14; + end_t->tm_hour = 20; + break; + case EVENING: + start_t->tm_hour = 20; + end_t->tm_hour = 26; + break; + case NIGHT: + start_t->tm_hour = 26; + end_t->tm_hour = 32; + break; + } +} + +/* + * Check whether it is night or day. Until we have a way to get the + * exact times for sunrise and sunset, we'll have to use reasonable + * hardcoded values. + */ +gboolean +is_night_time() +{ + time_t now; + struct tm tm_now; + time(&now); + tm_now = *localtime(&now); + return (tm_now.tm_hour >= 21 || tm_now.tm_hour < 5); +} + +time_t +time_calc(struct tm tm_time, gint year, gint month, gint day, gint hour, gint min, gint sec) +{ + time_t result; + struct tm tm_new; + tm_new = tm_time; + if (year) + tm_new.tm_year += year; + if (month) + tm_new.tm_mon += month; + if (day) + tm_new.tm_mday += day; + if (hour) + tm_new.tm_hour += hour; + if (min) + tm_new.tm_min += min; + if (sec) + tm_new.tm_sec += sec; + result = mktime(&tm_new); + return result; +} + +time_t +time_calc_hour(struct tm tm_time, gint hours) { + return time_calc(tm_time, 0, 0, 0, hours, 0, 0); +} + +time_t +time_calc_day(struct tm tm_time, gint days) { + return time_calc(tm_time, 0, 0, days, 0, 0, 0); +} + +/* + * Find a timeslice that best matches the start and end times within + * reasonable limits. + */ +xml_time * +find_timeslice(xml_weather *data, struct tm tm_start, struct tm tm_end) +{ + time_t start_t, end_t; + gint hours, hours_limit = 3, interval = 0, interval_limit; + + /* first search for intervals of the same length */ + start_t = mktime(&tm_start); + end_t = mktime(&tm_end); + interval_limit = (gint) (difftime(end_t, start_t) / 3600); + + while (interval <= interval_limit) { + hours = 0; + while (hours <= hours_limit) { + /* check with previous hours */ + start_t = time_calc_hour(tm_start, 0 - hours); + end_t = time_calc_hour(tm_end, 0 - hours - interval); + + if (has_timeslice(data, start_t, end_t)) + return get_timeslice(data, start_t, end_t); + + /* check with later hours */ + start_t = time_calc_hour(tm_start, hours); + end_t = time_calc_hour(tm_end, hours - interval); + + if (has_timeslice(data, start_t, end_t)) + return get_timeslice(data, start_t, end_t); + + hours++; + } + interval++; + } + + return NULL; +} + +/* + * Take point and interval data and generate one combined timeslice + * that provides all information needed to present a forecast. + */ +xml_time * +make_combined_timeslice(xml_time *point, xml_time *interval) +{ + xml_time *forecast; + xml_location *loc; + gint i; + + if (point == NULL || interval == NULL) + return NULL; + + forecast = g_slice_new0(xml_time); + if (forecast == NULL) + return NULL; + + loc = g_slice_new0(xml_location); + if (loc == NULL) + return forecast; + + forecast->start = point->start; + forecast->end = interval->end; + + loc->altitude = g_strdup(point->location->altitude); + loc->latitude = g_strdup(point->location->latitude); + loc->longitude = g_strdup(point->location->longitude); + + loc->temperature_value = g_strdup(point->location->temperature_value); + loc->temperature_unit = g_strdup(point->location->temperature_unit); + + loc->wind_dir_deg = g_strdup(point->location->wind_dir_deg); + loc->wind_dir_name = g_strdup(point->location->wind_dir_name); + loc->wind_speed_mps = g_strdup(point->location->wind_speed_mps); + loc->wind_speed_beaufort = g_strdup(point->location->wind_speed_beaufort); + + loc->humidity_value = g_strdup(point->location->humidity_value); + loc->humidity_unit = g_strdup(point->location->humidity_unit); + + loc->pressure_value = g_strdup(point->location->pressure_value); + loc->pressure_unit = g_strdup(point->location->pressure_unit); + + for (i = 0; i < NUM_CLOUDINESS; i++) + loc->cloudiness_percent[i] = g_strdup(point->location->cloudiness_percent[i]); + + loc->fog_percent = g_strdup(point->location->fog_percent); + + loc->precipitation_value = g_strdup(interval->location->precipitation_value); + loc->precipitation_unit = g_strdup(interval->location->precipitation_unit); + + loc->symbol_id = interval->location->symbol_id; + loc->symbol = g_strdup(interval->location->symbol); + + forecast->location = loc; + + return forecast; +} + +/* + * Get forecast data for a given daytime for the day (today + day). + */ +xml_time * +make_forecast_data(xml_weather *data, int day, daytime dt) +{ + xml_time *forecast, *point, *interval; + struct tm tm_now, tm_start, tm_end; + time_t now, start_t, end_t; + + /* initialize times to the current day */ + time(&now); + tm_start = *localtime(&now); + tm_end = *localtime(&now); + + /* calculate daytime interval start and end times for the requested day */ + tm_start.tm_mday += day; + tm_end.tm_mday += day; + get_daytime_interval(&tm_start, &tm_end, dt); + start_t = mktime(&tm_start); + end_t = mktime(&tm_end); + + /* find point data */ + point = find_timeslice(data, tm_start, tm_start); + + /* next find interval data */ + interval = find_timeslice(data, tm_start, tm_end); + + /* create a new timeslice with combined point and interval data */ + forecast = make_combined_timeslice(point, interval); + return forecast; +} diff --git a/panel-plugin/weather-data.h b/panel-plugin/weather-data.h index 5e80763..190d726 100644 --- a/panel-plugin/weather-data.h +++ b/panel-plugin/weather-data.h @@ -21,6 +21,9 @@ G_BEGIN_DECLS typedef enum { + ALTITUDE, + LATITUDE, + LONGITUDE, TEMPERATURE, PRESSURE, WIND_SPEED, @@ -31,6 +34,7 @@ typedef enum { CLOUDINESS_LOW, CLOUDINESS_MED, CLOUDINESS_HIGH, + CLOUDINESS_OVERALL, FOG, PRECIPITATIONS, SYMBOL @@ -41,10 +45,27 @@ typedef enum { METRIC } units; +typedef enum { + MORNING, + AFTERNOON, + EVENING, + NIGHT +} daytime; + const gchar * -get_data (xml_weather *data, datas type); +get_data (xml_time *timeslice, datas type); const gchar * -get_unit (xml_weather *data, units unit, datas type); +get_unit (xml_time *timeslice, units unit, datas type); +gboolean +is_night_time(); +time_t +time_calc(struct tm tm_time, gint year, gint mon, gint day, gint hour, gint min, gint sec); +time_t +time_calc_hour(struct tm tm_time, gint hours); +time_t +time_calc_day(struct tm tm_time, gint days); +xml_time * +make_forecast_data(xml_weather *data, int day, daytime dt); G_END_DECLS #endif diff --git a/panel-plugin/weather-icon.c b/panel-plugin/weather-icon.c index da9c5b0..6aaf75c 100644 --- a/panel-plugin/weather-icon.c +++ b/panel-plugin/weather-icon.c @@ -25,25 +25,50 @@ #include "weather-icon.h" - - #define DEFAULT_W_THEME "liquid" - +const gchar *night_symbols[] = { + "CLOUD", + "LIGHTCLOUD", + "LIGHTRAINSUN", + "LIGHTRAINTHUNDERSUN", + "PARTLYCLOUD", + "SNOWSUN", + "SUN", + NULL +}; GdkPixbuf * get_icon (const gchar *number, - gint size) + gint size, + gboolean night) { GdkPixbuf *image = NULL; - gchar *filename; - gchar *night; + gchar *filename, *night_suffix = ""; + gint number_len, night_symbol_len; + guint i; - if (number == NULL || strcmp (number, "-") == 0) + if (number == NULL || strlen(number) == 0) number = "99"; + else if (night) + { + number_len = strlen(number); + for (i = 0; night_symbols[i] != NULL; i++) + { + night_symbol_len = strlen(night_symbols[i]); + if (number_len != night_symbol_len) + continue; + + if (number[0] != night_symbols[i][0]) + continue; + + if (!g_ascii_strncasecmp (night_symbols[i], number, number_len)) + night_suffix = "-night"; + } + } - filename = g_strdup_printf ("%s" G_DIR_SEPARATOR_S "%s" G_DIR_SEPARATOR_S "%s.png", - THEMESDIR, DEFAULT_W_THEME, number); + filename = g_strdup_printf ("%s" G_DIR_SEPARATOR_S "%s" G_DIR_SEPARATOR_S "%s%s.png", + THEMESDIR, DEFAULT_W_THEME, number, night_suffix); image = gdk_pixbuf_new_from_file_at_scale (filename, size, size, TRUE, NULL); @@ -51,7 +76,7 @@ get_icon (const gchar *number, g_warning ("Unable to open image: %s", filename); if (number && strcmp(number, "99")) { g_free(filename); - return get_icon("99", size); + return get_icon("99", size, FALSE); } } g_free (filename); diff --git a/panel-plugin/weather-icon.h b/panel-plugin/weather-icon.h index abea3da..cee80ef 100644 --- a/panel-plugin/weather-icon.h +++ b/panel-plugin/weather-icon.h @@ -20,7 +20,7 @@ G_BEGIN_DECLS -GdkPixbuf *get_icon (const gchar * icon, gint size); +GdkPixbuf *get_icon (const gchar * icon, gint size, gboolean night); G_END_DECLS diff --git a/panel-plugin/weather-parsers.c b/panel-plugin/weather-parsers.c index fd16609..f4f29bc 100644 --- a/panel-plugin/weather-parsers.c +++ b/panel-plugin/weather-parsers.c @@ -165,6 +165,9 @@ xml_time *get_current_timeslice(xml_weather *data, gboolean interval) int min_found = 7 * 24 * 3600; int i; + if (data == NULL) + return NULL; + for (i = 0; i < data->num_timeslices; i++) { if (interval != (data->timeslice[i]->start != data->timeslice[i]->end)) @@ -194,6 +197,19 @@ xml_time *get_current_timeslice(xml_weather *data, gboolean interval) void parse_location (xmlNode * cur_node, xml_location *loc) { xmlNode *child_node; + gchar *altitude, *latitude, *longitude; + + g_free(loc->altitude); + loc->altitude = PROP(cur_node, "altitude"); + xmlFree(altitude); + + g_free(loc->latitude); + loc->latitude = PROP(cur_node, "latitude"); + xmlFree(latitude); + + g_free(loc->longitude); + loc->longitude = PROP(cur_node, "longitude"); + xmlFree(longitude); for (child_node = cur_node->children; child_node; child_node = child_node->next) { @@ -227,6 +243,10 @@ void parse_location (xmlNode * cur_node, xml_location *loc) loc->pressure_unit = PROP(child_node, "unit"); loc->pressure_value = PROP(child_node, "value"); } + if (NODE_IS_TYPE (child_node, "cloudiness")) { + g_free(loc->cloudiness_percent[CLOUD_OVERALL]); + loc->cloudiness_percent[CLOUD_OVERALL] = PROP(child_node, "percent"); + } if (NODE_IS_TYPE (child_node, "fog")) { g_free(loc->fog_percent); loc->fog_percent = PROP(child_node, "percent"); @@ -279,7 +299,7 @@ static void xml_location_free(xml_location *loc) g_slice_free (xml_location, loc); } -static void xml_time_free(xml_time *timeslice) +void xml_time_free(xml_time *timeslice) { xml_location_free(timeslice->location); g_slice_free (xml_time, timeslice); diff --git a/panel-plugin/weather-parsers.h b/panel-plugin/weather-parsers.h index b461f90..ef97c6a 100644 --- a/panel-plugin/weather-parsers.h +++ b/panel-plugin/weather-parsers.h @@ -26,18 +26,23 @@ G_BEGIN_DECLS #define DATA(node) (gchar *) xmlNodeListGetString(node->doc, node->children, 1) #define PROP(node, prop) ((gchar *) xmlGetProp ((node), (const xmlChar *) (prop))) #define NODE_IS_TYPE(node, type) xmlStrEqual (node->name, (const xmlChar *) type) -#define MAX_TIMESLICE 250 +#define MAX_TIMESLICE 500 enum { CLOUD_LOW = 0, CLOUD_MED, CLOUD_HIGH, + CLOUD_OVERALL, NUM_CLOUDINESS }; typedef struct { + gchar *altitude; + gchar *latitude; + gchar *longitude; + gchar *temperature_value; gchar *temperature_unit; @@ -78,7 +83,6 @@ typedef struct } xml_weather; - xml_weather *parse_weather (xmlNode * cur_node); void parse_time (xmlNode * cur_node, xml_weather * data); @@ -88,6 +92,7 @@ void parse_location (xmlNode * cur_node, xml_location *location); xml_time *get_timeslice(xml_weather *data, time_t start, time_t end); xml_time *get_current_timeslice(xml_weather *data, gboolean interval); +void xml_time_free(xml_time *timeslice); void xml_weather_free (xml_weather * data); G_END_DECLS diff --git a/panel-plugin/weather-search.c b/panel-plugin/weather-search.c index d14a639..56f0823 100644 --- a/panel-plugin/weather-search.c +++ b/panel-plugin/weather-search.c @@ -283,7 +283,7 @@ create_search_dialog (GtkWindow *parent, G_CALLBACK (pass_search_results), dialog->dialog); gtk_container_add (GTK_CONTAINER (scroll), dialog->result_list); - gtk_widget_set_size_request (dialog->dialog, 425, 250); + gtk_widget_set_size_request (dialog->dialog, 600, 500); return dialog; } diff --git a/panel-plugin/weather-summary.c b/panel-plugin/weather-summary.c index b0a4aae..d250edd 100644 --- a/panel-plugin/weather-summary.c +++ b/panel-plugin/weather-summary.c @@ -43,8 +43,8 @@ static gboolean lnk_clicked (GtkTextTag *tag, GObject *obj, g_free (value); #define APPEND_TEXT_ITEM(text, item) value = g_strdup_printf("\t%s%s%s %s\n",\ text, text?": ":"", \ - get_data(data->weatherdata, item),\ - get_unit(data->weatherdata, data->unit, item));\ + get_data(timeslice, item), \ + get_unit(timeslice, data->unit, item)); \ APPEND_TEXT_ITEM_REAL(value); #define APPEND_LINK_ITEM(prefix, text, url, lnk_tag) \ gtk_text_buffer_insert(GTK_TEXT_BUFFER(buffer), \ @@ -242,6 +242,7 @@ create_summary_tab (xfceweather_data *data) view = gtk_text_view_new (); gtk_text_view_set_editable (GTK_TEXT_VIEW (view), FALSE); gtk_text_view_set_cursor_visible (GTK_TEXT_VIEW (view), FALSE); + gtk_container_set_border_width (GTK_CONTAINER (view), BORDER); frame = gtk_frame_new (NULL); scrolled = gtk_scrolled_window_new (NULL, NULL); @@ -268,8 +269,20 @@ create_summary_tab (xfceweather_data *data) g_free (value); timeslice = get_current_timeslice(data->weatherdata, FALSE); - value = g_strdup_printf (_("Coordinates: lat %s lon %s\nData applies to: %s\n"), - data->lat, data->lon, ctime(×lice->start)); + APPEND_BTEXT(_("Coordinates and Time\n")); + value = g_strdup_printf (_("\tAltitude: %s %s\n" + "\tLatitude: %s%s\n" + "\tLongitude: %s%s\n\n" + "\tData applies to time interval\n" + "\tfrom %s\tto %s"), + get_data(timeslice, ALTITUDE), + get_unit(timeslice, data->unit, ALTITUDE), + get_data(timeslice, LATITUDE), + get_unit(timeslice, data->unit, LATITUDE), + get_data(timeslice, LONGITUDE), + get_unit(timeslice, data->unit, LONGITUDE), + ctime(×lice->start), + ctime(×lice->end)); APPEND_TEXT_ITEM_REAL (value); /* Temperature */ @@ -278,211 +291,203 @@ create_summary_tab (xfceweather_data *data) /* Wind */ APPEND_BTEXT (_("\nWind\n")); - wind = translate_wind_speed (data->weatherdata, get_data (data->weatherdata, WIND_SPEED), data->unit); - value = g_strdup_printf ("\t%s: %s (%s on the Beaufort scale)\n", _("Speed"), wind, - get_data (data->weatherdata, WIND_BEAUFORT)); + wind = translate_wind_speed (timeslice, get_data (timeslice, WIND_SPEED), data->unit); + value = g_strdup_printf (_("\t%s: %s (%s on the Beaufort scale)\n"), _("Speed"), wind, + get_data (timeslice, WIND_BEAUFORT)); g_free (wind); APPEND_TEXT_ITEM_REAL (value); - wind = translate_wind_direction (get_data (data->weatherdata, WIND_DIRECTION)); + wind = translate_wind_direction (get_data (timeslice, WIND_DIRECTION)); value = g_strdup_printf ("\t%s: %s (%s%s)\n", _("Direction"), - wind ? wind : get_data (data->weatherdata, WIND_DIRECTION), - get_data (data->weatherdata, WIND_DIRECTION_DEG), - get_unit (data->weatherdata, data->unit, WIND_DIRECTION_DEG)); + wind ? wind : get_data (timeslice, WIND_DIRECTION), + get_data (timeslice, WIND_DIRECTION_DEG), + get_unit (timeslice, data->unit, WIND_DIRECTION_DEG)); g_free (wind); APPEND_TEXT_ITEM_REAL (value); - /* Atmospheric pressure */ - APPEND_BTEXT (_("\nAtmospheric pressure\n")); + /* Atmosphere */ + APPEND_BTEXT (_("\nAtmosphere\n")); APPEND_TEXT_ITEM (_("Pressure"), PRESSURE); - - /* Other */ - APPEND_BTEXT (_("\nOther\n")); APPEND_TEXT_ITEM (_("Humidity"), HUMIDITY); + + /* Clouds */ + APPEND_BTEXT (_("\nClouds\n")); + APPEND_TEXT_ITEM (_("Fog"), FOG); APPEND_TEXT_ITEM (_("Low clouds"), CLOUDINESS_LOW); APPEND_TEXT_ITEM (_("Medium clouds"), CLOUDINESS_MED); APPEND_TEXT_ITEM (_("High clouds"), CLOUDINESS_HIGH); - APPEND_TEXT_ITEM (_("Fog"), FOG); + APPEND_TEXT_ITEM (_("Cloudiness"), CLOUDINESS_OVERALL); APPEND_BTEXT (_("\nData from The Norwegian Meteorological Institute\n")); APPEND_LINK_ITEM ("\t", "Thanks to met.no", "http://met.no/", ltag1); g_signal_connect(G_OBJECT(view), "motion-notify-event", - G_CALLBACK(view_motion_notify), view); + G_CALLBACK(view_motion_notify), view); g_signal_connect(G_OBJECT(view), "leave-notify-event", - G_CALLBACK(view_leave_notify), view); + G_CALLBACK(view_leave_notify), view); if (hand_cursor == NULL) hand_cursor = gdk_cursor_new(GDK_HAND2); if (text_cursor == NULL) text_cursor = gdk_cursor_new(GDK_XTERM); - return frame; } -static GtkWidget * -make_forecast (xml_weather *weatherdata, - units unit) -{ - GtkWidget *item_vbox, *temp_hbox, *icon_hbox, - *label, *icon_d, *icon_n, *box_d, *box_n; - GdkPixbuf *icon; - gchar *str, *day, *wind; - - item_vbox = gtk_vbox_new (FALSE, 0); -#if 0 - DBG ("this day %s", weatherdata->day); - - gtk_container_set_border_width (GTK_CONTAINER (item_vbox), 6); - - - label = gtk_label_new (NULL); - gtk_misc_set_alignment (GTK_MISC (label), 0.5, 0.5); - - day = translate_day (get_data_f (weatherdata, WDAY)); - str = g_strdup_printf ("%s", day ? day : get_data_f (weatherdata, WDAY)); - g_free (day); - - gtk_label_set_markup (GTK_LABEL (label), str); - g_free (str); - - gtk_box_pack_start (GTK_BOX (item_vbox), label, FALSE, FALSE, 0); - - icon_hbox = gtk_hbox_new (FALSE, 0); - - icon = get_icon (get_data_f (weatherdata, ICON_D), 48); - icon_d = gtk_image_new_from_pixbuf (icon); - box_d = gtk_event_box_new (); - gtk_event_box_set_visible_window (GTK_EVENT_BOX (box_d), FALSE); - gtk_container_add (GTK_CONTAINER (box_d), icon_d); - - if (G_LIKELY (icon)) - g_object_unref (G_OBJECT (icon)); - - icon = get_icon (get_data_f (weatherdata, ICON_N), 48); - icon_n = gtk_image_new_from_pixbuf (icon); - box_n = gtk_event_box_new (); - gtk_event_box_set_visible_window (GTK_EVENT_BOX (box_n), FALSE); - gtk_container_add (GTK_CONTAINER (box_n), icon_n); - - if (G_LIKELY (icon)) - g_object_unref (G_OBJECT (icon)); - - if (G_UNLIKELY (!tooltips)) - tooltips = gtk_tooltips_new (); - - str = g_strdup_printf (_("Day: %s"), - translate_desc (get_data_f (weatherdata, TRANS_D))); - gtk_tooltips_set_tip (tooltips, box_d, str, NULL); - g_free (str); - - str = g_strdup_printf (_("Night: %s"), - translate_desc (get_data_f (weatherdata, TRANS_N))); - gtk_tooltips_set_tip (tooltips, box_n, str, NULL); - g_free (str); - - gtk_box_pack_start (GTK_BOX (icon_hbox), box_d, TRUE, TRUE, 0); - gtk_box_pack_start (GTK_BOX (icon_hbox), box_n, TRUE, TRUE, 0); - gtk_box_pack_start (GTK_BOX (item_vbox), icon_hbox, FALSE, FALSE, 0); - - label = gtk_label_new (NULL); - gtk_misc_set_alignment (GTK_MISC (label), 0.5, 0.5); - gtk_label_set_markup (GTK_LABEL (label), _("Precipitation")); - gtk_box_pack_start (GTK_BOX (item_vbox), label, FALSE, FALSE, 0); - - temp_hbox = gtk_hbox_new (FALSE, 0); - label = gtk_label_new (NULL); - gtk_misc_set_alignment (GTK_MISC (label), 0.5, 0.5); - str = g_strdup_printf ("%s %%", get_data_f (weatherdata, PPCP_D)); - gtk_label_set_markup (GTK_LABEL (label), str); - g_free (str); - gtk_box_pack_start (GTK_BOX (temp_hbox), label, TRUE, TRUE, 0); - - label = gtk_label_new (NULL); - gtk_misc_set_alignment (GTK_MISC (label), 0.5, 0.5); - str = g_strdup_printf ("%s %%", get_data_f (weatherdata, PPCP_N)); - gtk_label_set_markup (GTK_LABEL (label), str); - g_free (str); - - gtk_box_pack_start (GTK_BOX (temp_hbox), label, TRUE, TRUE, 0); - gtk_box_pack_start (GTK_BOX (item_vbox), temp_hbox, FALSE, FALSE, 0); - - label = gtk_label_new (NULL); - gtk_misc_set_alignment (GTK_MISC (label), 0.5, 0.5); - gtk_label_set_markup (GTK_LABEL (label), _("Temperature")); - gtk_box_pack_start (GTK_BOX (item_vbox), label, FALSE, FALSE, 0); - - temp_hbox = gtk_hbox_new (FALSE, 0); - label = gtk_label_new (NULL); - gtk_misc_set_alignment (GTK_MISC (label), 0.5, 0.5); - str = g_strdup_printf ("%s %s", - get_data_f (weatherdata, TEMP_MAX), get_unit (unit, - TEMP)); - gtk_label_set_markup (GTK_LABEL (label), str); - g_free (str); - gtk_box_pack_start (GTK_BOX (temp_hbox), label, TRUE, TRUE, 0); - label = gtk_label_new (NULL); - gtk_misc_set_alignment (GTK_MISC (label), 0.5, 0.5); - str = g_strdup_printf ("%s %s", - get_data_f (weatherdata, TEMP_MIN), get_unit (unit, - TEMP)); - gtk_label_set_markup (GTK_LABEL (label), str); - g_free (str); - gtk_box_pack_start (GTK_BOX (temp_hbox), label, TRUE, TRUE, 0); - gtk_box_pack_start (GTK_BOX (item_vbox), temp_hbox, FALSE, FALSE, 0); - - label = gtk_label_new (NULL); - gtk_misc_set_alignment (GTK_MISC (label), 0.5, 0.5); - gtk_label_set_markup (GTK_LABEL (label), _("Wind")); - gtk_box_pack_start (GTK_BOX (item_vbox), label, FALSE, FALSE, 0); - - temp_hbox = gtk_hbox_new (FALSE, 0); - label = gtk_label_new (NULL); - gtk_misc_set_alignment (GTK_MISC (label), 0.5, 0.5); - - wind = translate_wind_direction (get_data_f (weatherdata, W_DIRECTION_D)); - gtk_label_set_markup (GTK_LABEL (label), - wind ? wind : get_data_f (weatherdata, - W_DIRECTION_D)); - g_free (wind); - - gtk_box_pack_start (GTK_BOX (temp_hbox), label, TRUE, TRUE, 0); +GtkWidget * +add_forecast_cell(GtkWidget *widget, GdkColor *color) { + GtkWidget *ebox; + ebox = gtk_event_box_new(); + if (color == NULL) + gtk_event_box_set_visible_window(GTK_EVENT_BOX(ebox), FALSE); + else { + gtk_event_box_set_visible_window(GTK_EVENT_BOX(ebox), TRUE); + gtk_widget_modify_bg(GTK_WIDGET(ebox), GTK_STATE_NORMAL, color); + } + gtk_widget_show(GTK_WIDGET(ebox)); + gtk_container_add(GTK_CONTAINER(ebox), GTK_WIDGET(widget)); + return ebox; +} - label = gtk_label_new (NULL); - gtk_misc_set_alignment (GTK_MISC (label), 0.5, 0.5); +GtkWidget * +add_forecast_header(gchar *text, gdouble angle, GdkColor *color) +{ + GtkWidget *label, *align; + gchar *str; + + if (angle) + align = gtk_alignment_new(1, 1, 0, 1); + else + align = gtk_alignment_new(1, 1, 1, 0); + gtk_container_set_border_width(GTK_CONTAINER(align), 4); + gtk_widget_show(GTK_WIDGET(align)); + + label = gtk_label_new(NULL); + gtk_label_set_angle(GTK_LABEL(label), angle); + gtk_widget_show(GTK_WIDGET(label)); + str = g_strdup_printf("%s", text ? text : ""); + gtk_label_set_markup(GTK_LABEL(label), str); + g_free(str); + gtk_container_add(GTK_CONTAINER(align), GTK_WIDGET(label)); - wind = translate_wind_direction (get_data_f (weatherdata, W_DIRECTION_N)); - gtk_label_set_markup (GTK_LABEL (label), - wind ? wind : get_data_f (weatherdata, - W_DIRECTION_N)); - g_free (wind); + return add_forecast_cell(align, color); +} - gtk_box_pack_start (GTK_BOX (temp_hbox), label, TRUE, TRUE, 0); - gtk_box_pack_start (GTK_BOX (item_vbox), temp_hbox, FALSE, FALSE, 0); - - /* speed */ - temp_hbox = gtk_hbox_new (FALSE, 2); - label = gtk_label_new (NULL); - gtk_misc_set_alignment (GTK_MISC (label), 0.5, 0.5); - str = g_strdup_printf ("%s %s", get_data_f (weatherdata, W_SPEED_D), - get_unit (unit, WIND_SPEED)); - gtk_label_set_markup (GTK_LABEL (label), str); - g_free (str); - gtk_box_pack_start (GTK_BOX (temp_hbox), label, TRUE, TRUE, 0); - - label = gtk_label_new (NULL); - gtk_misc_set_alignment (GTK_MISC (label), 0.5, 0.5); - str = g_strdup_printf ("%s %s", get_data_f (weatherdata, W_SPEED_N), - get_unit (unit, WIND_SPEED)); - gtk_label_set_markup (GTK_LABEL (label), str); - g_free (str); - gtk_box_pack_start (GTK_BOX (temp_hbox), label, TRUE, TRUE, 0); - gtk_box_pack_start (GTK_BOX (item_vbox), temp_hbox, FALSE, FALSE, 0); - - DBG ("Done"); -#endif - return item_vbox; +static GtkWidget * +make_forecast (xfceweather_data *data, + units unit) +{ + GtkWidget *table, *ebox, *box, *align; + GtkWidget *forecast_box, *label, *image; + GdkPixbuf *icon; + GdkColor lightbg = {0, 0xeaea, 0xeaea, 0xeaea}; + GdkColor darkbg = {0, 0x6666, 0x6666, 0x6666}; + gint num_days = 5, i, weekday, daytime; + gchar *dayname, *value; + xml_time *fcdata; + time_t now_t = time(NULL), fcday_t; + struct tm tm_fcday; + + table = gtk_table_new(num_days + 1, 5, FALSE); + gtk_table_set_row_spacings(GTK_TABLE(table), 0); + gtk_table_set_col_spacings(GTK_TABLE(table), 0); + gtk_widget_show(GTK_WIDGET(table)); + + /* empty upper left corner */ + box = gtk_vbox_new(FALSE, 0); + gtk_widget_show(GTK_WIDGET(box)); + gtk_table_attach_defaults(GTK_TABLE(table), + add_forecast_cell(box, &darkbg), + 0, 1, 0, 1); + + /* daytime headers */ + gtk_table_attach_defaults(GTK_TABLE(table), + add_forecast_header(_("Morning"), 0.0, &darkbg), + 1, 2, 0, 1); + gtk_table_attach_defaults(GTK_TABLE(table), + add_forecast_header(_("Afternoon"), 0.0, &darkbg), + 2, 3, 0, 1); + gtk_table_attach_defaults(GTK_TABLE(table), + add_forecast_header(_("Evening"), 0.0, &darkbg), + 3, 4, 0, 1); + gtk_table_attach_defaults(GTK_TABLE(table), + add_forecast_header(_("Night"), 0.0, &darkbg), + 4, 5, 0, 1); + + for (i = 0; i < num_days; i++) { + /* Forecast day headers */ + tm_fcday = *localtime(&now_t); + fcday_t = time_calc_day(tm_fcday, i); + weekday = localtime(&fcday_t)->tm_wday; + if (i == 0) + dayname = _("Today"); + else if (i == 1) + dayname = _("Tomorrow"); + else + dayname = translate_day(weekday); + + ebox = add_forecast_header(dayname, 90.0, &darkbg); + + gtk_table_attach_defaults(GTK_TABLE(table), GTK_WIDGET(ebox), + 0, 1, i+1, i+2); + + /* Get forecast data for each daytime */ + for (daytime = MORNING; daytime <= NIGHT; daytime++) { + forecast_box = gtk_vbox_new(FALSE, 0); + align = gtk_alignment_new(0.5, 0.5, 1, 1); + gtk_container_set_border_width(GTK_CONTAINER(align), 4); + gtk_container_add(GTK_CONTAINER(align), GTK_WIDGET(forecast_box)); + if (i % 2) + ebox = add_forecast_cell(align, NULL); + else + ebox = add_forecast_cell(align, &lightbg); + + fcdata = make_forecast_data(data->weatherdata, i, daytime); + if (fcdata != NULL) { + if (fcdata->location != NULL) { + icon = get_icon(get_data(fcdata, SYMBOL), 48, (daytime == NIGHT)); + image = gtk_image_new_from_pixbuf(icon); + gtk_box_pack_start(GTK_BOX(forecast_box), GTK_WIDGET(image), + TRUE, TRUE, 0); + if (G_LIKELY (icon)) + g_object_unref (G_OBJECT (icon)); + + value = g_strdup_printf("%s", + translate_desc(get_data(fcdata, SYMBOL), + (daytime == NIGHT))); + label = gtk_label_new(NULL); + gtk_label_set_markup(GTK_LABEL(label), value); + gtk_widget_show(GTK_WIDGET(label)); + gtk_box_pack_start(GTK_BOX(forecast_box), GTK_WIDGET(label), + TRUE, TRUE, 0); + g_free(value); + + value = g_strdup_printf("%s %s", + get_data(fcdata, TEMPERATURE), + get_unit(fcdata, data->unit, TEMPERATURE)); + label = gtk_label_new(value); + gtk_widget_show(GTK_WIDGET(label)); + gtk_box_pack_start(GTK_BOX(forecast_box), GTK_WIDGET(label), + TRUE, TRUE, 0); + g_free(value); + + value = g_strdup_printf("%s %s %s", + translate_wind_direction(get_data(fcdata, WIND_DIRECTION)), + get_data(fcdata, WIND_SPEED), + get_unit(fcdata, data->unit, WIND_SPEED)); + label = gtk_label_new(value); + gtk_widget_show(GTK_WIDGET(label)); + gtk_box_pack_start(GTK_BOX(forecast_box), label, TRUE, TRUE, 0); + g_free(value); + } + xml_time_free(fcdata); + } + gtk_table_attach_defaults(GTK_TABLE(table), + GTK_WIDGET(ebox), + 1+daytime, 2+daytime, i+1, i+2); + } + } + return table; } @@ -490,34 +495,15 @@ make_forecast (xml_weather *weatherdata, static GtkWidget * create_forecast_tab (xfceweather_data *data) { - GtkWidget *widg = gtk_hbox_new (FALSE, 0); + GtkWidget *align; guint i; - gtk_container_set_border_width (GTK_CONTAINER (widg), 6); -#if 0 - if (data->weatherdata && data->weatherdata->dayf) - { - for (i = 0; i < XML_WEATHER_DAYF_N - 1; i++) - { - if (!data->weatherdata->dayf[i]) - break; - - DBG ("%s", data->weatherdata->dayf[i]->day); - - gtk_box_pack_start (GTK_BOX (widg), - make_forecast (data->weatherdata->dayf[i], data->unit), FALSE, - FALSE, 0); - gtk_box_pack_start (GTK_BOX (widg), gtk_vseparator_new (), TRUE, - TRUE, 0); - } - - if (data->weatherdata->dayf[i]) - gtk_box_pack_start (GTK_BOX (widg), - make_forecast (data->weatherdata->dayf[i], data->unit), FALSE, FALSE, - 0); - } -#endif - return widg; + align = gtk_alignment_new(0.5, 0, 0.5, 0); + gtk_container_set_border_width (GTK_CONTAINER (align), 6); + if (data->weatherdata) + gtk_container_add(GTK_CONTAINER(align), + GTK_WIDGET(make_forecast (data, data->unit))); + return align; } static void @@ -534,9 +520,10 @@ summary_dialog_response (GtkWidget *dlg, GtkWidget * create_summary_window (xfceweather_data *data) { - GtkWidget *window, *notebook, *vbox; + GtkWidget *window, *notebook, *vbox, *hbox, *label; gchar *title; GdkPixbuf *icon; + xml_time *timeslice; window = xfce_titled_dialog_new_with_buttons (_("Weather Update"), NULL, @@ -545,41 +532,52 @@ create_summary_window (xfceweather_data *data) GTK_RESPONSE_HELP, GTK_STOCK_CLOSE, GTK_RESPONSE_ACCEPT, NULL); - - title = g_strdup_printf (_("Weather report for: %s"), data->location_name); - - xfce_titled_dialog_set_subtitle (XFCE_TITLED_DIALOG (window), title); - g_free (title); + if (data->location_name_short != NULL) { + title = g_strdup_printf (_("Weather report for: %s"), data->location_name_short); + xfce_titled_dialog_set_subtitle (XFCE_TITLED_DIALOG (window), title); + g_free (title); + } vbox = gtk_vbox_new (FALSE, 0); gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->vbox), vbox, TRUE, TRUE, 0); - icon = get_icon (get_data (data->weatherdata, SYMBOL), 48); - - if (!icon) - icon = get_icon ("99", 48); + timeslice = get_current_timeslice(data->weatherdata, TRUE); + icon = get_icon (get_data (timeslice, SYMBOL), 48, is_night_time()); gtk_window_set_icon (GTK_WINDOW (window), icon); if (G_LIKELY (icon)) g_object_unref (G_OBJECT (icon)); - notebook = gtk_notebook_new (); - gtk_container_set_border_width (GTK_CONTAINER (notebook), BORDER); - gtk_notebook_append_page (GTK_NOTEBOOK (notebook), - create_forecast_tab (data), - gtk_label_new (_("Forecast"))); - gtk_notebook_append_page (GTK_NOTEBOOK (notebook), - create_summary_tab (data), - gtk_label_new (_("Details"))); - - gtk_box_pack_start (GTK_BOX (vbox), notebook, TRUE, TRUE, 0); + if (data->location_name == NULL || data->weatherdata == NULL) { + hbox = gtk_hbox_new (FALSE, 0); + gtk_widget_show(hbox); + if (data->location_name == NULL) + label = gtk_label_new(_("Please set a location in the plugin settings.")); + else + label = gtk_label_new(_("Currently no data available.")); + gtk_widget_show(label); + gtk_box_pack_start (GTK_BOX (hbox), GTK_WIDGET(label), + TRUE, TRUE, 0); + + gtk_box_pack_start (GTK_BOX (vbox), GTK_WIDGET(hbox), + TRUE, TRUE, 0); + } else { + notebook = gtk_notebook_new (); + gtk_container_set_border_width (GTK_CONTAINER (notebook), BORDER); + gtk_notebook_append_page (GTK_NOTEBOOK (notebook), + create_forecast_tab (data), + gtk_label_new (_("Forecast"))); + gtk_notebook_append_page (GTK_NOTEBOOK (notebook), + create_summary_tab (data), + gtk_label_new (_("Details"))); + + gtk_box_pack_start (GTK_BOX (vbox), notebook, TRUE, TRUE, 0); + } g_signal_connect (G_OBJECT (window), "response", G_CALLBACK (summary_dialog_response), window); - gtk_window_set_default_size (GTK_WINDOW (window), 500, 400); - return window; } diff --git a/panel-plugin/weather-translate.c b/panel-plugin/weather-translate.c index 6ba9c2f..97a0ecf 100644 --- a/panel-plugin/weather-translate.c +++ b/panel-plugin/weather-translate.c @@ -276,42 +276,46 @@ typedef struct { gint id; gchar *symbol; gchar *desc; + gchar *night_desc; } SymbolToDesc; static const SymbolToDesc symbol_to_desc[] = { - { 1, "SUN", N_("Sunny") }, - { 2, "LIGHTCLOUD", N_("Lightly cloudy") }, - { 3, "PARTLYCLOUD", N_("Partly cloudy") }, - { 4, "CLOUD", N_("Cloudy") }, - { 5, "LIGHTRAINSUN", N_("Sunny, rain showers") }, - { 6, "LIGHTRAINTHUNDERSUN", - N_("Sunny, rain showers with thunder") }, - { 7, "SLEETSUN", N_("Sunny, Sleet") }, - { 8, "SNOWSUN", N_("Sunny, Snow") }, - { 9, "LIGHTRAIN", N_("Rain showers") }, - { 10,"RAIN", N_("Rain") }, - { 11,"RAINTHUNDER", N_("Rain with thunder") }, - { 12,"SLEET", N_("Sleet") }, - { 13,"SNOW", N_("Snow") }, - { 14,"SNOWTHUNDER", N_("Snow with thunder") }, - { 15,"FOG", N_("Fog") }, - { 16,"SUN", N_("Sunny") }, - { 17,"LIGHTCLOUD", N_("Lightly cloudy") }, - { 18,"LIGHTRAINSUN", N_("Sunny, rain showers") }, - { 19,"SNOWSUN", N_("Sunny, Snow") }, - { 20,"SLEETSUNTHUNDER", N_("Sunny, Sleet and thunder") }, - { 21,"SNOWSUNTHUNDER", N_("Sunny, Snow and thunder") }, - { 22,"LIGHTRAINTHUNDER",N_("Rain showers with thunder") }, - { 23,"SLEETTHUNDER", N_("Sleet and thunder") }, + { 1, "SUN", N_("Sunny"), N_("Clear") }, + { 2, "LIGHTCLOUD", N_("Lightly cloudy"), N_("Lightly cloudy") }, + { 3, "PARTLYCLOUD", N_("Partly cloudy"), N_("Partly cloudy") }, + { 4, "CLOUD", N_("Cloudy"), N_("Cloudy") }, + { 5, "LIGHTRAINSUN", N_("Sunny, rain showers"), N_("Clear, rain showers") }, + { 6, "LIGHTRAINTHUNDERSUN", N_("Sunny, rain showers with thunder"), + N_("Clear, rain showers with thunder") }, + { 7, "SLEETSUN", N_("Sunny, Sleet"), N_("Clear, Sleet") }, + { 8, "SNOWSUN", N_("Sunny, Snow"), N_("Clear, Snow") }, + { 9, "LIGHTRAIN", N_("Rain showers"), N_("Rain showers") }, + { 10,"RAIN", N_("Rain"), N_("Rain") }, + { 11,"RAINTHUNDER", N_("Rain with thunder"), N_("Rain with thunder") }, + { 12,"SLEET", N_("Sleet"), N_("Sleet") }, + { 13,"SNOW", N_("Snow"), N_("Snow") }, + { 14,"SNOWTHUNDER", N_("Snow with thunder"), N_("Snow with thunder") }, + { 15,"FOG", N_("Fog"), N_("Fog") }, + { 16,"SUN", N_("Sunny"), N_("Clear") }, + { 17,"LIGHTCLOUD", N_("Lightly cloudy"), N_("Lightly cloudy") }, + { 18,"LIGHTRAINSUN", N_("Sunny, rain showers"), N_("Clear, rain showers") }, + { 19,"SNOWSUN", N_("Sunny, Snow"), N_("Clear, Snow") }, + { 20,"SLEETSUNTHUNDER", N_("Sunny, Sleet and thunder"), N_("Clear, sleet and thunder") }, + { 21,"SNOWSUNTHUNDER", N_("Sunny, Snow and thunder"), N_("Clear, snow and thunder") }, + { 22,"LIGHTRAINTHUNDER", N_("Rain showers with thunder"), N_("Rain showers with thunder") }, + { 23,"SLEETTHUNDER", N_("Sleet and thunder"), N_("Sleet and thunder") }, }; #define NUM_SYMBOLS (sizeof(symbol_to_desc)/sizeof(symbol_to_desc[0])) const gchar * -translate_desc (const gchar *desc) +translate_desc (const gchar *desc, gboolean nighttime) { int i; for (i = 0; i < NUM_SYMBOLS; i++) { if (!strcmp(desc, symbol_to_desc[i].symbol)) - return _(symbol_to_desc[i].desc); + if (nighttime) + return _(symbol_to_desc[i].night_desc); + else + return _(symbol_to_desc[i].desc); } return desc; } @@ -390,40 +394,28 @@ translate_lsup (const gchar *lsup) gchar * -translate_day (const gchar *day) +translate_day (gint weekday) { - gint wday = -1; struct tm time_tm; - guint i; - const gchar *days[] = {"su", "mo", "tu", "we", "th", "fr", "sa", NULL}; gchar *day_loc; int len; - if (day == NULL || strlen (day) < 2) + if (weekday < 0 || weekday > 6) return NULL; - for (i = 0; days[i] != NULL; i++) - if (!g_ascii_strncasecmp (day, days[i], 2)) - wday = i; + time_tm.tm_wday = weekday; - if (wday == -1) - return NULL; - else - { - time_tm.tm_wday = wday; + day_loc = g_malloc (DAY_LOC_N); - day_loc = g_malloc (DAY_LOC_N); - - len = strftime (day_loc, DAY_LOC_N, "%A", &time_tm); - day_loc[len] = 0; - if (!g_utf8_validate(day_loc, -1, NULL)) { - gchar *utf8 = g_locale_to_utf8(day_loc, -1, NULL, NULL, NULL); - g_free(day_loc); - day_loc = utf8; - } + len = strftime (day_loc, DAY_LOC_N, "%A", &time_tm); + day_loc[len] = 0; + if (!g_utf8_validate(day_loc, -1, NULL)) { + gchar *utf8 = g_locale_to_utf8(day_loc, -1, NULL, NULL, NULL); + g_free(day_loc); + day_loc = utf8; + } - return day_loc; - } + return day_loc; } @@ -474,7 +466,7 @@ translate_wind_direction (const gchar *wdir) /* calm or a number */ gchar * -translate_wind_speed (xml_weather *data, +translate_wind_speed (xml_time *timeslice, const gchar *wspeed, units unit) { @@ -484,9 +476,10 @@ translate_wind_speed (xml_weather *data, wspeed_loc = g_strdup (_("calm")); else if (g_ascii_strcasecmp (wspeed, "N/A") == 0) wspeed_loc = g_strdup (_("N/A")); - else + else { wspeed_loc = - g_strdup_printf ("%s %s", wspeed, get_unit (data, unit, WIND_SPEED)); + g_strdup_printf ("%s %s", wspeed, get_unit (timeslice, unit, WIND_SPEED)); + } return wspeed_loc; } diff --git a/panel-plugin/weather-translate.h b/panel-plugin/weather-translate.h index 7ef4674..a8b1adf 100644 --- a/panel-plugin/weather-translate.h +++ b/panel-plugin/weather-translate.h @@ -23,7 +23,7 @@ G_BEGIN_DECLS -const gchar *translate_desc (const gchar *); +const gchar *translate_desc (const gchar *, gboolean); const gchar *translate_bard (const gchar *); @@ -32,11 +32,11 @@ const gchar *translate_risk (const gchar *); /* these return a newly alocted string, that should be freed */ gchar *translate_lsup (const gchar *); -gchar *translate_day (const gchar *); +gchar *translate_day (gint); gchar *translate_wind_direction (const gchar *); -gchar *translate_wind_speed (xml_weather *data, const gchar *, units); +gchar *translate_wind_speed (xml_time *, const gchar *, units); gchar *translate_time (const gchar *); diff --git a/panel-plugin/weather.c b/panel-plugin/weather.c index 7b75c4b..23fcd12 100644 --- a/panel-plugin/weather.c +++ b/panel-plugin/weather.c @@ -102,6 +102,7 @@ make_label (xml_weather *weatherdata, { gchar *str, *value; + xml_time *timeslice; const gchar *rawvalue, *lbl, *txtsize; switch (opt) @@ -130,6 +131,9 @@ make_label (xml_weather *weatherdata, case CLOUDINESS_HIGH: lbl = _("CH"); break; + case CLOUDINESS_OVERALL: + lbl = _("CO"); + break; case FOG: lbl = _("F"); break; @@ -153,7 +157,10 @@ make_label (xml_weather *weatherdata, else txtsize = "xx-small"; - rawvalue = get_data (weatherdata, opt); + /* get data from current timeslice */ + timeslice = get_current_timeslice(weatherdata, + opt == PRECIPITATIONS || opt == SYMBOL); + rawvalue = get_data(timeslice, opt); switch (opt) { @@ -161,7 +168,7 @@ make_label (xml_weather *weatherdata, value = translate_wind_direction (rawvalue); break; case WIND_SPEED: - value = translate_wind_speed (weatherdata, rawvalue, unit); + value = translate_wind_speed (timeslice, rawvalue, unit); break; default: value = NULL; @@ -179,7 +186,7 @@ make_label (xml_weather *weatherdata, else { str = g_strdup_printf ("%s: %s %s", - txtsize, lbl, rawvalue, get_unit (weatherdata, unit, opt)); + txtsize, lbl, rawvalue, get_unit (timeslice, unit, opt)); } } else { if (value != NULL) @@ -191,7 +198,7 @@ make_label (xml_weather *weatherdata, else { str = g_strdup_printf ("%s %s", - txtsize, rawvalue, get_unit (weatherdata, unit, opt)); + txtsize, rawvalue, get_unit (timeslice, unit, opt)); } } return str; @@ -236,9 +243,9 @@ set_icon_error (xfceweather_data *data) gtk_widget_get_size_request (data->scrollbox, NULL, &height); if (data->orientation == GTK_ORIENTATION_VERTICAL) - icon = get_icon ("99", data->size - height - 2); + icon = get_icon ("99", data->size - height - 2, FALSE); else - icon = get_icon ("99", data->size); + icon = get_icon ("99", data->size, FALSE); gtk_image_set_from_pixbuf (GTK_IMAGE (data->iconimage), icon); @@ -256,11 +263,13 @@ set_icon_error (xfceweather_data *data) static void set_icon_current (xfceweather_data *data) { + xml_time *timeslice; guint i; GdkPixbuf *icon = NULL; datas opt; gchar *str; gint size, height; + gboolean nighttime; for (i = 0; i < data->labels->len; i++) { @@ -286,7 +295,10 @@ set_icon_current (xfceweather_data *data) size = data->size; } - icon = get_icon (get_data (data->weatherdata, SYMBOL), size); + /* get data from current timeslice */ + timeslice = get_current_timeslice(data->weatherdata, TRUE); + nighttime = is_night_time(); + icon = get_icon (get_data (timeslice, SYMBOL), size, nighttime); gtk_image_set_from_pixbuf (GTK_IMAGE (data->iconimage), icon); @@ -295,7 +307,7 @@ set_icon_current (xfceweather_data *data) #if !GTK_CHECK_VERSION(2,12,0) gtk_tooltips_set_tip (data->tooltips, data->tooltipbox, - translate_desc (get_data (data->weatherdata, SYMBOL)), + translate_desc (get_data (timeslice, SYMBOL), nighttime), NULL); #endif } @@ -461,6 +473,16 @@ xfceweather_read_config (XfcePanelPlugin *plugin, data->location_name = g_strdup (value); } + value = xfce_rc_read_entry (rc, "loc_name_short", NULL); + + if (value) + { + if (data->location_name_short) + g_free (data->location_name_short); + + data->location_name_short = g_strdup (value); + } + if (xfce_rc_read_bool_entry (rc, "celcius", TRUE)) data->unit = METRIC; else @@ -555,6 +577,9 @@ xfceweather_write_config (XfcePanelPlugin *plugin, if (data->location_name) xfce_rc_write_entry (rc, "loc_name", data->location_name); + if (data->location_name_short) + xfce_rc_write_entry (rc, "loc_name_short", data->location_name_short); + xfce_rc_write_bool_entry (rc, "proxy_fromenv", data->proxy_fromenv); if (data->proxy_host) @@ -618,10 +643,7 @@ forecast_click (GtkWidget *widget, xfceweather_data *data = (xfceweather_data *) user_data; if (data->summary_window != NULL) - { - - gtk_window_present (GTK_WINDOW (data->summary_window)); - } + gtk_widget_destroy (data->summary_window); else { data->summary_window = create_summary_window (data); @@ -757,7 +779,11 @@ static gboolean weather_get_tooltip_cb (GtkWidget *widget, { GdkPixbuf *icon; gchar *markup_text; + xml_time *timeslice; + gboolean nighttime; + timeslice = get_current_timeslice(data->weatherdata, TRUE); + nighttime = is_night_time(); if (data->weatherdata == NULL) { gtk_tooltip_set_text (tooltip, _("Cannot update weather data")); } else { @@ -765,12 +791,12 @@ static gboolean weather_get_tooltip_cb (GtkWidget *widget, "%s\n" "%s", data->location_name, - translate_desc (get_data (data->weatherdata, SYMBOL)) + translate_desc (get_data (timeslice, SYMBOL), nighttime) ); gtk_tooltip_set_markup (tooltip, markup_text); g_free(markup_text); } - icon = get_icon (get_data (data->weatherdata, SYMBOL), 32); + icon = get_icon (get_data (timeslice, SYMBOL), 32, nighttime); gtk_tooltip_set_icon (tooltip, icon); g_object_unref (G_OBJECT(icon)); @@ -795,7 +821,7 @@ xfceweather_create_control (XfcePanelPlugin *plugin) #endif data->scrollbox = gtk_scrollbox_new (); - icon = get_icon ("99", 16); + icon = get_icon ("99", 16, FALSE); data->iconimage = gtk_image_new_from_pixbuf (icon); if (G_LIKELY (icon)) @@ -843,7 +869,7 @@ xfceweather_create_control (XfcePanelPlugin *plugin) /* add refresh button to right click menu, for people who missed the middle mouse click feature */ mi = gtk_image_menu_item_new_with_mnemonic (_("_Forecast")); - icon = get_icon ("SUN", 16); + icon = get_icon ("SUN", 16, FALSE); gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(mi), gtk_image_new_from_pixbuf(icon)); if (G_LIKELY (icon)) diff --git a/panel-plugin/weather.h b/panel-plugin/weather.h index 81b666e..147f72f 100644 --- a/panel-plugin/weather.h +++ b/panel-plugin/weather.h @@ -52,6 +52,7 @@ typedef struct gchar *lat; gchar *lon; gchar *location_name; + gchar *location_name_short; units unit; xml_weather *weatherdata;