[gnome-initial-setup] timezone: Adapt to new UI design



commit 5c25c3b38377400551f3d1040a1ccdeb8af26e9d
Author: Jasper St. Pierre <jstpierre mecheye net>
Date:   Tue Oct 22 14:10:03 2013 -0400

    timezone: Adapt to new UI design
    
    This isn't 100% complete yet. Still investigating issues with GeoClue,
    the pin is in the wrong location on the cc-timezone-map, and we still
    have to add the "Search" bubble overlay. Spinner may not be necessary
    as we would have found this at startup, I hope...

 gnome-initial-setup/pages/timezone/Makefile.am     |    1 -
 .../pages/timezone/cc-timezone-map.c               |  480 ++++----------------
 .../pages/timezone/cc-timezone-map.h               |    9 +-
 gnome-initial-setup/pages/timezone/data/cc.png     |  Bin 52271 -> 0 bytes
 gnome-initial-setup/pages/timezone/data/pin.png    |  Bin 561 -> 666 bytes
 .../pages/timezone/datetime.gresource.xml          |    1 -
 .../pages/timezone/gis-timezone-page.c             |  338 +++++++-------
 .../pages/timezone/gis-timezone-page.ui            |  173 ++++----
 gnome-initial-setup/pages/timezone/tz.c            |  482 --------------------
 gnome-initial-setup/pages/timezone/tz.h            |   89 ----
 10 files changed, 333 insertions(+), 1240 deletions(-)
---
diff --git a/gnome-initial-setup/pages/timezone/Makefile.am b/gnome-initial-setup/pages/timezone/Makefile.am
index 205c065..cdecac4 100644
--- a/gnome-initial-setup/pages/timezone/Makefile.am
+++ b/gnome-initial-setup/pages/timezone/Makefile.am
@@ -29,7 +29,6 @@ timezone-resources.h: timezone.gresource.xml $(resource_files_timezone)
 BUILT_SOURCES += timezone-resources.c timezone-resources.h
 
 libgistimezone_la_SOURCES =    \
-       tz.c tz.h \
        cc-timezone-map.c cc-timezone-map.h \
        gis-timezone-page.c gis-timezone-page.h \
        $(BUILT_SOURCES)
diff --git a/gnome-initial-setup/pages/timezone/cc-timezone-map.c 
b/gnome-initial-setup/pages/timezone/cc-timezone-map.c
index 3e127b0..782940b 100644
--- a/gnome-initial-setup/pages/timezone/cc-timezone-map.c
+++ b/gnome-initial-setup/pages/timezone/cc-timezone-map.c
@@ -25,7 +25,6 @@
 #include "cc-timezone-map.h"
 #include <math.h>
 #include <string.h>
-#include "tz.h"
 
 G_DEFINE_TYPE (CcTimezoneMap, cc_timezone_map, GTK_TYPE_WIDGET)
 
@@ -33,90 +32,20 @@ G_DEFINE_TYPE (CcTimezoneMap, cc_timezone_map, GTK_TYPE_WIDGET)
   (G_TYPE_INSTANCE_GET_PRIVATE ((o), CC_TYPE_TIMEZONE_MAP, CcTimezoneMapPrivate))
 
 #define PIN_HOT_POINT_X 8
-#define PIN_HOT_POINT_Y 14
+#define PIN_HOT_POINT_Y 15
 
 #define DATETIME_RESOURCE_PATH "/org/gnome/control-center/datetime"
 
-typedef struct
-{
-  gdouble offset;
-  guchar red;
-  guchar green;
-  guchar blue;
-  guchar alpha;
-} CcTimezoneMapOffset;
-
 struct _CcTimezoneMapPrivate
 {
   GdkPixbuf *orig_background;
   GdkPixbuf *orig_background_dim;
-  GdkPixbuf *orig_color_map;
 
   GdkPixbuf *background;
-  GdkPixbuf *color_map;
-
-  guchar *visible_map_pixels;
-  gint visible_map_rowstride;
-
-  gdouble selected_offset;
-
-  TzDB *tzdb;
-  TzLocation *location;
-};
-
-enum
-{
-  LOCATION_CHANGED,
-  LAST_SIGNAL
-};
-
-static guint signals[LAST_SIGNAL];
-
 
-static CcTimezoneMapOffset color_codes[] =
-{
-    {-11.0, 43, 0, 0, 255 },
-    {-10.0, 85, 0, 0, 255 },
-    {-9.5, 102, 255, 0, 255 },
-    {-9.0, 128, 0, 0, 255 },
-    {-8.0, 170, 0, 0, 255 },
-    {-7.0, 212, 0, 0, 255 },
-    {-6.0, 255, 0, 1, 255 }, // north
-    {-6.0, 255, 0, 0, 255 }, // south
-    {-5.0, 255, 42, 42, 255 },
-    {-4.5, 192, 255, 0, 255 },
-    {-4.0, 255, 85, 85, 255 },
-    {-3.5, 0, 255, 0, 255 },
-    {-3.0, 255, 128, 128, 255 },
-    {-2.0, 255, 170, 170, 255 },
-    {-1.0, 255, 213, 213, 255 },
-    {0.0, 43, 17, 0, 255 },
-    {1.0, 85, 34, 0, 255 },
-    {2.0, 128, 51, 0, 255 },
-    {3.0, 170, 68, 0, 255 },
-    {3.5, 0, 255, 102, 255 },
-    {4.0, 212, 85, 0, 255 },
-    {4.5, 0, 204, 255, 255 },
-    {5.0, 255, 102, 0, 255 },
-    {5.5, 0, 102, 255, 255 },
-    {5.75, 0, 238, 207, 247 },
-    {6.0, 255, 127, 42, 255 },
-    {6.5, 204, 0, 254, 254 },
-    {7.0, 255, 153, 85, 255 },
-    {8.0, 255, 179, 128, 255 },
-    {9.0, 255, 204, 170, 255 },
-    {9.5, 170, 0, 68, 250 },
-    {10.0, 255, 230, 213, 255 },
-    {10.5, 212, 124, 21, 250 },
-    {11.0, 212, 170, 0, 255 },
-    {11.5, 249, 25, 87, 253 },
-    {12.0, 255, 204, 0, 255 },
-    {12.75, 254, 74, 100, 248 },
-    {13.0, 255, 85, 153, 250 },
-    {-100, 0, 0, 0, 0 }
+  GWeatherLocation *location;
 };
 
