← Back to team overview

weather-indicator-team team mailing list archive

[Merge] lp:~jtasker/weather-indicator/cloudy into lp:weather-indicator/2.0

 

Joshua has proposed merging lp:~jtasker/weather-indicator/cloudy into lp:weather-indicator/2.0.

Requested reviews:
  Weather Indicator Team (weather-indicator-team)

For more details, see:
https://code.launchpad.net/~jtasker/weather-indicator/cloudy/+merge/164598

This fixes all the "SIGSEGV" bugs related to glib/dbus; (libdbus is not thread-safe - I re-wrote some of the threading code to deal with this)
I also updated it to use Gtk3 and GObject, instead of the now-deprecated PyGtk.
Finally, I added code to calculate humidex/wind chill, and added a related tab to the Preferences Dialog.

Note that this version requires pywapi 0.3.1, which is available here:
http://code.google.com/p/python-weather-api/downloads/detail?name=pywapi-0.3.1.tar.gz

deb packages for pywapi 0.3.1 are available here:
https://launchpad.net/~pywapi-devel

>From the changelog:
  * Ported to GTK3 and GObject from PyGTK
  * Rewrite threading code to avoid dbus-related crashes (LP: #743541)
  * Added "feels like" temperature (humidex/heat index/wind chill)
  * New "Conditions" tab in Preferences dialog to choose temperature
    formulas and toggle display of some condition information
  * Bumped version number to reflect massive changes

Note that it still sometimes gives LIBDBUSMENU-GLIB warnings to .xsession-errors, but they can be safely ignored - I have left it running for a week straight with no crashes.
-- 
https://code.launchpad.net/~jtasker/weather-indicator/cloudy/+merge/164598
Your team Weather Indicator Team is requested to review the proposed merge of lp:~jtasker/weather-indicator/cloudy into lp:weather-indicator/2.0.
=== modified file 'AUTHORS'
--- AUTHORS	2011-03-19 09:27:37 +0000
+++ AUTHORS	2013-05-18 18:24:25 +0000
@@ -1,3 +1,4 @@
 Copyright (C) 2010 Sebastian MacDonald Sebas310@xxxxxxxxx
 Copyright (C) 2010 Mehdi Rejraji mehd36@xxxxxxxxx
 Copyright (C) 2010 Vadim Rutkovsky roignac@xxxxxxxxx
+Copyright (C) 2013 Joshua Tasker jtasker@xxxxxxxxx

=== modified file 'bin/indicator-weather'
--- bin/indicator-weather	2012-07-30 04:02:24 +0000
+++ bin/indicator-weather	2013-05-18 18:24:25 +0000
@@ -4,6 +4,7 @@
 # Copyright (C) 2010 Sebastian MacDonald Sebas310@xxxxxxxxx
 # Copyright (C) 2010 Mehdi Rejraji mehd36@xxxxxxxxx
 # Copyright (C) 2011 Vadim Rutkovsky roignac@xxxxxxxxx
+# Copyright (C) 2013 Joshua Tasker jtasker@xxxxxxxxx
 # This program is free software: you can redistribute it and/or modify it
 # under the terms of the GNU General Public License version 3, as published
 # by the Free Software Foundation.
@@ -17,29 +18,26 @@
 # with this program.  If not, see <http://www.gnu.org/licenses/>.
 ### END LICENSE
 
-try:
-    from gi.repository import Gio
-except ImportError:
-    pass
+from gi.repository import Gio, GLib, Gtk, Gdk, Notify, GObject, GdkPixbuf
+from gi.repository import AppIndicator3 as AppIndicator
+
 import sys, os, shutil, tempfile
-import gtk, pygtk, gobject, pynotify
-pygtk.require('2.0')
-import appindicator
+
 import urllib2, urllib
 from urllib import urlencode
 import re
 import locale
 from xml.dom.minidom import parseString
 import datetime
-import dbus
+#import dbus
 import time
 import traceback
 import types
-# Will be used for humidex
-#import math
+from math import exp
 import commands, threading
 import logging, logging.handlers
 import pywapi
+import Queue
 
 import gettext
 from gettext import gettext as _
@@ -55,7 +53,7 @@
     sys.path.insert(0, PROJECT_ROOT_DIRECTORY)
     os.putenv('PYTHONPATH', PROJECT_ROOT_DIRECTORY) # for subprocesses
 
-VERSION = "12.07.30 'Cloudy 10'"
+VERSION = "13.05.17 'Cloudy 11'"
 
 from indicator_weather.helpers import *
 
@@ -69,11 +67,16 @@
     WEATHER_KEY          = 'weather'
     LOCATIONS_KEY        = 'locations'
     INDICATOR_DISPLAY    = 'show_label'
+    RELATIVE_DISPLAY     = 'show_relative'
+    WIND_DISPLAY         = 'show_wind'
+    SUNTIMES_DISPLAY     = 'show_suntimes'
     NOTIFICATIONS        = 'notif'
     WEATHER_SOURCE       = 'data_source'
     REFRESH_RATE         = 'refresh_rate'
     METRIC_SYSTEM        = 'unit'
     WIND_UNIT            = 'wind'
+    HEAT_ESTIMATE        = 'heat'
+    CHILL_ESTIMATE       = 'chill'
     PLACECHOSEN          = 'placechosen'
     PLACES               = 'places'
 
@@ -84,47 +87,67 @@
         INDICATOR_DISPLAY : {
             INFO_TYPE : types.IntType,
             INFO_SETTING : 'indicator-display'
-        },
+            },
+        RELATIVE_DISPLAY : {
+            INFO_TYPE : types.BooleanType,
+            INFO_SETTING : 'relative-display'
+            },
+        WIND_DISPLAY : {
+            INFO_TYPE : types.BooleanType,
+            INFO_SETTING : 'wind-display'
+            },
+        SUNTIMES_DISPLAY : {
+            INFO_TYPE : types.BooleanType,
+            INFO_SETTING : 'suntimes-display'
+            },
         NOTIFICATIONS : {
             INFO_TYPE : types.StringType,
             INFO_SETTING : 'notifications'
-        },
+            },
         WEATHER_SOURCE : {
             INFO_TYPE : types.StringType,
             INFO_SETTING : 'weather-source'
-        },
+            },
         REFRESH_RATE : {
             INFO_TYPE : types.IntType,
             INFO_SETTING : 'refresh-rate'
-        },
+            },
         METRIC_SYSTEM : {
             INFO_TYPE : types.StringType,
             INFO_SETTING : 'metric-system'
-        },
+            },
         WIND_UNIT : {
             INFO_TYPE : types.StringType,
             INFO_SETTING : 'wind-unit'
-        },
+            },
+        HEAT_ESTIMATE: {
+            INFO_TYPE : types.StringType,
+            INFO_SETTING : 'heat-estimate'
+            },
+        CHILL_ESTIMATE: {
+            INFO_TYPE : types.StringType,
+            INFO_SETTING : 'chill-estimate'
+            },
         PLACECHOSEN : {
             INFO_TYPE : types.IntType,
             INFO_SETTING: 'placechosen'
-        },
+            },
         PLACES : {
             INFO_TYPE : types.ListType,
             INFO_SETTING: 'places'
-        },
+            },
     }
 
-    # Open the DB
     def prepare_settings_store(self):
+        """ Open the DB """
         log.debug("Settings: preparing settings store")
         try:
             self.db = Gio.Settings.new(self.BASE_KEY)
         except Exception as e:
             log.debug("Settings: exception occurred while opening settings:\n %s" % str(e))
 
-    # Make sure autostart file is installed. Inspired by GTG.
     def check_autostart(self):
+        """ Make sure autostart file is installed. Inspired by GTG. """
         autostart_dir = os.path.join(os.path.expanduser("~"),".config/autostart/")
         autostart_file = "indicator-weather.desktop"
         autostart_path = os.path.join(autostart_dir, autostart_file)
@@ -136,11 +159,11 @@
             this_directory = os.path.dirname(os.path.abspath(__file__))
             for path in desktop_file_directories:
                 fullpath = os.path.normpath(os.path.join(this_directory, path, \
-                                                        autostart_file))
+                                                         autostart_file))
                 if os.path.isfile(fullpath):
                     desktop_file_path = fullpath
                     break
-            #If we have found the desktop file, we make a link to in in
+            # If we have found the desktop file, we make a link to in in
             # autostart_path.
             if desktop_file_path:
                 if not os.path.exists(autostart_dir):
@@ -149,8 +172,8 @@
                     log.debug("Installing autostart file.")
                     os.symlink(desktop_file_path, autostart_path)
 
-    # Get a value of the setting
     def get_value(self, setting, return_id = False):
+        """ Get a value of the specified setting """
         log.debug("Settings: getting value for %s" % setting)
         setting_name = Settings.INFO[setting][INFO_SETTING]
         try:
@@ -162,15 +185,15 @@
                 types.ListType:    self.db.get_string,
                 types.DictType:    self.db.get_string,
                 types.NoneType:    self.db.get_value,
-            }[setting_type]
+                }[setting_type]
             return get_func(setting_name)
         except:
-            self.log.debug("Settings: can't find value for %s" % setting)
+            log.debug("Settings: can't find value for %s" % setting)
             return None
 
-    # Set a setting value
+    
     def set_value(self, setting, value):
-
+        """ Set a value for the specified setting """
         value = '' if value is None else value
         value = str(value) if type(value) is types.ListType else value
         log.debug("Settings: setting '%s'='%s'" % (setting, value))
@@ -185,17 +208,19 @@
                 types.ListType:    self.db.set_string,
                 types.DictType:    self.db.set_string,
                 types.NoneType:    self.db.set_value,
-            }[setting_type]
+                }[setting_type]
             set_func(setting_name, value)
         except:
             log.debug( \
                 "Settings: schema for '%s' not found, aborting" % setting)
 
-    # Get cached weather by location code.
-    # If return_id is True, only document id is returned, otherwise - full weather data
     def get_weather(self, location_code, return_id = False):
+        """Get cached weather by location code.
+        If return_id is True, only document id is returned, otherwise - full weather data
+        
+        """
         log.debug("Settings: getting cached weather for %s" % \
-            location_code)
+                  location_code)
         try:
             cached_weather_string = self.db.get_string(self.WEATHER_KEY)
             cached_weather = {} if cached_weather_string == ''\
@@ -207,22 +232,22 @@
                     "Settings: can't find value for %s" % location_code)
                 return None
         except:
-            log.debug("Settings: can't find %s setting" % WEATHER_KEY)
+            log.debug("Settings: can't find %s setting" % self.WEATHER_KEY)
             return None
 
-    # Save weather info in cache for specific location
     def save_weather(self, weather, location_code):
-
+        """ Save weather info in cache for specific location """
         record = {
-            "label"    : weather.get_temperature(needs_rounding=True),
-            "condition": weather.get_condition_label(),
-            "icon"     : weather.get_icon_name(),
-            "temper"   : weather.get_temperature_label(),
-            "humidex"  : weather.get_humidex_label(),
-            "humidity" : weather.get_humidity_label(),
-            "wind"     : weather.get_wind_label(),
-            "sunrise"  : weather.get_sunrise_label(),
-            "sunset"   : weather.get_sunset_label()
+##            "label"      : weather.get_temperature(needs_rounding=True),
+            "label"      : weather.get_temperature_string(),
+            "condition"  : weather.get_condition_label(),
+            "icon"       : weather.get_icon_name(),
+            "temper"     : weather.get_temperature_label(),
+            "feelslike"  : weather.get_relative_label(),
+            "humidity"   : weather.get_humidity_label(),
+            "wind"       : weather.get_wind_label(),
+            "sunrise"    : weather.get_sunrise_label(),
+            "sunset"     : weather.get_sunset_label()
         }
         log.debug("Settings: setting '%s'='%s'" % (location_code, record))
 
@@ -235,11 +260,14 @@
             self.db.set_string(self.WEATHER_KEY, cached_weather_string)
         except:
             log.debug(\
-                "Settings: schema for '%s' not found, aborting" % setting)
+                "Settings: schema for '%s' not found, aborting" % self.WEATHER_KEY)
 
-    # Get location details by location code
-    # If return_id is True, only document id is returned, otherwise - full location data
     def get_location_details(self, location_code, return_id = False):
+        """ Get location details by location code
+        If return_id is True, only document id is returned,
+        otherwise - full location data is returned
+        
+        """
         try:
             locations_string = self.db.get_string(self.LOCATIONS_KEY)
             locations = {} if locations_string == ''\
@@ -252,14 +280,13 @@
                 return None
         except:
             log.debug("Settings: can't find location details for %s" % \
-                location_code)
+                      location_code)
             return None
 
-    # Save location details
     def save_location_details(self, location_details, location_code):
+        """ Save location details """
         log.debug("Settings: setting '%s'='%s'" %\
-            (location_code, location_details))
-
+                  (location_code, location_details))
         try:
             locations_string = self.db.get_string(self.LOCATIONS_KEY)
             locations = {} if locations_string == ''\
@@ -270,8 +297,8 @@
         except:
             pass
 
-class MetricSystem:
-    """ Class with available metric systems units """
+class UnitSystem:
+    """ Class with available measurement unit systems """
     SI = 1
     IMPERIAL = 2
 
@@ -285,52 +312,65 @@
 
 class WeatherDataSource:
     """ Class for available weather data sources """
-    GOOGLE = 1
-    YAHOO = 2
+    YAHOO = 1
+    WEATHER_COM = 2
 
+class RelativeFormula:
+    """ Class for relative temperature formulas """
+    HEATINDEX = 1
+    HUMIDEX = 2
+    WINDCHILL = 3
+    APPARENT = 4
+    
 class Location:
     """ Data object to store location details """
 
-    # Initialize an object with a label
-    def __init__(self, metric_system, wind_unit, location_details = None):
+    def __init__(self, metric_system, wind_unit, heat_index, chill_index, location_details = None):
+        """ Initialize an object with a label """
         self.metric_system = metric_system
         self.wind_unit = wind_unit
+        self.heat_index = heat_index
+        self.chill_index = chill_index
         self.location_details = location_details
 
-    # Convert coordinate for google
     def convert_coordinate_for_google(self, value):
-       value = float(value) * 1e6
-       return int(round(value))
+        """ Convert coordinate for google """
+        value = float(value) * 1e6
+        return int(round(value))
 
-    # Get necessary location details by its GeoNames details
     def prepare_location(self, geonames_details):
+        """ Get necessary location details by its GeoNames details """
         self.location_details = {}
         self.location_details['full name'] = geonames_details[0]
         self.location_details['latitude'] = geonames_details[2]
         self.location_details['longitude'] = geonames_details[3]
         self.prepare_location_for_google(geonames_details)
         self.prepare_location_for_yahoo(geonames_details)
+        #TODO: Get weather.com id
+        #HACK, make a real routine to do this (pretty sure id is correct though)
+        self.location_details['weather-com id'] = self.location_details['yahoo id']
         #TODO: Get noaa id from geonames service
         self.location_details['noaa id'] = "woot"
 
         # check mandatory attributes
         if not hasattr(self, 'location_code') or \
-                'latitude' not in self.location_details or \
-                'longitude' not in self.location_details:
+           'latitude' not in self.location_details or \
+           'longitude' not in self.location_details:
             return False
 
         # check that we have at least one supported data source
         if 'google id' not in self.location_details and \
-                'yahoo id' not in self.location_details:
+           'yahoo id' not in self.location_details and \
+           'weather-com id' not in self.location_details:
             log.error(("Location '%s'" %
-                self.location_details['full name'])) + \
+                       self.location_details['full name'])) + \
                 "is not supported by current data sources"
             return False
 
         return True
 
     def prepare_location_for_google(self, geonames_details):
-        # Format latitude and longitude for Google needs
+        """ Format latitude and longitude for Google needs """
         try:
             lat = self.convert_coordinate_for_google(geonames_details[2])
             lon = self.convert_coordinate_for_google(geonames_details[3])
@@ -340,7 +380,7 @@
             log.error(e)
 
     def prepare_location_for_yahoo(self, geonames_details):
-        # Get location details in english for Yahoo
+        """ Get location details in english for Yahoo """
         baseurl = 'http://api.geonames.org/getJSON'
         params = {'geonameId': geonames_details[1], 'username': 'indicatorweather'}
         url = '?'.join((baseurl, urlencode(params)))
@@ -356,19 +396,13 @@
                 return
 
             # Get YAHOO WOEID by english name of location
-            baseurl = 'http://where.yahooapis.com/geocode'
-            params = {'location': displayed_city_name, 'appid': 'mOawLd4s', 'flags': 'J'}
-            url = '?'.join((baseurl, urlencode(params)))
-            log.debug("Location: Get Yahoo WOEID, url %s" % url)
-            f = urllib2.urlopen(url)
-            s=f.read()
-            null = None
-            yahoo_woeid_result = eval(s)
-            if (yahoo_woeid_result['ResultSet']['Error'] != 0) and  (yahoo_woeid_result['ResultSet']['Results'] != None):
-                log.error("Location: Yahoo woeid return error. Full response:\n %s" % str(yahoo_woeid_result))
+            woeid_result = pywapi.get_woeid_from_yahoo(displayed_city_name)            
+            if woeid_result.has_key('error'):
+                log.error("Location: Yahoo woeid return error. Full response:\n %s" % woeid_result['error'])
                 return
             else:
-                woeid = yahoo_woeid_result['ResultSet']['Results'][0]['woeid']
+                # only look at the the first woeid result
+                woeid = woeid_result[0][0]
                 self.location_code = woeid
                 log.debug("Location: woeid is %s" % woeid)
 
@@ -400,21 +434,24 @@
         except Exception, e:
             log.error(e)
 
-    # Return lcoation code and location details
     def export_location_details(self):
+        """ Return location code and location details """
         return (self.location_code, self.location_details)
 
-    # Get fresh weather data and store it to weather object
     def update_weather_data(self, source):
-        # gather existing source keys
+        """ Get fresh weather data and store it to weather object """
         valid_source = None
         loc_ids = {}
 
         SOURCES = {
-            WeatherDataSource.GOOGLE : ("google id", "Google"),
-            WeatherDataSource.YAHOO : ("yahoo id", "Yahoo"),
+            WeatherDataSource.WEATHER_COM : ("weather-com id", "Weather.com"),
+            WeatherDataSource.YAHOO : ("yahoo id", "Yahoo")
         }
 
+        log.debug("Location: update_weather_data: source=%s" % source)  #DEBUG
+        log.debug("SOURCES=%s" % SOURCES)       #DEBUG
+        log.debug("self.location_details=%s" % self.location_details)        #DEBUG
+        # gather existing source keys
         for source_id in SOURCES.keys():
             if SOURCES[source_id][0] in self.location_details:
                 loc_ids[source_id] = SOURCES[source_id][0]
@@ -423,158 +460,156 @@
         if source in loc_ids:
             valid_source = source
             log.debug(("Location: default weather source '%s' " +
-                "chosen for '%s'") % (SOURCES[valid_source][1],
-                self.location_details['label']))
+                       "chosen for '%s'") % (SOURCES[valid_source][1],
+                                             self.location_details['label']))
 
         # try with the first alternative
         elif len(loc_ids.keys()):
             valid_source = loc_ids.keys()[0]
-            log.debug(("Location: non default weather source '%s' " +
-                "chosen for '%s'") % (SOURCES[valid_source][1],
-                self.location_details['label']))
 
         if valid_source is None:
             log.error(("Location: no valid weather source can be " +
-                "chosen for '%s'") % (
-                self.location_details['label']))
+                       "chosen for '%s'") % (
+                           self.location_details['label']))
             self.weather = None
         else:
+            log.debug(("Location: non default weather source '%s' " +
+                       "chosen for '%s'") % (SOURCES[valid_source][1],
+                                             self.location_details['label']))
+            log.debug(("Location: update_weather_data: creating object: "
+                       "Weather(location_id=%s, weather_datasource=%s, "
+                       "metric_system=%s, wind_unit=%s, heat_index=%s, "
+                       "chill_index=%s, lat=%s, lon=%s)") % (
+                           self.location_details[loc_ids[valid_source]],
+                           valid_source, self.metric_system, self.wind_unit,
+                           self.heat_index, self.chill_index,
+                           self.location_details['latitude'],
+                           self.location_details['longitude']))    #DEBUG
             self.weather = Weather(
                 self.location_details[loc_ids[valid_source]],
                 valid_source, self.metric_system, self.wind_unit,
+                self.heat_index, self.chill_index,
                 self.location_details['latitude'],
                 self.location_details['longitude'])
+            log.debug("Location: update_weather_data: self.weather object created") #DEBUG
 
 class Forecast:
     """ Class to get forecast information """
 
-    # Initialize a class with metric system, wind units, location and current user locale
-    def __init__ (self, units, lat, lon, locale):
+    def __init__ (self, units, location_id, locale):
+        """Initialize a class with metric system, wind units,
+        location code and current user locale
+        
+        """
         self.metric_system = units
-        self.lat = self.convert_coordinate_for_google(lat)
-        self.lon = self.convert_coordinate_for_google(lon)
+        self.location_id = location_id
         self.locale = locale
 
-    # Convert coordinate for google
-    def convert_coordinate_for_google(self, value):
-       value = float(value) * 1e6
-       return int(round(value))
-
-    # Get and store forecast data. For now using Google only
     def prepare_forecast_data(self):
+        """ Get and store forecast data. For now using Yahoo only. """
+        # TODO: Implement Weather.com
         self.daysofweek = []
         self.icons = []
         self.conditions = []
         self.error_message = None
         try:
-            # Generate a fake location by current coordinates
-            location_name = ",,,%s,%s" % (self.lat, self.lon)
-            self.forecast = pywapi.get_weather_from_google (location_name, hl = self.locale)
-            self.unitsystem = self.forecast['forecast_information']['unit_system']
-
+            log.debug("Forecast: units set to %s" % self.metric_system)
+            # Check units, default to imperial
+            if self.metric_system == UnitSystem.SI:
+                self.unitsystem = 'metric'
+            elif self.metric_system == UnitSystem.IMPERIAL:
+                self.unitsystem = 'imperial'
+            else:
+                self.unitsystem = 'imperial'
+
+            log.debug("calling pywapi.get_weather_from_yahoo(%s, %s)" % (self.location_id, self.unitsystem))     #DEBUG
+            self.forecast = pywapi.get_weather_from_yahoo(self.location_id, self.unitsystem)
+
+            log.debug("get_weather_from_yahoo returned %s" % self.forecast)     #DEBUG
             for forecast in self.forecast['forecasts']:
-                self.daysofweek.append(forecast["day_of_week"])
-                forecast_icon = str(forecast["icon"])
-                if "/ig/images/weather/" in forecast_icon:
-                    self.icons.append(forecast_icon.split("/ig/images/weather/")[-1].split(".gif")[0])
-                elif "http://g0.gstatic.com/images/icons/onebox"; in forecast_icon:
-                    self.icons.append(forecast_icon.split("http://g0.gstatic.com/images/icons/onebox/weather_";)[-1].split("-40.gif")[0])
-                self.conditions.append(forecast["condition"])
+                self.daysofweek.append(forecast["day"])
+
+                # Yahoo forecast icon URL is "http://l.yimg.com/a/i/us/we/52/<code>.gif"
+                self.icons.append(forecast["code"])
+                self.conditions.append(forecast["text"])
+
             self.error_message = None
 
         except urllib2.URLError:
-            log.error("Forecast: error reading forecast for %s" % location_name)
+            log.error("Forecast: error reading forecast for %s" % self.location_id)
         except KeyError:
-            log.error("Forecast: returned empty forecast %s" % location_name)
+            log.error("Forecast: returned empty forecast %s" % self.location_id)
             self.error_message = _('Unknown error occurred while picking up weather data')
 
-    # Parse high values for forecast data
     def get_forecast_data(self):
+        """ Parse high and low values for forecast data """
         self.highdata = []
         self.lowdata = []
 
-        if not hasattr(self, 'unitsystem'):
-            return None
-
-        if ((self.unitsystem == 'SI') and (self.metric_system == MetricSystem.SI)) or ((self.unitsystem == 'US') and (self.metric_system == MetricSystem.IMPERIAL)):
-            #correct scale selected
-            for forecast in self.forecast['forecasts']:
-                self.highdata.append(forecast["high"])
-                self.lowdata.append(forecast["low"])
-
-        elif ((self.unitsystem == 'SI') and (self.metric_system == MetricSystem.IMPERIAL)):
-            #convert from SI to imperial
-            for forecast in self.forecast['forecasts']:
-                self.highdata.append(int(((int(forecast["high"])*9)/5)+32))
-                self.lowdata.append(int(((int(forecast["low"])*9)/5)+32))
-
-        elif ((self.unitsystem == 'US') and (self.metric_system == MetricSystem.SI)):
-            #convert from imperial to SI
-            for forecast in self.forecast['forecasts']:
-                self.highdata.append(int((((int(forecast["high"]))-32)*5)/9))
-                self.lowdata.append(int((((int(forecast["low"]))-32)*5)/9))
+        # Since we are now using Yahoo, forecast will always be in correct units
+        for forecast in self.forecast['forecasts']:
+            self.highdata.append(forecast["high"])
+            self.lowdata.append(forecast["low"])
 
         return (self.highdata, self.lowdata)
 
-    # Parse a list of days of week with forecast data
     def get_forecast_daysofweek(self):
+        """ Parse a list of days of week with forecast data """
         return self.daysofweek
 
-    # Parse icons for forecast data
     def get_forecast_icons(self):
+        """ Parse icons for forecast data """
         return self.icons
 
-    # Parse conditions for forecast data
     def get_forecast_conditions(self):
+        """ Parse conditions for forecast data """
         return self.conditions
 
 class Weather:
-    """
-    Data object to parse weather data with unit convertion
-    """
-
-    #Available conditions by google icon
-    #Format: Google icon name: (day icon, night icon, is a severe weather condition)
-    #Reference: http://www.blindmotion.com/2009/03/google-weather-api-images/
-    _GoogleConditions = {
-        "sunny"            : ( "weather-clear",      "weather-clear-night",      False),
-        "mostly_sunny"     : ( "weather-clear",      "weather-clear-night",      False),
-        "partlycloudy"     : ( "weather-few-clouds", "weather-few-clouds-night", False),
-        "partly_cloudy"    : ( "weather-few-clouds", "weather-few-clouds-night", False),
-        "windy"            : ( "weather-few-clouds", "weather-few-clouds-night", False),
-        "cloudy"           : ( "weather-clouds",     "weather-clouds-night",     False),
-        "mostlycloudy"     : ( "weather-overcast",   "weather-overcast",         False),
-        "mostly_cloudy"    : ( "weather-overcast",   "weather-overcast",         False),
-        "overcast"         : ( "weather-overcast",   "weather-overcast",         False),
-        "rain"             : ( "weather-showers",    "weather-showers",          False),
-        "chanceofrain"     : ( "weather-showers",    "weather-showers",          False),
-        "chance_of_rain"   : ( "weather-showers",    "weather-showers",          False),
-        "heavyrain"        : ( "weather-showers",    "weather-showers",          False),
-        "drizzle"          : ( "weather-showers",    "weather-showers",          False),
-        "sleet"            : ( "weather-snow",       "weather-snow",             False),
-        "rain_snow"        : ( "weather-snow",       "weather-snow",             False),
-        "rainsnow"         : ( "weather-snow",       "weather-snow",             False),
-        "snow"             : ( "weather-snow",       "weather-snow",             False),
-        "chanceofsnow"     : ( "weather-snow",       "weather-snow",             False),
-        "chance_of_snow"   : ( "weather-snow",       "weather-snow",             False),
-        "heavysnow"        : ( "weather-snow",       "weather-snow",             False),
-        "icy"              : ( "weather-snow",       "weather-snow",             False),
-        "snowflurries"     : ( "weather-snow",       "weather-snow",             False),
-        "flurries"         : ( "weather-snow",       "weather-snow",             False),
-        "dust"             : ( "weather-fog",        "weather-fog",              False),
-        "fog"              : ( "weather-fog",        "weather-fog",              False),
-        "smoke"            : ( "weather-fog",        "weather-fog",              False),
-        "haze"             : ( "weather-fog",        "weather-fog",              False),
-        "mist"             : ( "weather-fog",        "weather-fog",              False),
-        "thunderstorm"     : ( "weather-storm",      "weather-storm",            True),
-        "chance_of_storm"  : ( "weather-storm",      "weather-storm",            True),
-        "thunderstorms"    : ( "weather-storm",      "weather-storm",            True),
-        "scatteredshowers" : ( "weather-showers-scattered", "weather-showers-scattered", True),
-        "scatteredthunderstorms" : ( "weather-storm",       "weather-storm",             True),
-    }
-
-    #Available conditions by yahoo condition code
-    #Format: condition code: (day icon, night icon, is a severe weather condition, localized condition name)
+    """Data object to parse weather data with unit conversion """
+
+##    #Available conditions by google icon
+##    #Format: Google icon name: (day icon, night icon, is a severe weather condition)
+##    #Reference: http://www.blindmotion.com/2009/03/google-weather-api-images/
+##    _GoogleConditions = {
+##        "sunny"            : ( "weather-clear",      "weather-clear-night",      False),
+##        "mostly_sunny"     : ( "weather-clear",      "weather-clear-night",      False),
+##        "partlycloudy"     : ( "weather-few-clouds", "weather-few-clouds-night", False),
+##        "partly_cloudy"    : ( "weather-few-clouds", "weather-few-clouds-night", False),
+##        "windy"            : ( "weather-few-clouds", "weather-few-clouds-night", False),
+##        "cloudy"           : ( "weather-clouds",     "weather-clouds-night",     False),
+##        "mostlycloudy"     : ( "weather-overcast",   "weather-overcast",         False),
+##        "mostly_cloudy"    : ( "weather-overcast",   "weather-overcast",         False),
+##        "overcast"         : ( "weather-overcast",   "weather-overcast",         False),
+##        "rain"             : ( "weather-showers",    "weather-showers",          False),
+##        "chanceofrain"     : ( "weather-showers",    "weather-showers",          False),
+##        "chance_of_rain"   : ( "weather-showers",    "weather-showers",          False),
+##        "heavyrain"        : ( "weather-showers",    "weather-showers",          False),
+##        "drizzle"          : ( "weather-showers",    "weather-showers",          False),
+##        "sleet"            : ( "weather-snow",       "weather-snow",             False),
+##        "rain_snow"        : ( "weather-snow",       "weather-snow",             False),
+##        "rainsnow"         : ( "weather-snow",       "weather-snow",             False),
+##        "snow"             : ( "weather-snow",       "weather-snow",             False),
+##        "chanceofsnow"     : ( "weather-snow",       "weather-snow",             False),
+##        "chance_of_snow"   : ( "weather-snow",       "weather-snow",             False),
+##        "heavysnow"        : ( "weather-snow",       "weather-snow",             False),
+##        "icy"              : ( "weather-snow",       "weather-snow",             False),
+##        "snowflurries"     : ( "weather-snow",       "weather-snow",             False),
+##        "flurries"         : ( "weather-snow",       "weather-snow",             False),
+##        "dust"             : ( "weather-fog",        "weather-fog",              False),
+##        "fog"              : ( "weather-fog",        "weather-fog",              False),
+##        "smoke"            : ( "weather-fog",        "weather-fog",              False),
+##        "haze"             : ( "weather-fog",        "weather-fog",              False),
+##        "mist"             : ( "weather-fog",        "weather-fog",              False),
+##        "thunderstorm"     : ( "weather-storm",      "weather-storm",            True),
+##        "chance_of_storm"  : ( "weather-storm",      "weather-storm",            True),
+##        "thunderstorms"    : ( "weather-storm",      "weather-storm",            True),
+##        "scatteredshowers" : ( "weather-showers-scattered", "weather-showers-scattered", True),
+##        "scatteredthunderstorms" : ( "weather-storm",       "weather-storm",             True),
+##    }
+
+    # Available conditions by yahoo condition code
+    # Format: condition code: (day icon, night icon, is a severe weather condition, localized condition name)
     _YahooConditions = {
         '0' : ("weather-storm",             "weather-storm",            True,  _("Tornado")),
         '1' : ("weather-storm",             "weather-storm",            True,  _("Tropical storm")),
@@ -628,55 +663,66 @@
         '3200': (False,                     False,                      False, _("Unknown condition"))
     }
 
