]> Pileus Git - aweather/blobdiff - src/plugins/alert.c
Fix return values in alert plugin
[aweather] / src / plugins / alert.c
index 4d4a556e0695511b07acdb9a9161e361be51b9d7..73cb56451cbab60f55242a6c5903d42b60ef7a8b 100644 (file)
 
 #include <time.h>
 #include <grits.h>
-#include <GL/gl.h>
 #include <stdio.h>
 #include <string.h>
 
 #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
 
 /* Format for single cap alert:
  *   "http://alerts.weather.gov/cap/wwacapget.php?x="
@@ -423,7 +425,7 @@ void fips_parse(gchar *text, GTree **_counties, GList **_states)
                GritsPoly *poly = grits_poly_parse(sparts[3], "\t", " ", ",");
 
                /* Insert polys into the tree */
-               gint id = g_ascii_strtoll(sparts[0], NULL, 10);
+               glong id = g_ascii_strtoll(sparts[0], NULL, 10);
                g_tree_insert(counties, (gpointer)id, poly);
 
                /* Insert into states list */
@@ -477,7 +479,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,7 +499,7 @@ 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");
@@ -520,10 +522,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 +537,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,11 +550,12 @@ static void _alert_enter(GritsPoly *county, GritsPluginAlert *alert)
                county->width     = 2;
        }
        grits_object_queue_draw(GRITS_OBJECT(county));
+       return FALSE;
 }
 
 /* Update polygons */
 static void _load_common(GritsPluginAlert *alert, AlertMsg *msg, GritsPoly *poly,
-               float color, float border, int width)
+               float color, float border, int width, gchar *hidden)
 {
        g_object_set_data(G_OBJECT(poly), "msg", msg);
        poly->color[0]  = poly->border[0] = (float)msg->info->color[0] / 256;
@@ -559,7 +565,8 @@ static void _load_common(GritsPluginAlert *alert, AlertMsg *msg, GritsPoly *poly
        poly->border[3] = border;
        poly->width     = width;
        GRITS_OBJECT(poly)->lod    = 0;
-       GRITS_OBJECT(poly)->hidden = msg->info->hidden;
+       GRITS_OBJECT(poly)->hidden = msg->info->hidden ||
+               grits_prefs_get_boolean(alert->prefs, hidden, NULL);
        g_signal_connect(poly, "enter",   G_CALLBACK(_alert_enter),  alert);
        g_signal_connect(poly, "leave",   G_CALLBACK(_alert_leave),  alert);
        g_signal_connect(poly, "clicked", G_CALLBACK(_show_details), alert);
@@ -573,8 +580,8 @@ static GritsPoly *_load_storm_based(GritsPluginAlert *alert, AlertMsg *msg)
        msg_load_cap(alert->http, msg);
 
        GritsPoly *poly = grits_poly_parse(msg->polygon, "\t", " ", ",");
-       _load_common(alert, msg, poly, 0, 1, 3);
-       grits_viewer_add(alert->viewer, GRITS_OBJECT(poly), GRITS_LEVEL_WORLD+2, TRUE);
+       _load_common(alert, msg, poly, 0, 1, 3, "alert/hide_storm_based");
+       grits_viewer_add(alert->viewer, GRITS_OBJECT(poly), GRITS_LEVEL_WORLD+4, FALSE);
 
        return poly;
 }
@@ -585,7 +592,7 @@ static GritsPoly *_load_county_based(GritsPluginAlert *alert, AlertMsg *msg)
        gchar **fipses  = g_strsplit(msg->cap.fips6, " ", -1);
        GList *counties = NULL;
        for (int i = 0; fipses[i]; i++) {
-               gint fips = g_ascii_strtoll(fipses[i], NULL, 10);
+               glong fips = g_ascii_strtoll(fipses[i], NULL, 10);
                GritsPoly *county = g_tree_lookup(alert->counties, (gpointer)fips);
                if (!county)
                        continue;
@@ -599,7 +606,7 @@ static GritsPoly *_load_county_based(GritsPluginAlert *alert, AlertMsg *msg)
 
        /* Create new county based warning */
        GritsPoly *poly = fips_combine(counties);
-       _load_common(alert, msg, poly, 0.25, 0.25, 0);
+       _load_common(alert, msg, poly, 0.25, 0.25, 0, "alert/hide_county_based");
        grits_viewer_add(alert->viewer, GRITS_OBJECT(poly), GRITS_LEVEL_WORLD+1, FALSE);
 
        g_list_free(counties);
@@ -607,24 +614,40 @@ static GritsPoly *_load_county_based(GritsPluginAlert *alert, AlertMsg *msg)
 }
 
 /* Update buttons */
-static void _button_click(GtkToggleButton *button, gpointer _alert)
+static gboolean _show_hide(GtkToggleButton *button, GritsPluginAlert *alert)
 {
-       g_debug("GritsPluginAlert: _button_click");
-       GritsPluginAlert *alert = _alert;
+       g_debug("GritsPluginAlert: _show_hide - alert=%p, config=%p", alert, alert->config);
+
+       /* Check if we've clicked a alert type button */
        AlertInfo *info = g_object_get_data(G_OBJECT(button), "info");
-       info->hidden = !gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(button));
+       if (info)
+               info->hidden = !gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(button));
+
+       /* Update county/storm based hiding */
+       GtkWidget *ctoggle = g_object_get_data(G_OBJECT(alert->config), "county_based");
+       GtkWidget *stoggle = g_object_get_data(G_OBJECT(alert->config), "storm_based");
+
+       gboolean   cshow   = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(ctoggle));
+       gboolean   sshow   = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(stoggle));
+
+       grits_prefs_set_boolean(alert->prefs, "alert/hide_county_based", !cshow);
+       grits_prefs_set_boolean(alert->prefs, "alert/hide_storm_based",  !sshow);
 