-
 static void
 cc_timezone_map_get_property (GObject    *object,
                               guint       property_id,
@@ -151,45 +80,15 @@ cc_timezone_map_dispose (GObject *object)
   g_clear_object (&priv->orig_background);
   g_clear_object (&priv->orig_background_dim);
 
-  if (priv->orig_color_map)
-    {
-      g_object_unref (priv->orig_color_map);
-      priv->orig_color_map = NULL;
-    }
-
   if (priv->background)
     {
       g_object_unref (priv->background);
       priv->background = NULL;
     }
 
-  if (priv->color_map)
-    {
-      g_object_unref (priv->color_map);
-      priv->color_map = NULL;
-
-      priv->visible_map_pixels = NULL;
-      priv->visible_map_rowstride = 0;
-    }
-
   G_OBJECT_CLASS (cc_timezone_map_parent_class)->dispose (object);
 }
 
-static void
-cc_timezone_map_finalize (GObject *object)
-{
-  CcTimezoneMapPrivate *priv = CC_TIMEZONE_MAP (object)->priv;
-
-  if (priv->tzdb)
-    {
-      tz_db_free (priv->tzdb);
-      priv->tzdb = NULL;
-    }
-
-
-  G_OBJECT_CLASS (cc_timezone_map_parent_class)->finalize (object);
-}
-
 /* GtkWidget functions */
 static void
 cc_timezone_map_get_preferred_width (GtkWidget *widget,
@@ -243,51 +142,11 @@ cc_timezone_map_size_allocate (GtkWidget     *widget,
                                               allocation->height,
                                               GDK_INTERP_BILINEAR);
 
-  if (priv->color_map)
-    g_object_unref (priv->color_map);
-
-  priv->color_map = gdk_pixbuf_scale_simple (priv->orig_color_map,
-                                             allocation->width,
-                                             allocation->height,
-                                             GDK_INTERP_BILINEAR);
-
-  priv->visible_map_pixels = gdk_pixbuf_get_pixels (priv->color_map);
-  priv->visible_map_rowstride = gdk_pixbuf_get_rowstride (priv->color_map);
-
-  GTK_WIDGET_CLASS (cc_timezone_map_parent_class)->size_allocate (widget,
-                                                                  allocation);
+  GTK_WIDGET_CLASS (cc_timezone_map_parent_class)->size_allocate (widget, allocation); 
 }
 
-static void
-cc_timezone_map_realize (GtkWidget *widget)
-{
-  GdkWindowAttr attr = { 0, };
-  GtkAllocation allocation;
-  GdkWindow *window;
-
-  gtk_widget_get_allocation (widget, &allocation);
-
-  gtk_widget_set_realized (widget, TRUE);
-
-  attr.window_type = GDK_WINDOW_CHILD;
-  attr.wclass = GDK_INPUT_OUTPUT;
-  attr.width = allocation.width;
-  attr.height = allocation.height;
-  attr.x = allocation.x;
-  attr.y = allocation.y;
-  attr.event_mask = gtk_widget_get_events (widget)
-                                 | GDK_EXPOSURE_MASK | GDK_BUTTON_PRESS_MASK;
-
-  window = gdk_window_new (gtk_widget_get_parent_window (widget), &attr,
-                           GDK_WA_X | GDK_WA_Y);
-
-  gdk_window_set_user_data (window, widget);
-  gtk_widget_set_window (widget, window);
-}
-
-
 static gdouble
-convert_longtitude_to_x (gdouble longitude, gint map_width)
+convert_longitude_to_x (gdouble longitude, gint map_width)
 {
   const gdouble xdeg_offset = -6;
   gdouble x;
@@ -322,123 +181,104 @@ convert_latitude_to_y (gdouble latitude, gdouble map_height)
   return y;
 }
 
-
-static gboolean
-cc_timezone_map_draw (GtkWidget *widget,
-                      cairo_t   *cr)
+static void
+draw_hilight (CcTimezoneMap *map,
+              cairo_t       *cr)
 {
-  CcTimezoneMapPrivate *priv = CC_TIMEZONE_MAP (widget)->priv;
-  GdkPixbuf *hilight, *orig_hilight, *pin;
+  GtkWidget *widget = GTK_WIDGET (map);
+  CcTimezoneMapPrivate *priv = map->priv;
+  const char *fmt;
+  GWeatherTimezone *zone;
+  double selected_offset;
+  GdkPixbuf *hilight, *orig_hilight;
   GtkAllocation alloc;
-  gchar *file;
+  char *file;
   GError *err = NULL;
-  gdouble pointx, pointy;
-  char buf[16];
-  const char *fmt;
 
-  gtk_widget_get_allocation (widget, &alloc);
+  if (!priv->location)
+    return;
 
-  /* paint background */
-  gdk_cairo_set_source_pixbuf (cr, priv->background, 0, 0);
-  cairo_paint (cr);
+  gtk_widget_get_allocation (widget, &alloc);
 
   /* paint hilight */
   if (gtk_widget_is_sensitive (widget))
-    fmt = DATETIME_RESOURCE_PATH "/timezone_%s.png";
+    fmt = DATETIME_RESOURCE_PATH "/timezone_%g.png";
   else
-    fmt = DATETIME_RESOURCE_PATH "/timezone_%s_dim.png";
+    fmt = DATETIME_RESOURCE_PATH "/timezone_%g_dim.png";
 
-  file = g_strdup_printf (fmt,
-                          g_ascii_formatd (buf, sizeof (buf),
-                                           "%g", priv->selected_offset));
+  zone = gweather_location_get_timezone (priv->location);
+
+  /* XXX: Do we need to do anything for DST? I don't think so... */
+  selected_offset = gweather_timezone_get_offset (zone) / 60.0;
+
+  file = g_strdup_printf (fmt, selected_offset);
   orig_hilight = gdk_pixbuf_new_from_resource (file, &err);
   g_free (file);
   file = NULL;
 
-  if (!orig_hilight)
-    {
-      g_warning ("Could not load hilight: %s",
-                 (err) ? err->message : "Unknown Error");
-      if (err)
-        g_clear_error (&err);
-    }
-  else
-    {
-
-      hilight = gdk_pixbuf_scale_simple (orig_hilight, alloc.width,
-                                         alloc.height, GDK_INTERP_BILINEAR);
-      gdk_cairo_set_source_pixbuf (cr, hilight, 0, 0);
-
-      cairo_paint (cr);
-      g_object_unref (hilight);
-      g_object_unref (orig_hilight);
-    }
+  hilight = gdk_pixbuf_scale_simple (orig_hilight, alloc.width, alloc.height, GDK_INTERP_BILINEAR);
+  gdk_cairo_set_source_pixbuf (cr, hilight, 0, 0);
 
-  /* load pin icon */
-  pin = gdk_pixbuf_new_from_resource (DATETIME_RESOURCE_PATH "/pin.png", &err);
+  cairo_paint (cr);
+  g_object_unref (hilight);
+  g_object_unref (orig_hilight);
 
-  if (err)
-    {
-      g_warning ("Could not load pin icon: %s", err->message);
-      g_clear_error (&err);
-    }
+  g_clear_error (&err);
+}
 
