basic picker; basic lat/long (broken)
[belltower] / belltower.c
index fc24d60..9649b04 100644 (file)
@@ -8,6 +8,7 @@
 
 #include <stdio.h>
 #include <stdlib.h>
+#include <string.h>
 #include <glib.h>
 #include <hildon/hildon.h>
 #include <gtk/gtk.h>
 
 #define MAX_FIELDS 50
 
-#define EM_DASH "\xE2\x80\x94"
-
 GtkWidget *window;
 
+/*
+  FIXME:
+  We should really do this by looking at the header row of the table.
+  They might decide to put in new columns some day.
+*/
 typedef enum {
   FieldPrimaryKey,
   FieldNationalGrid,
@@ -69,6 +73,13 @@ typedef struct {
   int n_fields;
 } tower;
 
+/*
+ * we're going to pretend you're in Helsinki
+ * until I get the GPS working
+ */
+double current_lat = 60.161790;
+double current_long = 23.924902;
+
 static void
 show_message (char *message)
 {
@@ -80,6 +91,28 @@ show_message (char *message)
   gtk_widget_destroy (GTK_WIDGET (note));
 }
 
+static gchar*
+distance_to_tower (tower *details)
+{
+  char *endptr;
+  double tower_lat;
+  double tower_long;
+  double km_distance;
+  const double km_to_miles = 1.609344;
+
+  tower_lat = strtod(details->fields[FieldLat], &endptr);
+  if (*endptr) return g_strdup ("unknown");
+  tower_long = strtod(details->fields[FieldLong], &endptr);
+  if (*endptr) return g_strdup ("unknown");
+
+  km_distance = location_distance_between (current_lat,
+                                          current_long,
+                                          tower_lat,
+                                          tower_long);
+
+  return g_strdup_printf("%dmi", (int) (km_distance / km_to_miles));
+}
+
 static void
 call_dbus (DBusBusType type,
           char *name,
@@ -210,35 +243,50 @@ show_peals_list (void)
 }
 
 static gboolean
-get_areas_cb (tower *details,
-             gpointer data)
+get_countries_cb (tower *details,
+                 gpointer data)
 {
   GHashTable *hash = (GHashTable *)data;
 
-  /*
   if (details->serial==0)
     return TRUE; /* header row */
 
   if (!g_hash_table_lookup_extended (hash,
-                                   details->fields[FieldCounty],
+                                   details->fields[FieldCountry],
                                     NULL, NULL))
     {
-      char *display_format;
+      g_hash_table_insert (hash,
+                          g_strdup(details->fields[FieldCountry]),
+                          g_strdup (details->fields[FieldCountry]));
+    }
 
-      if (strcmp (details->fields[FieldCounty], "")==0)
-       {
-         display_format = g_strdup (details->fields[FieldCountry]);
-       }
-      else
-       {
-         display_format = g_strdup_printf ("%s " EM_DASH " %s",
-                                           details->fields[FieldCountry],
-                                           details->fields[FieldCounty]);
-       }
+  return TRUE;
+}
 
-      g_hash_table_insert (hash,
+typedef struct {
+  GHashTable *hash;
+  gchar *country_name;
+} country_cb_data;
+
+static gboolean
+get_counties_cb (tower *details,
+                gpointer data)
+{
+  country_cb_data *d = (country_cb_data *)data;
+
+  if (details->serial==0)
+    return TRUE; /* header row */
+
+  if (strcmp(details->fields[FieldCountry], d->country_name)!=0)
+    return TRUE; /* wrong country */
+
+  if (!g_hash_table_lookup_extended (d->hash,
+                                   details->fields[FieldCounty],
+                                    NULL, NULL))
+    {
+      g_hash_table_insert (d->hash,
                           g_strdup(details->fields[FieldCounty]),
-                          display_format);
+                          g_strdup (details->fields[FieldCounty]));
     }
 
   return TRUE;
@@ -253,6 +301,7 @@ single_tower_cb (tower *details,
   gchar *str;
   gint tenor_weight;
   gchar *primary_key = (gchar*) data;
+  gchar *miles;
 
   if (strcmp(details->fields[FieldPrimaryKey], primary_key)!=0)
     {
@@ -297,6 +346,9 @@ single_tower_cb (tower *details,
   buttons = gtk_vbox_new (TRUE, 0);
   menu = HILDON_APP_MENU (hildon_app_menu_new ());
 
+  miles = distance_to_tower(details);
+
+  add_table_field ("Distance", miles);
   add_table_field ("Postcode", details->fields[FieldPostcode]);
   add_table_field ("County", details->fields[FieldCounty]);
   add_table_field ("Country", details->fields[FieldCountry]);
@@ -304,6 +356,8 @@ single_tower_cb (tower *details,
   add_table_field ("Practice night", details->fields[FieldPracticeNight]);
   add_table_field ("Bells", details->fields[FieldBells]);
 
+  g_free (miles);
+
   tenor_weight = atoi (details->fields[FieldWt]);
   str = g_strdup_printf("%dcwt %dqr %dlb in %s",
                        tenor_weight/112,
@@ -401,6 +455,8 @@ parse_dove (ParseDoveCallback callback,
          fclose (dove);
          return;
        }
+
+      result.serial++;
     }
 
   fclose (dove);
@@ -438,93 +494,194 @@ show_tower (char *primary_key)
              primary_key);
 }
 
+static gint strcmp_f (gconstpointer a,
+                     gconstpointer b)
+{
+  return strcmp ((char*)a, (char*)b);
+}
+
 static void
 put_areas_into_list (gpointer key,
                     gpointer value,
                     gpointer data)
 {
-  GtkTreeIter iter;
-  GtkListStore *list_store = (GtkListStore*) data;
-  gtk_list_store_append (list_store, &iter);
-  gtk_list_store_set (list_store, &iter,
-                     0, value, 
-                     -1);
+  GSList **list = (GSList **)data;
+  *list = g_slist_insert_sorted (*list,
+                                value,
+                                strcmp_f);
 }
 
 static void
-towers_by_area (void)
+towers_by_subarea (gchar *area)
 {
-  GtkWidget *dialog = gtk_dialog_new ();
-  GtkWidget *vbox = GTK_DIALOG(dialog)->vbox;
-  GtkCellRenderer *renderer = gtk_cell_renderer_text_new ();
-  GtkWidget *treeview = hildon_gtk_tree_view_new (HILDON_UI_MODE_NORMAL);
-  GtkWidget *pan = hildon_pannable_area_new ();
-  GtkListStore *list_store = gtk_list_store_new(1, G_TYPE_STRING);
+  GtkWidget *dialog = hildon_picker_dialog_new (GTK_WINDOW (window));
+
+  GtkWidget *selector = hildon_touch_selector_new_text ();
+
+  GHashTable *hash = g_hash_table_new_full (g_str_hash,
+                                           g_str_equal,
+                                           g_free,
+                                           g_free);
+
+  GSList *list=NULL, *cursor;
+
+  gchar *title = g_strdup_printf ("Areas of %s", area);
+
+  country_cb_data d = { hash, area };
+
+  gtk_window_set_title (GTK_WINDOW (dialog), title);
+  g_free (title);
+
+  parse_dove (get_counties_cb,
+             &d);
 
+  g_hash_table_foreach (hash,
+                       put_areas_into_list,
+                       &list);
+
+  for (cursor=list; cursor; cursor=cursor->next)
+    {
+      hildon_touch_selector_append_text (HILDON_TOUCH_SELECTOR (selector),
+                                        cursor->data);
+    }
+
+  hildon_picker_dialog_set_selector (HILDON_PICKER_DIALOG (dialog),
+                                    HILDON_TOUCH_SELECTOR (selector));
+
+  gtk_widget_show_all (GTK_WIDGET (dialog));
+
+  if (gtk_dialog_run (GTK_DIALOG (dialog))==GTK_RESPONSE_OK)
+    {
+      show_message (hildon_touch_selector_get_current_text (HILDON_TOUCH_SELECTOR (selector)));
+    }
+  g_hash_table_unref (hash);
+  gtk_widget_destroy (GTK_WIDGET (dialog));
+}
+
+static void
+towers_by_area (void)
+{
+  GtkWidget *dialog = hildon_picker_dialog_new (GTK_WINDOW (window));
+  GtkWidget *selector = hildon_touch_selector_new_text ();
   GHashTable *hash = g_hash_table_new_full (g_str_hash,
                                            g_str_equal,
                                            g_free,
                                            g_free);
-  /*
-  g_free (hash);
-  */
+  GSList *list = NULL, *cursor;
+  gchar *result = NULL;
+
+  gtk_window_set_title (GTK_WINDOW (dialog), "Areas of the world");
 
-  parse_dove (get_areas_cb,
+  parse_dove (get_countries_cb,
              hash);
 
   g_hash_table_foreach (hash,
                        put_areas_into_list,
-                       list_store);      
+                       &list);
 
-  gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (list_store),
-                                       0,
-                                       GTK_SORT_ASCENDING);
+  for (cursor=list; cursor; cursor=cursor->next)
+    {
+      hildon_touch_selector_append_text (HILDON_TOUCH_SELECTOR (selector),
+                                        cursor->data);
+    }
 
-  g_object_set (GTK_OBJECT(renderer), "yalign", 0.5, NULL);
-  g_object_set (GTK_OBJECT(renderer), "xpad", 24, NULL);
+  hildon_picker_dialog_set_selector (HILDON_PICKER_DIALOG (dialog),
+                                    HILDON_TOUCH_SELECTOR (selector));
 
-  gtk_window_set_title (GTK_WINDOW (dialog), "Towers by area");
+  gtk_widget_show_all (GTK_WIDGET (dialog));
 
-  gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (treeview),
-                                              0, "",
-                                              renderer,
-                                              "text", 0,
-                                              NULL);
+  if (gtk_dialog_run (GTK_DIALOG (dialog))==GTK_RESPONSE_OK)
+    {
+      result = g_strdup (hildon_touch_selector_get_current_text (HILDON_TOUCH_SELECTOR (selector)));
+    }
+  g_hash_table_unref (hash);
+  gtk_widget_destroy (GTK_WIDGET (dialog));
 
-  gtk_tree_view_set_model (GTK_TREE_VIEW (treeview),
-                          GTK_TREE_MODEL (list_store));
-  g_object_unref (list_store);
+  if (result)
+    {
+      towers_by_subarea (result);
+      g_free (result);
+    }
+}
+
+static void
+show_towers_from_list (GSList *list)
+{
+  GtkWidget *dialog;
+  GtkWidget *selector;
+  gchar *result = NULL;
+  GSList *cursor;
+
+  if (!list)
+    {
+      hildon_banner_show_information(window,
+                                    NULL,
+                                    "No towers found.");
+      return;
+    }
+
+  if (!list->next)
+    {
+      /* don't bother showing the list */
+      hildon_banner_show_information(window,
+                                    NULL,
+                                    "One tower found.");
+      show_tower (list->data);
+      return;
+    }
+
+  dialog = hildon_picker_dialog_new (GTK_WINDOW (window));
+  selector = hildon_touch_selector_new_text ();
 
-  hildon_pannable_area_add_with_viewport (HILDON_PANNABLE_AREA (pan),
-                                         treeview);
+  for (cursor=list; cursor; cursor=cursor->next)
+    {
+      hildon_touch_selector_append_text (HILDON_TOUCH_SELECTOR (selector),
+                                        cursor->data);
+    }
 
-  gtk_widget_set_size_request (treeview, 480, 800);
-  hildon_pannable_area_set_size_request_policy (HILDON_PANNABLE_AREA (pan),
-                                               HILDON_SIZE_REQUEST_CHILDREN);
-  gtk_container_add(GTK_CONTAINER (vbox), pan);
+  hildon_picker_dialog_set_selector (HILDON_PICKER_DIALOG (dialog),
+                                    HILDON_TOUCH_SELECTOR (selector));
 
   gtk_widget_show_all (GTK_WIDGET (dialog));
 
-  gtk_dialog_run (GTK_DIALOG (dialog));
+  if (gtk_dialog_run (GTK_DIALOG (dialog))==GTK_RESPONSE_OK)
+    {
+      result = g_strdup (hildon_touch_selector_get_current_text (HILDON_TOUCH_SELECTOR (selector)));
+    }
+
   gtk_widget_destroy (GTK_WIDGET (dialog));
+
+  if (result)
+    {
+      show_tower (result);
+      g_free (result);
+    }
 }
 
 static void
 show_bookmarks (void)
 {
-  /* nothing */
+  GSList *test = NULL;
+  show_towers_from_list (test);
 }
 
 static void
 tower_search (void)
 {
-  /* nothing */
+  GSList *test = NULL;
+  test = g_slist_append (test, "NORTON  HE");
+
+  show_towers_from_list (test);
 }
 
 static void
 recent_towers (void)
 {
-  show_tower ("NORTON  HE");
+  GSList *test = NULL;
+  test = g_slist_append (test, "BARFORD");
+  test = g_slist_append (test, "BRAUGHING");
+
+  show_towers_from_list (test);
 }
 
 int