-       /* Show/hide each polygons */
+       /* Show/hide each message */
        for (GList *cur = alert->msgs; cur; cur = cur->next) {
                AlertMsg *msg = cur->data;
-               if (msg->info != info)
-                       continue;
-               if (msg->county_based) GRITS_OBJECT(msg->county_based)->hidden = info->hidden;
-               if (msg->storm_based)  GRITS_OBJECT(msg->storm_based)->hidden  = info->hidden;
+               gboolean hide = msg->info->hidden;
+               if (msg->county_based)
+                       GRITS_OBJECT(msg->county_based)->hidden = !cshow || hide;
+               if (msg->storm_based)
+                       GRITS_OBJECT(msg->storm_based)->hidden  = !sshow || hide;
        }
-       gtk_widget_queue_draw(GTK_WIDGET(alert->viewer));
+
+       grits_viewer_queue_draw(alert->viewer);
+       return TRUE;
 }
 
+
 static GtkWidget *_button_new(AlertInfo *info)
 {
        g_debug("GritsPluginAlert: _button_new - %s", info->title);
@@ -685,18 +708,15 @@ static gboolean _update_buttons(GritsPluginAlert *alert)
                GtkWidget *table = g_object_get_data(G_OBJECT(alerts),
                                alert_info[i].category);
                GList *kids = gtk_container_get_children(GTK_CONTAINER(table));
-               gint nkids = g_list_length(kids);
-               guint rows, cols;
-               gtk_table_get_size(GTK_TABLE(table), &rows, &cols);
-               gint x = nkids % cols;
-               gint y = nkids / cols;
+               gint  nkids = g_list_length(kids);
+               gint x = nkids / CONFIG_HEIGHT;
+               gint y = nkids % CONFIG_HEIGHT;
                g_list_free(kids);
 
                GtkWidget *button = _button_new(&alert_info[i]);
                gtk_table_attach(GTK_TABLE(table), button, x, x+1, y, y+1,
                                GTK_FILL|GTK_EXPAND, GTK_FILL, 0, 0);
-               g_signal_connect(button, "clicked",
-                               G_CALLBACK(_button_click), alert);
+               g_signal_connect(button, "clicked", G_CALLBACK(_show_hide), alert);
        }
 
        /* Set time widget */
@@ -708,6 +728,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;
 }
 
@@ -737,11 +758,17 @@ static void _update_warnings(GritsPluginAlert *alert, GList *old)
        }
 
        /* Add new messages */
+       /* Load counties first since it does not require network access */
        for (GList *cur = alert->msgs; cur; cur = cur->next) {
                AlertMsg *msg = cur->data;
                msg->county_based = _load_county_based(alert, msg);
+       }
+       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);
        }
+       grits_viewer_queue_draw(alert->viewer);
 
        g_debug("GritsPluginAlert: _load_warnings - end");
 }