-  if (priv->location)
-    {
-      pointx = convert_longtitude_to_x (priv->location->longitude, alloc.width);
-      pointy = convert_latitude_to_y (priv->location->latitude, alloc.height);
+static void
+draw_pin (CcTimezoneMap *map,
+          cairo_t       *cr)
+{
+  GtkWidget *widget = GTK_WIDGET (map);
+  CcTimezoneMapPrivate *priv = map->priv;
+  GdkPixbuf *pin;
+  GtkAllocation alloc;
+  GError *err = NULL;
+  double longitude, latitude;
+  double pointx, pointy;
 
-      if (pointy > alloc.height)
-        pointy = alloc.height;
+  gtk_widget_get_allocation (widget, &alloc);
 
-      if (pin)
-        {
-          gdk_cairo_set_source_pixbuf (cr, pin, pointx - PIN_HOT_POINT_X, pointy - PIN_HOT_POINT_Y);
-          cairo_paint (cr);
-        }
-    }
+  if (!priv->location)
+    return;
 
-  if (pin)
-    {
-      g_object_unref (pin);
-    }
+  if (!gweather_location_has_coords (priv->location))
+    return;
 
-  return TRUE;
-}
+  /* load pin icon */
+  pin = gdk_pixbuf_new_from_resource (DATETIME_RESOURCE_PATH "/pin.png", &err);
 
-static void
-update_cursor (GtkWidget *widget)
-{
-  GdkWindow *window;
-  GdkCursor *cursor = NULL;
+  gweather_location_get_coords (priv->location, &longitude, &latitude);
 
-  if (!gtk_widget_get_realized (widget))
-    return;
+  pointx = convert_longitude_to_x (longitude, alloc.width);
+  pointy = convert_latitude_to_y (latitude, alloc.height);
 
-  if (gtk_widget_is_sensitive (widget))
-    {
-      GdkDisplay *display;
-      display = gtk_widget_get_display (widget);
-      cursor = gdk_cursor_new_for_display (display, GDK_HAND2);
-    }
+  if (pointy > alloc.height)
+    pointy = alloc.height;
 
-  window = gtk_widget_get_window (widget);
-  gdk_window_set_cursor (window, cursor);
+  gdk_cairo_set_source_pixbuf (cr, pin, pointx - PIN_HOT_POINT_X, pointy - PIN_HOT_POINT_Y);
+  cairo_paint (cr);
 
-  if (cursor)
-    g_object_unref (cursor);
+  g_object_unref (pin);
 }
 
-static void
-cc_timezone_map_state_flags_changed (GtkWidget     *widget,
-                                     GtkStateFlags  prev_state)
+static gboolean
+cc_timezone_map_draw (GtkWidget *widget,
+                      cairo_t   *cr)
 {
-  update_cursor (widget);
+  CcTimezoneMap *map = CC_TIMEZONE_MAP (widget);
+  CcTimezoneMapPrivate *priv = map->priv;
 
-  if (GTK_WIDGET_CLASS (cc_timezone_map_parent_class)->state_flags_changed)
-    GTK_WIDGET_CLASS (cc_timezone_map_parent_class)->state_flags_changed (widget, prev_state);
-}
+  /* paint background */
+  gdk_cairo_set_source_pixbuf (cr, priv->background, 0, 0);
+  cairo_paint (cr);
+
+  draw_hilight (map, cr);
+  draw_pin (map, cr);
 
+  return TRUE;
+}
 
 static void
 cc_timezone_map_class_init (CcTimezoneMapClass *klass)
@@ -451,130 +291,11 @@ cc_timezone_map_class_init (CcTimezoneMapClass *klass)
   object_class->get_property = cc_timezone_map_get_property;
   object_class->set_property = cc_timezone_map_set_property;
   object_class->dispose = cc_timezone_map_dispose;
-  object_class->finalize = cc_timezone_map_finalize;
 
   widget_class->get_preferred_width = cc_timezone_map_get_preferred_width;
   widget_class->get_preferred_height = cc_timezone_map_get_preferred_height;
   widget_class->size_allocate = cc_timezone_map_size_allocate;
-  widget_class->realize = cc_timezone_map_realize;
   widget_class->draw = cc_timezone_map_draw;