-    # Initialize and get fresh data
-    def __init__(self, location_id, weather_datasource, metric_system, wind_unit, lat, lon):
+    # Available conditions by Weather.com condition code; same as Yahoo
+    _WeathercomConditions = _YahooConditions
+    
+    def __init__(self, location_id, weather_datasource, metric_system,
+                 wind_unit, heat_index, chill_index, lat, lon):
+        """ Initialize and get fresh weather data """
         self.__weather_datasource = weather_datasource
         self.__metric_system = metric_system
         self._wind_unit = wind_unit
         self.__current_condition = None
+        self.__heat_index = heat_index
+        self.__chill_index = chill_index
         self.__lat = lat
         self.__lon = lon
 
-        # Get data from Google
-        if self.__weather_datasource == WeatherDataSource.GOOGLE:
-            # Get data in english locale, then - switch back
-            self.__report = pywapi.get_weather_from_google (location_id, hl = 'en')
-            # Get data in original locale for condition name
-            self.__localized_report = pywapi.get_weather_from_google (location_id, hl = locale_name)
-
+        # TODO: modify pywapi to use UnitSystem class? (and rename __metric_system !)
+        if self.__metric_system == UnitSystem.SI:
+            unit_system = 'metric'
+        elif self.__metric_system == UnitSystem.IMPERIAL:
+            unit_system = 'imperial'
+        else:
+            unit_system = 'imperial'
+                
+        # Get data from Weather.com
+        if self.__weather_datasource == WeatherDataSource.WEATHER_COM:
+            log.debug(("Weather: __init__: calling " +
+                       "pywapi.get_weather_from_weather_com(location_id=%s, " +
+                       "units=%s)") % (location_id, metric_system))   #DEBUG
+            
+            self.__report = pywapi.get_weather_from_weather_com(location_id, unit_system)
+            ##self.__localized_report = self.__report
+            log.debug("Weather: __init__: checking Weather.com report for " +
+                      "weather condition and icon name")   #DEBUG
             if 'current_conditions' not in self.__report.keys():
-                log.error("Weather: could not get Google weather condition from report")
+                icon_name = ""
+                log.error("Weather: could not get Weather.com weather condition from report")
                 log.error("Weather: got data '%s'" % str(self.__report))
                 self.__current_condition = (False, False, False, _("Unknown condition"))
 
-            if 'current_conditions' not in self.__localized_report.keys():
-                log.error("Weather: could not get Google weather condition from localized report")
-                log.error("Weather: got data '%s'" % str(self.__localized_report))
-                self.__current_condition = (False, False, False, _("Unknown condition"))
+            elif 'icon' in self.__report['current_conditions'].keys():
+                icon_name = self.__report['current_conditions']['icon']
+                self.__current_condition = self._WeathercomConditions.get(icon_name)
 
-            if 'icon' in self.__report['current_conditions'].keys():
-                icon_path = self.__report['current_conditions']['icon']
-                if '/ig/images/weather/' in icon_path:
-                    icon_name = icon_path.replace('/ig/images/weather/', '').replace('.gif', '')
-                elif 'http://g0.gstatic.com/images/icons/onebox' in icon_path:
-                    icon_name = icon_path.replace('http://g0.gstatic.com/images/icons/onebox/weather_', '').replace('-40.gif', '')
-                else:
-                    icon_name = icon_path
             else:
-                log.error("Weather: could not get weather icon from report")
+                icon_name = ""
+                log.error("Weather: could not get icon name from Weather.com report")
                 log.error("Weather: got data '%s'" % str(self.__report['current_conditions']))
-                icon_name = ""
-
-            self.__current_condition = self._GoogleConditions.get(icon_name)
-            if self.__current_condition == None:
-                log.error("ExtendedForecast: unknown Google weather condition '%s'" % icon_name)
                 self.__current_condition = (False, False, False, _("Unknown condition"))
-
+            
         # Get data from Yahoo
         if self.__weather_datasource == WeatherDataSource.YAHOO:
-            self.__report = pywapi.get_weather_from_yahoo (location_id, 'imperial')
-            self.__localized_report = self.__report
+            log.debug(("Weather: __init__: calling " +
+                       "pywapi.get_weather_from_yahoo(location_id=%s, " +
+                       "units=%s)") % (location_id, metric_system))   #DEBUG
+            self.__report = pywapi.get_weather_from_yahoo(location_id, unit_system)
+            ##self.__localized_report = self.__report
+            log.debug("Weather: __init__: checking Yahoo report for " +
+                      "weather condition and icon name")   #DEBUG
             if 'condition' not in self.__report.keys():
+                icon_name = ""
                 log.error("Weather: could not get Yahoo weather condition from report")
                 log.error("Weather: got data '%s'" % str(self.__report))
                 self.__current_condition = (False, False, False, _("Unknown condition"))
@@ -693,10 +739,11 @@
 
         log.debug("Weather: current condition: '%s', '%s'" % (icon_name, str(self.__current_condition)))
         #Prepare sunrise/sunset data
+        log.debug("Weather: __init__: preparing sunrise/sunset data")  #DEBUG
         self.get_sun_data()
 
-    #Get sunrise/sunset times, calculate whether it is night already
     def get_sun_data(self):
+        """ Get sunrise/sunset times and calculate whether it is night already """
         self.__night = False
         self.__sunrise_t = None
         self.__sunset_t = None
@@ -705,6 +752,8 @@
         url = 'http://www.earthtools.org/timezone-1.1/%s/%s' % \
             (self.__lat, self.__lon)
         try:
+            log.debug(("Weather: get_sun_data: getting local datetime and " +
+                       "dst status from %s") % url)  #DEBUG
             f = urllib2.urlopen(url)
             s = f.read()
             parsed = parseString(s)
@@ -714,7 +763,7 @@
                 "dst")[0].firstChild.nodeValue
             # strip timezone info
             localtime = datetime.datetime.strptime(localtime.rsplit(' ',1)[0],
-                '%Y-%m-%d %H:%M:%S')
+                                                   '%Y-%m-%d %H:%M:%S')
             dst = 1 if dst == "True" else 0
 
         except urllib2.URLError:
@@ -725,6 +774,7 @@
         url = 'http://www.earthtools.org/sun/%s/%s/%s/%s/99/%s' % \
             (self.__lat, self.__lon, localtime.day, localtime.month, dst)
         try:
+            log.debug("Weather: get_sun_data: getting sunrise/sunset from %s" % url)  #DEBUG
             f = urllib2.urlopen(url)
             s=f.read()
             parsed = parseString(s)
@@ -742,20 +792,20 @@
         else:
             self.__night = False
         log.debug("Weather: got localtime " +
-            "%s, dst %s, sunrise '%s', sunset '%s', night = %s" % (
-            localtime, dst, self.__sunrise_t, self.__sunset_t, self.__night))
+                  "%s, dst %s, sunrise '%s', sunset '%s', night = %s" % (
+                      localtime, dst, self.__sunrise_t, self.__sunset_t, self.__night))
 
-    # Return True, if weather condition is severe
     def condition_is_severe(self):
+        """ Return True if weather condition is severe """
         if self.__current_condition != None:
             log.debug("Weather: got severe condition '%s'" % self.__current_condition[2])
             return self.__current_condition[2]
         else:
             log.error("Weather: condition is not set while condition severity check")
-            return False;
+            return False
 
-    # Get associated icon name
     def get_icon_name(self):
+        """ Get icon name associated with current condition """
         if self.__current_condition != None:
             if self.__night:
                 log.debug("Weather: night, show '%s' icon" % self.__current_condition[1])
@@ -767,217 +817,441 @@
             log.error("Weather: return 'offline' icon due to empty condition")
             return False
 
-    # Get condition text
     def get_condition_label(self):
-        if self.__weather_datasource == WeatherDataSource.GOOGLE:
-            if 'condition' in self.__localized_report['current_conditions'].keys():
-                condition = self.__localized_report['current_conditions']['condition']
-            else:
-                condition = _("Unknown condition")
+        """ Get text of current condition """
+        if self.__weather_datasource == WeatherDataSource.WEATHER_COM:
+            condition = self.__report['current_conditions']['text']
         if self.__weather_datasource == WeatherDataSource.YAHOO:
             condition = self.__current_condition[3]
         return condition
 
-    # Get humidity label
     def get_humidity_label(self):
+        """ Get text string for current humidity """
         humidity = "%s: ---%%" % (_("Humidity"))
-        if self.__weather_datasource == WeatherDataSource.GOOGLE \
-            and 'humidity' in self.__localized_report['current_conditions']:
-            humidity = self.__localized_report['current_conditions']['humidity']
+        if self.__weather_datasource == WeatherDataSource.WEATHER_COM \
+           and 'humidity' in self.__report['current_conditions']:
+            humidity = "%s: %s%%" % (_("Humidity"), self.__report['current_conditions']['humidity'])
         if self.__weather_datasource == WeatherDataSource.YAHOO \
-            and 'humidity' in self.__localized_report['atmosphere']:
-            humidity = "%s: %s%%" % (_("Humidity"), self.__localized_report['atmosphere']['humidity'])
+           and 'humidity' in self.__report['atmosphere']:
+            humidity = "%s: %s%%" % (_("Humidity"), self.__report['atmosphere']['humidity'])
         return humidity
 
-    # Get dew point - using in humidex calculation
-    #TODO: Update with NOAA
     def get_dew_point_label(self):
-        if self.__weather_datasource == WeatherDataSource.GOOGLE or self.__weather_datasource == WeatherDataSource.YAHOO:
-            # Not returned by Google and Yahoo
+        """ Get dew point, which is used in humidex calculation """
+        #TODO: Update with NOAA
+        _value = "---"
+        _unit = ""        
+        if self.__weather_datasource == WeatherDataSource.YAHOO:
+            # Not returned by Yahoo
             return None
+        if self.__weather_datasource == WeatherDataSource.WEATHER_COM:
+            _value = self.__report['current_conditions']['dewpoint']
+            _unit = self.__report['units']['temperature']
+        return u"%s: %s °%s" % (_("Dewpoint"), _value, _unit)
 
-    # Get pressure label
     def get_pressure_label(self):
-        if self.__weather_datasource == WeatherDataSource.GOOGLE:
-            # TODO: Empty for Google, use NOAA data?
-            value = "---"
-            unit = ""
+        """ Get text string for current air pressure """
+        _value = "---"
+        _unit = ""
+        if self.__weather_datasource == WeatherDataSource.WEATHER_COM \
+           and 'barometer' in self.__report['current_conditions'].keys() \
+           and 'pressure' in self.__report['units'].keys():
+            _value = self.__report['current_conditions']['barometer']['reading']
+            _unit = self.__report['units']['pressure']
         if self.__weather_datasource == WeatherDataSource.YAHOO \
-            and 'pressure' in self.__localized_report['atmosphere'].keys() \
-            and 'pressure' in self.__localized_report['units'].keys():
-            value = self.__localized_report['atmosphere']['pressure']
-            unit = self.__localized_report['units']['pressure']
-        return "%s: %s %s" % (_("Pressure"), value, units)
+           and 'pressure' in self.__report['atmosphere'].keys() \
+           and 'pressure' in self.__report['units'].keys():
+            _value = self.__report['atmosphere']['pressure']
+            _unit = self.__report['units']['pressure']
+        return "%s: %s %s" % (_("Pressure"), _value, _unit)
 
-    # Get temperature with units value - doesn't include 'Temperature' label
-    def get_temperature(self, needs_rounding = False):
-        _value = "---"
+##    def get_temperature(self, needs_rounding = False):
+    def get_temperature(self):
+        """ Get temperature value and units string """
+        _value = None
         _unit = ""
-        if self.__weather_datasource == WeatherDataSource.GOOGLE:
-            if (self.__metric_system == MetricSystem.SI) \
-            and 'temp_c' in self.__report['current_conditions'].keys():
-                _value = self.__report['current_conditions']['temp_c']
-                _unit  = "˚C"
-            elif 'temp_f' in self.__report['current_conditions'].keys():
-                _value = self.__report['current_conditions']['temp_f']
-                _unit  = "˚F"
-        if self.__weather_datasource == WeatherDataSource.YAHOO:
-            if (self.__metric_system == MetricSystem.SI) \
-            and 'temp' in self.__report['condition'].keys():
-                _value = NumberFormatter.format_float(
-                    ((float(self.__report['condition']['temp']) - 32) * 5/9), 1)
-                _unit  = "˚C"
-            else:
+        if (self.__weather_datasource == WeatherDataSource.WEATHER_COM and
+            'temperature' in self.__report['current_conditions'].keys() and
+            'temperature' in self.__report['units'].keys()):
+            if ((self.__metric_system == UnitSystem.SI and
+                    self.__report['units']['temperature'] == u"C") or
+               (self.__metric_system == UnitSystem.IMPERIAL and
+                    self.__report['units']['temperature' ] == u"F")):
+                _value = self.__report['current_conditions']['temperature']
+                _unit = u"°%s" % self.__report['units']['temperature']
+        if (self.__weather_datasource == WeatherDataSource.YAHOO and
+            'temp' in self.__report['condition'].keys() and
+            'temperature' in self.__report['units'].keys()):
+            if ((self.__metric_system == UnitSystem.SI and
+                    self.__report['units']['temperature'] == u"C") or
+               (self.__metric_system == UnitSystem.IMPERIAL and
+                    self.__report['units']['temperature'] == u"F")):
                 _value = self.__report['condition']['temp']
-                _unit  = "˚F"
-        # round the value if required
-        if needs_rounding and _value != "---":
-            _value = NumberFormatter.format_float(locale.atof(_value), 0)
-        return ("%s %s" % (_value, _unit))
-
-    # Get temperature label
+                _unit = u"°%s" % self.__report['units']['temperature']                
+##        # round the value if required
+##        if needs_rounding and _value != "---":
+##            _value = NumberFormatter.format_float(locale.atof(_value), 0)
+        return (_value, _unit)
+
+    def get_temperature_string(self):
+        """ Get temperature with units value - doesn't include 'Temperature' string """
+        (_value, _unit) = self.get_temperature()
+        if _value is None:
+            _value = "---"
+            _unit = ""
+        return (u"%s %s" % (_value, _unit))
+
     def get_temperature_label(self):
-        return "%s: %s" % (_("Temperature"), self.get_temperature())
-
-    # Get humidex parameter
-    def get_humidex_label(self):
-        if self.__weather_datasource == WeatherDataSource.GOOGLE or self.__weather_datasource == WeatherDataSource.YAHOO:
-            #Empty for Yahoo and Google
-            return None
-        #TODO: Update with NOAA data
-        #dewPoint=2
-        #temp_c = 1
-        #self.vapour_pressure = 6.11 * math.exp(5417.7530 * ( (1/273.16) - (1/(dewPoint+273.16))))
-        #self.humidex = temp_c + (0.5555)*(self.vapour_pressure  - 10.0);
-        #return ("%s: %.1f" % (_("Humidex"), self.humidex)).replace(".0", "")
-
-    # Get wind label
+        """ Get text string for current temperature label """
+        return "%s: %s" % (_("Temperature"), self.get_temperature_string())
+
+    def get_relative_string(self):
+        """ Get relative temperature with units value - doesn't include 'Feels Like' string """        
+        # try relative heat
+        if self.__heat_index == RelativeFormula.HUMIDEX:
+            (_value, _unit) = self.get_humidex()
+        if self.__heat_index == RelativeFormula.HEATINDEX:
+            (_value, _unit) = self.get_heat_index()
+        if _value is not None:
+            return (u"%s %s" % (_value, _unit))
+        # try relative chill
+        if self.__chill_index == RelativeFormula.WINDCHILL:
+            (_value, _unit) = self.get_wind_chill()
+        if self.__chill_index == RelativeFormula.APPARENT:
+            (_value, _unit) = self.get_apparent_temp()
+        if _value is not None:
+            return (u"%s %s" % (_value, _unit))
+        # use current temperature
+        return self.get_temperature_string()
+
+    def get_relative_label(self):
+        """ Get text string for relative temperature ("feels like") label """
+        return "%s: %s" % (_("Feels Like"), self.get_relative_string())
+    
+    def get_humidex(self):
+        """ Calculate humidex and get value and units
+        
+        The standard Humidex formula used by Environment Canada is:
+        
+        humidex = (air temperature) + h
+        
+        h = (0.5555)*(e - 10.0);
+        e = vapour pressure in hPa (mbar), given by:
+        e = 6.11 * exp [5417.7530 * ( (1/273.16) - (1/dewpoint) ) ]
+        where dewpoint is expressed in Kelvins
+        (temperature in K = temperature in °C + 273.1)
+        and 5417.7530 is a rounded constant based on the molecular weight
+        of water, latent heat of evaporation, and the universal gas constant.
+        
+        """
+        #TODO: Update with NOAA data
+        log.debug("Weather: get_humidex_label: checking weather_datasource")      # DEBUG
+        
+        if self.__weather_datasource == WeatherDataSource.YAHOO:
+            log.debug("Weather: get_humidex_label: weather_datasource is Yahoo, returning None")      # DEBUG
+            # Empty for Yahoo
+            return (None, "")
+        if self.__weather_datasource == WeatherDataSource.WEATHER_COM:
+            log.debug("Weather: get_humidex_label: weather_datasource is Weather.com, calculating humidex")      # DEBUG
+            if self.__report['units']['temperature'] == "F":
+                # Humidex is calculated in C
+                dew_point_f = float(self.__report['current_conditions']['dewpoint'])
+                temp_f = float(self.__report['current_conditions']['temperature'])
+                dew_point_c = ((dew_point_f - 32.0) * 5.0/9.0)
+                temp_c = ((temp_f - 32.0) * 5.0/9.0)
+            else:
+                dew_point_c = float(self.__report['current_conditions']['dewpoint'])
+                temp_c = float(self.__report['current_conditions']['temperature'])
+            vapour_pressure = 6.11 * exp(5417.7530 * ( (1/273.16) - (1/(dew_point_c+273.16))))
+            humidex = temp_c + (0.5555)*(vapour_pressure  - 10.0)
+            log.debug("humidex = temp + 0.555 * (6.11 * exp(5417.7530 * (1/273.16 - 1/dewpoint in kelvins)) - 10)") # DEBUG
+            log.debug("temp = %s, dewpoint in kelvins = %s" % (temp_c, dew_point_c+273.16))  #DEBUG
+            log.debug("Weather: get_humidex_label: humidex is %s (C)" % humidex)      # DEBUG
+            # Humidex is meaningless if it is lower than temperature
+            if humidex < temp_c:
+                #return (u"%s: N/A" % _("Humidex"))
+                return (None, "")
+            if self.__report['units']['temperature'] == "F":
+                humidex_f = (humidex*9.0/5.0) + 32.0
+                # Humidex is unitless (represents Celsius) so in F show units
+                #return (u"%s: %s°F" % (_("Humidex"), NumberFormatter.format_float(humidex_f, 1))).replace(".0", "")    
+                #return (NumberFormatter.format_float(humidex_f, 1).replace(".0", ""), u"°F")
+                return (int(round(humidex_f)), u"°F")
+            else:
+                #return ("%s: %.1f" % (_("Humidex"), humidex)).replace(".0", "")
+                #return (u"%s: %s" % (_("Humidex"), NumberFormatter.format_float(humidex, 1))).replace(".0", "")
+                #return (NumberFormatter.format_float(humidex, 1).replace(".0", ""), u"°C")
+                return (int(round(humidex)), u"°C")
+
+    def get_heat_index(self):
+        """ Calculate heat index and get value and units
+        
+        The formula below approximates the heat index in degrees
+        Fahrenheit, to within ±1.3 °F. It is the result of a
+        multivariate fit (temperature equal to or greater than
+        80°F and relative humidity equal to or greater than 40%)
+        to a model of the human body.
+       
+        Heat Index = c_1 + (c_2 * T) + (c_3 * R) + (c_4 * T * R) +
+                      (c_5 * T^2) + (c_6 * R^2) + (c_7 * T^2 * R) +
+                      (c_8 * T * R^2) + (c_9 * T^2 * R^2) 
+        where:
+          T = ambient dry-bulb temperature (in degrees Fahrenheit)
+          R = relative humidity (percentage value between 0 and 100)
+
+        """
+        #TODO: Update with NOAA data
+        _value = None
+
+        if self.__weather_datasource == WeatherDataSource.YAHOO:
+            log.debug("Weather: get_heat_index: weather_datasource is Yahoo, returning, checking temp and humidity")      # DEBUG
+            if self.__report['units']['temperature'] == "C":
+                units = 'metric'
+            elif self.__report['units']['temperature'] == "F":     # else here?
+                units = 'imperial'
+            T = float(self.__report['condition']['temp'])
+            R = float(self.__report['atmosphere']['humidity'])
+            _value = pywapi.heat_index(T, R, units)
+
+        if self.__weather_datasource == WeatherDataSource.WEATHER_COM:
+            log.debug("Weather: get_heat_index: weather_datasource is Weather.com, checking temp and humidity")      # DEBUG
+            if self.__report['units']['temperature'] == "C":
+                units = 'metric'
+            elif self.__report['units']['temperature'] == "F":  #else here?
+                units = 'imperial'
+            T = float(self.__report['current_conditions']['temperature'])
+            R = float(self.__report['current_conditions']['humidity'])
+            _value = pywapi.heat_index(T, R, units)
+
+        # Heat Index is only valid for temp >= 80°F and humidity >= 40%)
+        if _value is None:
+            return (_value, "")
+        if units == 'metric':
+            #return (u"%s: %s°C" % (_("Heat Index"), NumberFormatter.format_float(heat_index, 1))).replace(".0", "")    
+            #return (NumberFormatter.format_float(_value, 1).replace(".0", ""), u"°C")
+            return (int(round(_value)), u"°C")
+            
+        elif units == 'imperial': # else here?
+            #return (u"%s: %s°F" % (_("Heat Index"), NumberFormatter.format_float(heat_index, 1))).replace(".0", "")
+            #return (NumberFormatter.format_float(_value, 1).replace(".0", ""), u"°F")
+            return (int(round(_value)), u"°F")
+
+    def get_wind_chill(self):
+        """ Calculate wind chill index and get text string for label
+        
+        The standard Wind Chill formula used by Environment Canada,
+        the 2001 JAG/TI Wind Chill Equivalent Temperature Index, is:
+
+            T_wc = 13.12 + 0.6215 * T_a -
+                        11.37 * V^0.16 +
+                        0.3965 * T_a * V^0.16
+        where:
+          T_wc is the wind chill index based on Celsius
+          T_a is the air temperature in °C
+          V is the wind speed in km/h, at 10 m (standard anemometer height)
+
+        The equivalent formula in US customary units is:
+        
+            T_wc = 35.74 + 0.6215 * T_a -
+                        35.75 * V^0.16 +
+                        0.4275 * T_a * V^0.16
+        
+        where:
+          T_wc is the wind chill index based on Fahrenheit
+          T_a is the air temperature °F
+          V is the wind speed in mph
+
+        Windchill temperature is defined only for temperatures at or
+        below 10 °C (50 °F) and wind speeds above 4.8 kilometres per
+        hour (3.0 mph).
+
+        """
+        #TODO: Update with NOAA data
+        _value = None
+
+        if self.__report['units']['temperature'] == "C":
+            units = 'metric'
+        elif self.__report['units']['temperature'] == "F":     # else here?
+            units = 'imperial'
+
+        if self.__weather_datasource == WeatherDataSource.YAHOO:
+            log.debug("Weather: get_wind_chill: weather_datasource is Yahoo, returning, checking temp and humidity")      # DEBUG
+            T_a = float(self.__report['condition']['temp'])
+            V = float(self.__report['wind']['speed'])
+            
+        if self.__weather_datasource == WeatherDataSource.WEATHER_COM:
+            log.debug("Weather: get_wind_chill: weather_datasource is Weather.com, checking temp and humidity")      # DEBUG
+            T_a = float(self.__report['current_conditions']['temperature'])
+            wind_speed = self.__report['current_conditions']['wind']['speed']
+            V = (0.0 if wind_speed == 'calm' else float(wind_speed))
+        
+        # move below to pywapi
+        if units == 'metric':
+            _value = 13.12 + 0.6215 * T_a - 11.37 * pow(V, 0.16) + 0.3965 * T_a * pow(V, 0.16)
+            return (int(round(_value)), u"°C")
+        elif units == 'imperial':
+            _value = 35.74 + 0.6215 * T_a - 35.75 * pow(V, 0.16) + 0.4275 * T_a * pow(V, 0.16)
+            return (int(round(_value)), u"°F")
+            
+        if _value is None:
+            return (_value, "")
+        
+    def get_apparent_temp(self):
+        """ Calculate Australian apparent temperature and get text string for label
+
+        The standard formula for cooler temperatures used by the Australian 
+        Bureau of Meteorology, the Australian Apparent Temperature, is:
+
+            AT = T_a + 0.33e - 0.70ws - 4.00
+        
+        Where:
+            T_a = Dry bulb temperature (°C)
+            e = Water vapour pressure (hPa)
+            ws = Wind speed (m/s) at an elevation of 10 meters
+        
+        The vapour pressure can be calculated from the temperature and
+        relative humidity using the equation:
+        
+            e = (rh / 100) * 6.105 * exp^[(17.27 * T_a) / (237.7 + T_a)]
+        
+        Where:
+            T_a = Dry bulb temperature (°C)
+            rh = Relative humidity [%]
+            exp^ represents the exponential function
+        
+        The Australian chill formula is only defined for temperatures
+        at or below 20°C (68°F) and wind speeds above 4.8 km/h (3.0 mph).
+
+        """
+        #TODO: Update with NOAA data
+        _value = None
+
+        if self.__report['units']['temperature'] == "C":
+            units = 'metric'
+        elif self.__report['units']['temperature'] == "F":     # else here?
+            units = 'imperial'
+
+        if self.__weather_datasource == WeatherDataSource.YAHOO:
+            log.debug("Weather: get_wind_chill: weather_datasource is Yahoo, returning, checking temp and humidity")      # DEBUG
+            T_a = float(self.__report['condition']['temp'])
+            rh = float(self.__report['atmosphere']['humidity'])
+            ws = float(self.__report['wind']['speed'])
+        if self.__weather_datasource == WeatherDataSource.WEATHER_COM:
+            log.debug("Weather: get_wind_chill: weather_datasource is Weather.com, checking temp and humidity")      # DEBUG
+            T_a = float(self.__report['current_conditions']['temperature'])
+            rh = float(self.__report['current_conditions']['humidity'])
+            ws = float(self.__report['current_conditions']['wind']['speed'])
+        
+        # calculated in °C, so need to convert from °F
+        if units == 'imperial':
+            T_a = ((T_a - 32.0) * 5.0/9.0)
+
+        e = (rh / 100) * 6.105 * exp((17.27 * T_a) / (237.7 + T_a))
+        _value = T_a + 0.33 * e - 0.70 * ws - 4.00
+
+        # Now convert back to °F
+        if units == 'imperial':
+            _value = (_value*9.0/5.0) + 32.0
+            return (int(round(_value)), u"°F")
+        if units == 'metric':    
+            return (int(round(_value)), u"°C")
+
+        if _value is None:
+            return (_value, "")
+        
     def get_wind_label(self):
-        if self.__weather_datasource == WeatherDataSource.GOOGLE:
-            # Convert units picked up from Google and replace units with currently configured
-            if 'wind_condition' in self.__localized_report['current_conditions'].keys():
-                localized_wind_info = self.__localized_report['current_conditions']['wind_condition'].split(' ')
-                wind_direction = localized_wind_info[1]
-                wind_info = self.__report['current_conditions']['wind_condition'].split(' ')
-                wind_speed = wind_info[3]
-            else:
-                return _("Unknown")
-
+        """ Get text string for current wind speed and direction """
+        if self.__weather_datasource == WeatherDataSource.WEATHER_COM:
+            # Create a wind_info structure from Weather.com data
+            wind_direction = u"%s (%s°)" % (self.__report['current_conditions']['wind']['text'],
+                                            self.__report['current_conditions']['wind']['direction'])
+            wind_speed = self.__report['current_conditions']['wind']['speed']
+            wind_units = self.__report['units']['speed']
+            if wind_speed == "calm":
+                wind_speed = 0
+                ##wind_direction = wind_direction.replace("CALM","Calm")
+            wind_info = [_("Wind") + ":", wind_direction, wind_speed, wind_units]
         if self.__weather_datasource == WeatherDataSource.YAHOO:
-            # Create a similar to Google wind_info structure from Yahoo data
-            wind_direction = "%s (%s˚)" % (self.get_wind_direction(self.__localized_report['wind']['direction']), self.__localized_report['wind']['direction'])
-            wind_speed = self.__localized_report['wind']['speed']
-            wind_units = self.__localized_report['units']['speed']
-            localized_wind_info = [_("Wind") + ":", wind_direction, wind_speed, wind_units]
-
+            # Create a wind_info structure from Yahoo data
+            wind_direction = u"%s (%s°)" % (_(pywapi.get_wind_direction(self.__report['wind']['direction'])), self.__report['wind']['direction'])
+            wind_speed = self.__report['wind']['speed']
+            wind_units = self.__report['units']['speed']
+            wind_info = [_("Wind") + ":", wind_direction, wind_speed, wind_units]
 
         try:
             _value = float(wind_speed)
         except ValueError as e:
             log.error("Could not parse '%s' as wind speed." % str(wind_speed))
             _value = -1.0