@@ -758,13 +785,13 @@ 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);
        g_list_free(old);
 
-       gtk_widget_queue_draw(GTK_WIDGET(alert->viewer));
        g_debug("GritsPluginAlert: _update - end");
 }
 
@@ -774,27 +801,34 @@ static void _on_update(GritsPluginAlert *alert)
 }
 
 /* Init helpers */
-static GtkWidget *_make_config(void)
+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");
        gtk_label_set_use_markup(GTK_LABEL(updated), TRUE);
-       gtk_box_pack_start(GTK_BOX(tools), updated, FALSE, FALSE, 0);
+       gtk_box_pack_start(GTK_BOX(tools), updated,      FALSE, FALSE, 0);
+       gtk_box_pack_end  (GTK_BOX(tools), storm_based,  FALSE, FALSE, 0);
+       gtk_box_pack_end  (GTK_BOX(tools), county_based, FALSE, FALSE, 0);
        gtk_box_pack_start(GTK_BOX(config), tools, FALSE, FALSE, 0);
-       g_object_set_data(G_OBJECT(config), "updated", updated);
+       g_object_set_data(G_OBJECT(config), "updated",      updated);
+       g_object_set_data(G_OBJECT(config), "storm_based",  storm_based);
+       g_object_set_data(G_OBJECT(config), "county_based", county_based);
+       g_signal_connect(storm_based,  "toggled", G_CALLBACK(_show_hide), alert);
+       g_signal_connect(county_based, "toggled", G_CALLBACK(_show_hide), alert);
 
        /* Setup alerts */
        gchar *labels[] = {"<b>Warnings</b>", "<b>Watches</b>",
                           "<b>Advisories</b>", "<b>Other</b>"};
        gchar *keys[]   = {"warning",  "watch",   "advisory",   "other"};
-       gint   cols[]   = {2, 2, 3, 2};
-       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, cols[i], TRUE);
+               GtkWidget *table = gtk_table_new(1, 1, TRUE);
                GtkWidget *label = gtk_frame_get_label_widget(GTK_FRAME(frame));
                gtk_label_set_use_markup(GTK_LABEL(label), TRUE);
                gtk_frame_set_shadow_type(GTK_FRAME(frame), GTK_SHADOW_NONE);
@@ -820,7 +854,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");
@@ -871,6 +905,13 @@ GritsPluginAlert *grits_plugin_alert_new(GritsViewer *viewer, GritsPrefs *prefs)
        for (GList *cur = alert->states; cur; cur = cur->next)
                grits_viewer_add(viewer, cur->data, GRITS_LEVEL_WORLD+1, FALSE);
 
+       gboolean   chide   = grits_prefs_get_boolean(alert->prefs, "alert/hide_county_based", NULL);
+       gboolean   shide   = grits_prefs_get_boolean(alert->prefs, "alert/hide_storm_based",  NULL);
+       GtkWidget *ctoggle = g_object_get_data(G_OBJECT(alert->config), "county_based");
+       GtkWidget *stoggle = g_object_get_data(G_OBJECT(alert->config), "storm_based");
+       gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(ctoggle), !chide);
+       gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(stoggle), !shide);
+
        _on_update(alert);
        return alert;
 }
@@ -897,8 +938,8 @@ static void grits_plugin_alert_init(GritsPluginAlert *alert)
 {
        g_debug("GritsPluginAlert: init");
        /* Set defaults */
-       alert->threads = g_thread_pool_new(_update, alert, 1, TRUE, NULL);
-       alert->config  = _make_config();
+       alert->threads = g_thread_pool_new(_update, alert, 1, FALSE, NULL);
+       alert->config  = _make_config(alert);
        alert->http    = grits_http_new(G_DIR_SEPARATOR_S
                        "alerts" G_DIR_SEPARATOR_S
                        "cap"    G_DIR_SEPARATOR_S);
@@ -918,14 +959,13 @@ static void grits_plugin_alert_dispose(GObject *gobject)
        /* 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);
                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,
@@ -935,6 +975,7 @@ static void grits_plugin_alert_dispose(GObject *gobject)
                }
                for (GList *cur = alert->states; cur; cur = cur->next)
                        grits_viewer_remove(viewer, cur->data);
+               gtk_widget_destroy(alert->details);
                g_object_unref(alert->prefs);
                g_object_unref(viewer);
        }