-  widget_class->state_flags_changed = cc_timezone_map_state_flags_changed;
-
-  signals[LOCATION_CHANGED] = g_signal_new ("location-changed",
-                                            CC_TYPE_TIMEZONE_MAP,
-                                            G_SIGNAL_RUN_FIRST,
-                                            0,
-                                            NULL,
-                                            NULL,
-                                            g_cclosure_marshal_VOID__POINTER,
-                                            G_TYPE_NONE, 1,
-                                            G_TYPE_POINTER);
-}
-
-
-static gint
-sort_locations (TzLocation *a,
-                TzLocation *b)
-{
-  if (a->dist > b->dist)
-    return 1;
-
-  if (a->dist < b->dist)
-    return -1;
-
-  return 0;
-}
-
-static void
-set_location (CcTimezoneMap *map,
-              TzLocation    *location)
-{
-  CcTimezoneMapPrivate *priv = map->priv;
-  TzInfo *info;
-
-  priv->location = location;
-
-  info = tz_info_from_location (priv->location);
-
-  priv->selected_offset = tz_location_get_utc_offset (priv->location)
-    / (60.0*60.0) + ((info->daylight) ? -1.0 : 0.0);
-
-  g_signal_emit (map, signals[LOCATION_CHANGED], 0, priv->location);
-
-  tz_info_free (info);
-}
-
-static gboolean
-button_press_event (GtkWidget      *widget,
-                    GdkEventButton *event)
-{
-  CcTimezoneMapPrivate *priv = CC_TIMEZONE_MAP (widget)->priv;
-  gint x, y;
-  guchar r, g, b, a;
-  guchar *pixels;
-  gint rowstride;
-  gint i;
-
-  const GPtrArray *array;
-  gint width, height;
-  GList *distances = NULL;
-  GtkAllocation alloc;
-
-  x = event->x;
-  y = event->y;
-
-
-  rowstride = priv->visible_map_rowstride;
-  pixels = priv->visible_map_pixels;
-
-  r = pixels[(rowstride * y + x * 4)];
-  g = pixels[(rowstride * y + x * 4) + 1];
-  b = pixels[(rowstride * y + x * 4) + 2];
-  a = pixels[(rowstride * y + x * 4) + 3];
-
-
-  for (i = 0; color_codes[i].offset != -100; i++)
-    {
-       if (color_codes[i].red == r && color_codes[i].green == g
-           && color_codes[i].blue == b && color_codes[i].alpha == a)
-         {
-           priv->selected_offset = color_codes[i].offset;
-         }
-    }
-
-  gtk_widget_queue_draw (widget);
-
-  /* work out the co-ordinates */
-
-  array = tz_get_locations (priv->tzdb);
-
-  gtk_widget_get_allocation (widget, &alloc);
-  width = alloc.width;
-  height = alloc.height;
-
-  for (i = 0; i < array->len; i++)
-    {
-      gdouble pointx, pointy, dx, dy;
-      TzLocation *loc = array->pdata[i];
-
-      pointx = convert_longtitude_to_x (loc->longitude, width);
-      pointy = convert_latitude_to_y (loc->latitude, height);
-
-      dx = pointx - x;
-      dy = pointy - y;
-
-      loc->dist = dx * dx + dy * dy;
-      distances = g_list_prepend (distances, loc);
-
-    }
-  distances = g_list_sort (distances, (GCompareFunc) sort_locations);
-
-
-  set_location (CC_TIMEZONE_MAP (widget), (TzLocation*) distances->data);
-
-  g_list_free (distances);
-
-  return TRUE;
 }
 
 static void
@@ -605,19 +326,7 @@ cc_timezone_map_init (CcTimezoneMap *self)
       g_clear_error (&err);
     }
 
-  priv->orig_color_map = gdk_pixbuf_new_from_resource (DATETIME_RESOURCE_PATH "/cc.png",
-                                                       &err);
-  if (!priv->orig_color_map)
-    {
-      g_warning ("Could not load background image: %s",
-                 (err) ? err->message : "Unknown error");
-      g_clear_error (&err);
-    }
-
-  priv->tzdb = tz_load_db ();
-
-  g_signal_connect (self, "button-press-event", G_CALLBACK (button_press_event),
-                    NULL);
+  gtk_widget_set_has_window (GTK_WIDGET (self), FALSE);
 }
 
 CcTimezoneMap *
@@ -626,42 +335,19 @@ cc_timezone_map_new (void)
   return g_object_new (CC_TYPE_TIMEZONE_MAP, NULL);
 }
 
-gboolean
-cc_timezone_map_set_timezone (CcTimezoneMap *map,
-                              const gchar   *timezone)
+void
+cc_timezone_map_set_location (CcTimezoneMap    *map,
+                              GWeatherLocation *location)
 {
-  GPtrArray *locations;
-  guint i;
-  char *real_tz;
-  gboolean ret;
-
-  real_tz = tz_info_get_clean_name (map->priv->tzdb, timezone);
-
-  locations = tz_get_locations (map->priv->tzdb);
-  ret = FALSE;
-
-  for (i = 0; i < locations->len; i++)
-    {
-      TzLocation *loc = locations->pdata[i];
-
-      if (!g_strcmp0 (loc->zone, real_tz ? real_tz : timezone))
-        {
-          set_location (map, loc);
-          ret = TRUE;
-          break;
-        }
-    }
-
-  if (ret)
-    gtk_widget_queue_draw (GTK_WIDGET (map));
+  CcTimezoneMapPrivate *priv = map->priv;
 
-  g_free (real_tz);
+  if (priv->location)
+    gweather_location_unref (priv->location);
 
-  return ret;
-}
+  if (location)
+    priv->location = gweather_location_ref (location);
+  else
+    priv->location = NULL;
 
-TzLocation *
-cc_timezone_map_get_location (CcTimezoneMap *map)
-{
-  return map->priv->location;
+  gtk_widget_queue_draw (GTK_WIDGET (map));
 }
diff --git a/gnome-initial-setup/pages/timezone/cc-timezone-map.h 
b/gnome-initial-setup/pages/timezone/cc-timezone-map.h
index bb15def..d2bf5ab 100644
--- a/gnome-initial-setup/pages/timezone/cc-timezone-map.h
+++ b/gnome-initial-setup/pages/timezone/cc-timezone-map.h
@@ -24,7 +24,9 @@
 #define _CC_TIMEZONE_MAP_H
 
 #include <gtk/gtk.h>