-            
+
         # Parse Wind_direction - convert to selected scale
-        if (self._wind_unit == WindUnits.MPH):
-            _unit  = __("mph", "mph", _value)
-        if (self._wind_unit == WindUnits.MPS):
-            _value *= 0.44704
-            _unit  = __("m/s", "m/s", _value)
-        if (self._wind_unit == WindUnits.BEAUFORT):
-            if _value >= 0.0:
-                _value = self.get_beaufort_from_mph(_value)
-            _unit  = ""
-        if (self._wind_unit == WindUnits.KPH):
-            _value *= 1.609344
-            _unit  = __("km/h", "km/h", _value)
-        if (self._wind_unit == WindUnits.KNOTS):
-            _value *= 0.868976241900648
-            _unit  = __("knot", "knots", _value)
-               
+        if wind_units == "mph":
+            if (self._wind_unit == WindUnits.MPH):
+                _unit  = __("mph", "mph", _value)
+            if (self._wind_unit == WindUnits.MPS):
+                _value *= 0.44704
+                _unit  = __("m/s", "m/s", _value)
+            if (self._wind_unit == WindUnits.BEAUFORT):
+                if _value >= 0.0:
+                    _value = pywapi.wind_beaufort_scale(_value, WindUnits.MPH)
+                _unit  = ""
+            if (self._wind_unit == WindUnits.KPH):
+                _value *= 1.609344
+                _unit  = __("km/h", "km/h", _value)
+            if (self._wind_unit == WindUnits.KNOTS):
+                _value *= 0.868976241900648
+                _unit  = __("knot", "knots", _value)
+        elif wind_units == "km/h":
+            if (self._wind_unit == WindUnits.MPH):
+                _value *= 0.621371
+                _unit  = __("mph", "mph", _value)
+            if (self._wind_unit == WindUnits.MPS):
+                _value *= 0.277778
+                _unit  = __("m/s", "m/s", _value)
+            if (self._wind_unit == WindUnits.BEAUFORT):
+                if _value >= 0.0:
+                    _value = pywapi.wind_beaufort_scale(_value, WindUnits.KPH)
+                _unit  = ""
+            if (self._wind_unit == WindUnits.KPH):
+                _unit  = __("km/h", "km/h", _value)
+            if (self._wind_unit == WindUnits.KNOTS):
+                _value *= 0.539957
+                _unit  = __("knot", "knots", _value)
+        else:
+            log.error("Could not parse '%s' as wind units." % wind_units)
+            _value = -1.0
+            
         # Join wind_info data in a label
-        localized_wind_info[len(localized_wind_info)-1] = _unit
-        localized_wind_info[len(localized_wind_info)-2] = \
+        wind_info[len(wind_info)-1] = _unit
+        wind_info[len(wind_info)-2] = \
             NumberFormatter.format_float(_value, 1)
         if _value < 0.0:
-            localized_wind_info[1:] = ["", "N\A", ""]
-        return "%s %s %s %s" % (localized_wind_info[0], localized_wind_info[1], \
-            localized_wind_info[2], localized_wind_info[3])
+            wind_info[1:] = ["", "N\A", ""]
+        if _value == 0.0:
+            wind_info[1:] = [_("Calm"), "", ""]
+        return "%s %s %s %s" % (wind_info[0], wind_info[1], \
+                                wind_info[2], wind_info[3])
 
-    # Get sunrise label
     def get_sunrise_label(self):
+        """ Get text string for sunrise time """
         return "%s: %s" % (_("Sunrise"), TimeFormatter.format_time(self.__sunrise_t))
 
-    # Get sunset label
     def get_sunset_label(self):
+        """ Get text string for sunset time """
         return "%s: %s" % (_("Sunset"), TimeFormatter.format_time(self.__sunset_t))
 
 
-    # Additional functions
-    # Convert wind direction from degrees to localized direction
-    def get_wind_direction(self, degrees):
-        try:
-            degrees = int(degrees)
-        except ValueError:
-            return ''
-
-        if degrees < 23 or degrees >= 338:
-            #Short wind direction - north
-            return _('N')
-        elif degrees < 68:
-            return _('NE')
-        elif degrees < 113:
-            return _('E')
-        elif degrees < 158:
-            return _('SE')
-        elif degrees < 203:
-            return _('S')
-        elif degrees < 248:
-            return _('SW')
-        elif degrees < 293:
-            return _('W')
-        elif degrees < 338:
-            return _('NW')
-
-    # Convert mph to Beufort scale
-    def get_beaufort_from_mph(self, value):
-        if value < 1:
-            return 0
-        elif value < 4:
-            return 1
-        elif value < 8:
-            return 2
-        elif value < 13:
-            return 3
-        elif value < 18:
-            return 4
-        elif value < 25:
-            return 5
-        elif value < 27:
-            return 6
-        elif value < 39:
-            return 7
-        elif value < 47:
-            return 8
-        elif value < 89:
-            return 9
-        elif value < 64:
-            return 10
-        elif value < 73:
-            return 11
-        elif value >= 73:
-            return 12
-
 class indicator_weather(threading.Thread):
     """ Indicator class """
     last_update_time = None
 
     # Settings values
     # Formats: setting value, object name (for preferences dialog), value assigned (optional)
-    metric_systems = { 'S': ('si',       MetricSystem.SI),
-                       'I': ('imperial', MetricSystem.IMPERIAL)}
+    metric_systems = { 'S': ('si',       UnitSystem.SI),
+                       'I': ('imperial', UnitSystem.IMPERIAL)}
 
-    weather_sources = { 'G': ('google', WeatherDataSource.GOOGLE),
-                        'Y': ('yahoo',  WeatherDataSource.YAHOO)}
+    weather_sources = { 'Y': ('yahoo',  WeatherDataSource.YAHOO),
+                        'W': ('weather-com', WeatherDataSource.WEATHER_COM)}
 
     notifications = {'N': 'nonotif',
                      'O': 'notifsevere',
@@ -989,16 +1263,27 @@
                     'beaufort': ("beaufort", WindUnits.BEAUFORT),
                     'knots':    ("knots",    WindUnits.KNOTS)}
 
-    # Initializing and reading settings
+    heat_estimates = {'heatindex': ("heatindex", RelativeFormula.HEATINDEX),
+                      'humidex':   ("humidex",   RelativeFormula.HUMIDEX)}
+    
+    chill_estimates = {'windchill': ("wctindex", RelativeFormula.WINDCHILL),
+                       'apparent':  ("aatindex", RelativeFormula.APPARENT)}
+    
     def __init__(self):
+        """ Initializing and reading previously-saved settings """
         log.debug("Indicator: creating")
         threading.Thread.__init__(self)
         self.main_icon = os.path.join
-        self.winder = appindicator.Indicator ("indicator-weather", "weather-indicator", appindicator.CATEGORY_OTHER)
-        self.winder.set_status (appindicator.STATUS_ACTIVE)
-        self.winder.set_attention_icon ("weather-indicator-error")
-
+        self.winder = AppIndicator.Indicator.new("indicator-weather", "weather-indicator", AppIndicator.IndicatorCategory.OTHER)
+        
         self.menu_update_lock = threading.Lock()
+        self.status_update_lock = threading.Lock()
+
+        self.status_update_lock.acquire(True)
+        self.winder.set_status(AppIndicator.IndicatorStatus.ACTIVE)
+        self.winder.set_attention_icon("weather-indicator-error")
+        self.status_update_lock.release()
+        
         self.refreshed_minutes_ago = -1
         monitor_upower(self.on_system_sleep, self.on_system_resume, log)
 
@@ -1010,27 +1295,37 @@
         self.unit  = self.settings.get_value("unit")
         self.notif = self.settings.get_value("notif")
         self.wind  = self.settings.get_value("wind")
+        self.heat = self.settings.get_value("heat")
+        self.chill = self.settings.get_value("chill")
         self.source = self.settings.get_value("data_source")
         self.placechosen = self.settings.get_value("placechosen")
         self.places = str(self.settings.get_value("places"))
         self.show_label = self.settings.get_value("show_label")
-
-        log.debug("Preferences: got settings: rate=%s, unit=%s, notif=%s, wind=%s, placechosen=%s, places=%s" %
-                (self.rate, self.unit, self.notif, self.wind, self.placechosen, self.places))
+        self.show_relative = self.settings.get_value("show_relative")
+        self.show_wind = self.settings.get_value("show_wind")
+        self.show_suntimes = self.settings.get_value("show_suntimes")
+        
+        log.debug("Preferences: got settings: rate=%s, unit=%s, notif=%s, "
+                  "wind=%s, placechosen=%s, places=%s, heat=%s, chill=%s" %
+                  (self.rate, self.unit, self.notif, self.wind, 
+                   self.placechosen, self.places, self.heat, self.chill))
 
         #Setting default values
-        self.metric_system = MetricSystem.SI
+        self.metric_system = UnitSystem.SI
         self.wind_unit = WindUnits.MPH
         self.place = None
         self.menu = None
         self.condition = None
         self.icon = None
-
+        self.heat_index = RelativeFormula.HUMIDEX
+        self.chill_index = RelativeFormula.WINDCHILL
+        
         #Parsing settings
         # Metric system
         if self.unit in (False, None):
             default_value = 'S'
-            log.debug("Indicator: could not parse unit, setting to %s" % default_value)
+            log.debug("Indicator: could not parse unit, "
+                      "setting to %s" % default_value)
             self.settings.set_value("unit", default_value)
             self.unit = default_value
         self.metric_system = self.metric_systems[self.unit][1]
@@ -1038,25 +1333,70 @@
         # Notification
         if self.notif in (False, None):
             default_value = 'N'
-            log.debug("Indicator: could not parse notif, setting to %s" % default_value)
+            log.debug("Indicator: could not parse notif, "
+                      "setting to %s" % default_value)
             self.settings.set_value("notif", default_value)
             self.notif = default_value
+        Notify.init("weather-indicator")    
 
         # Wind units
         if self.wind in (False, None):
             default_value = 'mph'
-            log.debug("Indicator: could not parse wind, setting to %s" % default_value)
+            log.debug("Indicator: could not parse wind, "
+                      "setting to %s" % default_value)
             self.settings.set_value("wind", default_value)
             self.wind = default_value
         self.wind_unit = self.wind_systems[self.wind][1]
 
+        # Heat estimate formula
+        if self.heat in (False, None):
+            default_value = 'humidex'
+            log.debug("Indicator: could not parse heat, "
+                      "setting to %s" % default_value)
+            self.settings.set_value("heat", default_value)
+            self.heat = default_value
+        self.heat_index = self.heat_estimates[self.heat][1]
+            
+        # Chill estimate formula
+        if self.chill in (False, None):
+            default_value = 'windchill'
+            log.debug("Indicator: could not parse chill, "
+                      "setting to %s" % default_value)
+            self.settings.set_value("chill", default_value)
+            self.chill = default_value
+        self.chill_index = self.chill_estimates[self.chill][1]
+
         # Show label in indicator?
-        self.show_label = True if self.show_label == 1 else False
+        if self.show_label == 1:
+            self.show_label = True
+            self.label_guide = "100 ˚C"    # Guide for width of label
+        else:
+            self.show_label = False
+            self.label_guide = " "
 
+        # Show relative temperature in dropdown?
+        if self.show_relative == 1:
+            self.show_relative = True
+        else:
+            self.show_relative = False
+            
+        # Show windspeed & direction in dropdown?
+        if self.show_wind == 1:
+            self.show_wind = True
+        else:
+            self.show_wind = False
+            
+        # Show sunrise & sunset times in dropdown?
+        if self.show_suntimes == 1:
+            self.show_suntimes = True
+        else:
+            self.show_suntimes = False
+            
         # Weather source
-        if self.source in (False, None):
+        if self.source in (False, None, 'G'):   # If set to Google, reset it
             default_value = 'Y'
-            log.debug("Indicator: could not parse data source, setting to %s" % default_value)
+            log.debug("Indicator: could not parse data source, "
+                      "setting to %s" % default_value)
             self.settings.set_value("data_source", default_value)
             self.source = default_value
         self.weather_source = self.weather_sources[self.source][1]
@@ -1064,7 +1404,8 @@
         # Rate
         if self.rate in (False, None):
             default_value = 15
-            log.debug("Indicator: could not parse rate, setting to %s" % str(default_value))
+            log.debug("Indicator: could not parse rate, "
+                      "setting to %s" % str(default_value))
             self.settings.set_value("refresh_rate", default_value)
             self.rate = default_value
 
@@ -1077,9 +1418,11 @@
             self.placechosen = int(self.placechosen)
 
         # Places list
+        self.menu_update_lock.acquire(True)
         if self.places in (False, None, '', '[]', "['']"):
             log.debug("Indicator: could not parse places")
             self.menu_noplace()
+            self.menu_update_lock.release()
         else:
             self.places = eval(self.places)
             if self.placechosen >= len(self.places):
@@ -1089,89 +1432,107 @@
             if self.location_details in (False, None, '', '[]', "['']"):
                 log.debug("Indicator: could not parse current location details")
                 self.menu_noplace()
+                self.menu_update_lock.release()
             else:
+                log.debug("Indicator: __init__: location_details = %s" % self.location_details)     #DEBUG
                 self.location_details = eval(self.location_details)
-                self.menu_normal()
+                log.debug("    eval(location_details) = %s" % self.location_details)        #DEBUG
+##                log.debug("Indicator: __init__: calling menu_normal()")      #DEBUG
+##                self.menu_normal()
+                log.debug("Indicator: __init__: calling update_weather()")      #DEBUG
+                self.menu_update_lock.release()
                 self.update_weather()
 
-    # Set a label of indicator
     def update_label(self, label):
+        """ Set the label of the indicator """
         if (hasattr(self.winder, 'set_label')):
             log.debug("Indicator: update_label: setting label to '%s'" % label)
             self.previous_label_value = label
-            self.winder.set_label(label) if self.show_label else self.winder.set_label(" ")
-            self.winder.set_status(appindicator.STATUS_ATTENTION)
-            self.winder.set_status(appindicator.STATUS_ACTIVE)
+            log.debug("Indicator: saved label ('%s') to previous_label_value" % label)      #DEBUG
+            log.debug("Indicator: checking value of show_label")       #DEBUG
+            self.status_update_lock.acquire(True)
+            self.winder.set_label(label, self.label_guide) if self.show_label else self.winder.set_label(" ", " ")
+            log.debug("Indicator: show_label is %s" % self.show_label)       #DEBUG
+            log.debug("Indicator: calling set_status(AppIndicator.IndicatorStatus.ATTENTION)")       #DEBUG
+            self.winder.set_status(AppIndicator.IndicatorStatus.ATTENTION)
+            log.debug("Indicator: calling set_status(AppIndicator.IndicatorStatus.ACTIVE)")       #DEBUG
+            self.winder.set_status(AppIndicator.IndicatorStatus.ACTIVE)
+            log.debug("Indicator: returned from set_status")       # DEBUG
+            self.status_update_lock.release()
 
-    # Show a menu if no places specified
     def menu_noplace(self):
+        """ Show a menu if no places specified """
         log.debug("Indicator: making a menu for no places")
-        menu_noplace = gtk.Menu()
+        menu_noplace = Gtk.Menu()
 
-        setup = gtk.MenuItem(_("Set Up Weather..."))
+        setup = Gtk.MenuItem(_("Set Up Weather..."))
         setup.connect("activate", self.prefs)
         setup.show()
         menu_noplace.append(setup)
 
-        quit = gtk.ImageMenuItem(gtk.STOCK_QUIT)
+        quit = Gtk.ImageMenuItem.new_from_stock(Gtk.STOCK_QUIT, None)
         quit.connect("activate", self.quit)
         quit.show()
         menu_noplace.append(quit)
 
+        self.status_update_lock.acquire(True)
         self.winder.set_menu(menu_noplace)
         self.winder.set_icon(os.path.join(PROJECT_ROOT_DIRECTORY, "share/indicator-weather/media/icon.png"))
-        self.winder.set_status(appindicator.STATUS_ATTENTION)
-        self.winder.set_status(appindicator.STATUS_ACTIVE)
-
-    # Show menu with data
+        self.winder.set_status(AppIndicator.IndicatorStatus.ATTENTION)
+        self.winder.set_status(AppIndicator.IndicatorStatus.ACTIVE)
+        self.status_update_lock.release()
+                
     def menu_normal(self):
+        """ Show a menu with weather and location data """
+        # TODO: rewrite this ??!??
         log.debug("Indicator: menu_normal: filling in a menu for found places")
-        self.menu = gtk.Menu()
+                    
+        self.menu = Gtk.Menu()
 
     ##City
-        self.city_show = gtk.MenuItem()
+        self.city_show = Gtk.MenuItem()
         self.city_show.set_sensitive(True)
         self.menu.append(self.city_show)
         self.city_show.show()
 
     ##Condition
-        self.cond_show = gtk.MenuItem()
+        self.cond_show = Gtk.MenuItem()
         self.cond_show.set_sensitive(True)
         self.cond_show.show()
         self.menu.append(self.cond_show)
 
     ##Temperature
-        self.temp_show = gtk.MenuItem()
+        self.temp_show = Gtk.MenuItem()
         self.temp_show.set_sensitive(True)
         self.temp_show.show()
         self.menu.append(self.temp_show)
 
-    ##Humidex
-        self.humidex_show = gtk.MenuItem()
-        self.humidex_show.set_sensitive(True)
-        self.humidex_show.show()
-        self.menu.append(self.humidex_show)
+    ##Relative Temperature
+        self.relative_show = Gtk.MenuItem()
+        self.relative_show.set_sensitive(True)
+        self.relative_show.show()
+        self.menu.append(self.relative_show)
 
     ##Humidity
-        self.humid_show = gtk.MenuItem()
+        self.humid_show = Gtk.MenuItem()
         self.humid_show.set_sensitive(True)
         self.humid_show.show()
         self.menu.append(self.humid_show)
 
     ##Wind
-        self.wind_show = gtk.MenuItem()
+        self.wind_show = Gtk.MenuItem()
         self.wind_show.set_sensitive(True)
         self.wind_show.show()
         self.menu.append(self.wind_show)
 
     ##Sunrise
-        self.sunrise_show = gtk.MenuItem()
+        self.sunrise_show = Gtk.MenuItem()
         self.sunrise_show.set_sensitive(True)
         self.sunrise_show.show()
         self.menu.append(self.sunrise_show)
 
     ##Sunset
-        self.sunset_show = gtk.MenuItem()
+        self.sunset_show = Gtk.MenuItem()
         self.sunset_show.set_sensitive(True)
         self.sunset_show.show()
         self.menu.append(self.sunset_show)
@@ -1179,65 +1540,68 @@
     ##Cities
         if len(self.places) != 1:
             ##Breaker
-            breaker = gtk.SeparatorMenuItem()
+            breaker = Gtk.SeparatorMenuItem()
             breaker.show()
             self.menu.append(breaker)
 
             log.debug("Indicator: menu_normal: adding first location menu item '%s'" % self.places[0][1])
-            loco1 = gtk.RadioMenuItem(None, self.places[0][1])
+            loco1 = Gtk.RadioMenuItem.new_with_label([], self.places[0][1])
             if self.placechosen == 0:
                 loco1.set_active(True)
             loco1.connect("toggled", self.on_city_changed)
             loco1.show()
             self.menu.append(loco1)
+            group = loco1.get_group()
             for place in self.places[1:]:
                 log.debug("Indicator: menu_normal: adding location menu item '%s'" % place[1])
-                loco = gtk.RadioMenuItem(loco1, place[1])
+                loco = Gtk.RadioMenuItem.new_with_label(group, place[1])
                 if self.places.index(place) == self.placechosen:
                     loco.set_active(True)
                 loco.connect("toggled", self.on_city_changed)
                 loco.show()
                 self.menu.append(loco)
+                group = loco.get_group()
 
     ##Breaker
-        breaker = gtk.SeparatorMenuItem()
+        breaker = Gtk.SeparatorMenuItem()
         breaker.show()
         self.menu.append(breaker)
 
-        self.refresh_show = gtk.MenuItem()
+        self.refresh_show = Gtk.MenuItem()
         #label will be set later
         self.refresh_show.connect("activate", self.update_weather)
         self.refresh_show.show()
         self.menu.append(self.refresh_show)
 
-        ext_show = gtk.MenuItem(_("Forecast"))
+        ext_show = Gtk.MenuItem(_("Forecast"))
         ext_show.connect("activate", self.extforecast)
         ext_show.show()
         self.menu.append(ext_show)
 
     ##Preferences
-        prefs_show = gtk.MenuItem(_("Preferences..."))
+        prefs_show = Gtk.MenuItem(_("Preferences..."))
         prefs_show.connect("activate", self.prefs)
         prefs_show.show()
         self.menu.append(prefs_show)
 
     ##About
-        about_show = gtk.MenuItem(_("About..."))
+        about_show = Gtk.MenuItem(_("About..."))
         about_show.connect("activate", self.about)
         about_show.show()
         self.menu.append(about_show)
 
     ##Quit
-        quit = gtk.ImageMenuItem(gtk.STOCK_QUIT)
+        quit = Gtk.ImageMenuItem.new_from_stock(Gtk.STOCK_QUIT, None)
         quit.connect("activate", self.quit)
         quit.show()
         self.menu.append(quit)
 
         self.winder.set_menu(self.menu)
         self.update_label(" ")
+                
 
-    # Another city has been selected from radiobutton
     def on_city_changed(self,widget):
+        """ Another city has been selected from radiobutton """
         if widget.get_active():
             for place in self.places:
                 if (place[1] == widget.get_label()):
@@ -1251,28 +1615,30 @@
             self.location_details = self.settings.get_location_details(self.place[0])
             if self.location_details in (False, None, '', '[]', "['']"):
                 log.debug("Indicator: could not parse location details for placechosen='%s'" % self.placechosen)
+                self.menu_update_lock.acquire(True)                
                 self.menu_noplace()
+                self.menu_update_lock.release()
             else:
                 self.location_details = eval(self.location_details)
             self.settings.set_value("placechosen", self.placechosen)
             self.update_weather(False)
 
     def on_system_sleep(self):
-        """
-        Callback from UPower that system suspends/hibernates
+        """Callback from UPower that system suspends/hibernates
+        
         """
         # store time
         self.sleep_time = datetime.datetime.now()
         log.debug("Indicator: system goes to sleep at %s" % self.sleep_time)
         # remove gobject timeouts
         if hasattr(self, "refresh_id"):
-            gobject.source_remove(self.refresh_id)
+            GObject.source_remove(self.refresh_id)
         if hasattr(self, "rate_id"):
-            gobject.source_remove(self.rate_id)
+            GObject.source_remove(self.rate_id)
 
     def on_system_resume(self):
-        """
-        Callback from UPower that system resumes
+        """Callback from UPower that system resumes
+        
         """
         now = datetime.datetime.now()
         log.debug("Indicator: system resumes at %s" % now)
@@ -1291,25 +1657,25 @@
             else:
                 self.update_weather()
 
-    # Schedule weather update
     def schedule_weather_update(self, rate_override = None):
+        """ Schedule the next weather update """
         if hasattr(self, "rate_id"):
-            gobject.source_remove(self.rate_id)
+            GObject.source_remove(self.rate_id)
         if rate_override:
