X-Git-Url: http://pileus.org/git/?p=aweather;a=blobdiff_plain;f=src%2Fplugins%2Falert.c;h=bbdae3ff37a39fa46c60e5fd67b515ee55dd8198;hp=a82528b874c3574f8856fe05454a437889300125;hb=09e7e102e065b1984669c93fb4f8d324a774116b;hpb=1594a29752461f76e001c6a6d7f5a3f946304a00 diff --git a/src/plugins/alert.c b/src/plugins/alert.c index a82528b..bbdae3f 100644 --- a/src/plugins/alert.c +++ b/src/plugins/alert.c @@ -24,6 +24,8 @@ #include "alert.h" #include "alert-info.h" +#include "../compat.h" + #define MSG_INDEX "http://alerts.weather.gov/cap/us.php?x=0" #define CONFIG_HEIGHT 3 @@ -319,22 +321,22 @@ GList *msg_load_index(GritsHttp *http, time_t when, time_t *updated, gboolean of return msgs; } -void msg_load_cap(GritsHttp *http, AlertMsg *msg) +gboolean msg_load_cap(GritsHttp *http, AlertMsg *msg) { if (msg->description || msg->instruction || msg->polygon) - return; + return TRUE; g_debug("GritsPlguinAlert: update_cap"); /* Download */ gchar *id = strrchr(msg->link, '='); - if (!id) return; id++; + if (!id) return FALSE; id++; gchar *dir = g_strdelimit(g_strdup(msg->info->abbr), " ", '_'); gchar *tmp = g_strdup_printf("%s/%s.xml", dir, id); gchar *file = grits_http_fetch(http, msg->link, tmp, GRITS_ONCE, NULL, NULL); g_free(tmp); g_free(dir); if (!file) - return; + return FALSE; /* Parse */ gchar *text; gsize len; @@ -342,6 +344,7 @@ void msg_load_cap(GritsHttp *http, AlertMsg *msg) msg_parse_cap(msg, text, len); g_free(file); g_free(text); + return TRUE; } @@ -477,7 +480,7 @@ static GtkWidget *_make_msg_details(AlertMsg *msg) g_free(alert_str); GtkWidget *align = gtk_alignment_new(0, 0, 1, 1); - GtkWidget *box = gtk_vbox_new(FALSE, 10); + GtkWidget *box = gtk_box_new(GTK_ORIENTATION_VERTICAL, 10); gtk_alignment_set_padding(GTK_ALIGNMENT(align), 10, 10, 10, 10); gtk_container_add(GTK_CONTAINER(align), box); gtk_box_pack_start(GTK_BOX(box), title, FALSE, FALSE, 0); @@ -497,11 +500,14 @@ static GtkWidget *_find_details(GtkNotebook *notebook, AlertMsg *msg) return NULL; } -static void _show_details(GritsPoly *county, GritsPluginAlert *alert) +static gboolean _show_details(GritsPoly *county, GdkEvent *_, GritsPluginAlert *alert) { /* Add details for this messages */ AlertMsg *msg = g_object_get_data(G_OBJECT(county), "msg"); - msg_load_cap(alert->http, msg); + + // TODO: move this to a thread since it blocks on net access + if (!msg_load_cap(alert->http, msg)) + return FALSE; GtkWidget *dialog = alert->details; GtkWidget *content = gtk_dialog_get_content_area(GTK_DIALOG(dialog)); @@ -520,10 +526,12 @@ static void _show_details(GritsPoly *county, GritsPluginAlert *alert) gtk_widget_show_all(dialog); gint num = gtk_notebook_page_num(GTK_NOTEBOOK(notebook), details); gtk_notebook_set_current_page(GTK_NOTEBOOK(notebook), num); + + return FALSE; } /* Update counties */ -static void _alert_leave(GritsPoly *county, GritsPluginAlert *alert) +static gboolean _alert_leave(GritsPoly *county, GdkEvent *_, GritsPluginAlert *alert) { g_debug("_alert_leave"); if (county->width == 3) { @@ -533,9 +541,10 @@ static void _alert_leave(GritsPoly *county, GritsPluginAlert *alert) county->width = 1; } grits_object_queue_draw(GRITS_OBJECT(county)); + return FALSE; } -static void _alert_enter(GritsPoly *county, GritsPluginAlert *alert) +static gboolean _alert_enter(GritsPoly *county, GdkEvent *_, GritsPluginAlert *alert) { g_debug("_alert_enter"); if (county->width == 3) { @@ -545,6 +554,7 @@ static void _alert_enter(GritsPoly *county, GritsPluginAlert *alert) county->width = 2; } grits_object_queue_draw(GRITS_OBJECT(county)); + return FALSE; } /* Update polygons */ @@ -571,11 +581,15 @@ static GritsPoly *_load_storm_based(GritsPluginAlert *alert, AlertMsg *msg) if (!msg->info->ispoly) return NULL; - msg_load_cap(alert->http, msg); + if (!msg_load_cap(alert->http, msg)) + return NULL; + + if (!msg->polygon) + return NULL; GritsPoly *poly = grits_poly_parse(msg->polygon, "\t", " ", ","); _load_common(alert, msg, poly, 0, 1, 3, "alert/hide_storm_based"); - grits_viewer_add(alert->viewer, GRITS_OBJECT(poly), GRITS_LEVEL_WORLD+2, TRUE); + grits_viewer_add(alert->viewer, GRITS_OBJECT(poly), GRITS_LEVEL_WORLD+4, FALSE); return poly; } @@ -637,7 +651,7 @@ static gboolean _show_hide(GtkToggleButton *button, GritsPluginAlert *alert) GRITS_OBJECT(msg->storm_based)->hidden = !sshow || hide; } - gtk_widget_queue_draw(GTK_WIDGET(alert->viewer)); + grits_viewer_queue_draw(alert->viewer); return TRUE; } @@ -722,6 +736,7 @@ static gboolean _update_buttons(GritsPluginAlert *alert) g_free(date_str); gtk_widget_show_all(GTK_WIDGET(alert->config)); + alert->update_source = 0; return FALSE; } @@ -732,13 +747,6 @@ static gint _sort_warnings(gconstpointer _a, gconstpointer _b) (a->info->prior == b->info->prior) ? 0 : 1; } -static gboolean _update_end(gpointer _alert) -{ - GritsPluginAlert *alert = _alert; - gtk_widget_queue_draw(GTK_WIDGET(alert->viewer)); - return FALSE; -} - static void _update_warnings(GritsPluginAlert *alert, GList *old) { g_debug("GritsPluginAlert: _update_warnings"); @@ -751,10 +759,8 @@ static void _update_warnings(GritsPluginAlert *alert, GList *old) /* Remove old messages */ for (GList *cur = old; cur; cur = cur->next) { AlertMsg *msg = cur->data; - if (msg->county_based) grits_viewer_remove(alert->viewer, - GRITS_OBJECT(msg->county_based)); - if (msg->storm_based) grits_viewer_remove(alert->viewer, - GRITS_OBJECT(msg->storm_based)); + grits_object_destroy_pointer(&msg->county_based); + grits_object_destroy_pointer(&msg->storm_based); } /* Add new messages */ @@ -763,12 +769,14 @@ static void _update_warnings(GritsPluginAlert *alert, GList *old) AlertMsg *msg = cur->data; msg->county_based = _load_county_based(alert, msg); } - g_idle_add(_update_end, alert); + grits_viewer_queue_draw(alert->viewer); for (GList *cur = alert->msgs; cur; cur = cur->next) { AlertMsg *msg = cur->data; msg->storm_based = _load_storm_based(alert, msg); + if (alert->aborted) + return; } - g_idle_add(_update_end, alert); + grits_viewer_queue_draw(alert->viewer); g_debug("GritsPluginAlert: _load_warnings - end"); } @@ -777,6 +785,8 @@ static void _update_warnings(GritsPluginAlert *alert, GList *old) static void _update(gpointer _, gpointer _alert) { GritsPluginAlert *alert = _alert; + if (alert->aborted) + return; GList *old = alert->msgs; g_debug("GritsPluginAlert: _update"); @@ -785,7 +795,8 @@ static void _update(gpointer _, gpointer _alert) if (!(alert->msgs = msg_load_index(alert->http, when, &alert->updated, offline))) return; - g_idle_add((GSourceFunc)_update_buttons, alert); + if (!alert->update_source) + alert->update_source = g_idle_add((GSourceFunc)_update_buttons, alert); _update_warnings(alert, old); g_list_foreach(old, (GFunc)msg_free, NULL); @@ -802,10 +813,10 @@ static void _on_update(GritsPluginAlert *alert) /* Init helpers */ static GtkWidget *_make_config(GritsPluginAlert *alert) { - GtkWidget *config = gtk_vbox_new(FALSE, 0); + GtkWidget *config = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0); /* Setup tools area */ - GtkWidget *tools = gtk_hbox_new(FALSE, 10); + GtkWidget *tools = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 10); GtkWidget *updated = gtk_label_new(" Loading..."); GtkWidget *storm_based = gtk_toggle_button_new_with_label("Storm based"); GtkWidget *county_based = gtk_toggle_button_new_with_label("County based"); @@ -824,7 +835,7 @@ static GtkWidget *_make_config(GritsPluginAlert *alert) gchar *labels[] = {"Warnings", "Watches", "Advisories", "Other"}; gchar *keys[] = {"warning", "watch", "advisory", "other"}; - GtkWidget *alerts = gtk_hbox_new(FALSE, 10); + GtkWidget *alerts = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 10); for (int i = 0; i < G_N_ELEMENTS(labels); i++) { GtkWidget *frame = gtk_frame_new(labels[i]); GtkWidget *table = gtk_table_new(1, 1, TRUE); @@ -853,7 +864,7 @@ static gboolean _clear_details(GtkWidget *dialog) return TRUE; } -static gboolean _set_details_uri(GtkWidget *notebook, GtkNotebookPage *_, +static gboolean _set_details_uri(GtkWidget *notebook, gpointer _, guint num, GtkWidget *button) { g_debug("_set_details_uri"); @@ -955,26 +966,25 @@ static void grits_plugin_alert_dispose(GObject *gobject) { g_debug("GritsPluginAlert: dispose"); GritsPluginAlert *alert = GRITS_PLUGIN_ALERT(gobject); + alert->aborted = TRUE; /* Drop references */ if (alert->viewer) { GritsViewer *viewer = alert->viewer; - alert->viewer = NULL; g_signal_handler_disconnect(viewer, alert->refresh_id); g_signal_handler_disconnect(viewer, alert->time_changed_id); - soup_session_abort(alert->http->soup); + grits_http_abort(alert->http); g_thread_pool_free(alert->threads, TRUE, TRUE); - gtk_widget_destroy(alert->details); - while (gtk_events_pending()) - gtk_main_iteration(); + if (alert->update_source) + g_source_remove(alert->update_source); + alert->viewer = NULL; for (GList *cur = alert->msgs; cur; cur = cur->next) { AlertMsg *msg = cur->data; - if (msg->county_based) grits_viewer_remove(viewer, - GRITS_OBJECT(msg->county_based)); - if (msg->storm_based) grits_viewer_remove(viewer, - GRITS_OBJECT(msg->storm_based)); + grits_object_destroy_pointer(&msg->county_based); + grits_object_destroy_pointer(&msg->storm_based); } for (GList *cur = alert->states; cur; cur = cur->next) - grits_viewer_remove(viewer, cur->data); + grits_object_destroy_pointer(&cur->data); + gtk_widget_destroy(alert->details); g_object_unref(alert->prefs); g_object_unref(viewer); }