-#include "tz.h"
+
+#define GWEATHER_I_KNOW_THIS_IS_UNSTABLE
+#include <libgweather/gweather.h>
 
 G_BEGIN_DECLS
 
@@ -70,9 +72,8 @@ GType cc_timezone_map_get_type (void) G_GNUC_CONST;
 
 CcTimezoneMap *cc_timezone_map_new (void);
 
-gboolean cc_timezone_map_set_timezone (CcTimezoneMap *map,
-                                       const gchar   *timezone);
-TzLocation * cc_timezone_map_get_location (CcTimezoneMap *map);
+void cc_timezone_map_set_location (CcTimezoneMap    *map,
+                                   GWeatherLocation *location);
 
 G_END_DECLS
 
diff --git a/gnome-initial-setup/pages/timezone/data/pin.png b/gnome-initial-setup/pages/timezone/data/pin.png
index 599a751..40dd4ea 100644
Binary files a/gnome-initial-setup/pages/timezone/data/pin.png and 
b/gnome-initial-setup/pages/timezone/data/pin.png differ
diff --git a/gnome-initial-setup/pages/timezone/datetime.gresource.xml 
b/gnome-initial-setup/pages/timezone/datetime.gresource.xml
index 675a915..fa316ed 100644
--- a/gnome-initial-setup/pages/timezone/datetime.gresource.xml
+++ b/gnome-initial-setup/pages/timezone/datetime.gresource.xml
@@ -3,7 +3,6 @@
   <gresource prefix="/org/gnome/control-center/datetime">
     <file alias="bg.png">data/bg.png</file>
     <file alias="bg_dim.png">data/bg_dim.png</file>
-    <file alias="cc.png">data/cc.png</file>
     <file alias="pin.png">data/pin.png</file>
     <file alias="timezone_0.png">data/timezone_0.png</file>
     <file alias="timezone_0_dim.png">data/timezone_0_dim.png</file>
diff --git a/gnome-initial-setup/pages/timezone/gis-timezone-page.c 
b/gnome-initial-setup/pages/timezone/gis-timezone-page.c
index 7d0e6ee..be3d24b 100644
--- a/gnome-initial-setup/pages/timezone/gis-timezone-page.c
+++ b/gnome-initial-setup/pages/timezone/gis-timezone-page.c
@@ -37,7 +37,7 @@
 #include <string.h>
 
 #define GWEATHER_I_KNOW_THIS_IS_UNSTABLE
-#include <libgweather/location-entry.h>
+#include <libgweather/gweather.h>
 
 #include "cc-timezone-map.h"
 #include "timedated.h"
@@ -47,7 +47,8 @@
 struct _GisTimezonePagePrivate
 {
   CcTimezoneMap *map;
-  TzLocation *current_location;
+  GWeatherLocation *auto_location;
+  GWeatherLocation *current_location;
   Timedate1 *dtm;
 };
 typedef struct _GisTimezonePagePrivate GisTimezonePagePrivate;