-            self.rate_id = gobject.timeout_add(
+            self.rate_id = GObject.timeout_add(
                 int(rate_override) * 60000, self.update_weather)
         else:
-            self.rate_id = gobject.timeout_add(
+            self.rate_id = GObject.timeout_add(
                 int(self.rate) * 60000, self.update_weather)
 
-    # Schedule weather update
     def schedule_refresh_label_update(self):
+        """ Schedule the next 'Refresh' label update """
         if hasattr(self, "refresh_id"):
-            gobject.source_remove(self.refresh_id)
-        self.refresh_id = gobject.timeout_add(60000, self.update_refresh_label)
+            GObject.source_remove(self.refresh_id)
+        self.refresh_id = GObject.timeout_add(60000, self.update_refresh_label)
 
-    # Update 'Refresh' label with time since last successful data refresh
     def update_refresh_label(self, reset_minutes = None):
+        """ Update 'Refresh' label with time since last successful data refresh """
         if reset_minutes is not None:
             self.refreshed_minutes_ago = reset_minutes
         else:
@@ -1319,6 +1685,7 @@
         return False
 
     def set_refresh_label(self, refreshing=False):
+        """ Update the 'Refresh' label text """
         if refreshing:
             refresh_label=_("Refreshing, please wait")
         elif self.refreshed_minutes_ago < 0:
@@ -1329,68 +1696,97 @@
             refresh_label = "%s (%s)" % (_("Refresh"), _("%d min. ago") % self.refreshed_minutes_ago)
         self.refresh_show.set_label(refresh_label)
 
-    # Load weather data from cache and display its values
-    def show_cached_weather(self):
+    def get_cached_weather(self, queue):
+        """ Load weather data from cache and put it onto the queue """
         try:
-            self.menu_update_lock.acquire(True)
+            log.debug("Indicator: show_cached_weather: setting previous_condition to None")  #DEBUG
             self.previous_condition = None
+            log.debug("Indicator: show_cached_weather: calling settings.get_weather('%s')" % self.places[self.placechosen][0])   #DEBUG
             cached_weather = self.settings.get_weather(self.places[self.placechosen][0])
             if cached_weather is not None:
+                log.debug("Indicator: show_cached_weather: got cached_weather: '%s', len=%i)" % (cached_weather, len(cached_weather)))     #DEBUG
                 cached_weather = eval(cached_weather)
+                log.debug("Indicator: show_cached_weather: after eval(), cached_weather is: '%s', len=%i" % (cached_weather, len(cached_weather)))    #DEBUG
                 log.debug("Indicator: loading weather from cache for %s" % self.places[self.placechosen])
-                self.menu_normal()
-                self.set_refresh_label(True)
-                self.icon = cached_weather['icon']
-                if (self.icon == False):
-                    self.winder.set_icon(os.path.join(PROJECT_ROOT_DIRECTORY, "share/indicator-weather/media/icon_unknown_condition.png"))
-                else:
-                    self.winder.set_icon(self.icon)
+            # Put the cached weather onto to the Queue
+            queue.put(cached_weather)
+        except Exception, e:
+            log.error(e)
+            log.debug(traceback.format_exc(e))
 
-                self.city_show.set_label(self.places[self.placechosen][1])
-                self.previous_condition = cached_weather['condition']
-                self.cond_show.set_label(cached_weather['condition'])
-                self.temp_show.set_label(cached_weather['temper'])
-                if cached_weather['humidex'] != None:
-                    self.humidex_show.set_label(cached_weather['humidex'])
-                else:
-                    self.humidex_show.destroy()
-                self.humid_show.set_label(cached_weather['humidity'])
+    def show_cached_weather(self, cached_weather):
+        """ Update the indicator icon, label and menu with cached weather data """
+        try:
+            self.menu_normal()
+            log.debug("Indicator: show_cached_weather: calling set_refresh_label")    #DEBUG
+            self.set_refresh_label(True)
+            log.debug("Indicator: show_cached_weather: setting icon")    #DEBUG
+            self.icon = cached_weather['icon']
+            if (self.icon == False):
+                self.winder.set_icon(os.path.join(PROJECT_ROOT_DIRECTORY, "share/indicator-weather/media/icon_unknown_condition.png"))
+            else:
+                self.winder.set_icon(self.icon)
+    
+            log.debug("Indicator: show_cached_weather: set_label for city_show")  #DEBUG
+            self.city_show.set_label(self.places[self.placechosen][1])
+            log.debug("Indicator: show_cached_weather: setting previous_condition from cache")   #DEBUG
+            self.previous_condition = cached_weather['condition']
+            log.debug("Indicator: show_cached_weather: set_label for cond_show")  #DEBUG
+            self.cond_show.set_label(cached_weather['condition'])
+            log.debug("Indicator: show_cached_weather: set_label for temp_show")  #DEBUG
+            self.temp_show.set_label(cached_weather['temper'])
+            log.debug("Indicator: show_cached_weather: checking feelslike value")  #DEBUG                
+            if (self.show_relative and cached_weather['feelslike'] != None):
+                self.relative_show.set_visible(True)
+                self.relative_show.set_label(cached_weather['feelslike'])
+            else:
+                self.relative_show.set_visible(False)
+            log.debug("Indicator: show_cached_weather: set_label for humid_show")  #DEBUG
+            self.humid_show.set_label(cached_weather['humidity'])
+            if self.show_wind:
+                log.debug("Indicator: show_cached_weather: set_label for wind_show")  #DEBUG
+                self.wind_show.set_visible(True)
                 self.wind_show.set_label(cached_weather['wind'])
+            else:
+                self.wind_show.set_visible(False)
+            if self.show_suntimes:
+                log.debug("Indicator: show_cached_weather: set_label for sunrise_show")  #DEBUG
+                self.sunrise_show.set_visible(True)
                 self.sunrise_show.set_label(cached_weather['sunrise'])
+                log.debug("Indicator: show_cached_weather: set_label for sunset_show")  #DEBUG
+                self.sunset_show.set_visible(True)
                 self.sunset_show.set_label(cached_weather['sunset'])
-                self.update_label(cached_weather['label'])
-                self.winder.set_status(appindicator.STATUS_ATTENTION)
-                self.winder.set_status(appindicator.STATUS_ACTIVE)
+            else:
+                self.sunrise_show.set_visible(False)
+                self.sunset_show.set_visible(False)
 
+            log.debug("Indicator: show_cached_weather: calling update_label")  #DEBUG
+            self.update_label(cached_weather['label'])
+                        
         except Exception, e:
             log.error(e)
             log.debug(traceback.format_exc(e))
 
-        self.menu_update_lock.release()
-
-    # Get fresh weather data
-    def get_new_weather_data(self, notif = True):
-
+    def get_new_weather_data(self, notif, queue):
+        """ Get fresh weather data from source and put it onto the queue """
+        log.debug("Indicator: entered get_new_weather_data")        #DEBUG
         # get weather and catch any exception
         weather = None
         try:
             weather = self.get_weather()
-
         except urllib2.URLError, e:
             weather = None
             log.error("Indicator: networking error: %s" % e)
-
         except Exception, e:
             weather = None
             log.error(e)
             log.debug(traceback.format_exc(e))
+        # Put the new weather data onto the Queue
+        queue.put(weather)
 
+    def show_new_weather_data(self, weather):
+        """ Update the indicator icon, label and menu with new weather data """
         try:
-            # wait until cacher finishes
-            log.debug("Indicator: updateWeather: waiting for 'Cacher' thread to terminate")
-            self.menu_update_lock.acquire(True)
-            self.menu_update_lock.release()
-
             if weather is None:
                 # remove the "Refreshing" status
                 self.set_refresh_label()
@@ -1399,35 +1795,58 @@
                 # Repeat an attempt in one minute
                 self.schedule_weather_update(1)
                 return
-
+            
             # Fill in menu with data
             log.debug("Indicator: updateWeather: got condition '%s', icon '%s'" % (self.condition, self.icon))
             self.condition = weather.get_condition_label()
             self.icon = weather.get_icon_name()
-            log.debug("Indicator: fill in menu with params: city='%s', temp='%s', humid='%s', wind='%s', sunrise='%s', sunset='%s', puretemp=%s" % (self.places[self.placechosen][1], weather.get_temperature_label(), weather.get_humidity_label(), weather.get_wind_label(), weather.get_sunrise_label(), weather.get_sunset_label(), weather.get_temperature()))
-
+            log.debug("Indicator: fill in menu with params: " \
+                      "city='%s', temp='%s', humid='%s', " \
+                      "wind='%s', sunrise='%s', sunset='%s', " \
+                      "puretemp=%s" % (self.places[self.placechosen][1],
+                                       weather.get_temperature_label(),
+                                       weather.get_humidity_label(),
+                                       weather.get_wind_label(),
+                                       weather.get_sunrise_label(),
+                                       weather.get_sunset_label(),
+                                       weather.get_temperature_string()))
             self.menu_normal()
             self.update_refresh_label(0)
             self.city_show.set_label(self.places[self.placechosen][1])
             self.cond_show.set_label(self.condition)
             self.temp_show.set_label(weather.get_temperature_label())
-            if (weather.get_humidex_label() != None):
-                self.humidex_show.set_label(weather.get_humidex_label())
+            _relative_label = weather.get_relative_label()
+            if (self.show_relative and "---" not in _relative_label):
+                log.debug("Indicator: updateWeather: _relative_label is not None")      # DEBUG
+                self.relative_show.set_visible(True)
+                self.relative_show.set_label(_relative_label)
             else:
-                self.humidex_show.destroy()
+                log.debug("Indicator: updateWeather: label = None")      # DEBUG
+                self.relative_show.set_visible(False)
             self.humid_show.set_label(weather.get_humidity_label())
-            self.wind_show.set_label(weather.get_wind_label())
-            self.sunrise_show.set_label(weather.get_sunrise_label())
-            self.sunset_show.set_label(weather.get_sunset_label())
-
-            # Saving cached data, unless correct icon is supplied
+            if self.show_wind:
+                self.wind_show.set_visible(True)
+                self.wind_show.set_label(weather.get_wind_label())
+            else:
+                self.wind_show.set_visible(False)
+            if self.show_suntimes:
+                self.sunrise_show.set_visible(True)
+                self.sunrise_show.set_label(weather.get_sunrise_label())
+                self.sunset_show.set_visible(True)
+                self.sunset_show.set_label(weather.get_sunset_label())
+            else:
+                self.sunrise_show.set_visible(False)
+                self.sunset_show.set_visible(False)
+    
+            # Save cached data if correct icon is supplied
             if (self.icon == False):
                 self.winder.set_icon(os.path.join(PROJECT_ROOT_DIRECTORY, "share/indicator-weather/media/icon_unknown_condition.png"))
             else:
                 self.winder.set_icon(self.icon)
                 self.settings.save_weather(weather, self.places[self.placechosen][0])
-            self.update_label(weather.get_temperature(needs_rounding=True))
-
+            # Update the indicator label
+            self.update_label(weather.get_temperature_string())
+    
             # Notify user, if notifications are enabled
             if self.condition != self.previous_condition and self.notif == 'U':
                 # Weather condition has changed
@@ -1437,53 +1856,83 @@
                 # Severe weather condition notification
                 log.debug("Indicator: updateWeather: severe condition notification")
                 self.notify(self.condition, self.icon, severe=True)
-
+            # Save the current condition to track changes for notifications
             self.previous_condition = self.condition
-
         except Exception, e:
             log.error(e)
             log.debug(traceback.format_exc(e))
 
+        # Schedule the next weather fetch    
         self.schedule_weather_update()
-
-    # Update weather
+        
     def update_weather(self, notif=True, widget=None):
-        log.debug("Indicator: updateWeather: updating weather for %s" % self.places[self.placechosen])
+        """ Update the displayed weather data from cache and fetch new data """
+        #TODO: rewrite this to use a single queue? (have threads .put() dicts into queue?)
+        
+        log.debug("Indicator: updateWeather: updating weather for %s" %
+                  self.places[self.placechosen])
         # First, display cached data
-        threading.Thread(target=self.show_cached_weather, name='Cache').start()
+        cache_queue = Queue.Queue()
+        log.debug("Indicator: updateWeather: spawning Cache thread -> show_cached_weather()")       #DEBUG
+        cache_thread = threading.Thread(target=self.get_cached_weather,
+                                        name='Cache', args=(cache_queue,))
+        cache_thread.start()
+        
         # Then, start a new thread with real data pickup
-        threading.Thread(target=self.get_new_weather_data, name='Fetcher').start()
-
-    # Get current weather for selected location
+        fetcher_queue = Queue.Queue()
+        log.debug("Indicator: updateWeather: spawning Fetcher thread -> get_new_weather_data()")       #DEBUG
+        fetcher_thread = threading.Thread(target=self.get_new_weather_data,
+                                          name='Fetcher',
+                                          args=(self.notif, fetcher_queue))
+        fetcher_thread.start()
+
+        # Update the menu with the cached weather
+        cache_thread.join()
+        cached_weather = cache_queue.get()
+        if cached_weather is not None:
+            self.show_cached_weather(cached_weather)        
+
+        # Update the menu with the new weather
+        fetcher_thread.join()
+        weather = fetcher_queue.get()
+        #TODO: is this conditional necessary?
+        if weather is not None:
+            self.show_new_weather_data(weather)
+
     def get_weather(self):
-        log.debug("Indicator: getWeather for location '%s'" % self.location_details['full name'])
-        self.current_location = Location(self.metric_system, self.wind_unit, self.location_details)
+        """ Get current weather for selected location """
+        log.debug("Indicator: getWeather for location '%s'" %
+                  self.location_details['full name'])
+        log.debug("Indicator: getWeather: location_details=%s" % self.location_details) #DEBUG
+        self.current_location = Location(self.metric_system, self.wind_unit,
+                                         self.heat_index, self.chill_index,
+                                         self.location_details)
         log.debug("Indicator: getWeather: updating weather report")
         self.current_location.update_weather_data(self.weather_source)
         return self.current_location.weather
 
-    # Show notification to user
-    def notify(self,conditon,icon,severe=False):
-        log.debug("Indicator: Notify on weather condition, severe=%s, condition=%s, icon=%s" % (severe, self.condition, icon))
+    def notify(self,condition,icon,severe=False):
+        """ Show notification to user according to preferences """
+        log.debug("Indicator: Notify on weather condition, severe=%s, condition=%s, icon=%s" % (severe, condition, icon))
         if severe:
-			n = pynotify.Notification (_("Severe weather alert"),
-                self.condition,
-                icon)
+            n = Notify.Notification (_("Severe weather alert"),
+                                       condition,
+                                       icon)
         else:
-		    n = pynotify.Notification (self.condition, "", icon)
+            n = Notify.Notification (condition, "", icon)
         n.show ()
 
-    # Menu callbacks
-    # Open Preferences dialog
     def prefs(self, widget):
+        """ Menu callback to open Preferences dialog """
         log.debug("Indicator: open Preferences")
         if ((not hasattr(self, 'prefswindow')) or (not self.prefswindow.get_visible())):
             self.prefswindow = PreferencesDialog()
             self.prefswindow.show()
 
     def about(self, widget):
+        """ Menu callback to open About dialog """
         log.debug("Indicator: open About dialog")
-        self.aboutdialog = gtk.AboutDialog()
+        self.aboutdialog = Gtk.AboutDialog()
         self.aboutdialog.set_name(_("Weather Indicator"))
         self.aboutdialog.set_version(VERSION)
 
@@ -1498,45 +1947,47 @@
         self.aboutdialog.set_website("https://launchpad.net/weather-indicator";)
         self.aboutdialog.set_translator_credits(_("translator-credits"))
         logo_path = os.path.join(PROJECT_ROOT_DIRECTORY, "share/indicator-weather/media/icon.png")
-        self.aboutdialog.set_logo(gtk.gdk.pixbuf_new_from_file(logo_path))
-
+        self.aboutdialog.set_logo(GdkPixbuf.Pixbuf.new_from_file(logo_path))
 
         self.aboutdialog.connect("response", self.about_close)
         self.aboutdialog.show()
 
     def about_close(self, widget, event=None):
+        """ Menu callback to close About dialog """
         log.debug("Indicator: closing About dialog")
         self.aboutdialog.destroy()
 
-    # Open Extended forecast window
     def extforecast(self, widget):
+        """ Menu callback to open Extended forecast window """
         log.debug("Indicator: open Forecast")
         if ((not hasattr(self, 'forecastwd')) or (not self.forecastwd.get_visible())):
             self.forecastwd = ExtendedForecast()
             self.forecastwd.show()
 
-    # Quit the applet
     def quit(self, widget, data=None):
+        """ Menu callback to quit the indicator applet """
         log.debug("Indicator: Quitting")
-        gtk.main_quit()
+        Gtk.main_quit()
 
-class PreferencesDialog(gtk.Dialog):
+class PreferencesDialog(Gtk.Dialog):
     """ Class for preferences dialog """
     __gtype_name__ = "PreferencesDialog"
 
-    # Creating a new preferences dialog
     def __new__(cls):
+        """ Creating a new preferences dialog """
         log.debug("Preferences: creating")
         builder = get_builder('PreferencesDialog')
         new_object = builder.get_object("preferences_dialog")
         new_object.finish_initializing(builder)
         return new_object
 
-    # Fill in preferences dialog with currect data
     def finish_initializing(self, builder):
+        """ Fill in preferences dialog with correct data """
         log.debug("Preferences: finishing initialization")
-        log.debug("Preferences: got settings: unit=%s, notif=%s, wind=%s, rate=%s, source=%s" %
-                (wi.unit, wi.notif, wi.wind, wi.rate, wi.source))
+        log.debug("Preferences: got settings: unit=%s, notif=%s, wind=%s, "
+                  "rate=%s, source=%s, heat=%s, chill=%s" %
+                  (wi.unit, wi.notif, wi.wind, wi.rate, wi.source,
+                   wi.heat, wi.chill))
         self.builder = builder
 
         # Set correct wind_unit using dictionary of wind value and object name
@@ -1547,11 +1998,16 @@
         self.builder.get_object('show_label').set_active(wi.show_label)
         self.builder.get_object('show_label').set_visible(hasattr(wi.winder, 'set_label'))
         self.builder.get_object('rate').set_value(float(wi.rate))
+        self.builder.get_object(wi.heat_estimates[wi.heat][0]).set_active(True)
+        self.builder.get_object(wi.chill_estimates[wi.chill][0]).set_active(True)
+        self.builder.get_object('show_relative').set_active(wi.show_relative)
+        self.builder.get_object('show_wind').set_active(wi.show_wind)
+        self.builder.get_object('show_suntimes').set_active(wi.show_suntimes)
 
         log.debug("Preferences: Loading places")
         if wi.places != None:
             for place in wi.places:
-                if len(place)>1:
+                if len(place)>1 and place[0] is not None:
                     log.debug("Preferences: Places: got (%s, %s)" % (place[1], place[0]))
                     newplace = list()
                     newplace.append(place[1])
@@ -1563,32 +2019,65 @@
 
         self.builder.connect_signals(self)
 
-    # 'Remove' clicked - remove location from list
-    #TODO: Update settings object
     def on_remove_location(self, widget):
+        """ 'Remove' clicked - remove location from list """
+        # TODO: Update settings object
         selection = self.builder.get_object('location_list').get_selection()
         model, iter = selection.get_selected()
         if iter != None:
             log.debug("Preferences: Removing location %s (code %s)" % (model[iter][0], model[iter][1]))
+##            placename = model[iter][0]
+            log.debug("Preferences: Need to update settings object here")            # DEBUG
+            log.debug("wi.settings.places = %s" % wi.settings.get_value("places"))       # DEBUG
+            log.debug("wi.places = %s" % wi.places)                                 # DEBUG
+            log.debug("Should to remove above location from wi.places and wi.settings")     # DEBUG
             model.remove(iter)
-
+# TODO: Fix code to update Settings object here
+# need to update both of these:
+#            wi.places
+#            wi.settings.set_value("places").set_places
+##"""
+##        # Get places from location list
+##        newplaces = list()
+##        item = self.builder.get_object('citieslist').get_iter_first()
+##        while (item != None):
+##            newplace = list()
+##            newplace.append(self.builder.get_object('citieslist').get_value (item, 1))
+##            newplace.append(self.builder.get_object('citieslist').get_value (item, 0))
+##            newplaces.append(newplace)
+##            item = self.builder.get_object('citieslist').iter_next(item)
+##
+##        # If places have changed - update weather data
+##        if newplaces != wi.places:
+##            wi.places = newplaces
+##            log.debug("Preferences: Places changed to '%s'" % str(wi.places))
+##            wi.settings.set_value("places", str(wi.places))
+##            if (type(wi.place) != None) and (wi.place in wi.places):
+##                wi.placechosen = wi.places.index(wi.place)
+##            else:
+##                wi.placechosen = 0
+##                wi.place = wi.places[0]
+##"""
+##            places = eval(wi.places)
+            
         if (self.builder.get_object('citieslist').get_iter_first() == None):
             self.builder.get_object('ok_button').set_sensitive(False)
-
-    # 'Add' clicked - create a new Assistant
+        
     def on_add_location(self, widget):
+        """ 'Add' clicked - create a new Assistant """
         log.debug("Preferences: Add location clicked")
         if ((not hasattr(self, 'assistant')) or (not self.assistant.get_visible())):
             self.assistant = Assistant()
             self.assistant.show()
 
-    # 'OK' clicked - save settings
     def ok(self, widget, data=None):
+        """ 'OK' clicked - save settings """
+        #TODO: rewrite this to copy all pertinent values to a queue, then destroy the window
         log.debug("Preferences: Saving settings")
         need_to_update_weather = False
         need_to_update_indicator = False
 
-        #Show label near icon
+        # Show label near icon
         new_show_label = self.builder.get_object('show_label').get_active()
         if (wi.show_label != new_show_label):
             wi.show_label = new_show_label
@@ -1597,6 +2086,30 @@
             need_to_update_indicator = True
             log.debug("Preferences: Show Label changed to '%s'" % wi.show_label)
 
+        # Show relative temperature
+        new_show_relative = self.builder.get_object('show_relative').get_active()
+        if (wi.show_relative != new_show_relative):
+            wi.show_relative = new_show_relative
+            wi.settings.set_value("show_relative", new_show_relative)
+            need_to_update_weather = True
+            log.debug("PreferencesDialog: Show Relative Temp changed to %s" % wi.show_relative)
+            
+        # Show wind speed & direction
+        new_show_wind = self.builder.get_object('show_wind').get_active()
+        if (wi.show_wind != new_show_wind):
+            wi.show_wind = new_show_wind
+            wi.settings.set_value("show_relative", new_show_wind)
+            need_to_update_weather = True
+            log.debug("PreferencesDialog: Show Wind Data changed to %s" % wi.show_wind)
+        
+        # Show sunrise & sunset times
+        new_show_suntimes = self.builder.get_object('show_suntimes').get_active()
+        if (wi.show_suntimes != new_show_suntimes):
+            wi.show_suntimes = new_show_suntimes
+            wi.settings.set_value("show_suntimes", new_show_suntimes)
+            need_to_update_weather = True
+            log.debug("PreferencesDialog: Show Sunrise/Sunset Times changed to %s" % wi.show_suntimes)
+        
         # Metric systems
         for k in wi.metric_systems.keys():
             if self.builder.get_object(wi.metric_systems[k][0]).get_active():
@@ -1634,6 +2147,32 @@
             need_to_update_weather = True
             log.debug("Preferences: Wind Unit changed to '%s'" % wi.wind)
 
+        # Heat estimate formula
+        for k in wi.heat_estimates.keys():
+            if self.builder.get_object(wi.heat_estimates[k][0]).get_active():
+                new_heat_index = k
+                new_heat_estimate = wi.heat_estimates[k][1]
+
+        if (wi.heat != new_heat_index):
+            wi.heat = new_heat_index
+            wi.heat_index = new_heat_estimate
+            wi.settings.set_value("heat", wi.heat)
+            need_to_update_weather = True
+            log.debug("Preferences: Heat Estimate changed to '%s'" % wi.heat)
+
+        # Chill estimate formula
+        for k in wi.chill_estimates.keys():
+            if self.builder.get_object(wi.chill_estimates[k][0]).get_active():
+                new_chill_index = k
+                new_chill_estimate = wi.chill_estimates[k][1]
+
+        if (wi.chill != new_chill_index):
+            wi.chill = new_chill_index
+            wi.chill_index = new_chill_estimate
+            wi.settings.set_value("chill", wi.chill)
+            need_to_update_weather = True
+            log.debug("Preferences: Chill Estimate changed to '%s'" % wi.chill)
+
         # Weather source
         for k in wi.weather_sources.keys():
             if self.builder.get_object(wi.weather_sources[k][0]).get_active():
@@ -1677,8 +2216,8 @@
             log.debug("Preferences: Place Chosen changed to '%s'" % wi.placechosen)
             wi.settings.set_value("placechosen", wi.placechosen)
             wi.location_details = eval(wi.settings.get_location_details(wi.place[0]))
-            wi.menu_normal()
-            wi.set_refresh_label()
+##            wi.menu_normal()
+##            wi.set_refresh_label()
             need_to_update_weather = True
 
         if need_to_update_weather:
@@ -1689,34 +2228,34 @@
 
         self.destroy()
 
-    # 'Cancel' click - forget all changes
     def cancel(self, widget, data=None):
+        """ 'Cancel' clicked - forget all changes """
         log.debug("Preferences: Cancelling")
         self.destroy()
 
-class ExtendedForecast(gtk.Window):
+class ExtendedForecast(Gtk.Window):
     """ Class for forecast window """
     __gtype_name__ = "ExtendedForecast"
 
-    # Create forecast
     def __new__(cls):
+        """ Create forecast """
         log.debug("ExtendedForecast: creating")
         builder = get_builder('ExtendedForecast')
         new_object = builder.get_object("extended_forecast")
         new_object.finish_initializing(builder)
         return new_object
 
-    # Fill in forecast parameters
     def finish_initializing(self, builder):
+        """ Fill in forecast parameters """
         log.debug("ExtendedForecast: finishing initialization")
         self.builder = builder
         self.builder.connect_signals(self)
 
         # Get forecast data using Forecast object
         log.debug("ExtendedForecast: chosen place: %s (code %s)" % (wi.places[wi.placechosen][1], wi.places[wi.placechosen][0]))
-        self.builder.get_object('extended_forecast').set_title("%s %s" % (_('Weather Forecast for '), wi.places[wi.placechosen][1]))
+        self.builder.get_object('extended_forecast').set_title("%s %s" % (_('Weather Forecast for'), wi.places[wi.placechosen][1]))
         log.debug("ExtendedForecast: getting forecast data")
-        forecast = Forecast(wi.metric_system, wi.current_location.location_details['latitude'], wi.current_location.location_details['longitude'], locale_name)
+        forecast = Forecast(wi.metric_system, wi.current_location.location_details['yahoo id'], locale_name)
         forecast.prepare_forecast_data()
         if forecast.error_message != None:
             #Error occurred while getting forecast data
@@ -1728,9 +2267,9 @@
             forecast_data = forecast.get_forecast_data()
             if forecast_data == None:
                 # Forecast data unavailable - hide elements and show 'connection_error' label
-                self.builder.get_object('connection_error').set_visible(True);
-                self.builder.get_object('hbox1').set_visible(False);
-                self.builder.get_object('hseparator1').set_visible(False);
+                self.builder.get_object('connection_error').set_visible(True)
+                self.builder.get_object('hbox1').set_visible(False)
+                self.builder.get_object('hseparator1').set_visible(False)
                 return
             (highdata, lowdata) = forecast_data
             icons      = forecast.get_forecast_icons()
@@ -1745,19 +2284,19 @@
 
             # Fill in icons
             for i in xrange(1,5):
-                # Get icon name from dictionary in Weather object for Google icons
+                # Get icon name from dictionary in Weather object for Yahoo condition codes
                 try:
-                    conds = Weather._GoogleConditions.get(icons[i-1])
+                    conds = Weather._YahooConditions.get(icons[i-1])
                     if conds != None:
-                        google_icon = conds[0]
+                        yahoo_icon = conds[0]
                     else:
-                        log.error("ExtendedForecast: unknown Google weather condition '%s'" % icons[i-1])
+                        log.error("ExtendedForecast: unknown Yahoo weather condition code '%s'" % icons[i-1])
                         log.error(forecast.forecast)
-                        google_icon = 'weather-indicator-unknown'
-                    self.builder.get_object('day%simage' % str(i)).set_from_icon_name(google_icon,gtk.ICON_SIZE_BUTTON)
+                        yahoo_icon = 'weather-indicator-unknown'
+                    self.builder.get_object('day%simage' % str(i)).set_from_icon_name(yahoo_icon,Gtk.IconSize.BUTTON)
                 except IndexError:
-                     log.error("ExtendedForecast: Google didn't return condition for %s days" % i-1)
-                     log.error(forecast.forecast)
+                    log.error("ExtendedForecast: Yahoo didn't return condition for %s days" % i-1)
+                    log.error(forecast.forecast)
 
             # Fill in condition labels
             for i in xrange(1,5):
@@ -1768,38 +2307,38 @@
                 self.builder.get_object('day%scond' % str(i)).set_label(condition)
 
             # Fill in High and Low temperatures
-            if wi.metric_system == MetricSystem.SI:
-                tempunit = '°C'
+            if wi.metric_system == UnitSystem.SI:
+                tempunit = u"°C"
             else:
-                tempunit = '°F'
+                tempunit = u"°F"
             for i in xrange(1,5):
                 label = "%s: %s%s" % (_('High'), highdata[i-1],tempunit)
                 self.builder.get_object('day%stemphigh' % str(i)).set_label(label)
                 label = "%s: %s%s" % (_('Low'), lowdata[i-1],tempunit)
                 self.builder.get_object('day%stemplow' % str(i)).set_label(label)
 
-    # Closing forecast window
     def close(self, widget, data=None):
+        """ 'Close' clicked - close forecast window """
         log.debug("ExtendedForecast: closing window")
         self.destroy()
 
     def on_destroy(self, widget):
         pass
 
-class Assistant(gtk.Assistant):
+class Assistant(Gtk.Assistant):
     """ Class for a wizard, which helps to add a new location in location list """
     __gtype_name__ = "Assistant"
 
-    # Create new object
     def __new__(cls):
+        """ Create new object """
         log.debug("Assistant: creating new Assistance instance")
         builder = get_builder('Assistant')
         new_object = builder.get_object("assistant")
         new_object.finish_initializing(builder)
         return new_object
 
-    # Finish UI initialization - prepare combobox
     def finish_initializing(self, builder):
+        """ Finish UI initialization - prepare combobox """
         log.debug("Assistant: finishing initialization")
         self.builder = builder
         self.builder.connect_signals(self)
@@ -1809,18 +2348,18 @@
 
         # Set up combobox
         log.debug("Assistant: setting up location combobox")
-        self.store = gtk.ListStore(str, str, str, str, str)
+        self.store = Gtk.ListStore(str, str, str, str, str)
         self.location_input_combo = self.builder.get_object("combolocations")
         self.location_input_combo.set_model(self.store)
-        self.location_input_combo.set_text_column(0)
+        self.location_input_combo.set_entry_text_column(0)
         self.location_entry = self.builder.get_object("entrylocation")
         self.place_selected = None
         self.location = None
 
-        self.assistant.set_forward_page_func(self.next_page)
+        self.assistant.set_forward_page_func(self.next_page, None)
 
-    # 'Get cities' button clicked - get suggested cities list
     def on_get_city_names(self, widget):
+        """ 'Get cities' button clicked - get suggested cities list """
         new_text = self.location_entry.get_text()
         log.debug("Assistant: looking for location '%s'" % new_text)
         try:
@@ -1843,8 +2382,8 @@
         except urllib2.URLError:
             log.error("Assistant: error reaching url '%s'" % url)
 
-    # A city is selected from suggested list
     def on_select_city(self, entry):
+        """ A city is selected from suggested list """
         if self.location_input_combo.get_active() != -1:
             self.place_selected = self.store[self.location_input_combo.get_active()]
             self.assistant.set_page_complete(self.builder.get_object("placeinput"),True)
@@ -1853,13 +2392,13 @@
             self.location = None
             self.assistant.set_page_complete(self.builder.get_object("placeinput"), False)
 
-    # Create a location object out of a selected location
-    def next_page(self, current_page):
+    def next_page(self, current_page, data):
+        """ Create a location object out of a selected location """
         log.debug("Assistant: moved to page %s" % current_page)
         if (self.assistant.get_current_page() == 0) and not self.location and self.place_selected:
             # Label input page
             log.debug("Assistant: Page %s: got location with code %s" % (current_page, self.place_selected[1]))
-            self.location = Location(wi.metric_system, wi.wind_unit)
+            self.location = Location(wi.metric_system, wi.wind_unit, wi.heat_index, wi.chill_index)
             if self.location.prepare_location(self.place_selected):
                 log.debug("Assistant: Page %s: City %s found" % (current_page, self.place_selected[0]))
                 # Set a short city name as default label
@@ -1882,13 +2421,13 @@
 
         return self.assistant.get_current_page() + 1
 
-    # 'Cancel' clicked
     def on_cancel(self,widget):
+        """ 'Cancel' clicked """
         log.debug("Assistant: Cancelled")
         self.destroy()
 
-    # 'Apply' clicked - save location details, add an entry in a location list
     def on_apply(self,widget):
+        """ 'Apply' clicked - save location details, add an entry in a location list """
         (location_code, location_details) = self.location.export_location_details()
         log.debug("Assistant: Apply: adding location ('%s', '%s')" % (self.location.location_details['label'], location_code))
         newplace = list()
@@ -1904,8 +2443,8 @@
 class SingleInstance(object):
     """ Class to ensure, that single instance of the applet is run for each user """
 
-    # Initialize, specifying a path to store pids
     def __init__(self, pidPath):
+        """ Initialize, specifying a path to store pids """
         self.pidPath=pidPath
         # See if pidFile exists
         if os.path.exists(pidPath):
@@ -1939,7 +2478,8 @@
             os.unlink(self.pidPath)
 
 def main():
-    gtk.main()
+    Gtk.main()
+
     return 0
 
 if __name__ == "__main__":
@@ -1974,8 +2514,7 @@
     TimeFormatter.monitor_indicator_datetime(log)
 
     # not running, safe to continue...
-    gtk.gdk.threads_init()
-    gtk.gdk.threads_enter()
+
     # Remember locale name
     global locale_name
     locale_name = locale.getlocale()[0]
@@ -1984,6 +2523,20 @@
     else:
         locale.setlocale(locale.LC_ALL, 'C') # use default (C) locale
         locale_name = "en"
+
+    # init GLib/GObject
+    GObject.threads_init()
+
+    # init Gdk threads and get Gdk lock
+    Gdk.threads_init()
+    Gdk.threads_enter()
+    
+    # init Gtk
+    Gtk.init(None)
+
+    # create main thread and enter main loop
     wi = indicator_weather()
     main()
-    gtk.gdk.threads_leave()
+    
+    # release Gdk lock
+    Gdk.threads_leave()   
\ No newline at end of file

=== modified file 'data/indicator-weather.gschema.xml'
--- data/indicator-weather.gschema.xml	2011-05-31 09:49:23 +0000
+++ data/indicator-weather.gschema.xml	2013-05-18 18:24:25 +0000
@@ -6,6 +6,21 @@
       <summary>Display icon/label in the indicator</summary>
       <description>0 - display icon only, 1 - display label only, 2 - display both icon and text</description>
     </key>
+    <key type="b" name="relative-display">
+      <default>false</default>
+      <summary>Display relative temperature</summary>
+      <description>Display relative temperature</description>
+    </key>
+    <key type="b" name="wind-display">
+      <default>true</default>
+      <summary>Display wind speed and direction</summary>
+      <description>Display wind speed and direction</description>
+    </key>
+    <key type="b" name="suntimes-display">
+      <default>true</default>
+      <summary>Display sunrise and sunset times</summary>
+      <description>Display sunrise and sunset times</description>
+    </key>
     <key type="s" name="notifications">
       <default>'N'</default>
       <summary>Notifications</summary>
@@ -36,6 +51,16 @@
       <summary>wind unit</summary>
       <description>wind unit</description>
     </key>
+    <key type="s" name="heat-estimate">
+      <default>'humidex'</default>
+      <summary>heat estimate formula</summary>
+      <description>heat estimate formula</description>
+    </key>
+    <key type="s" name="chill-estimate">
+      <default>'windchill'</default>
+      <summary>chill estimate formula</summary>
+      <description>chill estimate formula</description>
+    </key>
     <key type="b" name="show-forecast">
       <default>true</default>
       <summary>show forecast</summary>

=== modified file 'data/ui/Assistant.ui'
--- data/ui/Assistant.ui	2011-04-03 05:00:19 +0000
+++ data/ui/Assistant.ui	2013-05-18 18:24:25 +0000
@@ -1,29 +1,28 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <interface>
-  <requires lib="gtk+" version="2.16"/>
+  <!-- interface-requires gtk+ 3.0 -->
   <!-- interface-requires assistant 1.0 -->
-  <!-- interface-naming-policy project-wide -->
   <!-- interface-local-resource-path ../media -->
   <object class="Assistant" id="assistant">
+    <property name="can_focus">False</property>
     <property name="border_width">12</property>
     <property name="title" translatable="yes">Add a location</property>
+    <property name="resizable">False</property>
     <property name="window_position">mouse</property>
     <property name="default_width">400</property>
     <property name="default_height">200</property>
-    <property name="resizable">False</property>
-    <signal name="apply" handler="on_apply"/>
-    <signal name="cancel" handler="on_cancel"/>
-    <!--<child>
-      <placeholder/>
-    </child> -->
+    <signal name="apply" handler="on_apply" swapped="no"/>
+    <signal name="cancel" handler="on_cancel" swapped="no"/>
     <child>
       <object class="GtkVBox" id="placeinput">
         <property name="visible">True</property>
+        <property name="can_focus">False</property>
         <property name="border_width">12</property>
         <property name="spacing">6</property>
         <child>
           <object class="GtkLabel" id="lblplaceinput">
             <property name="visible">True</property>
+            <property name="can_focus">False</property>
             <property name="xalign">0</property>
             <property name="yalign">0</property>
             <property name="ypad">6</property>
@@ -32,43 +31,56 @@
             <property name="wrap_mode">word-char</property>
           </object>
           <packing>
+            <property name="expand">True</property>
+            <property name="fill">True</property>
             <property name="position">0</property>
           </packing>
         </child>
         <child>
-            <object class="GtkHBox" id="city_input_vbox">
-                <property name="visible">True</property>
-                <property name="border_width">12</property>
-                <property name="spacing">6</property>
-                <child>
-                    <object class="GtkComboBoxEntry" id="combolocations">
-                        <property name="visible">True</property>
-                        <signal name="changed" handler="on_select_city"/>
-                        <child internal-child="entry"> 
-                            <object class="GtkEntry" id="entrylocation"> 
-                                <property name="visible">True</property> 
-                                <property name="can_focus">True</property>
-                            </object> 
-                        </child> 
-                    </object>
-                    <packing>
-                        <property name="position">0</property>
-                    </packing>
-                </child>
-                <child>
-                    <object class="GtkButton" id="getcities">
-                        <property name="visible">True</property>
-                        <property name="label" translatable="yes">Search</property>
-                        <signal name="clicked" handler="on_get_city_names"/>
-                    </object>
-                    <packing>
-                        <property name="position">1</property>
-                    </packing>
-                </child>
-            </object>
-            <packing>
+          <object class="GtkHBox" id="city_input_vbox">
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+            <property name="border_width">12</property>
+            <property name="spacing">6</property>
+            <child>
+              <object class="GtkComboBox" id="combolocations">
+                <property name="visible">True</property>
+                <property name="can_focus">False</property>
+                <property name="has_entry">True</property>
+                <signal name="changed" handler="on_select_city" swapped="no"/>
+                <child internal-child="entry">
+                  <object class="GtkEntry" id="entrylocation">
+                    <property name="visible">True</property>
+                    <property name="can_focus">True</property>
+                  </object>
+                </child>
+              </object>
+              <packing>
+                <property name="expand">True</property>
+                <property name="fill">True</property>
+                <property name="position">0</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkButton" id="getcities">
+                <property name="label" translatable="yes">Search</property>
+                <property name="visible">True</property>
+                <property name="can_focus">False</property>
+                <property name="receives_default">False</property>
+                <signal name="clicked" handler="on_get_city_names" swapped="no"/>
+              </object>
+              <packing>
+                <property name="expand">True</property>
+                <property name="fill">True</property>
                 <property name="position">1</property>
-            </packing>
+              </packing>
+            </child>
+          </object>
+          <packing>
+            <property name="expand">True</property>
+            <property name="fill">True</property>
+            <property name="position">1</property>
+          </packing>
         </child>
       </object>
       <packing>
@@ -78,16 +90,19 @@
     <child>
       <object class="GtkVBox" id="label">
         <property name="visible">True</property>
+        <property name="can_focus">False</property>
         <property name="border_width">12</property>
         <property name="spacing">6</property>
         <child>
           <object class="GtkLabel" id="lblwould">
             <property name="visible">True</property>
+            <property name="can_focus">False</property>
             <property name="xalign">0</property>
             <property name="label" translatable="yes">Please enter a name for this location:</property>
           </object>
           <packing>
             <property name="expand">False</property>
+            <property name="fill">True</property>
             <property name="position">0</property>
           </packing>
         </child>
@@ -99,6 +114,7 @@
           </object>
           <packing>
             <property name="expand">False</property>
+            <property name="fill">True</property>
             <property name="position">1</property>
           </packing>
         </child>
@@ -110,10 +126,12 @@
     <child>
       <object class="GtkVBox" id="review">
         <property name="visible">True</property>
+        <property name="can_focus">False</property>
         <property name="border_width">12</property>
         <child>
           <object class="GtkLabel" id="lblreview">
             <property name="visible">True</property>
+            <property name="can_focus">False</property>
             <property name="xalign">0</property>
             <property name="ypad">6</property>
             <property name="label" translatable="yes">Please review the choices below. If anything is not correct, please go back and select the correct options.</property>
@@ -122,99 +140,120 @@
           </object>
           <packing>
             <property name="expand">False</property>
+            <property name="fill">True</property>
             <property name="position">0</property>
           </packing>
         </child>
         <child>
           <object class="GtkAlignment" id="alignment1">
             <property name="visible">True</property>
+            <property name="can_focus">False</property>
             <property name="left_padding">12</property>
             <child>
               <object class="GtkVBox" id="vbox1">
                 <property name="visible">True</property>
+                <property name="can_focus">False</property>
                 <child>
                   <object class="GtkHBox" id="revlabel">
                     <property name="visible">True</property>
+                    <property name="can_focus">False</property>
                     <property name="spacing">5</property>
                     <child>
                       <object class="GtkArrow" id="arrow3">
                         <property name="visible">True</property>
                         <property name="sensitive">False</property>
+                        <property name="can_focus">False</property>
                       </object>
                       <packing>
                         <property name="expand">False</property>
+                        <property name="fill">True</property>
                         <property name="position">0</property>
                       </packing>
                     </child>
                     <child>
                       <object class="GtkLabel" id="lbl3">
                         <property name="visible">True</property>
+                        <property name="can_focus">False</property>
                         <property name="xalign">0</property>
                         <property name="label" translatable="yes">Label:</property>
                         <property name="use_markup">True</property>
                       </object>
                       <packing>
                         <property name="expand">False</property>
+                        <property name="fill">True</property>
                         <property name="position">1</property>
                       </packing>
                     </child>
                     <child>
                       <object class="GtkLabel" id="labellbl">
                         <property name="visible">True</property>
+                        <property name="can_focus">False</property>
                         <property name="xalign">0</property>
                         <property name="label" translatable="yes">&lt;b&gt;Home&lt;/b&gt;</property>
                         <property name="use_markup">True</property>
                       </object>
                       <packing>
+                        <property name="expand">True</property>
+                        <property name="fill">True</property>
                         <property name="position">2</property>
                       </packing>
                     </child>
                   </object>
                   <packing>
                     <property name="expand">False</property>
+                    <property name="fill">True</property>
                     <property name="position">0</property>
                   </packing>
                 </child>
                 <child>
                   <object class="GtkHBox" id="revplace">
                     <property name="visible">True</property>
+                    <property name="can_focus">False</property>
                     <property name="spacing">5</property>
                     <child>
                       <object class="GtkArrow" id="arrow2">
                         <property name="visible">True</property>
                         <property name="sensitive">False</property>
+                        <property name="can_focus">False</property>
                       </object>
                       <packing>
                         <property name="expand">False</property>
+                        <property name="fill">True</property>
                         <property name="position">0</property>
                       </packing>
                     </child>
                     <child>
                       <object class="GtkLabel" id="lbl2">
                         <property name="visible">True</property>
+                        <property name="can_focus">False</property>
                         <property name="xalign">0</property>
                         <property name="label" translatable="yes">Location:</property>
                         <property name="use_markup">True</property>
                       </object>
                       <packing>
                         <property name="expand">False</property>
+                        <property name="fill">True</property>
                         <property name="position">1</property>
                       </packing>
                     </child>
                     <child>
                       <object class="GtkLabel" id="placelbl">
                         <property name="visible">True</property>
+                        <property name="can_focus">False</property>
                         <property name="xalign">0</property>
                         <property name="label" translatable="yes">&lt;b&gt;Orange, Texas&lt;/b&gt;</property>
                         <property name="use_markup">True</property>
                       </object>
                       <packing>
+                        <property name="expand">True</property>
+                        <property name="fill">True</property>
                         <property name="position">2</property>
                       </packing>
                     </child>
                   </object>
                   <packing>
                     <property name="expand">False</property>
+                    <property name="fill">True</property>
                     <property name="position">1</property>
                   </packing>
                 </child>
@@ -223,6 +262,7 @@
           </object>
           <packing>
             <property name="expand">False</property>
+            <property name="fill">True</property>
             <property name="position">1</property>
           </packing>
         </child>
@@ -235,5 +275,10 @@
         <property name="title" translatable="yes">Review choices</property>
       </packing>
     </child>
+    <child internal-child="action_area">
+      <object class="GtkBox" id="Assistant-action_area1">
+        <property name="can_focus">False</property>
+      </object>
+    </child>
   </object>
 </interface>

=== modified file 'data/ui/ExtendedForecast.ui'
--- data/ui/ExtendedForecast.ui	2011-11-27 07:38:08 +0000
+++ data/ui/ExtendedForecast.ui	2013-05-18 18:24:25 +0000
@@ -1,64 +1,76 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <interface>
-  <requires lib="gtk+" version="2.16"/>
+  <!-- interface-requires gtk+ 3.0 -->
   <!-- interface-requires extended_forecast 1.0 -->
-  <!-- interface-naming-policy project-wide -->
   <!-- interface-local-resource-path ../media -->
   <object class="ExtendedForecast" id="extended_forecast">
+    <property name="can_focus">False</property>
     <property name="border_width">12</property>
     <property name="title" translatable="yes">Extended Forecast</property>
     <property name="resizable">False</property>
     <property name="window_position">mouse</property>
     <property name="icon">../media/icon.png</property>
-    <signal name="destroy" handler="on_destroy"/>
+    <signal name="destroy" handler="on_destroy" swapped="no"/>
     <child>
       <object class="GtkVBox" id="mainvbox">
         <property name="visible">True</property>
+        <property name="can_focus">False</property>
         <child>
-            <object class="GtkLabel" id="connection_error">
-                <property name="visible">False</property>
-                <property name="ypad">10</property>
-                <property name="label">&lt;big&gt;Forecast information cannot be fetched. Connection cannot be established.&lt;/big&gt;</property>
-                <property name="use_markup">True</property>
-                <property name="wrap">False</property>
-            </object>
-            <packing>
-                <property name="position">0</property>
-            </packing>
+          <object class="GtkLabel" id="connection_error">
+            <property name="can_focus">False</property>
+            <property name="ypad">10</property>
+            <property name="label">&lt;big&gt;Forecast information cannot be fetched. Connection cannot be established.&lt;/big&gt;</property>
+            <property name="use_markup">True</property>
+          </object>
+          <packing>
+            <property name="expand">True</property>
+            <property name="fill">True</property>
+            <property name="position">0</property>
+          </packing>
         </child>
         <child>
           <object class="GtkHBox" id="hbox1">
             <property name="visible">True</property>
+            <property name="can_focus">False</property>
             <property name="spacing">5</property>
             <property name="homogeneous">True</property>
             <child>
               <object class="GtkHBox" id="hbox2">
                 <property name="visible">True</property>
+                <property name="can_focus">False</property>
                 <child>
                   <object class="GtkAlignment" id="alignment3">
                     <property name="visible">True</property>
+                    <property name="can_focus">False</property>
                     <property name="right_padding">6</property>
                     <child>
                       <object class="GtkVBox" id="day1vbox">
                         <property name="visible">True</property>
+                        <property name="can_focus">False</property>
                         <child>
                           <object class="GtkLabel" id="day1lbl">
                             <property name="visible">True</property>
+                            <property name="can_focus">False</property>
                             <property name="ypad">10</property>
                             <property name="label">&lt;big&gt;Today (fri.)&lt;/big&gt;</property>
                             <property name="use_markup">True</property>
                           </object>
                           <packing>
+                            <property name="expand">True</property>
+                            <property name="fill">True</property>
                             <property name="position">0</property>
                           </packing>
                         </child>
                         <child>
                           <object class="GtkImage" id="day1image">
                             <property name="visible">True</property>
+                            <property name="can_focus">False</property>
                             <property name="pixel_size">50</property>
                             <property name="icon_name">weather-showers</property>
                           </object>
                           <packing>
+                            <property name="expand">True</property>
+                            <property name="fill">True</property>
                             <property name="position">1</property>
                           </packing>
                         </child>
@@ -66,6 +78,7 @@
                           <object class="GtkLabel" id="day1cond">
                             <property name="height_request">80</property>
                             <property name="visible">True</property>
+                            <property name="can_focus">False</property>
                             <property name="label">Partially cloudy</property>
                             <property name="justify">center</property>
                             <property name="wrap">True</property>
@@ -73,33 +86,44 @@
                             <property name="width_chars">15</property>
                           </object>
                           <packing>
+                            <property name="expand">True</property>
+                            <property name="fill">True</property>
                             <property name="position">2</property>
                           </packing>
                         </child>
                         <child>
                           <object class="GtkVBox" id="vbox1">
                             <property name="visible">True</property>
+                            <property name="can_focus">False</property>
                             <property name="homogeneous">True</property>
                             <child>
                               <object class="GtkLabel" id="day1temphigh">
                                 <property name="visible">True</property>
+                                <property name="can_focus">False</property>
                                 <property name="label">High : 23°C</property>
                               </object>
                               <packing>
+                                <property name="expand">True</property>
+                                <property name="fill">True</property>
                                 <property name="position">0</property>
                               </packing>
                             </child>
                             <child>
                               <object class="GtkLabel" id="day1templow">
                                 <property name="visible">True</property>
+                                <property name="can_focus">False</property>
                                 <property name="label">Low : 19°C</property>
                               </object>
                               <packing>
+                                <property name="expand">True</property>
+                                <property name="fill">True</property>
                                 <property name="position">1</property>
                               </packing>
                             </child>
                           </object>
                           <packing>
+                            <property name="expand">True</property>
+                            <property name="fill">True</property>
                             <property name="position">3</property>
                           </packing>
                         </child>
@@ -107,6 +131,8 @@
                     </child>
                   </object>
                   <packing>
+                    <property name="expand">True</property>
+                    <property name="fill">True</property>
                     <property name="position">0</property>
                   </packing>
                 </child>
@@ -114,45 +140,58 @@
                   <object class="GtkVSeparator" id="vseparator1">
                     <property name="width_request">2</property>
                     <property name="visible">True</property>
+                    <property name="can_focus">False</property>
                   </object>
                   <packing>
                     <property name="expand">False</property>
+                    <property name="fill">True</property>
                     <property name="position">1</property>
                   </packing>
                 </child>
               </object>
               <packing>
+                <property name="expand">True</property>
+                <property name="fill">True</property>
                 <property name="position">0</property>
               </packing>
             </child>
             <child>
               <object class="GtkHBox" id="hbox3">
                 <property name="visible">True</property>
+                <property name="can_focus">False</property>
                 <child>
                   <object class="GtkAlignment" id="alignment2">
                     <property name="visible">True</property>
+                    <property name="can_focus">False</property>
                     <property name="right_padding">6</property>
                     <child>
                       <object class="GtkVBox" id="day2vbox">
                         <property name="visible">True</property>
+                        <property name="can_focus">False</property>
                         <child>
                           <object class="GtkLabel" id="day2lbl">
                             <property name="visible">True</property>
+                            <property name="can_focus">False</property>
                             <property name="ypad">10</property>
                             <property name="label">&lt;big&gt;Tomorrow (sat.)&lt;/big&gt;</property>
                             <property name="use_markup">True</property>
                           </object>
                           <packing>
+                            <property name="expand">True</property>
+                            <property name="fill">True</property>
                             <property name="position">0</property>
                           </packing>
                         </child>
                         <child>
                           <object class="GtkImage" id="day2image">
                             <property name="visible">True</property>
+                            <property name="can_focus">False</property>
                             <property name="pixel_size">50</property>
                             <property name="icon_name">weather-storm</property>
                           </object>
                           <packing>
+                            <property name="expand">True</property>
+                            <property name="fill">True</property>
                             <property name="position">1</property>
                           </packing>
                         </child>
@@ -160,6 +199,7 @@
                           <object class="GtkLabel" id="day2cond">
                             <property name="height_request">80</property>
                             <property name="visible">True</property>
+                            <property name="can_focus">False</property>
                             <property name="label">Couverture nuageuse partielle</property>
                             <property name="justify">center</property>
                             <property name="wrap">True</property>
@@ -167,33 +207,44 @@
                             <property name="width_chars">15</property>
                           </object>
                           <packing>
+                            <property name="expand">True</property>
+                            <property name="fill">True</property>
                             <property name="position">2</property>
                           </packing>
                         </child>
                         <child>
                           <object class="GtkVBox" id="vbox2">
                             <property name="visible">True</property>
+                            <property name="can_focus">False</property>
                             <property name="homogeneous">True</property>
                             <child>
                               <object class="GtkLabel" id="day2temphigh">
                                 <property name="visible">True</property>
+                                <property name="can_focus">False</property>
                                 <property name="label">High : 26°C</property>
                               </object>
                               <packing>
+                                <property name="expand">True</property>
+                                <property name="fill">True</property>
                                 <property name="position">0</property>
                               </packing>
                             </child>
                             <child>
                               <object class="GtkLabel" id="day2templow">
                                 <property name="visible">True</property>
+                                <property name="can_focus">False</property>
                                 <property name="label">Low : 16°C</property>
                               </object>
                               <packing>
+                                <property name="expand">True</property>
+                                <property name="fill">True</property>
                                 <property name="position">1</property>
                               </packing>
                             </child>
                           </object>
                           <packing>
+                            <property name="expand">True</property>
+                            <property name="fill">True</property>
                             <property name="position">3</property>
                           </packing>
                         </child>
@@ -201,6 +252,8 @@
                     </child>
                   </object>
                   <packing>
+                    <property name="expand">True</property>
+                    <property name="fill">True</property>
                     <property name="position">0</property>
                   </packing>
                 </child>
@@ -208,47 +261,58 @@
                   <object class="GtkVSeparator" id="vseparator2">
                     <property name="width_request">2</property>
                     <property name="visible">True</property>
+                    <property name="can_focus">False</property>
                   </object>
                   <packing>
                     <property name="expand">False</property>
+                    <property name="fill">True</property>
                     <property name="position">1</property>
                   </packing>
                 </child>
               </object>
               <packing>
+                <property name="expand">True</property>
+                <property name="fill">True</property>
                 <property name="position">1</property>
               </packing>
             </child>
             <child>
               <object class="GtkHBox" id="hbox4">
                 <property name="visible">True</property>
+                <property name="can_focus">False</property>
                 <child>
                   <object class="GtkAlignment" id="alignment4">
                     <property name="visible">True</property>
+                    <property name="can_focus">False</property>
                     <property name="right_padding">6</property>
                     <child>
                       <object class="GtkVBox" id="day3vbox">
                         <property name="visible">True</property>
+                        <property name="can_focus">False</property>
                         <child>
                           <object class="GtkLabel" id="day3lbl">
                             <property name="visible">True</property>
+                            <property name="can_focus">False</property>
                             <property name="ypad">10</property>
                             <property name="label">&lt;big&gt;Sunday&lt;/big&gt;</property>
                             <property name="use_markup">True</property>
                           </object>
                           <packing>
                             <property name="expand">False</property>
+                            <property name="fill">True</property>
                             <property name="position">0</property>
                           </packing>
                         </child>
                         <child>
                           <object class="GtkImage" id="day3image">
                             <property name="visible">True</property>
+                            <property name="can_focus">False</property>
                             <property name="pixel_size">50</property>
                             <property name="icon_name">weather-fog</property>
                           </object>
                           <packing>
                             <property name="expand">False</property>
+                            <property name="fill">True</property>
                             <property name="position">1</property>
                           </packing>
                         </child>
@@ -256,6 +320,7 @@
                           <object class="GtkLabel" id="day3cond">
                             <property name="height_request">80</property>
                             <property name="visible">True</property>
+                            <property name="can_focus">False</property>
                             <property name="label">Fogs</property>
                             <property name="justify">center</property>
                             <property name="wrap">True</property>
@@ -263,32 +328,43 @@
                             <property name="width_chars">15</property>
                           </object>
                           <packing>
+                            <property name="expand">True</property>
+                            <property name="fill">True</property>
                             <property name="position">2</property>
                           </packing>
                         </child>
                         <child>
                           <object class="GtkVBox" id="vbox3">
                             <property name="visible">True</property>
+                            <property name="can_focus">False</property>
                             <child>
                               <object class="GtkLabel" id="day3temphigh">
                                 <property name="visible">True</property>
+                                <property name="can_focus">False</property>
                                 <property name="label">High : 28°C</property>
                               </object>
                               <packing>
+                                <property name="expand">True</property>
+                                <property name="fill">True</property>
                                 <property name="position">0</property>
                               </packing>
                             </child>
                             <child>
                               <object class="GtkLabel" id="day3templow">
                                 <property name="visible">True</property>
+                                <property name="can_focus">False</property>
                                 <property name="label">Low : 16°C</property>
                               </object>
                               <packing>
+                                <property name="expand">True</property>
+                                <property name="fill">True</property>
                                 <property name="position">1</property>
                               </packing>
                             </child>
                           </object>
                           <packing>
+                            <property name="expand">True</property>
+                            <property name="fill">True</property>
                             <property name="position">3</property>
                           </packing>
                         </child>
@@ -296,50 +372,65 @@
                     </child>
                   </object>
                   <packing>
+                    <property name="expand">True</property>
+                    <property name="fill">True</property>
                     <property name="position">0</property>
                   </packing>
                 </child>
                 <child>
                   <object class="GtkVSeparator" id="vseparator3">
                     <property name="visible">True</property>
+                    <property name="can_focus">False</property>
                   </object>
                   <packing>
                     <property name="expand">False</property>
+                    <property name="fill">True</property>
                     <property name="position">1</property>
                   </packing>
                 </child>
               </object>
               <packing>
+                <property name="expand">True</property>
+                <property name="fill">True</property>
                 <property name="position">2</property>
               </packing>
             </child>
             <child>
               <object class="GtkHBox" id="hbox5">
                 <property name="visible">True</property>
+                <property name="can_focus">False</property>
                 <child>
                   <object class="GtkAlignment" id="alignment5">
                     <property name="visible">True</property>
+                    <property name="can_focus">False</property>
                     <child>
                       <object class="GtkVBox" id="day4vbox">
                         <property name="visible">True</property>
+                        <property name="can_focus">False</property>
                         <child>
                           <object class="GtkLabel" id="day4lbl">
                             <property name="visible">True</property>
+                            <property name="can_focus">False</property>
                             <property name="ypad">10</property>
                             <property name="label">&lt;big&gt;Monday&lt;/big&gt;</property>
                             <property name="use_markup">True</property>
                           </object>
                           <packing>
+                            <property name="expand">True</property>
+                            <property name="fill">True</property>
                             <property name="position">0</property>
                           </packing>
                         </child>
                         <child>
                           <object class="GtkImage" id="day4image">
                             <property name="visible">True</property>
+                            <property name="can_focus">False</property>
                             <property name="pixel_size">50</property>
                             <property name="icon_name">weather-clear</property>
                           </object>
                           <packing>
+                            <property name="expand">True</property>
+                            <property name="fill">True</property>
                             <property name="position">1</property>
                           </packing>
                         </child>
@@ -347,6 +438,7 @@
                           <object class="GtkLabel" id="day4cond">
                             <property name="height_request">80</property>
                             <property name="visible">True</property>
+                            <property name="can_focus">False</property>
                             <property name="label">Clear</property>
                             <property name="justify">center</property>
                             <property name="wrap">True</property>
@@ -354,32 +446,43 @@
                             <property name="width_chars">15</property>
                           </object>
                           <packing>
+                            <property name="expand">True</property>
+                            <property name="fill">True</property>
                             <property name="position">2</property>
                           </packing>
                         </child>
                         <child>
                           <object class="GtkVBox" id="vbox4">
                             <property name="visible">True</property>
+                            <property name="can_focus">False</property>
                             <child>
                               <object class="GtkLabel" id="day4temphigh">
                                 <property name="visible">True</property>
+                                <property name="can_focus">False</property>
                                 <property name="label">High : 26°C</property>
                               </object>
                               <packing>
+                                <property name="expand">True</property>
+                                <property name="fill">True</property>
                                 <property name="position">0</property>
                               </packing>
                             </child>
                             <child>
                               <object class="GtkLabel" id="day4templow">
                                 <property name="visible">True</property>
+                                <property name="can_focus">False</property>
                                 <property name="label">Low : 14°C</property>
                               </object>
                               <packing>
+                                <property name="expand">True</property>
+                                <property name="fill">True</property>
                                 <property name="position">1</property>
                               </packing>
                             </child>
                           </object>
                           <packing>
+                            <property name="expand">True</property>
+                            <property name="fill">True</property>
                             <property name="position">3</property>
                           </packing>
                         </child>
@@ -387,16 +490,21 @@
                     </child>
                   </object>
                   <packing>
+                    <property name="expand">True</property>
+                    <property name="fill">True</property>
                     <property name="position">0</property>
                   </packing>
                 </child>
               </object>
               <packing>
+                <property name="expand">True</property>
+                <property name="fill">True</property>
                 <property name="position">3</property>
               </packing>
             </child>
           </object>
           <packing>
+            <property name="expand">True</property>
             <property name="fill">False</property>
             <property name="position">1</property>
           </packing>
@@ -404,26 +512,31 @@
         <child>
           <object class="GtkHSeparator" id="hseparator1">
             <property name="visible">True</property>
+            <property name="can_focus">False</property>
           </object>
           <packing>
             <property name="expand">False</property>
+            <property name="fill">True</property>
             <property name="position">2</property>
           </packing>
         </child>
         <child>
           <object class="GtkAlignment" id="alignment1">
             <property name="visible">True</property>
+            <property name="can_focus">False</property>
             <property name="xalign">1</property>
             <child>
               <object class="GtkVButtonBox" id="hbuttonbox1">
                 <property name="visible">True</property>
+                <property name="can_focus">False</property>
                 <child>
                   <object class="GtkButton" id="closebtn">
                     <property name="label">gtk-close</property>
                     <property name="visible">True</property>
+                    <property name="can_focus">False</property>
                     <property name="receives_default">True</property>
                     <property name="use_stock">True</property>
-                    <signal name="clicked" handler="close"/>
+                    <signal name="clicked" handler="close" swapped="no"/>
                   </object>
                   <packing>
                     <property name="expand">False</property>
@@ -435,6 +548,8 @@
             </child>
           </object>
           <packing>
+            <property name="expand">True</property>
+            <property name="fill">True</property>
             <property name="position">3</property>
           </packing>
         </child>

=== modified file 'data/ui/PreferencesDialog.ui'
--- data/ui/PreferencesDialog.ui	2012-03-12 04:53:24 +0000
+++ data/ui/PreferencesDialog.ui	2013-05-18 18:24:25 +0000
@@ -1,19 +1,25 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <interface>
-  <requires lib="gtk+" version="2.16"/>
+  <!-- interface-requires gtk+ 3.0 -->
   <!-- interface-requires preferences_dialog 1.0 -->
-  <!-- interface-naming-policy project-wide -->
   <object class="GtkListStore" id="citieslist">
     <columns>
       <!-- column-name Label -->
       <column type="gchararray"/>
       <!-- column-name City -->
       <column type="gchararray"/>
-      <!-- column-name Location Details -->
+      <!-- column-name Location -->
       <column type="gchararray"/>
     </columns>
   </object>
+  <object class="GtkAdjustment" id="rate">
+    <property name="lower">1</property>
+    <property name="upper">30</property>
+    <property name="step_increment">1</property>
+    <property name="page_increment">10</property>
+  </object>
   <object class="PreferencesDialog" id="preferences_dialog">
+    <property name="can_focus">False</property>
     <property name="border_width">12</property>
     <property name="title" translatable="yes">Weather Indicator Preferences</property>
     <property name="window_position">mouse</property>
@@ -22,62 +28,118 @@
     <property name="icon">../media/icon.png</property>
     <property name="type_hint">normal</property>
     <child internal-child="vbox">
-      <object class="GtkVBox" id="dialog-vbox1">
+      <object class="GtkBox" id="dialog-vbox1">
         <property name="visible">True</property>
+        <property name="can_focus">False</property>
+        <property name="orientation">vertical</property>
         <property name="spacing">6</property>
+        <child internal-child="action_area">
+          <object class="GtkButtonBox" id="dialog-action_area1">
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+            <property name="layout_style">end</property>
+            <child>
+              <object class="GtkButton" id="cancel_button">
+                <property name="label">gtk-cancel</property>
+                <property name="visible">True</property>
+                <property name="can_focus">False</property>
+                <property name="receives_default">True</property>
+                <property name="use_stock">True</property>
+                <signal name="clicked" handler="cancel" swapped="no"/>
+              </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">False</property>
+                <property name="position">0</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkButton" id="ok_button">
+                <property name="label">gtk-ok</property>
+                <property name="visible">True</property>
+                <property name="sensitive">False</property>
+                <property name="can_focus">False</property>
+                <property name="receives_default">True</property>
+                <property name="use_stock">True</property>
+                <signal name="clicked" handler="ok" swapped="no"/>
+              </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">False</property>
+                <property name="position">1</property>
+              </packing>
+            </child>
+          </object>
+          <packing>
+            <property name="expand">False</property>
+            <property name="fill">False</property>
+            <property name="pack_type">end</property>
+            <property name="position">0</property>
+          </packing>
+        </child>
         <child>
           <object class="GtkNotebook" id="notebook1">
             <property name="visible">True</property>
             <property name="can_focus">True</property>
             <child>
-              <object class="GtkVBox" id="vboxpreferences">
+              <object class="GtkBox" id="vboxpreferences">
                 <property name="visible">True</property>
+                <property name="can_focus">False</property>
                 <property name="border_width">12</property>
+                <property name="orientation">vertical</property>
                 <property name="spacing">12</property>
                 <child>
-                  <object class="GtkVBox" id="vbox10">
+                  <object class="GtkBox" id="vbox10">
                     <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="orientation">vertical</property>
                     <property name="homogeneous">True</property>
                     <child>
                       <object class="GtkCheckButton" id="enableindicator">
                         <property name="label" translatable="yes">Enable the Weather Indicator Applet</property>
                         <property name="can_focus">True</property>
                         <property name="receives_default">False</property>
-                        <property name="xalign">0.02</property>
+                        <property name="xalign">0.019999999552965164</property>
                         <property name="active">True</property>
                         <property name="draw_indicator">True</property>
                       </object>
                       <packing>
                         <property name="expand">False</property>
+                        <property name="fill">True</property>
                         <property name="position">0</property>
                       </packing>
                     </child>
                     <child>
                       <object class="GtkCheckButton" id="show_label">
-                        <property name="visible">True</property>
                         <property name="label" translatable="yes">Show temperature near indicator</property>
+                        <property name="visible">True</property>
                         <property name="can_focus">True</property>
                         <property name="receives_default">False</property>
+                        <property name="xalign">0</property>
                         <property name="draw_indicator">True</property>
                       </object>
                       <packing>
                         <property name="expand">False</property>
+                        <property name="fill">True</property>
                         <property name="position">1</property>
                       </packing>
                     </child>
                     <child>
-                      <object class="GtkHBox" id="hbox_updateevery">
+                      <object class="GtkBox" id="hbox_updateevery">
                         <property name="visible">True</property>
+                        <property name="can_focus">False</property>
                         <property name="spacing">6</property>
                         <child>
                           <object class="GtkLabel" id="updateevery">
                             <property name="visible">True</property>
+                            <property name="can_focus">False</property>
                             <property name="xalign">1</property>
                             <property name="label" translatable="yes">Update every</property>
                             <property name="use_markup">True</property>
                           </object>
                           <packing>
                             <property name="expand">False</property>
+                            <property name="fill">True</property>
                             <property name="position">0</property>
                           </packing>
                         </child>
@@ -86,6 +148,7 @@
                             <property name="visible">True</property>
                             <property name="can_focus">True</property>
                             <property name="invisible_char">•</property>
+                            <property name="invisible_char_set">True</property>
                             <property name="adjustment">rate</property>
                           </object>
                           <packing>
@@ -97,31 +160,39 @@
                         <child>
                           <object class="GtkLabel" id="label4">
                             <property name="visible">True</property>
+                            <property name="can_focus">False</property>
                             <property name="xalign">0</property>
                             <property name="label" translatable="yes">minutes</property>
                           </object>
                           <packing>
                             <property name="expand">False</property>
+                            <property name="fill">True</property>
                             <property name="position">2</property>
                           </packing>
                         </child>
                       </object>
                       <packing>
+                        <property name="expand">True</property>
+                        <property name="fill">True</property>
                         <property name="position">2</property>
                       </packing>
                     </child>
                   </object>
                   <packing>
                     <property name="expand">False</property>
+                    <property name="fill">True</property>
                     <property name="position">0</property>
                   </packing>
                 </child>
                 <child>
-                  <object class="GtkVBox" id="vbox1">
+                  <object class="GtkBox" id="vbox1">
                     <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="orientation">vertical</property>
                     <child>
                       <object class="GtkLabel" id="notificationslabel">
                         <property name="visible">True</property>
+                        <property name="can_focus">False</property>
                         <property name="xalign">0</property>
                         <property name="ypad">3</property>
                         <property name="label" translatable="yes">&lt;b&gt;Notifications&lt;/b&gt;</property>
@@ -129,16 +200,20 @@
                       </object>
                       <packing>
                         <property name="expand">False</property>
+                        <property name="fill">True</property>
                         <property name="position">0</property>
                       </packing>
                     </child>
                     <child>
                       <object class="GtkAlignment" id="alignment1">
                         <property name="visible">True</property>
+                        <property name="can_focus">False</property>
                         <property name="left_padding">12</property>
                         <child>
-                          <object class="GtkVBox" id="vbox4">
+                          <object class="GtkBox" id="vbox4">
                             <property name="visible">True</property>
+                            <property name="can_focus">False</property>
+                            <property name="orientation">vertical</property>
                             <property name="homogeneous">True</property>
                             <child>
                               <object class="GtkRadioButton" id="nonotif">
@@ -146,6 +221,7 @@
                                 <property name="visible">True</property>
                                 <property name="can_focus">True</property>
                                 <property name="receives_default">False</property>
+                                <property name="xalign">0.5</property>
                                 <property name="active">True</property>
                                 <property name="draw_indicator">True</property>
                               </object>
@@ -161,6 +237,7 @@
                                 <property name="visible">True</property>
                                 <property name="can_focus">True</property>
                                 <property name="receives_default">False</property>
+                                <property name="xalign">0.5</property>
                                 <property name="draw_indicator">True</property>
                                 <property name="group">nonotif</property>
                               </object>
@@ -176,6 +253,7 @@
                                 <property name="visible">True</property>
                                 <property name="can_focus">True</property>
                                 <property name="receives_default">False</property>
+                                <property name="xalign">0.5</property>
                                 <property name="draw_indicator">True</property>
                                 <property name="group">nonotif</property>
                               </object>
@@ -189,12 +267,15 @@
                         </child>
                       </object>
                       <packing>
+                        <property name="expand">True</property>
+                        <property name="fill">True</property>
                         <property name="position">1</property>
                       </packing>
                     </child>
                     <child>
                       <object class="GtkLabel" id="weathersourcelabel">
                         <property name="visible">True</property>
+                        <property name="can_focus">False</property>
                         <property name="xalign">0</property>
                         <property name="ypad">3</property>
                         <property name="label" translatable="yes">&lt;b&gt;Weather Data Source&lt;/b&gt;</property>
@@ -202,40 +283,46 @@
                       </object>
                       <packing>
                         <property name="expand">False</property>
+                        <property name="fill">True</property>
                         <property name="position">2</property>
                       </packing>
                     </child>
                     <child>
                       <object class="GtkAlignment" id="alignment2">
                         <property name="visible">True</property>
+                        <property name="can_focus">False</property>
                         <property name="left_padding">12</property>
                         <child>
-                          <object class="GtkVBox" id="vbox5">
+                          <object class="GtkBox" id="vbox5">
                             <property name="visible">True</property>
+                            <property name="can_focus">False</property>
+                            <property name="orientation">vertical</property>
                             <property name="homogeneous">True</property>
                             <child>
-                              <object class="GtkRadioButton" id="google">
-                                <property name="label" translatable="yes">Google</property>
-                                <property name="visible">True</property>
-                                <property name="can_focus">True</property>
-                                <property name="receives_default">False</property>
-                                <property name="active">True</property>
-                                <property name="draw_indicator">True</property>
-                              </object>
-                              <packing>
-                                <property name="expand">False</property>
-                                <property name="fill">False</property>
-                                <property name="position">0</property>
-                              </packing>
-                            </child>
-                            <child>
                               <object class="GtkRadioButton" id="yahoo">
                                 <property name="label" translatable="yes">Yahoo!</property>
                                 <property name="visible">True</property>
                                 <property name="can_focus">True</property>
                                 <property name="receives_default">False</property>
-                                <property name="draw_indicator">True</property>
-                                <property name="group">google</property>
+                                <property name="xalign">0.5</property>
+                                <property name="draw_indicator">True</property>
+                              </object>
+                              <packing>
+                                <property name="expand">False</property>
+                                <property name="fill">False</property>
+                                <property name="position">0</property>
+                              </packing>
+                            </child>
+                            <child>
+                              <object class="GtkRadioButton" id="weather-com">
+                                <property name="label" translatable="yes">Weather.com</property>
+                                <property name="visible">True</property>
+                                <property name="can_focus">True</property>
+                                <property name="receives_default">False</property>
+                                <property name="xalign">0.5</property>
+                                <property name="active">True</property>
+                                <property name="draw_indicator">True</property>
+                                <property name="group">yahoo</property>
                               </object>
                               <packing>
                                 <property name="expand">False</property>
@@ -247,12 +334,15 @@
                         </child>
                       </object>
                       <packing>
+                        <property name="expand">True</property>
+                        <property name="fill">True</property>
                         <property name="position">3</property>
                       </packing>
                     </child>
                   </object>
                   <packing>
                     <property name="expand">False</property>
+                    <property name="fill">True</property>
                     <property name="position">1</property>
                   </packing>
                 </child>
@@ -261,6 +351,7 @@
             <child type="tab">
               <object class="GtkLabel" id="label1">
                 <property name="visible">True</property>
+                <property name="can_focus">False</property>
                 <property name="label" translatable="yes">General</property>
               </object>
               <packing>
@@ -268,16 +359,296 @@
               </packing>
             </child>
             <child>
-              <object class="GtkVBox" id="vbox9">
-                <property name="visible">True</property>
-                <property name="border_width">12</property>
-                <property name="spacing">12</property>
-                <child>
-                  <object class="GtkVBox" id="vbox2">
-                    <property name="visible">True</property>
+              <object class="GtkBox" id="boxdisplay">
+                <property name="visible">True</property>
+                <property name="can_focus">False</property>
+                <property name="border_width">12</property>
+                <property name="orientation">vertical</property>
+                <property name="spacing">12</property>
+                <child>
+                  <object class="GtkBox" id="box1">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="orientation">vertical</property>
+                    <child>
+                      <object class="GtkLabel" id="conditionslabel">
+                        <property name="visible">True</property>
+                        <property name="can_focus">False</property>
+                        <property name="xalign">0</property>
+                        <property name="ypad">3</property>
+                        <property name="label" translatable="yes">&lt;b&gt;Weather Conditions&lt;/b&gt;</property>
+                        <property name="use_markup">True</property>
+                      </object>
+                      <packing>
+                        <property name="expand">False</property>
+                        <property name="fill">True</property>
+                        <property name="position">0</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <object class="GtkAlignment" id="alignment5">
+                        <property name="visible">True</property>
+                        <property name="can_focus">False</property>
+                        <property name="left_padding">12</property>
+                        <child>
+                          <object class="GtkBox" id="box3">
+                            <property name="visible">True</property>
+                            <property name="can_focus">False</property>
+                            <property name="orientation">vertical</property>
+                            <property name="homogeneous">True</property>
+                            <child>
+                              <object class="GtkCheckButton" id="show_relative">
+                                <property name="label" translatable="yes">Relative temperature ("Feels like")</property>
+                                <property name="visible">True</property>
+                                <property name="can_focus">True</property>
+                                <property name="receives_default">False</property>
+                                <property name="xalign">0</property>
+                                <property name="draw_indicator">True</property>
+                              </object>
+                              <packing>
+                                <property name="expand">False</property>
+                                <property name="fill">False</property>
+                                <property name="position">0</property>
+                              </packing>
+                            </child>
+                            <child>
+                              <object class="GtkCheckButton" id="show_wind">
+                                <property name="label" translatable="yes">Wind speed and direction</property>
+                                <property name="visible">True</property>
+                                <property name="can_focus">True</property>
+                                <property name="receives_default">False</property>
+                                <property name="xalign">0</property>
+                                <property name="active">True</property>
+                                <property name="draw_indicator">True</property>
+                              </object>
+                              <packing>
+                                <property name="expand">False</property>
+                                <property name="fill">False</property>
+                                <property name="position">1</property>
+                              </packing>
+                            </child>
+                            <child>
+                              <object class="GtkCheckButton" id="show_suntimes">
+                                <property name="label" translatable="yes">Sunrise and sunset times</property>
+                                <property name="visible">True</property>
+                                <property name="can_focus">True</property>
+                                <property name="receives_default">False</property>
+                                <property name="xalign">0</property>
+                                <property name="active">True</property>
+                                <property name="draw_indicator">True</property>
+                              </object>
+                              <packing>
+                                <property name="expand">False</property>
+                                <property name="fill">False</property>
+                                <property name="position">2</property>
+                              </packing>
+                            </child>
+                          </object>
+                        </child>
+                      </object>
+                      <packing>
+                        <property name="expand">True</property>
+                        <property name="fill">True</property>
+                        <property name="position">1</property>
+                      </packing>
+                    </child>
+                  </object>
+                  <packing>
+                    <property name="expand">False</property>
+                    <property name="fill">True</property>
+                    <property name="position">0</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkBox" id="box6">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="orientation">vertical</property>
+                    <child>
+                      <object class="GtkLabel" id="heatlabel">
+                        <property name="visible">True</property>
+                        <property name="can_focus">False</property>
+                        <property name="xalign">0</property>
+                        <property name="ypad">3</property>
+                        <property name="label" translatable="yes">&lt;b&gt;Relative Heat Formula&lt;/b&gt;</property>
+                        <property name="use_markup">True</property>
+                      </object>
+                      <packing>
+                        <property name="expand">False</property>
+                        <property name="fill">True</property>
+                        <property name="position">0</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <object class="GtkAlignment" id="alignment6">
+                        <property name="visible">True</property>
+                        <property name="can_focus">False</property>
+                        <property name="left_padding">12</property>
+                        <child>
+                          <object class="GtkBox" id="box4">
+                            <property name="visible">True</property>
+                            <property name="can_focus">False</property>
+                            <property name="orientation">vertical</property>
+                            <property name="homogeneous">True</property>
+                            <child>
+                              <object class="GtkRadioButton" id="heatindex">
+                                <property name="label" translatable="yes">Heat Index (US)</property>
+                                <property name="visible">True</property>
+                                <property name="can_focus">True</property>
+                                <property name="receives_default">False</property>
+                                <property name="xalign">0</property>
+                                <property name="active">True</property>
+                                <property name="draw_indicator">True</property>
+                              </object>
+                              <packing>
+                                <property name="expand">False</property>
+                                <property name="fill">False</property>
+                                <property name="position">0</property>
+                              </packing>
+                            </child>
+                            <child>
+                              <object class="GtkRadioButton" id="humidex">
+                                <property name="label" translatable="yes">Humidex (Canada)</property>
+                                <property name="visible">True</property>
+                                <property name="can_focus">True</property>
+                                <property name="receives_default">False</property>
+                                <property name="xalign">0</property>
+                                <property name="draw_indicator">True</property>
+                                <property name="group">heatindex</property>
+                              </object>
+                              <packing>
+                                <property name="expand">False</property>
+                                <property name="fill">False</property>
+                                <property name="position">1</property>
+                              </packing>
+                            </child>
+                          </object>
+                        </child>
+                      </object>
+                      <packing>
+                        <property name="expand">False</property>
+                        <property name="fill">True</property>
+                        <property name="position">1</property>
+                      </packing>
+                    </child>
+                  </object>
+                  <packing>
+                    <property name="expand">False</property>
+                    <property name="fill">True</property>
+                    <property name="position">1</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkBox" id="box2">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="orientation">vertical</property>
+                    <child>
+                      <object class="GtkLabel" id="chilllabel">
+                        <property name="visible">True</property>
+                        <property name="can_focus">False</property>
+                        <property name="xalign">0</property>
+                        <property name="ypad">3</property>
+                        <property name="label" translatable="yes">&lt;b&gt;Wind Chill Formula&lt;/b&gt;</property>
+                        <property name="use_markup">True</property>
+                      </object>
+                      <packing>
+                        <property name="expand">False</property>
+                        <property name="fill">True</property>
+                        <property name="position">0</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <object class="GtkAlignment" id="alignment7">
+                        <property name="visible">True</property>
+                        <property name="can_focus">False</property>
+                        <property name="left_padding">12</property>
+                        <child>
+                          <object class="GtkBox" id="box7">
+                            <property name="visible">True</property>
+                            <property name="can_focus">False</property>
+                            <property name="orientation">vertical</property>
+                            <property name="homogeneous">True</property>
+                            <child>
+                              <object class="GtkRadioButton" id="wctindex">
+                                <property name="label" translatable="yes">JAG/TI Wind Chill Index (US/UK/Canada)</property>
+                                <property name="visible">True</property>
+                                <property name="can_focus">True</property>
+                                <property name="receives_default">False</property>
+                                <property name="xalign">0</property>
+                                <property name="active">True</property>
+                                <property name="draw_indicator">True</property>
+                              </object>
+                              <packing>
+                                <property name="expand">False</property>
+                                <property name="fill">False</property>
+                                <property name="position">0</property>
+                              </packing>
+                            </child>
+                            <child>
+                              <object class="GtkRadioButton" id="aatindex">
+                                <property name="label" translatable="yes">Apparent Temperature (Australia)</property>
+                                <property name="visible">True</property>
+                                <property name="can_focus">True</property>
+                                <property name="receives_default">False</property>
+                                <property name="xalign">0</property>
+                                <property name="draw_indicator">True</property>
+                                <property name="group">wctindex</property>
+                              </object>
+                              <packing>
+                                <property name="expand">False</property>
+                                <property name="fill">False</property>
+                                <property name="position">1</property>
+                              </packing>
+                            </child>
+                          </object>
+                        </child>
+                      </object>
+                      <packing>
+                        <property name="expand">False</property>
+                        <property name="fill">True</property>
+                        <property name="position">1</property>
+                      </packing>
+                    </child>
+                  </object>
+                  <packing>
+                    <property name="expand">False</property>
+                    <property name="fill">True</property>
+                    <property name="position">2</property>
+                  </packing>
+                </child>
+              </object>
+              <packing>
+                <property name="position">1</property>
+              </packing>
+            </child>
+            <child type="tab">
+              <object class="GtkLabel" id="label5">
+                <property name="visible">True</property>
+                <property name="can_focus">False</property>
+                <property name="label" translatable="yes">Conditions</property>
+              </object>
+              <packing>
+                <property name="position">1</property>
+                <property name="tab_fill">False</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkBox" id="vbox9">
+                <property name="visible">True</property>
+                <property name="can_focus">False</property>
+                <property name="border_width">12</property>
+                <property name="orientation">vertical</property>
+                <property name="spacing">12</property>
+                <child>
+                  <object class="GtkBox" id="vbox2">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="orientation">vertical</property>
                     <child>
                       <object class="GtkLabel" id="Metric System Unit">
                         <property name="visible">True</property>
+                        <property name="can_focus">False</property>
                         <property name="xalign">0</property>
                         <property name="ypad">3</property>
                         <property name="label" translatable="yes">&lt;b&gt;Temperature Scale&lt;/b&gt;</property>
@@ -285,16 +656,20 @@
                       </object>
                       <packing>
                         <property name="expand">False</property>
+                        <property name="fill">True</property>
                         <property name="position">0</property>
                       </packing>
                     </child>
                     <child>
                       <object class="GtkAlignment" id="alignment3">
                         <property name="visible">True</property>
+                        <property name="can_focus">False</property>
                         <property name="left_padding">12</property>
                         <child>
-                          <object class="GtkVBox" id="vbox6">
+                          <object class="GtkBox" id="box5">
                             <property name="visible">True</property>
+                            <property name="can_focus">False</property>
+                            <property name="orientation">vertical</property>
                             <property name="homogeneous">True</property>
                             <child>
                               <object class="GtkRadioButton" id="imperial">
@@ -302,6 +677,7 @@
                                 <property name="visible">True</property>
                                 <property name="can_focus">True</property>
                                 <property name="receives_default">False</property>
+                                <property name="xalign">0</property>
                                 <property name="active">True</property>
                                 <property name="draw_indicator">True</property>
                               </object>
@@ -317,6 +693,7 @@
                                 <property name="visible">True</property>
                                 <property name="can_focus">True</property>
                                 <property name="receives_default">False</property>
+                                <property name="xalign">0</property>
                                 <property name="draw_indicator">True</property>
                                 <property name="group">imperial</property>
                               </object>
@@ -331,21 +708,26 @@
                       </object>
                       <packing>
                         <property name="expand">False</property>
+                        <property name="fill">True</property>
                         <property name="position">1</property>
                       </packing>
                     </child>
                   </object>
                   <packing>
                     <property name="expand">False</property>
+                    <property name="fill">True</property>
                     <property name="position">0</property>
                   </packing>
                 </child>
                 <child>
-                  <object class="GtkVBox" id="vbox3">
+                  <object class="GtkBox" id="vbox3">
                     <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="orientation">vertical</property>
                     <child>
                       <object class="GtkLabel" id="Wind Speed Unit">
                         <property name="visible">True</property>
+                        <property name="can_focus">False</property>
                         <property name="xalign">0</property>
                         <property name="ypad">3</property>
                         <property name="label" translatable="yes">&lt;b&gt;Wind Speed Unit&lt;/b&gt;</property>
@@ -353,23 +735,28 @@
                       </object>
                       <packing>
                         <property name="expand">False</property>
+                        <property name="fill">True</property>
                         <property name="position">0</property>
                       </packing>
                     </child>
                     <child>
                       <object class="GtkAlignment" id="alignment4">
                         <property name="visible">True</property>
+                        <property name="can_focus">False</property>
                         <property name="left_padding">12</property>
                         <child>
-                          <object class="GtkVBox" id="vbox7">
+                          <object class="GtkBox" id="vbox7">
                             <property name="visible">True</property>
+                            <property name="can_focus">False</property>
+                            <property name="orientation">vertical</property>
                             <property name="homogeneous">True</property>
                             <child>
                               <object class="GtkRadioButton" id="mps">
-                                <property name="label" translatable="yes">Meter per second (m/s)</property>
+                                <property name="label" translatable="yes">Meters per second (m/s)</property>
                                 <property name="visible">True</property>
                                 <property name="can_focus">True</property>
                                 <property name="receives_default">False</property>
+                                <property name="xalign">0.5</property>
                                 <property name="active">True</property>
                                 <property name="draw_indicator">True</property>
                               </object>
@@ -385,6 +772,7 @@
                                 <property name="visible">True</property>
                                 <property name="can_focus">True</property>
                                 <property name="receives_default">False</property>
+                                <property name="xalign">0.5</property>
                                 <property name="draw_indicator">True</property>
                                 <property name="group">mps</property>
                               </object>
@@ -400,6 +788,7 @@
                                 <property name="visible">True</property>
                                 <property name="can_focus">True</property>
                                 <property name="receives_default">False</property>
+                                <property name="xalign">0.5</property>
                                 <property name="draw_indicator">True</property>
                                 <property name="group">mps</property>
                               </object>
@@ -411,10 +800,11 @@
                             </child>
                             <child>
                               <object class="GtkRadioButton" id="beaufort">
-                                <property name="label" translatable="yes">Beaufort</property>
+                                <property name="label" translatable="yes">Beaufort number</property>
                                 <property name="visible">True</property>
                                 <property name="can_focus">True</property>
                                 <property name="receives_default">False</property>
+                                <property name="xalign">0.5</property>
                                 <property name="draw_indicator">True</property>
                                 <property name="group">mps</property>
                               </object>
@@ -430,6 +820,7 @@
                                 <property name="visible">True</property>
                                 <property name="can_focus">True</property>
                                 <property name="receives_default">False</property>
+                                <property name="xalign">0.5</property>
                                 <property name="draw_indicator">True</property>
                                 <property name="group">mps</property>
                               </object>
@@ -444,41 +835,44 @@
                       </object>
                       <packing>
                         <property name="expand">False</property>
+                        <property name="fill">True</property>
                         <property name="position">1</property>
                       </packing>
                     </child>
                   </object>
                   <packing>
                     <property name="expand">False</property>
+                    <property name="fill">True</property>
                     <property name="position">1</property>
                   </packing>
                 </child>
               </object>
               <packing>
-                <property name="position">1</property>
+                <property name="position">2</property>
               </packing>
             </child>
             <child type="tab">
               <object class="GtkLabel" id="label2">
                 <property name="visible">True</property>
+                <property name="can_focus">False</property>
                 <property name="label" translatable="yes">Units</property>
               </object>
               <packing>
-                <property name="position">1</property>
+                <property name="position">2</property>
                 <property name="tab_fill">False</property>
               </packing>
             </child>
             <child>
-              <object class="GtkVBox" id="vbox8">
+              <object class="GtkBox" id="vbox8">
                 <property name="visible">True</property>
+                <property name="can_focus">False</property>
                 <property name="border_width">12</property>
+                <property name="orientation">vertical</property>
                 <property name="spacing">6</property>
                 <child>
                   <object class="GtkScrolledWindow" id="scrolledwindow1">
                     <property name="visible">True</property>
                     <property name="can_focus">True</property>
-                    <property name="hscrollbar_policy">automatic</property>
-                    <property name="vscrollbar_policy">automatic</property>
                     <property name="window_placement_set">True</property>
                     <property name="shadow_type">in</property>
                     <child>
@@ -490,6 +884,9 @@
                         <property name="headers_clickable">False</property>
                         <property name="reorderable">True</property>
                         <property name="search_column">0</property>
+                        <child internal-child="selection">
+                          <object class="GtkTreeSelection" id="treeview-selection1"/>
+                        </child>
                         <child>
                           <object class="GtkTreeViewColumn" id="City">
                             <property name="title">City</property>
@@ -506,12 +903,15 @@
                     </child>
                   </object>
                   <packing>
+                    <property name="expand">True</property>
+                    <property name="fill">True</property>
                     <property name="position">0</property>
                   </packing>
                 </child>
                 <child>
                   <object class="GtkHButtonBox" id="hbuttonbox1">
                     <property name="visible">True</property>
+                    <property name="can_focus">False</property>
                     <property name="spacing">6</property>
                     <property name="layout_style">start</property>
                     <child>
@@ -521,7 +921,7 @@
                         <property name="can_focus">True</property>
                         <property name="receives_default">True</property>
                         <property name="use_stock">True</property>
-                        <signal name="clicked" handler="on_add_location"/>
+                        <signal name="clicked" handler="on_add_location" swapped="no"/>
                       </object>
                       <packing>
                         <property name="expand">False</property>
@@ -536,7 +936,7 @@
                         <property name="can_focus">True</property>
                         <property name="receives_default">True</property>
                         <property name="use_stock">True</property>
-                        <signal name="clicked" handler="on_remove_location"/>
+                        <signal name="clicked" handler="on_remove_location" swapped="no"/>
                       </object>
                       <packing>
                         <property name="expand">False</property>
@@ -547,70 +947,33 @@
                   </object>
                   <packing>
                     <property name="expand">False</property>
+                    <property name="fill">True</property>
                     <property name="position">1</property>
                   </packing>
                 </child>
               </object>
               <packing>
-                <property name="position">2</property>
+                <property name="position">3</property>
               </packing>
             </child>
             <child type="tab">
               <object class="GtkLabel" id="label3">
                 <property name="visible">True</property>
+                <property name="can_focus">False</property>
                 <property name="label" translatable="yes">Locations</property>
               </object>
               <packing>
-                <property name="position">2</property>
+                <property name="position">3</property>
                 <property name="tab_fill">False</property>
               </packing>
             </child>
           </object>
           <packing>
+            <property name="expand">False</property>
+            <property name="fill">True</property>
             <property name="position">1</property>
           </packing>
         </child>
-        <child internal-child="action_area">
-          <object class="GtkHButtonBox" id="dialog-action_area1">
-            <property name="visible">True</property>
-            <property name="layout_style">end</property>
-            <child>
-              <object class="GtkButton" id="cancel_button">
-                <property name="label">gtk-cancel</property>
-                <property name="visible">True</property>
-                <property name="receives_default">True</property>
-                <property name="use_stock">True</property>
-                <signal name="clicked" handler="cancel"/>
-              </object>
-              <packing>
-                <property name="expand">False</property>
-                <property name="fill">False</property>
-                <property name="position">0</property>
-              </packing>
-            </child>
-            <child>
-              <object class="GtkButton" id="ok_button">
-                <property name="label">gtk-ok</property>
-                <property name="visible">True</property>
-                <property name="sensitive">False</property>
-                <property name="receives_default">True</property>
-                <property name="use_stock">True</property>
-                <signal name="clicked" handler="ok"/>
-              </object>
-              <packing>
-                <property name="expand">False</property>
-                <property name="fill">False</property>
-                <property name="position">1</property>
-              </packing>
-            </child>
-          </object>
-          <packing>
-            <property name="expand">False</property>
-            <property name="fill">False</property>
-            <property name="pack_type">end</property>
-            <property name="position">0</property>
-          </packing>
-        </child>
       </object>
     </child>
     <action-widgets>
@@ -618,10 +981,4 @@
       <action-widget response="-5">ok_button</action-widget>
     </action-widgets>
   </object>
-  <object class="GtkAdjustment" id="rate">
-    <property name="lower">1</property>
-    <property name="upper">30</property>
-    <property name="step_increment">1</property>
-    <property name="page_increment">10</property>
-  </object>
 </interface>

=== modified file 'debian/changelog'
--- debian/changelog	2012-07-30 04:02:24 +0000
+++ debian/changelog	2013-05-18 18:24:25 +0000
@@ -1,408 +1,247 @@
-indicator-weather (12.07.30~precise1) precise; urgency=low
-  * Skip sunset and sunrise check as Earthtools.org is down (LP: #964365)
-
- -- Vadim Rutkovsky <roignac@xxxxxxxxx>  Mon, 30 Jul 2012 07:01:51 +0300
-
-indicator-weather (11.11.28~precise2) precise; urgency=low
-  * Don't write too much debug info in the log (LP: #917253)
-
- -- Vadim Rutkovsky <roignac@xxxxxxxxx>  Wed, 18 Jan 2012 10:03:20 +0300
-
-indicator-weather (11.11.27~precise1) precise; urgency=low
-
-  * Bugfix version for Cloudy 9
-  * Preferences buttons OK and Cancel and Forecast's Close are not focusable (LP: #853774)
-  * Fixed installation error due to incorrect icon copying (LP: #808538)
-  * Don't crash if Google doesn't return icons (LP: #809187)
-  * Display degrees in wind info item if Yahoo is selected (LP: #838369)
-  * Fixed Assistant behavior for Forward/Back movements (LP: #804659)
-  * Fixed a crash when Unknown wind condition was returned, thanks Tomasz Maciejewski! (LP: #886028)
-  * Removed autostart feature - should be implemented in UI (LP: #873386)
-
- -- Vadim Rutkovsky <roignac@xxxxxxxxx>  Sun, 27 Nov 2011 10:47:41 +0300
-
-indicator-weather (11.05.31~precise7) precise; urgency=low
-
-  * Ported from python-support to dh_python2
-
- -- Vadim Rutkovsky <roignac@xxxxxxxxx>  Wed, 22 Jun 2011 02:27:38 -0700
-
-indicator-weather (11.05.31~precise6) precise; urgency=low
-
-  * Bugfix version for Cloudy 8
-  * Proper fix of self.db.list_keys() for precise users (LP: #791615)
-
- -- Vadim Rutkovsky <roignac@xxxxxxxxx>  Tue, 14 Jun 2011 05:12:19 -0700
-
-indicator-weather (11.05.31~precise5) precise; urgency=low
-
-  * Bugfix version for Cloudy 8
-  * Show default labels if some data from providers is missing (LP: #794473)
-  * Using try-catch instead self.db.list_keys() for precise users (LP: #791615)
-
- -- Vadim Rutkovsky <roignac@xxxxxxxxx>  Tue, 14 Jun 2011 04:12:33 -0700
-
-indicator-weather (11.05.31~precise4) precise; urgency=low
-
-  * Bugfix version for Cloudy 8
-  * Another update for Google icon path changes
-
- -- Vadim Rutkovsky <roignac@xxxxxxxxx>  Mon, 06 Jun 2011 02:57:42 -0700
-
-indicator-weather (11.05.31~precise3) precise; urgency=low
-
-  * Bugfix version for Cloudy 8
-  * Display correct icon and description for empty condition in forecast (LP: #791733)
-  * Updated google icon paths for Google icons (LP: #791724)
-
- -- Vadim Rutkovsky <roignac@xxxxxxxxx>  Thu, 02 Jun 2011 02:15:24 -0700
-
-indicator-weather (11.05.31~precise2) precise; urgency=low
-
-  * Bugfix version for Cloudy 8
-  * Attach dconf settings to apport results (LP: #731911)
-  * Store show_label in dconf correctly (LP: #791398)
-
- -- Vadim Rutkovsky <roignac@xxxxxxxxx>  Thu, 02 Jun 2011 00:53:06 -0700
-
-indicator-weather (11.05.31~precise1) precise; urgency=low
-
-  * New release in Cloudy series
-  * Ported settings to dconf, which will solve a number of desktopcouch-related bugs
-
- -- Vadim Rutkovsky <roignac@xxxxxxxxx>  Tue, 31 May 2011 02:43:24 -0700
-
-indicator-weather (11.05.30~precise1) precise; urgency=low
-
-  * New release in Cloudy series
-  * Fix for LP: #776586 "I get "Unknown error occurred while picking up weather data" when trying to open forecast."
-  * Fix for LP: #784935 "indicator-weather crash - KeyError: 'wind_condition'"
-  * Fix for LP: #788780	"indicator disappears with no reason"
-  * Fix for LP: #774406	"Insufficient http-proxy detection", thanks Panagiotis
-  * Fix for LP: #782572	"The log should contain Weather Indicator version"
-  * Fix for LP: #780585	"Celsius is not an SI unit"
-  * Fix for LP: #780817	"units mislabeled as kph"
-
- -- Vadim Rutkovsky <roignac@xxxxxxxxx>  Mon, 30 May 2011 03:20:58 -0700
-
-indicator-weather (11.05.01~precise2) precise; urgency=low
-
-  * New release in Cloudy series
-  * Fix for LP: #765464 "sunrise and sunset info incorrect", thanks Panagiotis!
-  * Fix for LP: #775630 "package indicator-weather 11.05.01~precise1 failed to install/upgrade"
-  * Fix for LP: #772552 "weather applet doesn't start"
-  * Fix for LP: #769842 "Weather Indicator should clear up corrupted DB"
-
- -- Vadim Rutkovsky <roignac@xxxxxxxxx>  Mon, 02 May 2011 19:59:36 +0300
-
-indicator-weather (11.04.24~precise4) precise; urgency=low
-
-  * New release in Cloudy series
-  * Fix for LP: #747733 "indicator-weather crashed with TypeError in next_page(): unknown type (null)"
-  * Fix for LP: #757195 "Again: Version 11.04.10~precise4 doesn't start"
-  * Fix for LP: #758309 "dpkg error when installing latest build on Ubuntu 11.04 Beta", using patch from Andrew Starr-Bochicchio
-  * Fix for LP: #766049 "Traceback on startup: No module named desktopcouch.records.server"
-  * Fix for LP: #753309 "weather applet displays wrong sunset/sunrise times", using earthtools for both Google and Yahoo
-  * Fix for LP: #765464 "do not see indicator-weather on the panel"
-  * python-apport is now recommended only, thanks Andrew
-
- -- Vadim Rutkovsky <roignac@xxxxxxxxx>  Sun, 24 Apr 2011 10:57:00 +0300
-
-indicator-weather (11.04.10~precise4) precise; urgency=low
-
-  * New release in Cloudy series
-  * Fix for LP: #743375 "indicator-weather crashed with error in _try_request_with_retries(): [Errno 111] Connection refused"
-  * Fix for LP: #747562 "indicator-weather crashed with AttributeError in get_value(): Settings instance has no attribute 'settings_design_doc'"
-  * Fix for LP: #743840 "Crashes on forecast view"
-  * Fix for LP: #750809 "No "Thunderstorm" icon shown in Forecast only empty place holder.", thanks Felix!
-  * Fix for LP: #743375 "indicator-weather should re-use the time-format of other indicators", thanks Panagiotis!
-  * debian/postinst: copy few-clouds to clouds to show all icons (LP: #710295)
-  * Updated dependencies - added python-gconf
-
- -- Vadim Rutkovsky <roignac@xxxxxxxxx>  Sun, 10 Apr 2011 10:05:12 +0300
-
-indicator-weather (11.04.02~precise) precise; urgency=low
-
-  * New release in Cloudy series
-  * Fix for LP: #739420 "indicator-weather crashed with KeyError in prepare_forecast_data(): 'unit_system'", thanks Felix!
-  * Fix for LP: #732569 "weather applet freezes on clicking refresh", thanks Panagiotis!
-  * Fix for LP: #745504 "no degree marker ℃ ℉ displayed", thanks Lucian!
-  * Fix for LP: #739029 "Indicator takes up too much space"
-  * Fix for LP: #739029 "Quit button doesn't work", thanks Panagiotis!
-  * Fix for LP: #745634 "http proxy not supported", thanks Panagiotis!
-  * Fix for LP: #742397 "weather applet doesn't refresh information after resume", thanks Panagiotis!
-
- -- Vadim Rutkovsky <roignac@xxxxxxxxx>  Sat, 02 Apr 2011 12:08:56 +0300
-
-indicator-weather (11.03.27~precise) precise; urgency=low
-
-  * New release in Cloudy series
-  * Fix for LP: #739907 "indicator-weather failed to start falsely reporting duplicate instance", thanks Felix!
-  * Fix for LP: #720030 "indicator invisible on first run", thanks Felix!
-  * Fix for LP: #743347 "what's the meaning of Mixed rain and snow/Sleet/Mixed rain and sleet/Mixed snow and sleet"
-  * Fix for LP: #738671 "Allow only one instance of any dialog"
-  * Fix for LP: #735667 "indicator-weather crashed with NetworkException in FetchReport(): HTTP Error 408: Request Time-out"
-  * Fix for LP: #739209 "indicator-weather crashed with AttributeError in get_value(): 'NoneType' object has no attribute 'execute_view'"
-  * Fix for LP: #738845 "indicator-weather crashed with IOError in about(): [Errno 2] No such file or directory: '/usr/share/doc/indicator-weather/COPYING'"
-  * Fix for LP: #743366 "Location selected but no weather"
-  * Updated Refresh label for plural forms
-
- -- Vadim Rutkovsky <roignac@xxxxxxxxx>  Sun, 27 Mar 2011 13:27:42 +0300
-
-indicator-weather (11.03.20~precise2) precise; urgency=low
-
-  * Quick fix release for Cloudy
-  * Fix for LP: #738804 "indicator-weather crashed with KeyError in on_get_city_names(): 'geonames'"
-  * Fix for LP: #738762 "indicator-weather crashed with ImportError in /usr/lib/pymodules/python2.7/desktopcouch/records/server.py: No module named application.server"
-
- -- Vadim Rutkovsky <roignac@xxxxxxxxx>  Sun, 20 Mar 2011 20:05:29 +0200
-
-indicator-weather (11.03.20~precise) precise; urgency=low
-
-  * Releasing 11.03.20 "Cloudy" version
-  * Fix for LP: #738503 "indicator-weather crashed with IOError in about(): [Errno 2] No such file or directory: '../AUTHORS' after clicking About..."
-
- -- Vadim Rutkovsky <roignac@xxxxxxxxx>  Sun, 20 Mar 2011 07:54:50 +0200
-
-indicator-weather (11.02.13+unstable+bzr217+rc3~precise) precise; urgency=low
-
-  * Release Candidate 3
-  * Fix for LP: #713846 "Weather Indicator should have About page"
-
- -- Vadim Rutkovsky <roignac@xxxxxxxxx>  Sat, 19 Mar 2011 11:26:54 +0200
-
-indicator-weather (11.02.13+unstable+bzr214+rc1~precise) precise; urgency=low
-
-  * Release Candidate 2
-  * Fix for LP: #735928 "indicator-weather crashed with NameError in prepare_settings_store(): global name 'DBusException' is not defined"
-  * Fix for LP: #734362 "Use plural forms in translations for units"
-  * Fix for LP: #721714 "Refresh label should contain info about time from last refresh"
-
- -- Vadim Rutkovsky <roignac@xxxxxxxxx>  Sat, 19 Mar 2011 01:33:31 +0200
-
-indicator-weather (11.02.13+unstable+bzr210+rc1~precise) precise; urgency=low
-
-  * Release Candidate 1
-  * Fix for LP: #733760 "indicator-weather crashed with KeyError in save_location_details(): 'yahoo id'"
-  * Fix for LP: #730193 "indicator-weather crashed with AttributeError in get_forecast_daysofweek(): Location instance has no attribute '_Location__parsedforecast'"
-  * Fix for LP: #728473 "Sunrise/sunset time being shown in DST"
-  * Fix for LP: #731236 "Sunset/sunrise time should not include seconds"
-  * Fix for LP: #719886 "An option to display temperature near the icon"
-
- -- Vadim Rutkovsky <roignac@xxxxxxxxx>  Thu, 10 Mar 2011 09:21:57 +0200
-
-indicator-weather (11.02.13+unstable+bzr204~precise) precise; urgency=low
-
-  * Fix for LP: #732434 "indicator-weather crashed with DBusException in call_blocking(): org.freedesktop.DBus.Error.NoReply"
-
- -- Vadim Rutkovsky <roignac@xxxxxxxxx>  Thu, 10 Mar 2011 09:21:57 +0200
-
-indicator-weather (11.02.13+unstable+bzr203~precise) precise; urgency=low
-
-  * Fixes for incorrect and missing icons
-  * Fix for LP: #732275 "CouchDB exception on db.compact()"
-
- -- Vadim Rutkovsky <roignac@xxxxxxxxx>  Thu, 10 Mar 2011 00:23:14 +0200
-
-indicator-weather (11.02.13~unstable+bzr200~precise) precise; urgency=low
-
-  * Implemented Desktopcouch support
-  * Using PyWAPI to get data
-  * Two data sources are available - Yahoo and Google
-
- -- Vadim Rutkovsky <roignac@xxxxxxxxx>  Wed, 09 Mar 2011 22:55:00 +0200
-
-indicator-weather (11.02.13+bzr180~precise) precise; urgency=low
-
-  * Implemented UI improvements. Thanks, Andrew
-  * Fix for LP: #719693 "[regression] Menu item will not show up in GNOME-Menu", thanks Andrew Starr-Bochicchio
-  * Fix for LP: #720112 "unsafe tempfile handling"
-  * Fix for LP: #719884 "Metric scales labels should include temperature units"
-  * Immideate update of icons
-  * Fix for missing kph setting on UI
-
- -- Vadim Rutkovsky <roignac@xxxxxxxxx>  Thu, 17 Feb 2011 00:13:01 +0200
-
-indicator-weather (11.02.13~precise) precise; urgency=low
-
-  * Migrate to gweather + pymetar data sources
-  * Added an option to choose wind units
-  * Fix for labels crash in precise
-  * Removed countries without cities from the tree
-  * Updated connection handling
-  * Minor fixes for UI in Preferences dialog
-  * Updated settings store logic
-  * Removed knots - caused exceptions, see Bug #712434 in pymetar
-  * Updated icons
-  * Fixed error with incorrect permissions for pid file - now using /tmp
-  * Fix for LP: #712359 "'OK' button in Preferences dialog should be disabled, if location list is empty"
-  * Fix for LP: #712347 "Synapse launcher shows Preferences window instead of Weather Indicator"
-  * Fix for LP: #711891 "cannot go back from "Confirm the place" dialog"
-  * Fix for LP: #711889 "Translation issues"
-  * Fix for LP: #670796 "weather indicator does not wake up after suspend"
-  * Fix for LP: #617801 "Weather Indicator should show humidex value"
-  * Fix for LP: #703561 "Show temperature in icon"
-  * Fix for LP: #705673 "Add city dialogs should have city tree"
-  * Fix for LP: #710870 "Indicator-weather crashed with AttributeError in get_city(): indicator_weather instance has no attribute '_wind_unit'"
-  * Fix for LP: #707681 "Allow only one instance of WI"
-  * Fix for LP: #712680	"Full city name from 'Australasia & Oceania' is not displayed on Assistant page 2"
-  * Fix for LP: #706805 "indicator-weather crashed with AttributeError in get_city(): 'Assistant' object has no attribute 'metric_system'"
-  * Fix for LP: #706796 "indicator-weather crashed with ImportError in __main__: No module named gtkcrashhandler"
-  * Fix for LP: #703681 "Indicator-Weather doesn't recheck for Internet	connectivity"
-  * Fix for LP: #703842 "Menus look pale in Ambiance theme"
-  * Fix for LP: #703617 "Use icons of ubuntus date indicator"
-  * Fix for LP: #703693 "Weather applet does not start (icon missing)"
-  * Fix for LP: #706148 "indicator doesn't respect temperature scale preferences (Fahrenheit, Celsius)"
-  * Fix for LP: #703819 "Weather indicator confuses time"
-  * Fix for LP: #703838 "Weather Indicator should have a Quit menu entry"
-  * Fix for LP: #606481 "indicator-weather crashes on startup"
-  * Fix for LP: #703730 "indicator-weather doesn't display an icon for some cities"
-  * Fix for LP: #703838 "Weather Indicator should have a Quit menu entry"
-  * Fix for LP: #618108 "Label is not shown in the dialogs when specified"
-  * Fix for LP: #604265 "First configuration weather unit setting not saved"
-  * Fix for LP: #717907 "Not having a condition name should not be a big deal" - updated error text and icon
-
- -- Vadim Rutkovsky <roignac@xxxxxxxxx>  Sun, 13 Feb 2011 09:28:08 +0200
-
-indicator-weather (11.01.16~precise) precise; urgency=low
-
-  * Fix for Bug #618108 "Label is not shown in the dialogs when specified"
-  * Fix for Bug #604265 "First configuration weather unit setting not saved"
-
- -- Vadim Rutkovsky <roignac@xxxxxxxxx>  Sun, 16 Jan 2011 14:17:27 +0200
-
-indicator-weather (10.07.16~precise) precise; urgency=low
-
-  * Bugfix : list index out of range fixed
-
- -- ridem <mehd36@xxxxxxxxx>  Sun, 11 Jul 2010 01:11:10 +0200
-
-indicator-weather (10.07.15~precise) precise; urgency=low
-
-  * Sunlight-sunset added/night-day icons/ assistant made thanks to
-    cullen, but no label support for now
-
- -- ridem <mehd36@xxxxxxxxx>  Sat, 10 Jul 2010 21:32:53 +0200
-
-indicator-weather (10.07.14~precise) precise; urgency=low
-
-  * Autostart hidden and works, Assistant works, but needs polish now
-
- -- ridem <mehd36@xxxxxxxxx>  Sat, 10 Jul 2010 04:06:24 +0200
-
-indicator-weather (10.07.13~precise) precise; urgency=low
-
-  * New release.
-
- -- Mehdi Rejraji <mehdi@portable-mehdi>  Sat, 10 Jul 2010 02:48:49 +0200
-
-indicator-weather (10.07.13~precise) precise; urgency=low
-
-  * New release.
-
- -- Mehdi Rejraji <mehdi@portable-mehdi>  Sat, 10 Jul 2010 02:44:18 +0200
-
-indicator-weather (10.07.13~precise) precise; urgency=low
-
-  * New release.
-
- -- Mehdi Rejraji <mehdi@portable-mehdi>  Sat, 10 Jul 2010 02:36:52 +0200
-
-indicator-weather (10.07.13~precise) precise; urgency=low
-
-  * New release.
-
- -- Mehdi Rejraji <mehdi@portable-mehdi>  Sat, 10 Jul 2010 02:31:03 +0200
-
-indicator-weather (10.07.13~precise) precise; urgency=low
-
-  * Autostart, right category, find location in assistant, assistant not
-    finished yet
-
- -- ridem <mehd36@xxxxxxxxx>  Sat, 10 Jul 2010 02:01:21 +0200
-
-indicator-weather (10.07.12~precise) precise; urgency=low
-
-  * New release.
-
- -- Mehdi Rejraji <mehdi@portable-mehdi>  Sat, 10 Jul 2010 02:00:37 +0200
-
-indicator-weather (10.07.12~precise) precise; urgency=low
-
-  * New release.
-
- -- Mehdi Rejraji <mehdi@portable-mehdi>  Sat, 10 Jul 2010 01:01:59 +0200
-
-indicator-weather (10.07.12~precise) precise; urgency=low
-
-  * New release.
-
- -- Mehdi Rejraji <mehdi@portable-mehdi>  Sat, 10 Jul 2010 00:54:23 +0200
-
-indicator-weather (10.07.12~precise) precise; urgency=low
-
-  * New release.
-
- -- Mehdi Rejraji <mehdi@portable-mehdi>  Sat, 10 Jul 2010 00:53:35 +0200
-
-indicator-weather (10.07.12~precise) precise; urgency=low
-
-  * New release.
-
- -- Mehdi Rejraji <mehdi@portable-mehdi>  Sat, 10 Jul 2010 00:49:41 +0200
-
-indicator-weather (10.07.12~precise) precise; urgency=low
-
-  * New release.
-
- -- Mehdi Rejraji <mehdi@portable-mehdi>  Sat, 10 Jul 2010 00:45:09 +0200
-
-indicator-weather (10.07.12~precise) precise; urgency=low
-
-  * New release.
-
- -- Mehdi Rejraji <mehdi@portable-mehdi>  Sat, 10 Jul 2010 00:44:28 +0200
-
-indicator-weather (10.07.12~precise) precise; urgency=low
-
-  * New release.
-
- -- Mehdi Rejraji <mehdi@portable-mehdi>  Sat, 10 Jul 2010 00:42:08 +0200
-
-indicator-weather (10.07.12~precise) precise; urgency=low
-
-  * New release.
-
- -- Mehdi Rejraji <mehdi@portable-mehdi>  Sat, 10 Jul 2010 00:38:48 +0200
-
-indicator-weather (10.07.12~precise) precise; urgency=low
-
-  * New release.
-
- -- Mehdi Rejraji <mehdi@portable-mehdi>  Sat, 10 Jul 2010 00:36:36 +0200
-
-indicator-weather (10.07.12~precise) precise; urgency=low
-
-  * New release.
-
- -- Mehdi Rejraji <mehdi@portable-mehdi>  Sat, 10 Jul 2010 00:27:40 +0200
-
-indicator-weather (10.07.12~precise) precise; urgency=low
-
-  * Work on assistant
-
- -- ridem <mehd36@xxxxxxxxx>  Fri, 09 Jul 2010 01:26:35 +0200
-
-indicator-weather (10.07.11~precise) precise; urgency=low
-
-  * No intrusion for the first run
-
- -- ridem <mehd36@xxxxxxxxx>  Fri, 09 Jul 2010 01:23:33 +0200
-
-indicator-weather (10.07.10~precise) precise; urgency=low
-
-  * Now etended forecast uses chosen unit
-  * places addded/edited/removed only after Ok. Nice editing and
-    reordering
-
- -- ridem <mehd36@xxxxxxxxx>  Tue, 06 Jul 2010 20:45:27 +0200
+indicator-weather (13.05.17-0ubuntu0-ppa1) quantal; urgency=low
+
+  * Ported to GTK3 and GObject from PyGTK
+  * Rewrite threading code to avoid dbus-related crashes (LP: #743541)
+  * Added "feels like" temperature (humidex/heat index/wind chill)
+  * New "Conditions" tab in Preferences dialog to choose temperature
+    formulas and toggle display of some condition information
+  * Bumped version number to reflect massive changes
+
+ -- Joshua Tasker <jtasker@xxxxxxxxx>  Sat, 18 May 2013 12:59:03 +0500
+
+indicator-weather (12.07.30-0ubuntu1.1-ppa2.4) quantal; urgency=low
+
+  * Don't crash if Yahoo doesn't return conditions
+  * Fixed a crash when reading saved Places with no location IDs
+
+ -- Joshua Tasker <jtasker@xxxxxxxxx>  Sat, 04 May 2013 01:20:38 +0500
+
+indicator-weather (12.07.30-0ubuntu1.1-ppa2.3) quantal; urgency=low
+
+  * Fix units in Forecast when metric is selected
+
+ -- Joshua Tasker <jtasker@xxxxxxxxx>  Sat, 27 Apr 2013 18:33:26 +0500
+
+indicator-weather (12.07.30-0ubuntu1.1-ppa2.2) quantal; urgency=low
+
+  * One-line fix for outdated data sources
+
+ -- Joshua Tasker <jtasker@xxxxxxxxx>  Wed, 24 Apr 2013 20:39:42 +0500
+
+indicator-weather (12.07.30-0ubuntu1.1-ppa2.1) quantal; urgency=low
+
+  * Updated package dependency on pywapi (>= 0.3)
+
+ -- Joshua Tasker <jtasker@xxxxxxxxx>  Wed, 17 Apr 2013 16:22:46 -0400
+
+indicator-weather (12.07.30-0ubuntu1.1-ppa2) quantal; urgency=low
+
+  * Fix adding location, now uses Yahoo's YQL service
+
+ -- Joshua Tasker <jtasker@xxxxxxxxx>  Wed, 10 Apr 2013 14:16:18 -0400
+
+indicator-weather (12.07.30-0ubuntu1.1-ppa1) quantal; urgency=low
+
+  * Fix for "Forecast", now uses Yahoo instead of Google
+  * Bump dependency for python-pywapi to 0.3
+  * Hide Google radio button on Preferences UI
+
+ -- Joshua Tasker <jtasker@xxxxxxxxx>  Tue, 09 Apr 2013 02:27:04 +0500
+
+indicator-weather (12.07.30-0ubuntu1.1) quantal-proposed; urgency=low
+
+  * fix crash when adding new location (LP: #821233)
+    Thanks to Mantas Kriaučiūnas (mantas)
+
+ -- Michael Vogt <michael.vogt@xxxxxxxxxx>  Tue, 18 Dec 2012 09:59:40 +0100
+
+indicator-weather (12.07.30-0ubuntu1) quantal; urgency=low
+
+  * New upstream release.
+   - If Earthtools.org is down, report 'Unknown' rather than
+     blocking on sunset and sunrise times (LP: #964365).
+   - Correctly preform .pid file matching so we can restart after
+     a crash (LP: #926433).
+   - Fixed flurries condition being marked as 'Unknown' (LP: #928596).
+   - Km in the units tab now written in full as kilometres (LP: #952661).
+  * debian/control: Bump standards version to 3.9.3, no changes needed.
+  * debian/postinst: Don't manually install or compile gschema. Distutils.Extras
+    now installs it correctly and an apt trigger compiles it.
+
+ -- Andrew Starr-Bochicchio <a.starr.b@xxxxxxxxx>  Mon, 30 Jul 2012 16:32:33 -0400
+
+indicator-weather (11.11.28-0ubuntu1) precise; urgency=low
+
+  * New upstream release.
+   - Preferences buttons OK and Cancel and Forecast's Close
+     are not focusable (LP: #853774)
+   - Don't crash if Google doesn't return icons (LP: #809187)
+   - Display degrees in wind info item if Yahoo is selected (LP: #838369)
+   - Fixed Assistant behavior for Forward/Back movements (LP: #804659)
+   - Fixed a crash when Unknown wind condition was returned, thanks
+     Tomasz Maciejewski! (LP: #886028)
+   - Don't write too much debug info in the log (LP: #917253)
+  * Drop debian/patches/autostart.patch, applied upstream.
+  * Drop debian/README.source, no longer needed.
+
+ -- Andrew Starr-Bochicchio <a.starr.b@xxxxxxxxx>  Fri, 20 Jan 2012 15:25:46 -0500
+
+indicator-weather (11.05.31-0ubuntu3) precise; urgency=low
+
+  * Forward port fix for LP: #873386 from oneiric-proposed.
+  * debian/copyright: Bring up-to-date with latest Dep-5 spec.
+
+ -- Andrew Starr-Bochicchio <a.starr.b@xxxxxxxxx>  Fri, 04 Nov 2011 17:13:10 -0400
+
+indicator-weather (11.05.31-0ubuntu2.1) oneiric-proposed; urgency=low
+
+  * debian/postinst: Do not attempt to install autostart
+    file in user's home directory (LP: #873386).
+  * debian/patches/autostart.patch: Instead, check for file's
+    existance at runtime. If it is not there, properly create it.
+
+ -- Andrew Starr-Bochicchio <a.starr.b@xxxxxxxxx>  Wed, 02 Nov 2011 11:51:55 -0400
+
+indicator-weather (11.05.31-0ubuntu2) oneiric; urgency=low
+
+  * debian/postinst: Make sure script only opperates on
+    directories and not files (LP: #819292).
+
+ -- Andrew Starr-Bochicchio <a.starr.b@xxxxxxxxx>  Wed, 03 Aug 2011 14:12:39 -0400
+
+indicator-weather (11.05.31-0ubuntu1) oneiric; urgency=low
+
+  * New upstream release.
+   - Ported settings to dconf, which will solve a number of
+     desktopcouch-related bugs
+   - Fix for LP: #747733 "indicator-weather crashed with
+     TypeError in next_page(): unknown type (null)"
+   - Fix for LP: #756704 "Numbers (temperature etc.) do
+     not use local number format"
+   - Fix for LP: #770652 "sunrise and sunset info incorrect"
+   - Fix for LP: #765464 "do not see indicator-weather on the panel"
+   - Fix for LP: #769842 "Weather Indicator should clear up corrupted DB"
+   - Fix for LP: #778941 "Weather Indicator can't be disabled"
+   - Fix for LP: #796314 "ROUND_CEiLiNG error in Turkish locale"
+   - Fix for LP: #780973 "indicator-weather crashed with Unauthorized in
+     request(): ('unauthorized', 'Authentication required.')"
+  * debian/control:
+   - Adjust dependencies for desktop-couch to dconf transition. 
+   - Bump Standards-Version to 3.9.2. 
+   - Explictily depend on libgtk2.0-bin to ensure we have
+     /usr/bin/gtk-update-icon-cache (LP: #808387). 
+  * Convert from python-support to dh_python2.
+  * debian/rules:
+   - Drop get-orig-source target, not needed.
+   - Fix debian/postinst to check for symbolic links as well.
+
+ -- Andrew Starr-Bochicchio <a.starr.b@xxxxxxxxx>  Tue, 12 Jul 2011 01:44:53 -0400
+
+indicator-weather (11.04.10+repack-0ubuntu2) natty; urgency=low
+
+  * debian/postinst: Test to make sure file doesn't already
+    exist before creating link. (LP: #758323)
+
+ -- Andrew Starr-Bochicchio <a.starr.b@xxxxxxxxx>  Mon, 11 Apr 2011 23:11:03 -0400
+
+indicator-weather (11.04.10+repack-0ubuntu1) natty; urgency=low
+
+  * New upstream bug fix release.
+   - Fix for LP: #720066 "indicator-weather should re-use the
+     time-format of other indicators"
+   - Fix for LP: #750809 "No "Thunderstorm" icon shown in Forecast
+     only empty place holder."
+   - Fix for LP: #747562 "indicator-weather crashed with AttributeError
+     in get_value(): Settings instance has no attribute 'settings_design_doc'"
+   - Fix for LP: #743375 "indicator-weather crashed with error
+     in _try_request_with_retries(): [Errno 111] Connection refused"
+  * Drop python-apport from Depends to Recommends. (LP: #757568)
+  * Drop patches. Included upstream.
+  * debian/postinst: Link weather-few-clouds{-night}.png with
+    weather-clouds{-night}.png, work-a-round for incomplete icon
+    themes. Add Depends on gnome-icon-theme and xdg-utils.
+
+ -- Andrew Starr-Bochicchio <a.starr.b@xxxxxxxxx>  Mon, 11 Apr 2011 15:08:07 -0400
+
+indicator-weather (11.03.27+repack-0ubuntu1) natty; urgency=low
+
+  * New upstream release.
+   - Fix for LP: #720030 "indicator invisible on first run",
+     thanks Felix!
+   - Fix for LP: #739209 "indicator-weather crashed with
+     AttributeError in get_value(): 'NoneType' object has no
+     attribute 'execute_view'"
+   - Fix for LP: #739907 "indicator-weather failed to start
+     falsely reporting duplicate instance", thanks Felix!
+   - Fix for LP: #735667 "indicator-weather crashed with NetworkException
+     in FetchReport(): HTTP Error 408: Request Time-out"
+   - And even more bug fixes.
+  * debian/indicator-weather.install: COPYING file no longer
+    needed. Now uses common-license version.
+  * Drop lintian over-ride for extra-license-file. 
+  * Drop debian/patches/01_lp_738804.patch, applied upstream.
+  * debian/rules: No need to delete empty dir anymore.
+  * fix-google-coordinates-lp739420.patch: Fix formatting
+    of coordinates Google. Patch by Felix Lawrence!
+    Fixes LP: #739420 and LP: #744702.
+
+ -- Andrew Starr-Bochicchio <a.starr.b@xxxxxxxxx>  Mon, 28 Mar 2011 18:39:38 -0400
+
+indicator-weather (11.03.20+repack-0ubuntu2) natty; urgency=low
+
+  * Directly depend on desktopcouch to work-around LP: #738762.
+
+ -- Andrew Starr-Bochicchio <a.starr.b@xxxxxxxxx>  Wed, 23 Mar 2011 22:31:37 -0400
+
+indicator-weather (11.03.20+repack-0ubuntu1) natty; urgency=low
+
+  * New upstream release.
+   - Fix unsafe tempfile handling (LP: #720112).
+   - Fix gconf related crashers (LP: #723557).
+   - Fix TypeError in getHumidex() (LP: #730287).
+   - Allow two userid's to run indicator-weather
+     simultaneously (LP: #730378).
+   - Fix night icon showing during daytime (LP: #715657).
+   - Fix indicator invisible on first run (LP: #720030).
+   - Fix AttributeError in __find_city_by_code() (LP: #733681).
+   - Fix AttributeError when clicking "Forecast" if there is
+     no network connection (LP: # 730193).
+  * debian/control:
+   - Drop depends on python-simplejson, python-gconf,
+     python-pymetar, and python-gweather.
+   - Add depends on python-desktopcouch-records and
+     python-pywapi.
+  * Drop all old patches, applied upstream.
+  * 01_lp_738804.patch: Fix crash on city names with spaces.
+  * debian/rules:
+   - Tweak get-orig-source target for new upstream
+     directory naming.
+   - Don't compress AUTHORS and COPYING. Needed for
+     about dialog.
+  * debian/indicator-weather.install: Install AUTHORS
+    and COPYING files to /usr/share/doc/indicator-weather
+    to fix crash in about dialog.
+  * debian/indicator-weather.lintian-overrides: Overide
+    lintian warning about extra copyright file.
+
+ -- Andrew Starr-Bochicchio <a.starr.b@xxxxxxxxx>  Sun, 20 Mar 2011 22:16:35 -0400
+
+indicator-weather (11.02.13+repack-0ubuntu1) natty; urgency=low
+
+  * New upstream release.
+   - Fixes crash due to icon missing (LP: #703693).
+  * debian/control: Depend on python-pymetar, python-gweather,
+    and python-apport.
+  * debian/patches/01_US_units.patch: Cherry pick upstream
+    revision 174 containing fix for forecast with US units.
+  * Install apport hook.
+  * debian/patches/02_menu_entry.patch: Allow indicator-weather
+    to show in GNOME menu and validate with desktop-file-validate.
+
+ -- Andrew Starr-Bochicchio <a.starr.b@xxxxxxxxx>  Mon, 14 Feb 2011 22:43:07 -0500
+
+indicator-weather (11.01.16+repack-0ubuntu1) natty; urgency=low
+
+  * Initial Ubuntu release. (LP: #711518)
+
+ -- Andrew Starr-Bochicchio <a.starr.b@xxxxxxxxx>  Tue, 01 Feb 2011 16:45:54 -0500

=== modified file 'debian/control'
--- debian/control	2011-06-22 09:52:46 +0000
+++ debian/control	2013-05-18 18:24:25 +0000
@@ -1,26 +1,33 @@
 Source: indicator-weather
 Section: python
 Priority: extra
-Build-Depends: cdbs (>= 0.4.90-1~),
- debhelper (>= 6),
- python (>= 2.6.6-3~),
- gobject-introspection,
- python-distutils-extra (>= 2.10)
-Maintainer: Vadim Rutkovsky <roignac@xxxxxxxxx>
-Standards-Version: 3.8.3
+Build-Depends: debhelper (>= 7.0.50~),
+               gobject-introspection,
+               python (>= 2.6.6-3~),
+               python-distutils-extra (>= 2.10)
+X-Python-Version: >= 2.6
+Maintainer: Ubuntu Developers <ubuntu-devel-discuss@xxxxxxxxxxxxxxxx>
+Standards-Version: 3.9.3
+Homepage: https://launchpad.net/weather-indicator
 
 Package: indicator-weather
 Architecture: all
-Depends: ${misc:Depends},
- ${python:Depends},
- libglib2.0-bin,
- python-appindicator,
- python-notify,
- python-gobject,
- python-gtk2,
- python-gconf,
- python-pywapi
+Depends: gir1.2-glib-2.0,
+         gir1.2-gtk-3.0,
+         gir1.2-appindicator3-0.1
+         gnome-icon-theme,
+         libglib2.0-bin,
+         libgtk-3-bin,
+         python-gconf,
+         python-gi,
+         python-pywapi (>= 0.3.1),
+         xdg-utils,
+         ${misc:Depends},
+         ${python:Depends}
 Recommends: python-apport
-Description: A weather indicator for Ubuntu's Indicator Applet
- A weather indicator that displays information for one or multiple places
- in the world
+Description: indicator that displays weather information
+ Indicator-Weather displays information for one or multiple places
+ in the world. Current weather status is displayed directly on your
+ panel and detailed forecasts are no more than a click away.
+ . 
+ It is implemented using the Indicator Applet API.

=== modified file 'debian/copyright'
--- debian/copyright	2011-06-22 09:52:46 +0000
+++ debian/copyright	2013-05-18 18:24:25 +0000
@@ -1,12 +1,31 @@
-Format-Specification: http://wiki.debian.org/Proposals/CopyrightFormat
-Upstream-Name: indicator-weather
-Upstream-Maintainer: Vadim Rutkovsky <roignac@xxxxxxxxx>
-Upstream-Source: https://launchpad.net/weather-indicator
+Format: http://dep.debian.net/deps/dep5
+Upstream-Name: Indicator-Weather
+Upstream-Contact: Vadim Rutkovsky <roignac@xxxxxxxxx>
+Source: https://launchpad.net/weather-indicator/+download
 
 Files: *
-Copyright: (C) 2010 Mehdi Rejraji mehd36@xxxxxxxxx
-Copyright: (C) 2010 Sebastian MacDonald Sebas310@xxxxxxxxx
-Copyright: (C) 2011 Vadim Rutkovsky <roignac@xxxxxxxxx>
-License: GPL-3
- The full text of the GPL is distributed in
- /usr/share/common-licenses/GPL-3 on Debian systems.
+Copyright: 2010, Mehdi Rejraji <mehd36@xxxxxxxxx>
+           2010, Sebastian MacDonald <Sebas310@xxxxxxxxx>
+           2011, Vadim Rutkovsky <roignac@xxxxxxxxx>
+           2013, Joshua Tasker <jtasker@xxxxxxxxx>
+License: GPL-3
+
+Files: debian/*
+Copyright: 2011, Andrew Starr-Bochicchio <a.starr.b@xxxxxxxxx>
+License: GPL-3
+
+License: GPL-3
+  This package is free software; you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation; version 3 of the License.
+  .
+  This package is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+  .
+  You should have received a copy of the GNU General Public License
+  along with this package; if not, write to the Free Software
+  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
+  .
+  On Debian systems, see `/usr/share/common-licenses/GPL-3'

=== modified file 'debian/indicator-weather.install'
--- debian/indicator-weather.install	2011-01-23 14:08:21 +0000
+++ debian/indicator-weather.install	2013-05-18 18:24:25 +0000
@@ -1,1 +1,2 @@
+AUTHORS /usr/share/doc/indicator-weather
 debian/source_indicator-weather.py usr/share/apport/package-hooks

=== modified file 'debian/postinst'
--- debian/postinst	2011-11-02 15:34:54 +0000
+++ debian/postinst	2013-05-18 18:24:25 +0000
@@ -1,19 +1,18 @@
 #!/bin/sh
-	
+
+set -e
+
 #DEBHELPER#
+
 echo "Installing indicator-specific icons..."
 xdg-icon-resource install --theme hicolor --novendor --size 22 /usr/share/indicator-weather/media/icon.png weather-indicator
 xdg-icon-resource install --theme hicolor --novendor --size 22 /usr/share/indicator-weather/media/icon_unknown_condition.png weather-indicator-unknown
 xdg-icon-resource install --theme hicolor --novendor --size 22 /usr/share/indicator-weather/media/icon_connection_error.png weather-indicator-error
 
-#installing dconf schema
-echo "Installing indicator dconf schema..."
-cp /usr/share/indicator-weather/indicator-weather.gschema.xml /usr/share/glib-2.0/schemas
-glib-compile-schemas /usr/share/glib-2.0/schemas
-
 #quick fix for incomplete icon themes
 echo "Fixing incomplete weather icons..."
-if [ ! -e "/usr/share/icons/gnome/22x22/status/weather-clouds.png" ]; then
+if [ ! -e "/usr/share/icons/gnome/22x22/status/weather-clouds.png" ] && \
+    [ !  -L "/usr/share/icons/gnome/22x22/status/weather-clouds.png" ]; then
     ln -s /usr/share/icons/gnome/22x22/status/weather-few-clouds.png /usr/share/icons/gnome/22x22/status/weather-clouds.png
     ln -s /usr/share/icons/gnome/22x22/status/weather-clouds-night.png /usr/share/icons/gnome/22x22/status/weather-clouds-night.png
     

=== modified file 'debian/rules'
--- debian/rules	2011-06-22 09:52:46 +0000
+++ debian/rules	2013-05-18 18:24:25 +0000
@@ -1,5 +1,11 @@
 #!/usr/bin/make -f
-DEB_PYTHON2_MODULE_PACKAGES:=indicator-weather
-
-include /usr/share/cdbs/1/rules/debhelper.mk
-include /usr/share/cdbs/1/class/python-distutils.mk
+
+%:
+	dh  $@ --with python2
+
+override_dh_auto_install:
+	dh_auto_install
+	find -iname "*.desktop" -exec chmod a-x {} \;
+
+override_dh_compress:
+	dh_compress -XAUTHORS

=== modified file 'indicator_weather/helpers.py'
--- indicator_weather/helpers.py	2012-07-30 03:58:13 +0000
+++ indicator_weather/helpers.py	2013-05-18 18:24:25 +0000
@@ -31,10 +31,10 @@
 except ImportError:
     DCONF_SCHEMAS = []
 
-import gconf
+from gi.repository import GConf
 import traceback
 import os
-import gtk
+from gi.repository import Gtk
 import urllib2
 import locale
 import re
@@ -47,7 +47,7 @@
 gettext.textdomain('indicator-weather')
 
 def get_builder(builder_file_name):
-    """Return a fully-instantiated gtk.Builder instance from specified ui
+    """Return a fully-instantiated Gtk.Builder instance from specified ui
     file
 
     :param builder_file_name: The name of the builder file, without extension.
@@ -58,7 +58,7 @@
     if not os.path.exists(ui_filename):
         ui_filename = None
 
-    builder = gtk.Builder()
+    builder = Gtk.Builder()
     builder.set_translation_domain('indicator-weather')
     builder.add_from_file(ui_filename)
     return builder
@@ -101,10 +101,10 @@
                 proxy_settings.connect("changed", ProxyMonitor.dconf_proxy_changed)
             else:
                 # load gconf settings
-                client = gconf.client_get_default()
-                client.add_dir("/system/http_proxy", gconf.CLIENT_PRELOAD_ONELEVEL)
+                client = GConf.Client.get_default()
+                client.add_dir("/system/http_proxy", GConf.ClientPreloadType.PRELOAD_ONELEVEL)
                 ProxyMonitor.gconf_proxy_changed(client)
-                client.notify_add("/system/http_proxy", ProxyMonitor.gconf_proxy_changed)
+                client.notify_add("/system/http_proxy", ProxyMonitor.gconf_proxy_changed, None)
 
         except Exception, e:
             log.error("ProxyMonitor: %s" % e)
@@ -113,7 +113,7 @@
     @staticmethod
     def dconf_proxy_changed(settings, changed_key=None):
         """
-        Loads dconf hhtp proxy settings
+        Loads dconf http proxy settings
         """
         try:
             ProxyMonitor.log.debug("ProxyMonitor: loading dconf settings")
@@ -135,7 +135,7 @@
     @staticmethod
     def gconf_proxy_changed(client, cnxn_id=None, entry=None, data=None):
         """
-        Loads gconf hhtp proxy settings
+        Loads gconf http proxy settings
         """
         try:
             ProxyMonitor.log.debug("ProxyMonitor: loading gconf settings")

=== modified file 'indicator_weather/indicator_weatherconfig.py'
--- indicator_weather/indicator_weatherconfig.py	2010-07-06 12:10:37 +0000
+++ indicator_weather/indicator_weatherconfig.py	2013-05-18 18:24:25 +0000
@@ -28,7 +28,7 @@
 
 # Where your project will look for your data (for instance, images and ui
 # files). By default, this is ../data, relative your trunk layout
-__indicator_weather_data_directory__ = '../data'
+__indicator_weather_data_directory__ = '/usr/share/indicator-weather'
 __license__ = 'GPL-3'
 
 import os
@@ -62,7 +62,7 @@
     # Get pathname absolute or relative.
     path = os.path.join(
         os.path.dirname(__file__), __indicator_weather_data_directory__)
-
+    
     abs_data_path = os.path.abspath(path)
     if not os.path.exists(abs_data_path):
         raise project_path_not_found

=== modified file 'po/indicator-weather.pot'
--- po/indicator-weather.pot	2011-06-22 09:52:46 +0000
+++ po/indicator-weather.pot	2013-05-18 18:24:25 +0000
@@ -8,7 +8,7 @@
 msgstr ""
 "Project-Id-Version: PACKAGE VERSION\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2011-06-22 02:48-0700\n"
+"POT-Creation-Date: 2012-07-30 07:11+0300\n"
 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
 "Language-Team: LANGUAGE <LL@xxxxxx>\n"
@@ -18,422 +18,425 @@
 "Content-Transfer-Encoding: 8bit\n"
 
 #: ../data/ui/PreferencesDialog.ui.h:1
-msgid "<b>Notifications</b>"
+msgid "Weather Indicator Preferences"
 msgstr ""
 
 #: ../data/ui/PreferencesDialog.ui.h:2
-msgid "<b>Temperature Scale</b>"
+msgid "Enable the Weather Indicator Applet"
 msgstr ""
 
 #: ../data/ui/PreferencesDialog.ui.h:3
-msgid "<b>Weather Data Source</b>"
+msgid "Show temperature near indicator"
 msgstr ""
 
 #: ../data/ui/PreferencesDialog.ui.h:4
-msgid "<b>Wind Speed Unit</b>"
+msgid "Update every"
 msgstr ""
 
 #: ../data/ui/PreferencesDialog.ui.h:5
-msgid "Beaufort"
+msgid "minutes"
 msgstr ""
 
 #: ../data/ui/PreferencesDialog.ui.h:6
-msgid "Enable the Weather Indicator Applet"
+msgid "<b>Notifications</b>"
 msgstr ""
 
 #: ../data/ui/PreferencesDialog.ui.h:7
-msgid "General"
+msgid "No notifications"
 msgstr ""
 
 #: ../data/ui/PreferencesDialog.ui.h:8
-msgid "Google"
+msgid "Only use notifications to give severe weather alerts"
 msgstr ""
 
 #: ../data/ui/PreferencesDialog.ui.h:9
-msgid "Imperial (°F)"
+msgid "Use notifications to give every weather condition change"
 msgstr ""
 
 #: ../data/ui/PreferencesDialog.ui.h:10
-msgid "Km per hour (km/h)"
+msgid "<b>Weather Data Source</b>"
 msgstr ""
 
 #: ../data/ui/PreferencesDialog.ui.h:11
-msgid "Knots"
+msgid "Google"
 msgstr ""
 
 #: ../data/ui/PreferencesDialog.ui.h:12
-msgid "Locations"
+msgid "Yahoo!"
 msgstr ""
 
 #: ../data/ui/PreferencesDialog.ui.h:13
-msgid "Meter per second (m/s)"
+msgid "General"
 msgstr ""
 
 #: ../data/ui/PreferencesDialog.ui.h:14
-msgid "Miles per hour (mph)"
+msgid "<b>Temperature Scale</b>"
 msgstr ""
 
 #: ../data/ui/PreferencesDialog.ui.h:15
-msgid "No notifications"
+msgid "Imperial (°F)"
 msgstr ""
 
 #: ../data/ui/PreferencesDialog.ui.h:16
-msgid "Only use notifications to give severe weather alerts"
+msgid "SI (metric, °C)"
 msgstr ""
 
 #: ../data/ui/PreferencesDialog.ui.h:17
-msgid "SI (metric, °C)"
+msgid "<b>Wind Speed Unit</b>"
 msgstr ""
 
 #: ../data/ui/PreferencesDialog.ui.h:18
-msgid "Show temperature near indicator"
+msgid "Meter per second (m/s)"
 msgstr ""
 
 #: ../data/ui/PreferencesDialog.ui.h:19
-msgid "Units"
+msgid "Miles per hour (mph)"
 msgstr ""
 
 #: ../data/ui/PreferencesDialog.ui.h:20
-msgid "Update every"
+msgid "Kilometers per hour (km/h)"
 msgstr ""
 
 #: ../data/ui/PreferencesDialog.ui.h:21
-msgid "Use notifications to give every weather condition change"
+msgid "Beaufort"
 msgstr ""
 
 #: ../data/ui/PreferencesDialog.ui.h:22
-msgid "Weather Indicator Preferences"
+msgid "Knots"
 msgstr ""
 
 #: ../data/ui/PreferencesDialog.ui.h:23
-msgid "Yahoo!"
+msgid "Units"
 msgstr ""
 
 #: ../data/ui/PreferencesDialog.ui.h:24
-msgid "minutes"
+msgid "Locations"
 msgstr ""
 
-#: ../bin/indicator-weather.py:463
+#: ../bin/indicator-weather.py:489
 msgid "Unknown error occurred while picking up weather data"
 msgstr ""
 
-#: ../bin/indicator-weather.py:551
+#: ../bin/indicator-weather.py:579
 msgid "Tornado"
 msgstr ""
 
-#: ../bin/indicator-weather.py:552
+#: ../bin/indicator-weather.py:580
 msgid "Tropical storm"
 msgstr ""
 
-#: ../bin/indicator-weather.py:553
+#: ../bin/indicator-weather.py:581
 msgid "Hurricane"
 msgstr ""
 
-#: ../bin/indicator-weather.py:554
+#: ../bin/indicator-weather.py:582
 msgid "Severe thunderstorms"
 msgstr ""
 
-#: ../bin/indicator-weather.py:555
+#: ../bin/indicator-weather.py:583
 msgid "Thunderstorms"
 msgstr ""
 
-#: ../bin/indicator-weather.py:556
+#: ../bin/indicator-weather.py:584
 msgid "Mixed rain and snow"
 msgstr ""
 
 #. Use American meaning of sleet - see http://en.wikipedia.org/wiki/Sleet
-#: ../bin/indicator-weather.py:558
+#: ../bin/indicator-weather.py:586
 msgid "Mixed rain and sleet"
 msgstr ""
 
-#: ../bin/indicator-weather.py:559
+#: ../bin/indicator-weather.py:587
 msgid "Mixed snow and sleet"
 msgstr ""
 
-#: ../bin/indicator-weather.py:560
+#: ../bin/indicator-weather.py:588
 msgid "Freezing drizzle"
 msgstr ""
 
-#: ../bin/indicator-weather.py:561
+#: ../bin/indicator-weather.py:589
 msgid "Drizzle"
 msgstr ""
 
-#: ../bin/indicator-weather.py:562
+#: ../bin/indicator-weather.py:590
 msgid "Freezing rain"
 msgstr ""
 
-#: ../bin/indicator-weather.py:563 ../bin/indicator-weather.py:564
+#: ../bin/indicator-weather.py:591 ../bin/indicator-weather.py:592
 msgid "Showers"
 msgstr ""
 
-#: ../bin/indicator-weather.py:565
+#: ../bin/indicator-weather.py:593
 msgid "Snow flurries"
 msgstr ""
 
-#: ../bin/indicator-weather.py:566
+#: ../bin/indicator-weather.py:594
 msgid "Light snow showers"
 msgstr ""
 
-#: ../bin/indicator-weather.py:567
+#: ../bin/indicator-weather.py:595
 msgid "Blowing snow"
 msgstr ""
 
-#: ../bin/indicator-weather.py:568
+#: ../bin/indicator-weather.py:596
 msgid "Snow"
 msgstr ""
 
-#: ../bin/indicator-weather.py:569
+#: ../bin/indicator-weather.py:597
 msgid "Hail"
 msgstr ""
 
-#: ../bin/indicator-weather.py:570
+#: ../bin/indicator-weather.py:598
 msgid "Sleet"
 msgstr ""
 
-#: ../bin/indicator-weather.py:571
+#: ../bin/indicator-weather.py:599
 msgid "Dust"
 msgstr ""
 
-#: ../bin/indicator-weather.py:572
+#: ../bin/indicator-weather.py:600
 msgid "Foggy"
 msgstr ""
 
-#: ../bin/indicator-weather.py:573
+#: ../bin/indicator-weather.py:601
 msgid "Haze"
 msgstr ""
 
-#: ../bin/indicator-weather.py:574
+#: ../bin/indicator-weather.py:602
 msgid "Smoky"
 msgstr ""
 
-#: ../bin/indicator-weather.py:575
+#: ../bin/indicator-weather.py:603
 msgid "Blustery"
 msgstr ""
 
-#: ../bin/indicator-weather.py:576
+#: ../bin/indicator-weather.py:604
 msgid "Windy"
 msgstr ""
 
-#: ../bin/indicator-weather.py:577
+#: ../bin/indicator-weather.py:605
 msgid "Cold"
 msgstr ""
 
-#: ../bin/indicator-weather.py:578
+#: ../bin/indicator-weather.py:606
 msgid "Cloudy"
 msgstr ""
 
-#: ../bin/indicator-weather.py:579 ../bin/indicator-weather.py:580
+#: ../bin/indicator-weather.py:607 ../bin/indicator-weather.py:608
 msgid "Mostly cloudy"
 msgstr ""
 
-#: ../bin/indicator-weather.py:581 ../bin/indicator-weather.py:582
-#: ../bin/indicator-weather.py:596
+#: ../bin/indicator-weather.py:609 ../bin/indicator-weather.py:610
+#: ../bin/indicator-weather.py:624
 msgid "Partly cloudy"
 msgstr ""
 
-#: ../bin/indicator-weather.py:583
+#: ../bin/indicator-weather.py:611
 msgid "Clear"
 msgstr ""
 
-#: ../bin/indicator-weather.py:584
+#: ../bin/indicator-weather.py:612
 msgid "Sunny"
 msgstr ""
 
-#: ../bin/indicator-weather.py:585 ../bin/indicator-weather.py:586
+#: ../bin/indicator-weather.py:613 ../bin/indicator-weather.py:614
 msgid "Fair"
 msgstr ""
 
-#: ../bin/indicator-weather.py:587
+#: ../bin/indicator-weather.py:615
 msgid "Mixed rain and hail"
 msgstr ""
 
-#: ../bin/indicator-weather.py:588
+#: ../bin/indicator-weather.py:616
 msgid "Hot"
 msgstr ""
 
-#: ../bin/indicator-weather.py:589
+#: ../bin/indicator-weather.py:617
 msgid "Isolated thunderstorms"
 msgstr ""
 
-#: ../bin/indicator-weather.py:590 ../bin/indicator-weather.py:591
+#: ../bin/indicator-weather.py:618 ../bin/indicator-weather.py:619
 msgid "Scattered thunderstorms"
 msgstr ""
 
-#: ../bin/indicator-weather.py:592
+#: ../bin/indicator-weather.py:620
 msgid "Scattered showers"
 msgstr ""
 
-#: ../bin/indicator-weather.py:593 ../bin/indicator-weather.py:595
+#: ../bin/indicator-weather.py:621 ../bin/indicator-weather.py:623
 msgid "Heavy snow"
 msgstr ""
 
-#: ../bin/indicator-weather.py:594
+#: ../bin/indicator-weather.py:622
 msgid "Scattered snow showers"
 msgstr ""
 
-#: ../bin/indicator-weather.py:597
+#: ../bin/indicator-weather.py:625
 msgid "Thundershowers"
 msgstr ""
 
-#: ../bin/indicator-weather.py:598
+#: ../bin/indicator-weather.py:626
 msgid "Snow showers"
 msgstr ""
 
-#: ../bin/indicator-weather.py:599
+#: ../bin/indicator-weather.py:627
 msgid "Isolated thundershowers"
 msgstr ""
 
-#: ../bin/indicator-weather.py:600 ../bin/indicator-weather.py:622
-#: ../bin/indicator-weather.py:627 ../bin/indicator-weather.py:645
-#: ../bin/indicator-weather.py:654 ../bin/indicator-weather.py:664
-#: ../bin/indicator-weather.py:748 ../bin/indicator-weather.py:1730
+#: ../bin/indicator-weather.py:628 ../bin/indicator-weather.py:650
+#: ../bin/indicator-weather.py:655 ../bin/indicator-weather.py:673
+#: ../bin/indicator-weather.py:682 ../bin/indicator-weather.py:692
+#: ../bin/indicator-weather.py:776 ../bin/indicator-weather.py:1767
 msgid "Unknown condition"
 msgstr ""
 
-#: ../bin/indicator-weather.py:755 ../bin/indicator-weather.py:761
+#: ../bin/indicator-weather.py:783 ../bin/indicator-weather.py:789
 msgid "Humidity"
 msgstr ""
 
-#: ../bin/indicator-weather.py:782
+#: ../bin/indicator-weather.py:810
 msgid "Pressure"
 msgstr ""
 
-#: ../bin/indicator-weather.py:812
+#: ../bin/indicator-weather.py:840
 msgid "Temperature"
 msgstr ""
 
-#: ../bin/indicator-weather.py:836 ../bin/indicator-weather.py:837
-#: ../bin/indicator-weather.py:838
+#: ../bin/indicator-weather.py:864
 msgid "Unknown"
 msgstr ""
 
-#: ../bin/indicator-weather.py:845
+#: ../bin/indicator-weather.py:871
 msgid "Wind"
 msgstr ""
 
-#: ../bin/indicator-weather.py:872
+#: ../bin/indicator-weather.py:908
 msgid "Sunrise"
 msgstr ""
 
-#: ../bin/indicator-weather.py:876
+#: ../bin/indicator-weather.py:912
 msgid "Sunset"
 msgstr ""
 
 #. Short wind direction - north
-#: ../bin/indicator-weather.py:889
+#: ../bin/indicator-weather.py:925
 msgid "N"
 msgstr ""
 
-#: ../bin/indicator-weather.py:891
+#: ../bin/indicator-weather.py:927
 msgid "NE"
 msgstr ""
 
-#: ../bin/indicator-weather.py:893
+#: ../bin/indicator-weather.py:929
 msgid "E"
 msgstr ""
 
-#: ../bin/indicator-weather.py:895
+#: ../bin/indicator-weather.py:931
 msgid "SE"
 msgstr ""
 
-#: ../bin/indicator-weather.py:897
+#: ../bin/indicator-weather.py:933
 msgid "S"
 msgstr ""
 
-#: ../bin/indicator-weather.py:899
+#: ../bin/indicator-weather.py:935
 msgid "SW"
 msgstr ""
 
-#: ../bin/indicator-weather.py:901
+#: ../bin/indicator-weather.py:937
 msgid "W"
 msgstr ""
 
-#: ../bin/indicator-weather.py:903
+#: ../bin/indicator-weather.py:939
 msgid "NW"
 msgstr ""
 
-#: ../bin/indicator-weather.py:1074
+#: ../bin/indicator-weather.py:1111
 msgid "Set Up Weather..."
 msgstr ""
 
-#: ../bin/indicator-weather.py:1176
+#: ../bin/indicator-weather.py:1213
 msgid "Forecast"
 msgstr ""
 
 #. #Preferences
-#: ../bin/indicator-weather.py:1182
+#: ../bin/indicator-weather.py:1219
 msgid "Preferences..."
 msgstr ""
 
 #. #About
-#: ../bin/indicator-weather.py:1188
+#: ../bin/indicator-weather.py:1225
 msgid "About..."
 msgstr ""
 
-#: ../bin/indicator-weather.py:1289
+#: ../bin/indicator-weather.py:1323
 msgid "Refreshing, please wait"
 msgstr ""
 
-#: ../bin/indicator-weather.py:1291 ../bin/indicator-weather.py:1293
-#: ../bin/indicator-weather.py:1295
+#: ../bin/indicator-weather.py:1325 ../bin/indicator-weather.py:1327
+#: ../bin/indicator-weather.py:1329
 msgid "Refresh"
 msgstr ""
 
-#: ../bin/indicator-weather.py:1293
+#: ../bin/indicator-weather.py:1327
 msgid "just now"
 msgstr ""
 
-#: ../bin/indicator-weather.py:1295
+#: ../bin/indicator-weather.py:1329
 #, python-format
 msgid "%d min. ago"
 msgstr ""
 
-#: ../bin/indicator-weather.py:1436
+#: ../bin/indicator-weather.py:1469
 msgid "Severe weather alert"
 msgstr ""
 
-#: ../bin/indicator-weather.py:1454 ../indicator-weather.desktop.in.h:2
+#: ../bin/indicator-weather.py:1487 ../indicator-weather.desktop.in.h:1
 msgid "Weather Indicator"
 msgstr ""
 
-#: ../bin/indicator-weather.py:1466
+#: ../bin/indicator-weather.py:1499
 msgid "translator-credits"
 msgstr ""
 
-#: ../bin/indicator-weather.py:1684
+#: ../bin/indicator-weather.py:1717
 msgid "Weather Forecast for "
 msgstr ""
 
-#: ../bin/indicator-weather.py:1739
+#: ../bin/indicator-weather.py:1776
 msgid "High"
 msgstr ""
 
-#: ../bin/indicator-weather.py:1741
+#: ../bin/indicator-weather.py:1778
 msgid "Low"
 msgstr ""
 
-#: ../bin/indicator-weather.py:1842 ../data/ui/Assistant.ui.h:4
+#: ../bin/indicator-weather.py:1879 ../data/ui/Assistant.ui.h:8
 msgid "Label:"
 msgstr ""
 
-#: ../bin/indicator-weather.py:1932
+#: ../bin/indicator-weather.py:1969
 msgid "Another instance of this program is already running"
 msgstr ""
 
 #: ../data/ui/Assistant.ui.h:1
-msgid "<b>Home</b>"
+msgid "Add a location"
 msgstr ""
 
 #: ../data/ui/Assistant.ui.h:2
-msgid "<b>Orange, Texas</b>"
+msgid "Please search our database for your location:"
 msgstr ""
 
 #: ../data/ui/Assistant.ui.h:3
-msgid "Add a location"
+msgid "Search"
+msgstr ""
+
+#: ../data/ui/Assistant.ui.h:4
+msgid "Select a location"
 msgstr ""
 
 #: ../data/ui/Assistant.ui.h:5
-msgid "Location:"
+msgid "Please enter a name for this location:"
 msgstr ""
 
 #: ../data/ui/Assistant.ui.h:6
@@ -441,36 +444,32 @@
 msgstr ""
 
 #: ../data/ui/Assistant.ui.h:7
-msgid "Please enter a name for this location:"
-msgstr ""
-
-#: ../data/ui/Assistant.ui.h:8
 msgid ""
 "Please review the choices below. If anything is not correct, please go back "
 "and select the correct options."
 msgstr ""
 
 #: ../data/ui/Assistant.ui.h:9
-msgid "Please search our database for your location:"
+msgid "<b>Home</b>"
 msgstr ""
 
 #: ../data/ui/Assistant.ui.h:10
-msgid "Review choices"
+msgid "Location:"
 msgstr ""
 
 #: ../data/ui/Assistant.ui.h:11
-msgid "Search"
+msgid "<b>Orange, Texas</b>"
 msgstr ""
 
 #: ../data/ui/Assistant.ui.h:12
-msgid "Select a location"
+msgid "Review choices"
 msgstr ""
 
 #: ../data/ui/ExtendedForecast.ui.h:1
 msgid "Extended Forecast"
 msgstr ""
 
-#: ../indicator-weather.desktop.in.h:1
+#: ../indicator-weather.desktop.in.h:2
 msgid ""
 "A weather indicator that displays information for one or multiple places in "
 "the world"

=== modified file 'setup.py'
--- setup.py	2011-12-10 10:11:20 +0000
+++ setup.py	2013-05-18 18:24:25 +0000
@@ -4,6 +4,7 @@
 # Copyright (C) 2010 Sebastian MacDonald Sebas310@xxxxxxxxx
 # Copyright (C) 2010 Mehdi Rejraji mehd36@xxxxxxxxx
 # Copyright (C) 2011 Vadim Rutkovsky roignac@xxxxxxxxx
+# Copyright (C) 2013 Joshua Tasker jtasker@xxxxxxxxx
 # This program is free software: you can redistribute it and/or modify it 
 # under the terms of the GNU General Public License version 3, as published 
 # by the Free Software Foundation.
@@ -85,10 +86,10 @@
 
 DistUtilsExtra.auto.setup(
     name='indicator-weather',
-    version='11.05.31',
+    version='13.05.17',
     license='GPL-3',
-    author='Vadim Rutkovsky | Sebastian MacDonald | Mehdi Rejraji',
-    author_email='roignac@xxxxxxxxx',
+    author='Joshua Tasker | Vadim Rutkovsky | Sebastian MacDonald | Mehdi Rejraji',
+    author_email='jtasker@xxxxxxxxx, roignac@xxxxxxxxx',
     description="A weather indicator for Ubuntu's Indicator Applet",
     long_description='A weather indicator that displays information for one or multiple places in the world',
     url='https://launchpad.net/weather-indicator',


Follow ups