]> Pileus Git - aweather/blobdiff - src/plugins/alert.c
Use grits_object_destroy api and fix memory leaks
[aweather] / src / plugins / alert.c
index 4302dd2599c222d35ef18d95fb6732e33b9b10fb..bbdae3ff37a39fa46c60e5fd67b515ee55dd8198 100644 (file)
@@ -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, GdkEvent *_, 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, GdkEvent *_, GritsPluginAlert *aler
        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, GdkEvent *_, 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, GdkEvent *_, GritsPluginAlert *alert
                county->width     = 1;
        }
        grits_object_queue_draw(GRITS_OBJECT(county));
+       return FALSE;
 }
 
-static void _alert_enter(GritsPoly *county, GdkEvent *_, 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, GdkEvent *_, GritsPluginAlert *alert
                county->width     = 2;
        }
        grits_object_queue_draw(GRITS_OBJECT(county));
+       return FALSE;
 }
 
 /* Update polygons */
@@ -571,7 +581,11 @@ 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");
@@ -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[] = {"<b>Warnings</b>", "<b>Watches</b>",
                           "<b>Advisories</b>", "<b>Other</b>"};
        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);
        }