@@ -78,199 +79,218 @@ set_timezone_cb (GObject      *source,
 
 
 static void
-queue_set_timezone (GisTimezonePage *page)
+queue_set_timezone (GisTimezonePage *page,
+                    const char      *tzid)
 {
   GisTimezonePagePrivate *priv = gis_timezone_page_get_instance_private (page);
 
   /* for now just do it */
-  if (priv->current_location) {
-    timedate1_call_set_timezone (priv->dtm,
-                                 priv->current_location->zone,
-                                 TRUE,
-                                 NULL,
-                                 set_timezone_cb,
-                                 page);
-  }
+  timedate1_call_set_timezone (priv->dtm,
+                               tzid,
+                               TRUE,
+                               NULL,
+                               set_timezone_cb,
+                               page);
 }
 
 static void
-update_timezone (GisTimezonePage *page)
+set_location (GisTimezonePage  *page,
+              GWeatherLocation *location)
 {
   GisTimezonePagePrivate *priv = gis_timezone_page_get_instance_private (page);
-  GString *str;
-  gchar *location;
-  gchar *timezone;
-  gchar *c;
-
-  str = g_string_new ("");
-  for (c = priv->current_location->zone; *c; c++) {
-    switch (*c) {
-    case '_':
-      g_string_append_c (str, ' ');
-      break;
-    case '/':
-      g_string_append (str, " / ");
-      break;
-    default:
-      g_string_append_c (str, *c);
-    }
-  }
 
-  c = strstr (str->str, " / ");
-  location = g_strdup (c + 3);
-  timezone = g_strdup (str->str);
+  if (priv->current_location)
+    gweather_location_unref (priv->current_location);
 
-  gtk_label_set_label (OBJ(GtkLabel*,"current-location-label"), location);
-  gtk_label_set_label (OBJ(GtkLabel*,"current-timezone-label"), timezone);
+  cc_timezone_map_set_location (priv->map, location);
 
-  g_free (location);
-  g_free (timezone);
+  if (location)
+    {
+      GWeatherTimezone *zone;
+      const char *tzid;
 
-  g_string_free (str, TRUE);
+      priv->current_location = gweather_location_ref (location);
+
+      zone = gweather_location_get_timezone (location);
+      tzid = gweather_timezone_get_tzid (zone);
+
+      queue_set_timezone (page, tzid);
+    }
 }
 
-static void
-location_changed_cb (CcTimezoneMap   *map,
-                     TzLocation      *location,
-                     GisTimezonePage *page)
+static char *
+get_location_name (GWeatherLocation *location)
 {
-  GisTimezonePagePrivate *priv = gis_timezone_page_get_instance_private (page);
+  GWeatherTimezone *zone = gweather_location_get_timezone (location);
 
-  g_debug ("location changed to %s/%s", location->country, location->zone);
+  /* XXX -- do something smarter eventually */
+  return g_strdup_printf ("%s (GMT%+g)",
+                          gweather_location_get_name (location),
+                          gweather_timezone_get_offset (zone) / 60.0);
+}
 
-  priv->current_location = location;
+static void
+set_auto_location (GisTimezonePage  *page,
+                   GWeatherLocation *location)
+{
+  GisTimezonePagePrivate *priv = gis_timezone_page_get_instance_private (page);
 
-  update_timezone (page);
+  if (priv->auto_location)
+    gweather_location_unref (priv->auto_location);
+
+  if (location)
+    {
+      char *tzname, *markup;
+      priv->auto_location = gweather_location_ref (location);
+
+      tzname = get_location_name (location);
+      markup = g_strdup_printf (_("We think that your timezone is <b>%s</b>. Press Next to continue"
+                                  " or search for a city to manually set the time zone."),
+                                tzname);
+      gtk_label_set_markup (GTK_LABEL (WID ("timezone-auto-result")), markup);
+      g_free (tzname);
+      g_free (markup);
+   }
+  else
+    {
+      priv->auto_location = NULL;
+
+      /* We have no automatic location; transition to search automatically */
+      gtk_widget_hide (WID ("timezone-search-button"));
+      gtk_widget_hide (WID ("timezone-auto-result"));
+    }
 
-  queue_set_timezone (page);
+  gtk_widget_show (WID ("timezone-stack"));
 }
 
 static void
-set_timezone_from_gweather_location (GisTimezonePage  *page,
-                                     GWeatherLocation *gloc)
+get_location_from_geoclue (GisTimezonePage *page)
 {
-  GisTimezonePagePrivate *priv = gis_timezone_page_get_instance_private (page);
-  GWeatherTimezone *zone = gweather_location_get_timezone (gloc);
-  gchar *city = gweather_location_get_city_name (gloc);
+  GDBusProxy *manager, *client, *location;
+  GVariant *value;
+  const char *object_path;
+  double latitude, longitude;
+  GWeatherLocation *glocation = NULL;
+
+  manager = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM,
+                                           G_DBUS_PROXY_FLAGS_NONE,
+                                           NULL,
+                                           "org.freedesktop.GeoClue2",
+                                           "/org/freedesktop/GeoClue2/Manager",
+                                           "org.freedesktop.GeoClue2.Manager",
+                                           NULL, NULL);
+  if (!manager)
+    goto out;
 
-  if (zone != NULL) {
-    const gchar *name;
-    const gchar *id;
-    GtkLabel *label;
+  value = g_dbus_proxy_call_sync (manager, "GetClient", NULL,
+                                  G_DBUS_CALL_FLAGS_NONE, -1,
+                                  NULL, NULL);
+  g_variant_get_child (value, 0, "&o", &object_path);
+
+  client = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM,
+                                          G_DBUS_PROXY_FLAGS_NONE,
+                                          NULL,
+                                          "org.freedesktop.GeoClue2",
+                                          object_path,
+                                          "org.freedesktop.GeoClue2.Client",
+                                          NULL, NULL);
+  g_variant_unref (value);
+
+  if (!client)
+    goto out;
 
-    label = OBJ(GtkLabel*, "current-timezone-label");
+  value = g_dbus_proxy_get_cached_property (client, "Location");
+  object_path = g_variant_get_string (value, NULL);
 
-    name = gweather_timezone_get_name (zone);
-    id = gweather_timezone_get_tzid (zone);
-    if (name == NULL) {
-      /* Why does this happen ? */
-      name = id;
-    }
-    gtk_label_set_label (label, name);
-    cc_timezone_map_set_timezone (priv->map, id);
-  }
+  location = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM,
+                                            G_DBUS_PROXY_FLAGS_NONE,
+                                            NULL,
+                                            "org.freedesktop.GeoClue2",
+                                            object_path,
+                                            "org.freedesktop.GeoClue2.Location",
+                                            NULL, NULL);
+  g_variant_unref (value);
 
-  if (city != NULL) {
-    GtkLabel *label;
+  if (!location)
+    goto out;
 
-    label = OBJ(GtkLabel*, "current-location-label");
-    gtk_label_set_label (label, city);
-  }
+  value = g_dbus_proxy_get_cached_property (location, "Latitude");
+
+  /* this happens under some circumstances, iunno why. needs zeenix */
+  if (!value)
+    goto out;
 
-  g_free (city);
+  latitude = g_variant_get_double (value);
+  g_variant_unref (value);
+  value = g_dbus_proxy_get_cached_property (location, "Longitude");
+  longitude = g_variant_get_double (value);
+  g_variant_unref (value);
+
+  glocation = gweather_location_find_nearest_city (latitude, longitude);
+
+ out:
+  set_auto_location (page, glocation);
+  set_location (page, glocation);
+  if (glocation)
+    gweather_location_unref (glocation);
+
+  if (manager)
+    g_object_unref (manager);
+  if (client)
+    g_object_unref (client);
+  if (location)
+    g_object_unref (location);
 }
 
 static void
-location_changed (GObject *object, GParamSpec *param, GisTimezonePage *page)
+entry_location_changed (GObject *object, GParamSpec *param, GisTimezonePage *page)
 {
   GWeatherLocationEntry *entry = GWEATHER_LOCATION_ENTRY (object);
-  GWeatherLocation *gloc;
+  GWeatherLocation *location;
 
-  gloc = gweather_location_entry_get_location (entry);
-  if (gloc == NULL)
+  location = gweather_location_entry_get_location (entry);
+  if (!location)
     return;
 
-  set_timezone_from_gweather_location (page, gloc);
-
-  gweather_location_unref (gloc);
+  set_location (page, location);
 }
 
-#define WANT_GEOCLUE 0
-
-#if WANT_GEOCLUE
 static void
-position_callback (GeocluePosition      *pos,
-                  GeocluePositionFields fields,
-                  int                   timestamp,
-                  double                latitude,
-                  double                longitude,
-                  double                altitude,
-                  GeoclueAccuracy      *accuracy,
-                  GError               *error,
-                  GisTimezonePage      *page)
+entry_mapped (GtkWidget *widget,
+              gpointer   user_data)
 {
-  if (error) {
-    g_printerr ("Error getting position: %s\n", error->message);
-    g_error_free (error);
-  } else {
-    if (fields & GEOCLUE_POSITION_FIELDS_LATITUDE &&
-        fields & GEOCLUE_POSITION_FIELDS_LONGITUDE) {
-      GWeatherLocation *city = gweather_location_find_nearest_city (latitude, longitude);
-      set_timezone_from_gweather_location (page, city);
-    } else {
-      g_print ("Position not available.\n");
-    }
-  }
+  gtk_widget_grab_focus (widget);
 }
 
 static void
-determine_timezone (GtkWidget       *widget,
-                    GisTimezonePage *page)
+visible_child_changed (GObject *object, GParamSpec *param, GisTimezonePage *page)
 {
-  GeoclueMaster *master;
-  GeoclueMasterClient *client;
-  GeocluePosition *position = NULL;
-  GError *error = NULL;
-
-  master = geoclue_master_get_default ();
-  client = geoclue_master_create_client (master, NULL, NULL);
-  g_object_unref (master);
-
-  if (!geoclue_master_client_set_requirements (client, 
-                                               GEOCLUE_ACCURACY_LEVEL_LOCALITY,
-                                               0, TRUE,
-                                               GEOCLUE_RESOURCE_ALL,
-                                               NULL)){
-    g_printerr ("Setting requirements failed");
-    goto out;
-  }
+  /* xxx -- text bubble */
+  /*
+  GtkWidget *child = gtk_stack_get_visible_child (GTK_STACK (WID ("timezone-stack")));
 
-  position = geoclue_master_client_create_position (client, &error);
-  if (position == NULL) {
-    g_warning ("Creating GeocluePosition failed: %s", error->message);
-    goto out;
+  if (child == WID ("timezone-search")) {
   }
+  */
+}
 
-  geoclue_position_get_position_async (position,
-                                       (GeocluePositionCallback) position_callback,
-                                       page);
+static void
+search_button_toggled (GtkToggleButton *button,
+                       GisTimezonePage *page)
+{
+  gboolean want_search = gtk_toggle_button_get_active (button);
 
- out:
-  g_clear_error (&error);
-  g_object_unref (client);
-  g_object_unref (position);
+  gtk_stack_set_visible_child_name (GTK_STACK (WID ("timezone-stack")),
+                                    want_search ? "search" : "status");
 }
-#endif
 
 static void
 gis_timezone_page_constructed (GObject *object)
 {
   GisTimezonePage *page = GIS_TIMEZONE_PAGE (object);
   GisTimezonePagePrivate *priv = gis_timezone_page_get_instance_private (page);
-  GtkWidget *frame, *map, *entry;
-  GWeatherLocation *world;
+  GtkWidget *frame, *map;
   GError *error;
-  const gchar *timezone;
 
   G_OBJECT_CLASS (gis_timezone_page_parent_class)->constructed (object);
 
@@ -300,44 +320,18 @@ gis_timezone_page_constructed (GObject *object)
 
   gtk_container_add (GTK_CONTAINER (frame), map);
 
-  world = gweather_location_new_world (TRUE);
-  entry = gweather_location_entry_new (world);
-  gtk_entry_set_placeholder_text (GTK_ENTRY (entry), _("Search for a location"));
-  gtk_widget_set_halign (entry, GTK_ALIGN_FILL);
-  gtk_widget_show (entry);
-
   frame = WID("timezone-page");
-#if WANT_GEOCLUE
-  gtk_grid_attach (GTK_GRID (frame), entry, 1, 1, 1, 1);
-#else
-  gtk_grid_attach (GTK_GRID (frame), entry, 0, 1, 2, 1);
-#endif
-
-  timezone = timedate1_get_timezone (priv->dtm);
-
-  if (!cc_timezone_map_set_timezone (priv->map, timezone)) {
-    g_warning ("Timezone '%s' is unhandled, setting %s as default", timezone, DEFAULT_TZ);
-    cc_timezone_map_set_timezone (priv->map, DEFAULT_TZ);
-  }
-  else {
-    g_debug ("System timezone is '%s'", timezone);
-  }
-
-  priv->current_location = cc_timezone_map_get_location (priv->map);
-  update_timezone (page);
-
-  g_signal_connect (G_OBJECT (entry), "notify::location",
-                    G_CALLBACK (location_changed), page);
 
-  g_signal_connect (map, "location-changed",
-                    G_CALLBACK (location_changed_cb), page);
+  get_location_from_geoclue (page);
 
-#if WANT_GEOCLUE
-  g_signal_connect (WID ("timezone-auto-button"), "clicked",
-                    G_CALLBACK (determine_timezone), page);
-#else
-  gtk_widget_hide (WID ("timezone-auto-button"));
-#endif
+  g_signal_connect (WID ("timezone-search"), "notify::location",
+                    G_CALLBACK (entry_location_changed), page);
+  g_signal_connect (WID ("timezone-search"), "map",
+                    G_CALLBACK (entry_mapped), page);
+  g_signal_connect (WID ("timezone-stack"), "notify::visible-child",
+                    G_CALLBACK (visible_child_changed), page);
+  g_signal_connect (WID ("timezone-search-button"), "toggled",
+                    G_CALLBACK (search_button_toggled), page);
 
   gis_page_set_complete (GIS_PAGE (page), TRUE);
 
diff --git a/gnome-initial-setup/pages/timezone/gis-timezone-page.ui 
b/gnome-initial-setup/pages/timezone/gis-timezone-page.ui
index 02fa5b6..c129205 100644
--- a/gnome-initial-setup/pages/timezone/gis-timezone-page.ui
+++ b/gnome-initial-setup/pages/timezone/gis-timezone-page.ui
@@ -1,125 +1,110 @@
-<?xml version="1.0"?>
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.16.0 on Tue Oct 22 19:34:41 2013 -->
 <interface>
-  <requires lib="gtk+" version="3.0"/>
-  <object class="GtkGrid" id="timezone-page">
-    <property name="name">timezone-page</property>
+  <!-- interface-requires gtk+ 3.0 -->
+  <object class="GtkBox" id="timezone-page">
     <property name="visible">True</property>
-    <property name="halign">center</property>
-    <property name="valign">start</property>
-    <property name="hexpand">True</property>
+    <property name="can_focus">False</property>
+    <property name="orientation">vertical</property>
     <child>
       <object class="GtkLabel" id="timezone-title">
         <property name="visible">True</property>
-        <property name="label" translatable="yes">Time Zone</property>
-        <property name="hexpand">False</property>
-        <property name="halign">start</property>
+        <property name="can_focus">False</property>
+        <property name="halign">center</property>
         <property name="valign">start</property>
-        <property name="margin-bottom">18</property>
+        <property name="margin_bottom">18</property>
+        <property name="label" translatable="yes">Time Zone</property>
         <attributes>
           <attribute name="weight" value="bold"/>
-          <attribute name="scale" value="1.2"/>
+          <attribute name="scale" value="1.6"/>
         </attributes>
       </object>
       <packing>
-        <property name="left_attach">0</property>
-        <property name="top_attach">0</property>
-        <property name="width">2</property>
-        <property name="height">1</property>
-      </packing>
-    </child>
-    <child>
-      <object class="GtkButton" id="timezone-auto-button">
-        <property name="visible">True</property>
-        <property name="label" translatable="yes">_Determine your timezone automatically</property>
-        <property name="use_underline">True</property>
-        <property name="halign">start</property>
-        <property name="margin-right">24</property>
-      </object>
-      <packing>
-        <property name="left_attach">0</property>
-        <property name="top_attach">1</property>
-        <property name="width">1</property>
-        <property name="height">1</property>
-      </packing>
-    </child>
-    <child>
-      <object class="GtkFrame" id="timezone-map-frame">
-        <property name="visible">True</property>
-        <property name="halign">fill</property>
-        <property name="valign">fill</property>
-        <property name="hexpand">True</property>
-        <property name="vexpand">True</property>
-        <property name="margin-top">6</property>
-        <property name="margin-bottom">6</property>
-      </object>
-      <packing>
-        <property name="left_attach">0</property>
-        <property name="top_attach">2</property>
-        <property name="width">2</property>
-        <property name="height">1</property>
+        <property name="expand">False</property>
+        <property name="fill">True</property>
+        <property name="position">0</property>
       </packing>
     </child>
     <child>
-      <object class="GtkGrid" id="timezone-info-grid">
+      <object class="GtkBox" id="timezone-status-box">
         <property name="visible">True</property>
-        <property name="halign">start</property>
-        <property name="valign">start</property>
-        <property name="row-spacing">6</property>
-        <property name="column-spacing">6</property>
-        <child>
-          <object class="GtkLabel" id="location-label">
-            <property name="visible">True</property>
-            <property name="label" translatable="yes">Location</property>
-            <property name="halign">end</property>
-            <style>
-              <class name="dim-label"/>
-            </style>
-          </object>
-          <packing>
-            <property name="left_attach">0</property>
-            <property name="top_attach">0</property>
-          </packing>
-        </child>
-        <child>
-          <object class="GtkLabel" id="current-location-label">
-            <property name="visible">True</property>
-            <property name="label">Boston, MA</property>
-            <property name="halign">start</property>
-          </object>
-          <packing>
-            <property name="left_attach">1</property>
-            <property name="top_attach">0</property>
-          </packing>
-        </child>
+        <property name="can_focus">False</property>
+        <property name="spacing">8</property>
         <child>
-          <object class="GtkLabel" id="timezone-label">
-            <property name="visible">True</property>
-            <property name="label" translatable="yes">Time Zone</property>
-            <property name="halign">end</property>
-            <style>
-              <class name="dim-label"/>
-            </style>
+          <object class="GtkStack" id="timezone-stack">
+            <property name="transition-type">crossfade</property>
+            <child>
+              <object class="GtkLabel" id="timezone-auto-result">
+                <property name="visible">True</property>
+                <property name="can_focus">False</property>
+                <property name="hexpand">True</property>
+                <property name="xalign">0</property>
+                <property name="wrap">True</property>
+              </object>
+              <packing>
+                <property name="name">status</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GWeatherLocationEntry" id="timezone-search">
+                <property name="visible">True</property>
+                <property name="hexpand">True</property>
+              </object>
+              <packing>
+                <property name="name">search</property>
+              </packing>
+            </child>
           </object>
           <packing>
-            <property name="left_attach">0</property>
-            <property name="top_attach">1</property>
+            <property name="expand">False</property>
+            <property name="fill">True</property>
+            <property name="position">0</property>
           </packing>
         </child>
         <child>
-          <object class="GtkLabel" id="current-timezone-label">
+          <object class="GtkToggleButton" id="timezone-search-button">
+            <property name="width_request">32</property>
+            <property name="height_request">32</property>
             <property name="visible">True</property>
-            <property name="label">America / New York</property>
-            <property name="halign">start</property>
+            <property name="can_focus">True</property>
+            <property name="receives_default">True</property>
+            <child>
+              <object class="GtkImage" id="image1">
+                <property name="visible">True</property>
+                <property name="can_focus">False</property>
+                <property name="pixel_size">16</property>
+                <property name="icon_name">edit-find-symbolic</property>
+                <property name="icon_size">0</property>
+              </object>
+            </child>
           </object>
           <packing>
-            <property name="left_attach">1</property>
-            <property name="top_attach">1</property>
+            <property name="expand">False</property>
+            <property name="fill">True</property>
+            <property name="position">1</property>
           </packing>
         </child>
       </object>
       <packing>
-        <property name="left_attach">0</property>
-        <property name="top_attach">3</property>
+        <property name="expand">False</property>
+        <property name="fill">True</property>
+        <property name="position">1</property>
+      </packing>
+    </child>
+    <child>
+      <object class="GtkFrame" id="timezone-map-frame">
+        <property name="visible">True</property>
+        <property name="can_focus">False</property>
+        <property name="margin_top">6</property>
+        <property name="margin_bottom">6</property>
+        <property name="hexpand">True</property>
+        <property name="vexpand">True</property>
+        <property name="label_xalign">0</property>
+      </object>
+      <packing>
+        <property name="expand">False</property>
+        <property name="fill">True</property>
+        <property name="position">2</property>
       </packing>
     </child>
   </object>



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]