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

Bug#810882: jessie-pu: package gnome-shell-extension-weather/0~20151125.gitccaa1eb-1~deb8u1



Package: release.debian.org
Severity: normal
Tags: jessie
User: release.debian.org@packages.debian.org
Usertags: pu

Dear Release Team,

I'd like to push a new upstream release of gnome-shell-extension-weather in jessie.

This package is a Gnome Shell extension (installed by default with Gnome
through metapackages) that fetches weather information from a third-party site
(openweathermap.org).

The API of the website has changed since the release of jessie.

First, an API key must now be entered by the user: this prompted a previous p-u
(0~20140924.git7e28508-1+deb8u1) to warn the use about that.

But the API change turned out to be more important than I initially thought: it
is currently impossible to add a new city location with the jessie version of
extension (see #804505).

Backporting minimal fixes to the version in jessie is difficult (if possible at
all), so I'd like to upload a new upstream version (which has been sitting in
testing for one month now).

In addition to fixing #804505, this would also restore the original behavior by
the time of the jessie release (when entering an API key was not needed).

The changelog is as follows (since the last p-u):


gnome-shell-extension-weather (0~20151125.gitccaa1eb-1~deb8u1) jessie; urgency=medium

  * New upstream snapshot.
      + Compatible with the new API of openweathermap.org. (Closes: #804505)
      + No need to manually enter an API key, since this release ships with a
        default one. This restores the behavior of the applet that was effective
        by the time of the jessie release.
  * Drop d/p/missing-api-key.patch. No longer needed, since this new release
    ships with a default API key.
  * d/copyright: reflect upstream changes.

 -- Sébastien Villemot <sebastien@debian.org>  Wed, 13 Jan 2016 10:34:14 +0100
 

I also attach a full debdiff (from which translation changes have been filtered out).

Cheers,

-- 
 .''`.    Sébastien Villemot
: :' :    Debian Developer
`. `'     http://sebastien.villemot.name
  `-      GPG Key: 4096R/381A7594
diff -Nru --exclude '*.pot' --exclude '*.po' gnome-shell-extension-weather-0~20140924.git7e28508/autogen.sh gnome-shell-extension-weather-0~20151125.gitccaa1eb/autogen.sh
--- gnome-shell-extension-weather-0~20140924.git7e28508/autogen.sh	2014-09-24 20:18:58.000000000 +0200
+++ gnome-shell-extension-weather-0~20151125.gitccaa1eb/autogen.sh	2015-12-09 21:55:47.000000000 +0100
@@ -1,5 +1,32 @@
 #!/bin/bash
 # Run this to generate all the initial makefiles, etc.
+#
+#
+#  Weather extension for GNOME Shell
+#  - generate Makefiles
+#
+# Copyright (C) 2012 - 2015
+#     Jens Lody <jens@jenslody.de>,
+#
+# This file is part of gnome-shell-extension-openweather.
+#
+# gnome-shell-extension-openweather 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, either version 3 of the License, or (at your option)
+# any later version.
+#
+# gnome-shell-extension-openweather 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 gnome-shell-extension-openweather.  If not, see
+# <http://www.gnu.org/licenses/>.
+#
+
+
 
 srcdir=`dirname $0`
 test -z "$srcdir" && srcdir=.
diff -Nru --exclude '*.pot' --exclude '*.po' gnome-shell-extension-weather-0~20140924.git7e28508/configure.ac gnome-shell-extension-weather-0~20151125.gitccaa1eb/configure.ac
--- gnome-shell-extension-weather-0~20140924.git7e28508/configure.ac	2014-09-24 20:18:58.000000000 +0200
+++ gnome-shell-extension-weather-0~20151125.gitccaa1eb/configure.ac	2015-12-09 21:55:47.000000000 +0100
@@ -21,6 +21,8 @@
 
 GLIB_GSETTINGS
 
+AC_ARG_VAR(GIT_VERSION, git-version to be placed in metadata.json, will be overwritten when uploaded to gnome.org (default not set))
+
 AC_ARG_WITH(desktop-dir, [  --with-desktop-dir=PATH where to install desktop files (default=PREFIX/share)])
 
 if test "x$with_desktop_dir" != x; then
diff -Nru --exclude '*.pot' --exclude '*.po' gnome-shell-extension-weather-0~20140924.git7e28508/data/Makefile.am gnome-shell-extension-weather-0~20151125.gitccaa1eb/data/Makefile.am
--- gnome-shell-extension-weather-0~20140924.git7e28508/data/Makefile.am	2014-09-24 20:18:58.000000000 +0200
+++ gnome-shell-extension-weather-0~20151125.gitccaa1eb/data/Makefile.am	2015-12-09 21:55:47.000000000 +0100
@@ -7,7 +7,7 @@
 
 extensiondir = $(topextensiondir)/$(uuid)
 
-dist_extension_DATA = stylesheet.css weather-settings.ui
+dist_extension_DATA = OpenWeather.png stylesheet.css weather-settings.ui
 
 nodist_extension_DATA = metadata.json $(EXTRA_EXTENSION)
 
@@ -16,7 +16,8 @@
 metadata.json: metadata.json.in $(top_builddir)/config.status
 	$(AM_V_GEN) sed -e "s|[@]LOCALEDIR@|$(datadir)/locale|" \
 	    -e "s|[@]uuid@|$(uuid)|" \
-	    -e "s|[@]url@|$(extensionurl)|" $< > $@
+	    -e "s|[@]url@|$(extensionurl)|" \
+	    -e "s|[@]version@|$(GIT_VERSION)|" $< > $@
 
 CLEANFILES = metadata.json
 
diff -Nru --exclude '*.pot' --exclude '*.po' gnome-shell-extension-weather-0~20140924.git7e28508/data/metadata.json.in gnome-shell-extension-weather-0~20151125.gitccaa1eb/data/metadata.json.in
--- gnome-shell-extension-weather-0~20140924.git7e28508/data/metadata.json.in	2014-09-24 20:18:58.000000000 +0200
+++ gnome-shell-extension-weather-0~20151125.gitccaa1eb/data/metadata.json.in	2015-12-09 21:55:47.000000000 +0100
@@ -1,8 +1,9 @@
 {
 "uuid": "@uuid@",
 "name": "OpenWeather",
-"description": "Weather extension to display weather information from http://openweathermap.org/ for many cities in GNOME Shell",
-"shell-version": [ "3.6", "3.8", "3.10", "3.12", "3.14" ],
+"description": "Weather extension to display weather information from https://openweathermap.org/ or https://forecast.io for almost all locations in the world.\nFor openweathermap.org, you can either use the extensions default-key or register at http://openweathermap.org/appid and set the appropriate switch in the preferences dialog to \"off\".\nFor forecast.io you have to register at https://developer.forecast.io/register and get a personal API-key.\n\nSince version 29 this extensions uses coordinates to store the locations and makes the names editable to support multiple weather-providers!\nIf you update from versions prior to 29 to 29 or greater (with forecast.io - support) you have to recreate your locations.",
+"shell-version": [ "3.12", "3.14", "3.16", "3.18", "3.19.1", "3.19.2" ],
 "localedir": "@LOCALEDIR@",
-"url": "@url@"
+"url": "@url@",
+"version": "@version@"
 }
diff -Nru --exclude '*.pot' --exclude '*.po' gnome-shell-extension-weather-0~20140924.git7e28508/data/org.gnome.shell.extensions.openweather.gschema.xml.in gnome-shell-extension-weather-0~20151125.gitccaa1eb/data/org.gnome.shell.extensions.openweather.gschema.xml.in
--- gnome-shell-extension-weather-0~20140924.git7e28508/data/org.gnome.shell.extensions.openweather.gschema.xml.in	2014-09-24 20:18:58.000000000 +0200
+++ gnome-shell-extension-weather-0~20151125.gitccaa1eb/data/org.gnome.shell.extensions.openweather.gschema.xml.in	2015-12-09 21:55:47.000000000 +0100
@@ -1,4 +1,13 @@
 <schemalist gettext-domain="gnome-shell-extension-openweather">
+  <enum id="org.gnome.shell.extensions.openweather.weather-provider">
+    <value nick="openweathermap" value="0" />
+    <value nick="forecast.io" value="1" />
+  </enum>
+  <enum id="org.gnome.shell.extensions.openweather.geolocation-provider">
+    <value nick="openstreetmaps" value="0" />
+    <value nick="geocode" value="1" />
+    <value nick="mapquest" value="2" />
+  </enum>
   <enum id="org.gnome.shell.extensions.openweather.unit">
     <value nick="celsius" value="0" />
     <value nick="fahrenheit" value="1" />
@@ -19,6 +28,7 @@
     <value nick="at" value="6" />
     <value nick="Torr" value="7" />
     <value nick="psi" value="8" />
+    <value nick="mmHg" value="9" />
   </enum>
   <enum id="org.gnome.shell.extensions.openweather.wind-speed-unit">
     <value nick="kph" value="0" />
@@ -38,6 +48,14 @@
     <value nick="left" value="2"  />
   </enum>
   <schema id="org.gnome.shell.extensions.openweather" path="/org/gnome/shell/extensions/openweather/">
+    <key name="weather-provider" enum="org.gnome.shell.extensions.openweather.weather-provider">
+      <default>'openweathermap'</default>
+      <_summary>Weather Provider</_summary>
+    </key>
+    <key name="geolocation-provider" enum="org.gnome.shell.extensions.openweather.geolocation-provider">
+      <default>'openstreetmaps'</default>
+      <_summary>Geolocation Provider</_summary>
+    </key>
     <key name="unit" enum="org.gnome.shell.extensions.openweather.unit">
       <default>'fahrenheit'</default>
       <_summary>Temperature Unit</_summary>
@@ -57,7 +75,7 @@
       <_description>Choose whether to display wind direction through arrows or letters.</_description>
     </key>
     <key name="city" type="s">
-      <default>'2516479>Eivissa (CA)'</default>
+      <default>'-8.5211767,179.1976747>Vaiaku, Tuvalu>-1'</default>
       <_summary>City to be displayed</_summary>
     </key>
     <key name="actual-city" type="i">
@@ -84,6 +102,10 @@
       <default>false</default>
       <_summary>Conditions in Panel</_summary>
     </key>
+    <key name="show-comment-in-forecast" type="b">
+      <default>true</default>
+      <_summary>Conditions in Forecast</_summary>
+    </key>
     <key name="position-in-panel" enum="org.gnome.shell.extensions.openweather.position">
       <default>'center'</default>
       <_summary>Position in Panel</_summary>
@@ -112,5 +134,17 @@
       <default>''</default>
       <_summary>Your personal API key from openweathermap.org</_summary>
     </key>
+    <key name="use-default-owm-key" type="b">
+      <default>true</default>
+      <_summary>Use the extensions default API key from openweathermap.org</_summary>
+    </key>
+    <key name="appid-fc" type="s">
+      <default>''</default>
+      <_summary>Your personal API key from forecast.io</_summary>
+    </key>
+    <key name="geolocation-appid-mapquest" type="s">
+      <default>''</default>
+      <_summary>Your personal AppKey from developer.geocode.farm</_summary>
+    </key>
   </schema>
 </schemalist>
diff -Nru --exclude '*.pot' --exclude '*.po' gnome-shell-extension-weather-0~20140924.git7e28508/data/stylesheet.css gnome-shell-extension-weather-0~20151125.gitccaa1eb/data/stylesheet.css
--- gnome-shell-extension-weather-0~20140924.git7e28508/data/stylesheet.css	2014-09-24 20:18:58.000000000 +0200
+++ gnome-shell-extension-weather-0~20151125.gitccaa1eb/data/stylesheet.css	2015-12-09 21:55:47.000000000 +0100
@@ -1,21 +1,3 @@
-.openweather-button {
-border-radius: 32px;
-padding: 13px;
-}
-
-.openweather-button:hover{
-border: none;
-padding: 14px;
-}
-
-.openweather-button > StIcon {
-icon-size: 16px;
-}
-
-.openweather-button > StLabel {
-padding:6px;
-}
-
 .openweather-menu-button-container{
 padding: 0px;
 }
@@ -31,12 +13,25 @@
 .openweather-button-box-38:rtl{
 padding-right: 24px;
 }
+
 .openweather-provider {
 border-width: 0px;
 border-radius:5px;
 padding:5px;
 }
 
+.openweather-current-summarybox,
+.openweather-forecast-icon,
+.openweather-current-databox-captions,
+.openweather-current-databox-values,
+.openweather-current-icon,
+.openweather-forecast-summary,
+.openweather-forecast-temperature{
+border-radius: 0px;
+padding: 0px;
+border: 0px;
+}
+
 .openweather-current-summarybox {
 padding-top:5px;
 }
@@ -68,7 +63,7 @@
 .openweather-current-databox-captions {
 text-align: right;
 padding-right: 5px;
-color: #999999;
+spacing: 0;
 }
 
 .openweather-forecast-icon {
@@ -79,19 +74,17 @@
 -st-hfade-offset: 60px;
 }
 
-.openweather-forecast-box {
-}
-
 .openweather-forecast-databox {
 min-width: 140px;
 }
 
 .openweather-forecast-day {
-color: #999999;
 font-size: 90%;
+spacing: 0;
 }
 
 .openweather-forecast-iconbox {
+vertical-align: top;
 }
 
 .openweather-sunrise-icon {
diff -Nru --exclude '*.pot' --exclude '*.po' gnome-shell-extension-weather-0~20140924.git7e28508/data/weather-settings.ui gnome-shell-extension-weather-0~20151125.gitccaa1eb/data/weather-settings.ui
--- gnome-shell-extension-weather-0~20140924.git7e28508/data/weather-settings.ui	2014-09-24 20:18:58.000000000 +0200
+++ gnome-shell-extension-weather-0~20151125.gitccaa1eb/data/weather-settings.ui	2015-12-09 21:55:47.000000000 +0100
@@ -1,117 +1,1328 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<interface>
-  <!-- interface-requires gtk+ 3.0 -->
-  <object class="GtkListStore" id="liststore">
+<!-- Generated with glade 3.18.3 -->
+<interface domain="gnome-shell-extension-openweather">
+  <requires lib="gtk+" version="3.12"/>
+  <object class="GtkAdjustment" id="current-refresh-adjustment">
+    <property name="lower">10</property>
+    <property name="upper">1440</property>
+    <property name="value">10</property>
+    <property name="step_increment">1</property>
+    <property name="page_increment">10</property>
+  </object>
+  <object class="GtkWindow" id="edit-widget">
+    <property name="can_focus">False</property>
+    <property name="modal">True</property>
+    <property name="window_position">center-on-parent</property>
+    <property name="destroy_with_parent">True</property>
+    <property name="hide_titlebar_when_maximized">True</property>
+    <property name="type_hint">dialog</property>
+    <child>
+      <object class="GtkBox" id="edit-box">
+        <property name="visible">True</property>
+        <property name="can_focus">False</property>
+        <property name="border_width">5</property>
+        <property name="orientation">vertical</property>
+        <child>
+          <object class="GtkLabel" id="label3">
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+            <property name="halign">start</property>
+            <property name="hexpand">True</property>
+            <property name="label" translatable="yes">Edit name</property>
+            <property name="ellipsize">end</property>
+          </object>
+          <packing>
+            <property name="expand">False</property>
+            <property name="fill">False</property>
+            <property name="position">0</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkEntry" id="edit-name">
+            <property name="width_request">350</property>
+            <property name="visible">True</property>
+            <property name="can_focus">True</property>
+            <property name="hexpand">True</property>
+            <property name="secondary_icon_name">edit-clear-symbolic</property>
+            <property name="primary_icon_activatable">False</property>
+            <property name="primary_icon_sensitive">False</property>
+            <property name="secondary_icon_tooltip_text" translatable="yes">Clear entry</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="label4">
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+            <property name="halign">start</property>
+            <property name="hexpand">True</property>
+            <property name="label" translatable="yes">Edit coordinates</property>
+          </object>
+          <packing>
+            <property name="expand">False</property>
+            <property name="fill">True</property>
+            <property name="position">2</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkEntry" id="edit-coord">
+            <property name="visible">True</property>
+            <property name="can_focus">True</property>
+            <property name="hexpand">True</property>
+            <property name="secondary_icon_name">edit-clear-symbolic</property>
+            <property name="primary_icon_activatable">False</property>
+            <property name="primary_icon_sensitive">False</property>
+            <property name="secondary_icon_tooltip_text" translatable="yes">Clear entry</property>
+          </object>
+          <packing>
+            <property name="expand">False</property>
+            <property name="fill">True</property>
+            <property name="position">3</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkComboBoxText" id="edit-combo">
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+            <property name="margin_top">5</property>
+            <items>
+              <item translatable="yes">Extensions default weather provider</item>
+              <item>http://openweathermap.org</item>
+              <item>http://forecast.io</item>
+            </items>
+          </object>
+          <packing>
+            <property name="expand">False</property>
+            <property name="fill">True</property>
+            <property name="position">4</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkSeparator" id="separator2">
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+            <property name="margin_top">5</property>
+            <property name="margin_bottom">5</property>
+          </object>
+          <packing>
+            <property name="expand">False</property>
+            <property name="fill">False</property>
+            <property name="position">5</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkBox" id="box2">
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+            <property name="valign">baseline</property>
+            <property name="vexpand">False</property>
+            <child>
+              <object class="GtkButton" id="button-edit-cancel">
+                <property name="label" translatable="yes">Cancel</property>
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="receives_default">True</property>
+                <property name="halign">start</property>
+                <accelerator key="Escape" signal="clicked"/>
+              </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">False</property>
+                <property name="position">0</property>
+              </packing>
+            </child>
+            <child>
+              <placeholder/>
+            </child>
+            <child>
+              <object class="GtkButton" id="button-edit-save">
+                <property name="label" translatable="yes">Save</property>
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="receives_default">True</property>
+              </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">True</property>
+                <property name="pack_type">end</property>
+                <property name="position">2</property>
+              </packing>
+            </child>
+          </object>
+          <packing>
+            <property name="expand">False</property>
+            <property name="fill">True</property>
+            <property name="pack_type">end</property>
+            <property name="position">6</property>
+          </packing>
+        </child>
+      </object>
+    </child>
+  </object>
+  <object class="GtkAdjustment" id="forecast-refresh-adjustment">
+    <property name="lower">10</property>
+    <property name="upper">1440</property>
+    <property name="value">10</property>
+    <property name="step_increment">1</property>
+    <property name="page_increment">10</property>
+  </object>
+  <object class="GtkMenu" id="search-menu">
+    <property name="visible">True</property>
+    <property name="can_focus">False</property>
+  </object>
+  <object class="GtkWindow" id="search-widget">
+    <property name="can_focus">False</property>
+    <property name="modal">True</property>
+    <property name="window_position">center-on-parent</property>
+    <property name="destroy_with_parent">True</property>
+    <property name="hide_titlebar_when_maximized">True</property>
+    <property name="type_hint">dialog</property>
+    <child>
+      <object class="GtkBox" id="search-box">
+        <property name="visible">True</property>
+        <property name="can_focus">False</property>
+        <property name="border_width">5</property>
+        <property name="orientation">vertical</property>
+        <child>
+          <object class="GtkLabel" id="label1">
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+            <property name="halign">start</property>
+            <property name="hexpand">True</property>
+            <property name="label" translatable="yes">Search by location or coordinates</property>
+            <property name="ellipsize">end</property>
+          </object>
+          <packing>
+            <property name="expand">False</property>
+            <property name="fill">False</property>
+            <property name="position">0</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkBox" id="box3">
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+            <property name="spacing">5</property>
+            <child>
+              <object class="GtkEntry" id="search-name">
+                <property name="width_request">350</property>
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="hexpand">True</property>
+                <property name="secondary_icon_name">edit-clear-symbolic</property>
+                <property name="primary_icon_activatable">False</property>
+                <property name="primary_icon_sensitive">False</property>
+                <property name="secondary_icon_tooltip_text" translatable="yes">Clear entry</property>
+                <property name="placeholder_text" translatable="yes">e.g. Vaiaku, Tuvalu or -8.5211767,179.1976747</property>
+              </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">True</property>
+                <property name="position">0</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkButton" id="button-search-find">
+                <property name="label" translatable="yes">Find</property>
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="receives_default">True</property>
+                <accelerator key="Return" signal="clicked"/>
+              </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="GtkComboBoxText" id="search-combo">
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+            <property name="margin_top">5</property>
+            <property name="active">0</property>
+            <items>
+              <item translatable="yes">Extensions default weather provider</item>
+              <item>http://openweathermap.org</item>
+              <item>http://forecast.io</item>
+            </items>
+          </object>
+          <packing>
+            <property name="expand">False</property>
+            <property name="fill">True</property>
+            <property name="position">2</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkSeparator" id="separator1">
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+            <property name="margin_top">5</property>
+            <property name="margin_bottom">5</property>
+          </object>
+          <packing>
+            <property name="expand">False</property>
+            <property name="fill">False</property>
+            <property name="position">3</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkBox" id="box1">
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+            <property name="valign">baseline</property>
+            <property name="vexpand">False</property>
+            <child>
+              <object class="GtkButton" id="button-search-cancel">
+                <property name="label" translatable="yes">Cancel</property>
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="receives_default">True</property>
+                <property name="halign">start</property>
+                <accelerator key="Escape" signal="clicked"/>
+              </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">False</property>
+                <property name="position">0</property>
+              </packing>
+            </child>
+            <child>
+              <placeholder/>
+            </child>
+            <child>
+              <object class="GtkButton" id="button-search-save">
+                <property name="label" translatable="yes">Save</property>
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="receives_default">True</property>
+              </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">True</property>
+                <property name="pack_type">end</property>
+                <property name="position">2</property>
+              </packing>
+            </child>
+          </object>
+          <packing>
+            <property name="expand">False</property>
+            <property name="fill">True</property>
+            <property name="pack_type">end</property>
+            <property name="position">4</property>
+          </packing>
+        </child>
+      </object>
+    </child>
+  </object>
+  <object class="GtkSpinner" id="spinner">
+    <property name="width_request">48</property>
+    <property name="height_request">48</property>
+    <property name="visible">True</property>
+    <property name="can_focus">False</property>
+    <property name="active">True</property>
+  </object>
+  <object class="GtkListStore" id="tree-liststore">
     <columns>
-      <!-- column-name text -->
+      <!-- column-name location -->
+      <column type="gchararray"/>
+      <!-- column-name provider -->
       <column type="gchararray"/>
     </columns>
     <data>
       <row>
-	<col id="0"></col>
+        <col id="0">dummy</col>
+        <col id="1">dummy</col>
       </row>
     </data>
   </object>
-      <object class="GtkBox" id="main-widget">
-  	  <property name="border-width">14</property>
-		  <child>
-		    <object class="GtkTable" id="left-widget">
-		      <property name="visible">True</property>
-		      <property name="can_focus">False</property>
-		      <property name="n_rows">2</property>
-		      <property name="n_columns">1</property>
-		      <property name="column_spacing">6</property>
-		      <child>
-		        <object class="GtkScrolledWindow" id="tree-scrolledwindow">
-		          <property name="visible">True</property>
-		          <property name="can_focus">True</property>
-		          <property name="shadow_type">in</property>
-		          <property name="min_content_width">200</property>
-		          <property name="min_content_height">250</property>
-		          <child>
-		            <object class="GtkTreeView" id="tree-treeview">
-		              <property name="visible">True</property>
-		              <property name="can_focus">True</property>
-		              <property name="headers_visible">False</property>
-		              <property name="show_expanders">False</property>
-		              <property name="level_indentation">12</property>
-		              <child internal-child="selection">
-		                <object class="GtkTreeSelection" id="treeview-selection">
-				</object>
-				<object class="GtkTreeViewColumn" id="tree-treeviewcolumn">
-				</object>
-		              </child>
-		            </object>
-		          </child>
-		        </object>
-		        <packing>
-		          <property name="x_options">GTK_FILL</property>
-		        </packing>
-		      </child>
-		      <child>
-		        <object class="GtkToolbar" id="tree-toolbar">
-		          <property name="visible">True</property>
-		          <property name="can_focus">False</property>
-		          <property name="toolbar_style">icons</property>
-		          <property name="icon_size">1</property>
-		          <style>
-		            <class name="inline-toolbar"/>
-		          </style>
-		          <child>
-		            <object class="GtkToolButton" id="tree-toolbutton-add">
-		              <property name="visible">True</property>
-		              <property name="can_focus">False</property>
-		              <property name="use_action_appearance">False</property>
-		              <property name="icon_name">list-add-symbolic</property>
-		            </object>
-		            <packing>
-		              <property name="expand">False</property>
-		              <property name="homogeneous">True</property>
-		            </packing>
-		          </child>
-		          <child>
-		            <object class="GtkToolButton" id="tree-toolbutton-remove">
-		              <property name="visible">True</property>
-		              <property name="can_focus">False</property>
-		              <property name="use_action_appearance">False</property>
-		              <property name="icon_name">list-remove-symbolic</property>
-		            </object>
-		            <packing>
-		              <property name="expand">False</property>
-		              <property name="homogeneous">True</property>
-		            </packing>
-		          </child>
-		        </object>
-		        <packing>
-		          <property name="top_attach">1</property>
-		          <property name="bottom_attach">2</property>
-		          <property name="x_options">GTK_FILL</property>
-		          <property name="y_options">GTK_SHRINK</property>
-		        </packing>
-		      </child>
-		    </object>
-		  </child>
-		  <child>
-          <object class="GtkBox" id="right-widget">
-            <property name="visible">True</property>
-            <property name="can_focus">False</property>
-            <property name="homogeneous">True</property>
-		  <child>
-				<object class="GtkTable" id="right-widget-table">
-				<property name="visible">True</property>
-				<property name="can_focus">False</property>
-				<property name="n_rows">12</property>
-				<property name="n_columns">2</property>
-				<property name="column_spacing">36</property>
-				<property name="row_spacing">12</property>
-				<property name="margin_left">36</property>
-				</object>
-		  </child>
+  <object class="GtkScrolledWindow" id="main-widget">
+    <property name="width_request">720</property>
+    <property name="height_request">480</property>
+    <property name="visible">True</property>
+    <property name="can_focus">True</property>
+    <property name="border_width">20</property>
+    <child>
+      <object class="GtkViewport" id="scrolled-viewport">
+        <property name="visible">True</property>
+        <property name="can_focus">False</property>
+        <property name="hscroll_policy">natural</property>
+        <property name="vscroll_policy">natural</property>
+        <property name="shadow_type">none</property>
+        <child>
+          <object class="GtkNotebook" id="prefs-notebook">
+            <property name="visible">True</property>
+            <property name="can_focus">True</property>
+            <property name="scrollable">True</property>
+            <property name="enable_popup">True</property>
+            <child>
+              <object class="GtkBox" id="locations-box">
+                <property name="visible">True</property>
+                <property name="can_focus">False</property>
+                <property name="hexpand">True</property>
+                <property name="vexpand">True</property>
+                <property name="orientation">vertical</property>
+                <child>
+                  <object class="GtkScrolledWindow" id="tree-scrolledwindow">
+                    <property name="visible">True</property>
+                    <property name="can_focus">True</property>
+                    <property name="shadow_type">in</property>
+                    <property name="min_content_width">300</property>
+                    <property name="min_content_height">250</property>
+                    <child>
+                      <object class="GtkTreeView" id="tree-treeview">
+                        <property name="visible">True</property>
+                        <property name="can_focus">True</property>
+                        <property name="model">tree-liststore</property>
+                        <property name="reorderable">True</property>
+                        <property name="search_column">0</property>
+                        <property name="show_expanders">False</property>
+                        <property name="level_indentation">12</property>
+                        <property name="tooltip_column">1</property>
+                        <child internal-child="selection">
+                          <object class="GtkTreeSelection" id="treeview-selection"/>
+                        </child>
+                      </object>
+                    </child>
+                  </object>
+                  <packing>
+                    <property name="expand">True</property>
+                    <property name="fill">True</property>
+                    <property name="position">0</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkToolbar" id="tree-toolbar">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="toolbar_style">icons</property>
+                    <property name="icon_size">1</property>
+                    <child>
+                      <object class="GtkToolButton" id="tree-toolbutton-add">
+                        <property name="use_action_appearance">False</property>
+                        <property name="visible">True</property>
+                        <property name="can_focus">False</property>
+                        <property name="icon_name">list-add</property>
+                      </object>
+                      <packing>
+                        <property name="expand">False</property>
+                        <property name="homogeneous">True</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <object class="GtkToolButton" id="tree-toolbutton-remove">
+                        <property name="use_action_appearance">False</property>
+                        <property name="visible">True</property>
+                        <property name="can_focus">False</property>
+                        <property name="icon_name">list-remove</property>
+                      </object>
+                      <packing>
+                        <property name="expand">False</property>
+                        <property name="homogeneous">True</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <object class="GtkToolButton" id="tree-toolbutton-edit">
+                        <property name="use_action_appearance">False</property>
+                        <property name="visible">True</property>
+                        <property name="can_focus">False</property>
+                        <property name="icon_name">gtk-edit</property>
+                      </object>
+                      <packing>
+                        <property name="expand">False</property>
+                        <property name="homogeneous">True</property>
+                      </packing>
+                    </child>
+                  </object>
+                  <packing>
+                    <property name="expand">False</property>
+                    <property name="fill">True</property>
+                    <property name="position">1</property>
+                  </packing>
+                </child>
+              </object>
+            </child>
+            <child type="tab">
+              <object class="GtkLabel" id="locations-label">
+                <property name="visible">True</property>
+                <property name="can_focus">False</property>
+                <property name="label" translatable="yes">Locations</property>
+              </object>
+              <packing>
+                <property name="tab_fill">False</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkGrid" id="provider-grid">
+                <property name="visible">True</property>
+                <property name="can_focus">False</property>
+                <property name="hexpand">True</property>
+                <property name="vexpand">True</property>
+                <property name="border_width">10</property>
+                <property name="row_spacing">5</property>
+                <property name="column_spacing">5</property>
+                <child>
+                  <object class="GtkLabel" id="label-weather-provider">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="halign">start</property>
+                    <property name="hexpand">True</property>
+                    <property name="label" translatable="yes">Chose default weather provider</property>
+                  </object>
+                  <packing>
+                    <property name="left_attach">0</property>
+                    <property name="top_attach">0</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkLabel" id="label-appid">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="halign">start</property>
+                    <property name="hexpand">True</property>
+                    <property name="label" translatable="yes">Personal Api key from openweathermap.org</property>
+                  </object>
+                  <packing>
+                    <property name="left_attach">0</property>
+                    <property name="top_attach">2</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkComboBoxText" id="weather_provider">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <items>
+                      <item>http://openweathermap.org</item>
+                      <item>http://forecast.io</item>
+                    </items>
+                  </object>
+                  <packing>
+                    <property name="left_attach">1</property>
+                    <property name="top_attach">0</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkEntry" id="appid">
+                    <property name="visible">True</property>
+                    <property name="can_focus">True</property>
+                    <property name="max_length">32</property>
+                    <property name="width_chars">32</property>
+                  </object>
+                  <packing>
+                    <property name="left_attach">1</property>
+                    <property name="top_attach">2</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkEntry" id="appid_fc">
+                    <property name="visible">True</property>
+                    <property name="can_focus">True</property>
+                    <property name="max_length">32</property>
+                    <property name="width_chars">32</property>
+                  </object>
+                  <packing>
+                    <property name="left_attach">1</property>
+                    <property name="top_attach">3</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkLabel" id="label-appid-fc">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="halign">start</property>
+                    <property name="hexpand">True</property>
+                    <property name="label" translatable="yes">Personal Api key from forecast.io</property>
+                  </object>
+                  <packing>
+                    <property name="left_attach">0</property>
+                    <property name="top_attach">3</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkLabel" id="label-current-refresh">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="halign">start</property>
+                    <property name="hexpand">True</property>
+                    <property name="label" translatable="yes">Refresh timeout for current weather [min]</property>
+                    <property name="ellipsize">end</property>
+                  </object>
+                  <packing>
+                    <property name="left_attach">0</property>
+                    <property name="top_attach">5</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkLabel" id="label-forecast-refresh">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="halign">start</property>
+                    <property name="hexpand">True</property>
+                    <property name="label" translatable="yes">Refresh timeout for weather forecast [min]</property>
+                    <property name="ellipsize">end</property>
+                  </object>
+                  <packing>
+                    <property name="left_attach">0</property>
+                    <property name="top_attach">6</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkSpinButton" id="spin-current-refresh">
+                    <property name="visible">True</property>
+                    <property name="can_focus">True</property>
+                    <property name="input_purpose">number</property>
+                    <property name="adjustment">current-refresh-adjustment</property>
+                    <property name="climb_rate">5</property>
+                    <property name="numeric">True</property>
+                    <property name="update_policy">if-valid</property>
+                    <property name="value">10</property>
+                  </object>
+                  <packing>
+                    <property name="left_attach">1</property>
+                    <property name="top_attach">5</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkSpinButton" id="spin-forecast-refresh">
+                    <property name="visible">True</property>
+                    <property name="can_focus">True</property>
+                    <property name="tooltip_text" translatable="yes">Note: the forecast-timout is not used for forecast.io, because they do not provide seperate downloads for current weather and forecasts.</property>
+                    <property name="input_purpose">number</property>
+                    <property name="adjustment">forecast-refresh-adjustment</property>
+                    <property name="climb_rate">5</property>
+                    <property name="numeric">True</property>
+                    <property name="value">10</property>
+                  </object>
+                  <packing>
+                    <property name="left_attach">1</property>
+                    <property name="top_attach">6</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkSeparator" id="separator3">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                  </object>
+                  <packing>
+                    <property name="left_attach">0</property>
+                    <property name="top_attach">4</property>
+                    <property name="width">2</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkLabel" id="label-use-default-owm-appid">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="halign">start</property>
+                    <property name="label" translatable="yes">Use extensions api-key for openweathermap.org</property>
+                  </object>
+                  <packing>
+                    <property name="left_attach">0</property>
+                    <property name="top_attach">1</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkSwitch" id="use_default_owm_key">
+                    <property name="visible">True</property>
+                    <property name="can_focus">True</property>
+                    <property name="tooltip_text" translatable="yes">Switch off, if you have your own api-key for openweathermap.org and put it into the text-box below.</property>
+                    <property name="halign">center</property>
+                  </object>
+                  <packing>
+                    <property name="left_attach">1</property>
+                    <property name="top_attach">1</property>
+                  </packing>
+                </child>
+              </object>
+              <packing>
+                <property name="position">1</property>
+              </packing>
+            </child>
+            <child type="tab">
+              <object class="GtkLabel" id="provider-label">
+                <property name="visible">True</property>
+                <property name="can_focus">False</property>
+                <property name="label" translatable="yes">Weather provider</property>
+              </object>
+              <packing>
+                <property name="position">1</property>
+                <property name="tab_fill">False</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkGrid" id="geolocation-grid">
+                <property name="visible">True</property>
+                <property name="can_focus">False</property>
+                <property name="hexpand">True</property>
+                <property name="vexpand">True</property>
+                <property name="border_width">10</property>
+                <property name="row_spacing">5</property>
+                <property name="column_spacing">5</property>
+                <child>
+                  <object class="GtkLabel" id="label-geolocation-provider">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="label" translatable="yes">Chose geolocation provider</property>
+                  </object>
+                  <packing>
+                    <property name="left_attach">0</property>
+                    <property name="top_attach">0</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkComboBoxText" id="geolocation_provider">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <items>
+                      <item>https://nominatim.openstreetmap.org/</item>
+                      <item>https://geocode.farm/</item>
+                      <item>https://open.mapquestapi.com/nominatim/</item>
+                    </items>
+                  </object>
+                  <packing>
+                    <property name="left_attach">1</property>
+                    <property name="top_attach">0</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkLabel" id="label-geolocation-appid-mapquest">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="label" translatable="yes">Personal AppKey from developer.mapquest.com</property>
+                  </object>
+                  <packing>
+                    <property name="left_attach">0</property>
+                    <property name="top_attach">1</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkEntry" id="geolocation_appid_mapquest">
+                    <property name="visible">True</property>
+                    <property name="can_focus">True</property>
+                    <property name="has_tooltip">True</property>
+                    <property name="max_length">32</property>
+                    <property name="width_chars">32</property>
+                  </object>
+                  <packing>
+                    <property name="left_attach">1</property>
+                    <property name="top_attach">1</property>
+                  </packing>
+                </child>
+              </object>
+              <packing>
+                <property name="position">2</property>
+              </packing>
+            </child>
+            <child type="tab">
+              <object class="GtkLabel" id="geolocation-provider-label">
+                <property name="visible">True</property>
+                <property name="can_focus">False</property>
+                <property name="label" translatable="yes">Geolocation provider</property>
+              </object>
+              <packing>
+                <property name="position">2</property>
+                <property name="tab_fill">False</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkGrid" id="units-grid">
+                <property name="visible">True</property>
+                <property name="can_focus">False</property>
+                <property name="hexpand">True</property>
+                <property name="vexpand">True</property>
+                <property name="border_width">10</property>
+                <property name="row_spacing">5</property>
+                <property name="column_spacing">5</property>
+                <child>
+                  <object class="GtkLabel" id="label-units">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="label" translatable="yes">Temperature Unit</property>
+                  </object>
+                  <packing>
+                    <property name="left_attach">0</property>
+                    <property name="top_attach">0</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkLabel" id="label-wind-speed-unit">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="label" translatable="yes">Wind Speed Unit</property>
+                  </object>
+                  <packing>
+                    <property name="left_attach">0</property>
+                    <property name="top_attach">1</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkLabel" id="label-pressure-unit">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="label" translatable="yes">Pressure Unit</property>
+                  </object>
+                  <packing>
+                    <property name="left_attach">0</property>
+                    <property name="top_attach">2</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkComboBoxText" id="units">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <items>
+                      <item>°C</item>
+                      <item>°F</item>
+                      <item>K</item>
+                      <item>°Ra</item>
+                      <item>°Ré</item>
+                      <item>°Rø</item>
+                      <item>°De</item>
+                      <item>°N</item>
+                    </items>
+                  </object>
+                  <packing>
+                    <property name="left_attach">1</property>
+                    <property name="top_attach">0</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkComboBoxText" id="wind_speed_unit">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <items>
+                      <item>km/h</item>
+                      <item>mph</item>
+                      <item>m/s</item>
+                      <item>kn</item>
+                      <item>ft/s</item>
+                      <item>Beaufort</item>
+                    </items>
+                  </object>
+                  <packing>
+                    <property name="left_attach">1</property>
+                    <property name="top_attach">1</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkComboBoxText" id="pressure_unit">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <items>
+                      <item>hPa</item>
+                      <item>inHg</item>
+                      <item>bar</item>
+                      <item>Pa</item>
+                      <item>kPa</item>
+                      <item>atm</item>
+                      <item>at</item>
+                      <item>Torr</item>
+                      <item>psi</item>
+                      <item>mmHg</item>
+                    </items>
+                  </object>
+                  <packing>
+                    <property name="left_attach">1</property>
+                    <property name="top_attach">2</property>
+                  </packing>
+                </child>
+              </object>
+              <packing>
+                <property name="position">3</property>
+              </packing>
+            </child>
+            <child type="tab">
+              <object class="GtkLabel" id="units-label">
+                <property name="visible">True</property>
+                <property name="can_focus">False</property>
+                <property name="label" translatable="yes">Units</property>
+              </object>
+              <packing>
+                <property name="position">3</property>
+                <property name="tab_fill">False</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkGrid" id="layout-grid">
+                <property name="visible">True</property>
+                <property name="can_focus">False</property>
+                <property name="hexpand">True</property>
+                <property name="vexpand">True</property>
+                <property name="border_width">10</property>
+                <property name="row_spacing">5</property>
+                <property name="column_spacing">5</property>
+                <child>
+                  <object class="GtkLabel" id="label-position-in-panel">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="label" translatable="yes">Position in Panel</property>
+                  </object>
+                  <packing>
+                    <property name="left_attach">0</property>
+                    <property name="top_attach">0</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkLabel" id="label-wind-direction">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="label" translatable="yes">Wind Direction by Arrows</property>
+                  </object>
+                  <packing>
+                    <property name="left_attach">0</property>
+                    <property name="top_attach">1</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkLabel" id="label-translate-condition">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="label" translatable="yes">Translate Conditions</property>
+                  </object>
+                  <packing>
+                    <property name="left_attach">0</property>
+                    <property name="top_attach">2</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkLabel" id="label-icon-type">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="label" translatable="yes">Symbolic Icons</property>
+                  </object>
+                  <packing>
+                    <property name="left_attach">0</property>
+                    <property name="top_attach">3</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkLabel" id="label-use-text-on-buttons">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="label" translatable="yes">Text on buttons</property>
+                  </object>
+                  <packing>
+                    <property name="left_attach">0</property>
+                    <property name="top_attach">4</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkLabel" id="label-text-in-panel">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="label" translatable="yes">Temperature in Panel</property>
+                  </object>
+                  <packing>
+                    <property name="left_attach">0</property>
+                    <property name="top_attach">5</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkLabel" id="label-comment-in-panel">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="label" translatable="yes">Conditions in Panel</property>
+                  </object>
+                  <packing>
+                    <property name="left_attach">0</property>
+                    <property name="top_attach">6</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkLabel" id="label-comment-in-forecast">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="label" translatable="yes">Conditions in Forecast</property>
+                  </object>
+                  <packing>
+                    <property name="left_attach">0</property>
+                    <property name="top_attach">7</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkLabel" id="label-center-in-forecast">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="label" translatable="yes">Center forecast</property>
+                  </object>
+                  <packing>
+                    <property name="left_attach">0</property>
+                    <property name="top_attach">8</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkLabel" id="label-days-forecast">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="label" translatable="yes">Number of days in forecast</property>
+                  </object>
+                  <packing>
+                    <property name="left_attach">0</property>
+                    <property name="top_attach">9</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkLabel" id="label-decimal-places">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="label" translatable="yes">Maximal number of digits after the decimal point</property>
+                  </object>
+                  <packing>
+                    <property name="left_attach">0</property>
+                    <property name="top_attach">10</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkComboBoxText" id="position_in_panel">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <items>
+                      <item translatable="yes">Center</item>
+                      <item translatable="yes">Right</item>
+                      <item translatable="yes">Left</item>
+                    </items>
+                  </object>
+                  <packing>
+                    <property name="left_attach">1</property>
+                    <property name="top_attach">0</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkSwitch" id="wind_direction">
+                    <property name="visible">True</property>
+                    <property name="can_focus">True</property>
+                    <property name="halign">center</property>
+                  </object>
+                  <packing>
+                    <property name="left_attach">1</property>
+                    <property name="top_attach">1</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkSwitch" id="translate_condition">
+                    <property name="visible">True</property>
+                    <property name="can_focus">True</property>
+                    <property name="halign">center</property>
+                  </object>
+                  <packing>
+                    <property name="left_attach">1</property>
+                    <property name="top_attach">2</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkSwitch" id="icon_type">
+                    <property name="visible">True</property>
+                    <property name="can_focus">True</property>
+                    <property name="halign">center</property>
+                  </object>
+                  <packing>
+                    <property name="left_attach">1</property>
+                    <property name="top_attach">3</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkSwitch" id="use_text_on_buttons">
+                    <property name="visible">True</property>
+                    <property name="can_focus">True</property>
+                    <property name="halign">center</property>
+                  </object>
+                  <packing>
+                    <property name="left_attach">1</property>
+                    <property name="top_attach">4</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkSwitch" id="text_in_panel">
+                    <property name="visible">True</property>
+                    <property name="can_focus">True</property>
+                    <property name="halign">center</property>
+                  </object>
+                  <packing>
+                    <property name="left_attach">1</property>
+                    <property name="top_attach">5</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkSwitch" id="comment_in_panel">
+                    <property name="visible">True</property>
+                    <property name="can_focus">True</property>
+                    <property name="halign">center</property>
+                  </object>
+                  <packing>
+                    <property name="left_attach">1</property>
+                    <property name="top_attach">6</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkSwitch" id="comment_in_forecast">
+                    <property name="visible">True</property>
+                    <property name="can_focus">True</property>
+                    <property name="halign">center</property>
+                  </object>
+                  <packing>
+                    <property name="left_attach">1</property>
+                    <property name="top_attach">7</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkSwitch" id="center_forecast">
+                    <property name="visible">True</property>
+                    <property name="can_focus">True</property>
+                    <property name="halign">center</property>
+                  </object>
+                  <packing>
+                    <property name="left_attach">1</property>
+                    <property name="top_attach">8</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkComboBoxText" id="days_forecast">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <items>
+                      <item>2</item>
+                      <item>3</item>
+                      <item>4</item>
+                      <item>5</item>
+                      <item>6</item>
+                      <item>7</item>
+                      <item>8</item>
+                      <item>9</item>
+                      <item>10</item>
+                    </items>
+                  </object>
+                  <packing>
+                    <property name="left_attach">1</property>
+                    <property name="top_attach">9</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkComboBoxText" id="decimal_places">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <items>
+                      <item>0</item>
+                      <item>1</item>
+                      <item>2</item>
+                      <item>3</item>
+                    </items>
+                  </object>
+                  <packing>
+                    <property name="left_attach">1</property>
+                    <property name="top_attach">10</property>
+                  </packing>
+                </child>
+              </object>
+              <packing>
+                <property name="position">4</property>
+              </packing>
+            </child>
+            <child type="tab">
+              <object class="GtkLabel" id="layout-label">
+                <property name="visible">True</property>
+                <property name="can_focus">False</property>
+                <property name="label" translatable="yes">Layout</property>
+              </object>
+              <packing>
+                <property name="position">4</property>
+                <property name="tab_fill">False</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkBox" id="about">
+                <property name="can_focus">False</property>
+                <property name="margin_top">24</property>
+                <property name="margin_bottom">24</property>
+                <property name="hexpand">True</property>
+                <property name="vexpand">True</property>
+                <property name="orientation">vertical</property>
+                <property name="spacing">5</property>
+                <child>
+                  <object class="GtkImage" id="logo-image">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="pixbuf">OpenWeather.png</property>
+                  </object>
+                  <packing>
+                    <property name="expand">False</property>
+                    <property name="fill">True</property>
+                    <property name="padding">10</property>
+                    <property name="position">0</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkLabel" id="extension-label">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="label">&lt;b&gt;OPenweather&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">1</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkBox" id="box4">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="halign">center</property>
+                    <child>
+                      <object class="GtkLabel" id="version-label">
+                        <property name="visible">True</property>
+                        <property name="can_focus">False</property>
+                        <property name="halign">end</property>
+                        <property name="label" translatable="yes">Version: </property>
+                        <property name="track_visited_links">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="version">
+                        <property name="visible">True</property>
+                        <property name="can_focus">False</property>
+                        <property name="halign">start</property>
+                        <property name="label" translatable="yes">unknown (self-build ?)</property>
+                        <property name="ellipsize">end</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">False</property>
+                    <property name="fill">True</property>
+                    <property name="position">2</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkLabel" id="description-label">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="label" translatable="yes">&lt;span&gt;Weather extension to display weather information from &lt;a href="https://openweathermap.org/"&gt;Openweathermap&lt;/a&gt; or &lt;a href="https://forecast.io"&gt;forecast.io&lt;/a&gt; for almost all locations in the world.&lt;/span&gt;</property>
+                    <property name="use_markup">True</property>
+                    <property name="justify">center</property>
+                    <property name="wrap">True</property>
+                    <property name="wrap_mode">word-char</property>
+                    <property name="max_width_chars">1</property>
+                  </object>
+                  <packing>
+                    <property name="expand">False</property>
+                    <property name="fill">True</property>
+                    <property name="position">3</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkBox" id="box10">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="halign">center</property>
+                    <property name="spacing">5</property>
+                    <child>
+                      <object class="GtkLabel" id="label15">
+                        <property name="visible">True</property>
+                        <property name="can_focus">False</property>
+                        <property name="label" translatable="yes">Maintained by</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="label16">
+                        <property name="visible">True</property>
+                        <property name="can_focus">True</property>
+                        <property name="label">Jens Lody (&lt;a href="mailto:openweather@jenslody.de"&gt;openweather@jenslody.de&lt;/a&gt;)</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>
+                  </object>
+                  <packing>
+                    <property name="expand">False</property>
+                    <property name="fill">True</property>
+                    <property name="position">4</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkLinkButton" id="github-link">
+                    <property name="label" translatable="yes">Webpage</property>
+                    <property name="visible">True</property>
+                    <property name="can_focus">True</property>
+                    <property name="receives_default">True</property>
+                    <property name="events"/>
+                    <property name="opacity">0.99999999977648257</property>
+                    <property name="halign">center</property>
+                    <property name="relief">none</property>
+                    <property name="uri">https://github.com/jenslody/gnome-shell-extension-openweather</property>
+                  </object>
+                  <packing>
+                    <property name="expand">False</property>
+                    <property name="fill">True</property>
+                    <property name="position">5</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkLabel" id="label2">
+                    <property name="visible">True</property>
+                    <property name="can_focus">True</property>
+                    <property name="valign">end</property>
+                    <property name="label" translatable="yes">&lt;span size="small"&gt;This program comes with ABSOLUTELY NO WARRANTY.
+See the &lt;a href="https://www.gnu.org/licenses/old-licenses/gpl-2.0.html"&gt;GNU General Public License, version 2 or later&lt;/a&gt; for details.&lt;/span&gt;</property>
+                    <property name="use_markup">True</property>
+                    <property name="justify">center</property>
+                    <property name="wrap">True</property>
+                  </object>
+                  <packing>
+                    <property name="expand">True</property>
+                    <property name="fill">True</property>
+                    <property name="position">6</property>
+                  </packing>
+                </child>
+              </object>
+              <packing>
+                <property name="position">5</property>
+              </packing>
+            </child>
+            <child type="tab">
+              <object class="GtkLabel" id="about-label">
+                <property name="visible">True</property>
+                <property name="can_focus">False</property>
+                <property name="label" translatable="yes">About</property>
+              </object>
+              <packing>
+                <property name="position">5</property>
+                <property name="tab_fill">False</property>
+              </packing>
+            </child>
           </object>
-          <packing>
-            <property name="expand">True</property>
-            <property name="fill">True</property>
-          </packing>
-		  </child>
-		</object>
+        </child>
+      </object>
+    </child>
+  </object>
 </interface>
diff -Nru --exclude '*.pot' --exclude '*.po' gnome-shell-extension-weather-0~20140924.git7e28508/debian/changelog gnome-shell-extension-weather-0~20151125.gitccaa1eb/debian/changelog
--- gnome-shell-extension-weather-0~20140924.git7e28508/debian/changelog	2015-10-25 19:24:57.000000000 +0100
+++ gnome-shell-extension-weather-0~20151125.gitccaa1eb/debian/changelog	2016-01-13 10:39:55.000000000 +0100
@@ -1,3 +1,16 @@
+gnome-shell-extension-weather (0~20151125.gitccaa1eb-1~deb8u1) jessie; urgency=medium
+
+  * New upstream snapshot.
+    + Compatible with the new API of openweathermap.org. (Closes: #804505)
+    + No need to manually enter an API key, since this release ships with a
+      default one. This restores the behavior of the applet that was effective
+      by the time of the jessie release.
+  * Drop d/p/missing-api-key.patch. No longer needed, since this new release
+    ships with a default API key.
+  * d/copyright: reflect upstream changes.
+
+ -- Sébastien Villemot <sebastien@debian.org>  Wed, 13 Jan 2016 10:34:14 +0100
+
 gnome-shell-extension-weather (0~20140924.git7e28508-1+deb8u1) jessie; urgency=medium
 
   * d/p/missing-api-key.patch: new patch. Displays a warning if API key
diff -Nru --exclude '*.pot' --exclude '*.po' gnome-shell-extension-weather-0~20140924.git7e28508/debian/copyright gnome-shell-extension-weather-0~20151125.gitccaa1eb/debian/copyright
--- gnome-shell-extension-weather-0~20140924.git7e28508/debian/copyright	2015-10-25 19:21:06.000000000 +0100
+++ gnome-shell-extension-weather-0~20151125.gitccaa1eb/debian/copyright	2016-01-13 10:39:40.000000000 +0100
@@ -4,7 +4,7 @@
 Source: https://github.com/jenslody/gnome-shell-extension-openweather
 
 Files: *
-Copyright: 2011-2013
+Copyright: 2011-2015
            Elad Alfassa <elad@fedoraproject.org>
            Mark Benjamin <weather.gnome.Markie1@dfgh.net>
            Simon Claessens <gagalago@gmail.com>
@@ -15,6 +15,8 @@
            Christian Metzler <neroth@xeked.com>
            Meng Zhuo <mengzhuo1203+spam@gmail.com>,
            Jens Lody <jens@jenslody.de>
+           2012-2013 Canek Peláez <canek@ciencias.unam.mx>
+           2012 Mantas Kriaučiūnas <mantas@akl.lt>
 License: GPL-3+
 
 Files: src/convenience.js
@@ -43,7 +45,7 @@
  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 Files: debian/*
-Copyright: 2013-2014 Sébastien Villemot <sebastien@debian.org>
+Copyright: 2013-2015 Sébastien Villemot <sebastien@debian.org>
 License: GPL-3+
 
 License: GPL-3+
diff -Nru --exclude '*.pot' --exclude '*.po' gnome-shell-extension-weather-0~20140924.git7e28508/debian/patches/missing-api-key.patch gnome-shell-extension-weather-0~20151125.gitccaa1eb/debian/patches/missing-api-key.patch
--- gnome-shell-extension-weather-0~20140924.git7e28508/debian/patches/missing-api-key.patch	2015-10-25 19:24:09.000000000 +0100
+++ gnome-shell-extension-weather-0~20151125.gitccaa1eb/debian/patches/missing-api-key.patch	1970-01-01 01:00:00.000000000 +0100
@@ -1,20 +0,0 @@
-Description: Add notification if API key is missing
- The API is now mandatory for using openweathermap.org.
-Origin: backport, https://github.com/jenslody/gnome-shell-extension-openweather/commit/f9f97dcaaa0b7d51a4b4193ba3802b3d0ba10441
-Bug-Debian: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=801979
-Reviewed-by: Sébastien Villemot <sebastien@debian.org>
-Last-Update: 2015-10-24
----
-This patch header follows DEP-3: http://dep.debian.net/deps/dep3/
---- a/src/extension.js
-+++ b/src/extension.js
-@@ -138,6 +138,9 @@ const OpenweatherMenuButton = new Lang.C
-         // Load settings
-         this.loadConfig();
- 
-+        if (this._appid.toString().trim() == '')
-+            Main.notify("Openweather", _("Openweathermap.org does not work without an api-key.\nPlease register at http://openweathermap.org/appid and paste your personal key into the preferences dialog."));
-+
-         // Label
-         this._weatherInfo = new St.Label({
-             y_align: Clutter.ActorAlign.CENTER,
diff -Nru --exclude '*.pot' --exclude '*.po' gnome-shell-extension-weather-0~20140924.git7e28508/debian/patches/series gnome-shell-extension-weather-0~20151125.gitccaa1eb/debian/patches/series
--- gnome-shell-extension-weather-0~20140924.git7e28508/debian/patches/series	2015-10-25 19:22:59.000000000 +0100
+++ gnome-shell-extension-weather-0~20151125.gitccaa1eb/debian/patches/series	2016-01-13 10:35:34.000000000 +0100
@@ -1 +0,0 @@
-missing-api-key.patch
diff -Nru --exclude '*.pot' --exclude '*.po' gnome-shell-extension-weather-0~20140924.git7e28508/gnome-shell-extension-openweather.cbp gnome-shell-extension-weather-0~20151125.gitccaa1eb/gnome-shell-extension-openweather.cbp
--- gnome-shell-extension-weather-0~20140924.git7e28508/gnome-shell-extension-openweather.cbp	2014-09-24 20:18:58.000000000 +0200
+++ gnome-shell-extension-weather-0~20151125.gitccaa1eb/gnome-shell-extension-openweather.cbp	2015-12-09 21:55:47.000000000 +0100
@@ -29,6 +29,7 @@
 		<Unit filename="autogen.sh" />
 		<Unit filename="configure.ac" />
 		<Unit filename="data/Makefile.am" />
+		<Unit filename="data/OpenWeather.png" />
 		<Unit filename="data/Screenshot.jpg" />
 		<Unit filename="data/metadata.json.in" />
 		<Unit filename="data/org.gnome.shell.extensions.openweather.gschema.xml.in" />
@@ -47,7 +48,7 @@
 		<Unit filename="po/es.po" />
 		<Unit filename="po/fi.po" />
 		<Unit filename="po/fr.po" />
-		<Unit filename="po/gnome-shell-extension-weather.pot" />
+		<Unit filename="po/gnome-shell-extension-openweather.pot" />
 		<Unit filename="po/he.po" />
 		<Unit filename="po/hu.po" />
 		<Unit filename="po/it.po" />
@@ -70,7 +71,10 @@
 		<Unit filename="src/Makefile.am" />
 		<Unit filename="src/convenience.js" />
 		<Unit filename="src/extension.js" />
+		<Unit filename="src/forecast_io.js" />
+		<Unit filename="src/openweathermap_org.js" />
 		<Unit filename="src/prefs.js" />
+		<Unit filename="update_revision.sh" />
 		<Extensions>
 			<envvars />
 			<code_completion />
diff -Nru --exclude '*.pot' --exclude '*.po' gnome-shell-extension-weather-0~20140924.git7e28508/gnome-shell-extension-openweather.spec gnome-shell-extension-weather-0~20151125.gitccaa1eb/gnome-shell-extension-openweather.spec
--- gnome-shell-extension-weather-0~20140924.git7e28508/gnome-shell-extension-openweather.spec	2014-09-24 20:18:58.000000000 +0200
+++ gnome-shell-extension-weather-0~20151125.gitccaa1eb/gnome-shell-extension-openweather.spec	2015-12-09 21:55:47.000000000 +0100
@@ -1,38 +1,47 @@
-%global git 2701627
+%global git 6368d32
 %global uuid openweather-extension@jenslody.de
 %global github jenslody-gnome-shell-extension-openweather
 %global checkout git%{git}
+%global checkout_date 20151108
+
 
 Name:           gnome-shell-extension-openweather
-Version:        0
-Release:        0.2.%(date +%Y%m%d).%{checkout}%{?dist}
-Summary:        An extension for displaying weather notifications from http://openweathermap.org in GNOME Shell
+Version:        1
+Release:        0.10.%{checkout_date}%{checkout}%{?dist}
+Summary:        Display weather information from many locations in the world
 
 Group:          User Interface/Desktops
-License:        GPLv3+
+
+# The entire source code is GPLv3+ except convenience.js, which is BSD
+License:        GPLv3+ and BSD
 URL:            https://github.com/jenslody/gnome-shell-extension-openweather
 Source0:        https://github.com/jenslody/gnome-shell-extension-openweather/tarball/master/%{github}-%{git}.tar.gz
 BuildArch:      noarch
 
-BuildRequires:  autoconf >= 2.53, automake >= 1.9, glib2-devel, gnome-common >= 3.6.0, intltool >= 0.25
-Requires:       gnome-shell >= 3.6.0
+BuildRequires:  autoconf, automake, glib2-devel, gnome-common >= 3.12.0, intltool
+Requires:       gnome-shell >= 3.12.0
 
 %description
 gnome-shell-extension-openweather is an extension to display weather information
-from http://openweathermap.org/ for many cities in GNOME Shell
+from http://openweathermap.org/ or http://forecast.io for (almost) all locations
+of the world in GNOME Shell.
 
 %prep
 %setup -q -n %{github}-%{git}
 
 %build
 NOCONFIGURE=1 ./autogen.sh
-%configure --prefix=%{_prefix}
+%configure --prefix=%{_prefix} GIT_VERSION=%{checkout}
 make %{?_smp_mflags}
 
 %install
 make install DESTDIR=%{buildroot}
 %find_lang %{name}
 
+# Fedora uses file-triggers for some stuff (e.g. compile schemas) since fc24.
+# Compiling schemas is the only thing done in %%postun and %%posttrans, so
+# I decided to make both completely conditional.
+%if 0%{?fedora} < 24
 %postun
 if [ $1 -eq 0 ] ; then
         %{_bindir}/glib-compile-schemas %{_datadir}/glib-2.0/schemas &> /dev/null || :
@@ -40,13 +49,61 @@
 
 %posttrans
 %{_bindir}/glib-compile-schemas %{_datadir}/glib-2.0/schemas &> /dev/null || :
+%endif
 
 %files -f %{name}.lang
-%doc AUTHORS COPYING README.md
+%license COPYING
+%doc AUTHORS README.md
 %{_datadir}/glib-2.0/schemas/org.gnome.shell.extensions.openweather.gschema.xml
-%{_datadir}/gnome-shell/extensions/%{uuid}/
+%if 0%{?fedora} < 23
+%dir %{_datadir}/gnome-shell/extensions
+%endif
+%{_datadir}/gnome-shell/extensions/%{uuid}
 
 %changelog
-* Fri Nov 08 2013 Jens Lody <jens@jenslody.de> - 0-0.1.git0d20641
-- Initial package for Fedora of the weather-extension fork using http://openweathermap.org
+* Sun Nov 08 2015 Jens Lody <fedora@jenslody.de> - 1-0.10.20151108git6368d32
+- Fix typo in metadata.json .
+
+* Sun Nov 08 2015 Jens Lody <fedora@jenslody.de> - 1-0.9.20151108gite4dbfee
+- Add default API-key for openweathermap.org. The key is in their FOSS-whitelist
+  now. Thanks to openweathermap.org .
+
+* Sat Nov 07 2015 Jens Lody <fedora@jenslody.de> - 1-0.8.20151107gitae12283
+- Fixes #1278686, can block gnome-shell temporarily in some cases .
+  See also: https://github.com/jenslody/gnome-shell-extension-openweather/issues/82 .
+
+* Sat Oct 17 2015 Jens Lody <fedora@jenslody.de> - 1-0.7.20151017git34aa242
+- Bug fix: warn message for empty forecast.io api-key was shown if the key
+  exists, not the if the key was empty, sorry.
+
+* Fri Oct 16 2015 Jens Lody <fedora@jenslody.de> - 1-0.6.20151016git13f9abf
+- Bug fix: forecast.io no longer accepts non-https requests.
+- Updated russioan translation, added indonesian translation.
+- Add warn-message if an api-key is empty.
+
+* Sat Oct 10 2015 Jens Lody <fedora@jenslody.de> - 1-0.5.20151010gitfe00513
+- New upstream:
+  make refresh-intervall configurable,
+  fix minor issue, when last location is removed,
+  add new languages for forecast.io.
+
+* Thu Sep 24 2015 Jens Lody <fedora@jenslody.de> - 1-0.4.20150924gite55253e
+- Always depend on gnome-shell (it's needed anyway).
+- On Fedora < 23 own the extensions dir explicitely to avoid unowned
+  directories.
+
+* Thu Sep 24 2015 Jens Lody <fedora@jenslody.de> - 1-0.3.20150924gite55253e
+- Do not require gnome-shell-extensions-common.
+- Require gnome-shell instead on Fedora >= 23.
+
+* Thu Sep 24 2015 Jens Lody <fedora@jenslody.de> - 1-0.2.20150924gite55253e
+- Use checkout-date instead of build-date in package-version.
+
+* Thu Aug 20 2015 Jens Lody <fedora@jenslody.de> - 1-0.1.20150821gitcb1f6f6
+- Remove dot before git in Release-tag.
+- Use (conditional) file-triggers for schema compiling, introduced in fc24.
+
+* Sat Jul 25 2015 Jens Lody <fedora@jenslody.de> - 1-0.1.20150725.git377244c
+- Initial package for Fedora of the weather-extension fork using
+  http://openweathermap.org or http://forecast.io.
 
diff -Nru --exclude '*.pot' --exclude '*.po' gnome-shell-extension-weather-0~20140924.git7e28508/po/LINGUAS gnome-shell-extension-weather-0~20151125.gitccaa1eb/po/LINGUAS
--- gnome-shell-extension-weather-0~20140924.git7e28508/po/LINGUAS	2014-09-24 20:18:58.000000000 +0200
+++ gnome-shell-extension-weather-0~20151125.gitccaa1eb/po/LINGUAS	2015-12-09 21:55:47.000000000 +0100
@@ -1,15 +1,14 @@
-cs
-it
-fr
-es
 bg
-de
 ca
+cs
 da
 el
+es
 fi
+fr
 he
 hu
+it
 ja
 lt
 nb
@@ -20,8 +19,12 @@
 ro
 ru
 sk
+sr
+sr@latin
 sv
 uk
 vi
 zh_CN
-zh_TW
\ Pas de fin de ligne à la fin du fichier
+zh_TW
+id
+de
\ Pas de fin de ligne à la fin du fichier
diff -Nru --exclude '*.pot' --exclude '*.po' gnome-shell-extension-weather-0~20140924.git7e28508/po/POTFILES.in gnome-shell-extension-weather-0~20151125.gitccaa1eb/po/POTFILES.in
--- gnome-shell-extension-weather-0~20140924.git7e28508/po/POTFILES.in	2014-09-24 20:18:58.000000000 +0200
+++ gnome-shell-extension-weather-0~20151125.gitccaa1eb/po/POTFILES.in	2015-12-09 21:55:47.000000000 +0100
@@ -1,2 +1,5 @@
 ../src/extension.js
+../src/forecast_io.js
+../src/openweathermap_org.js
 ../src/prefs.js
+../data/weather-settings.ui
diff -Nru --exclude '*.pot' --exclude '*.po' gnome-shell-extension-weather-0~20140924.git7e28508/po/update.js gnome-shell-extension-weather-0~20151125.gitccaa1eb/po/update.js
--- gnome-shell-extension-weather-0~20140924.git7e28508/po/update.js	2014-09-24 20:18:58.000000000 +0200
+++ gnome-shell-extension-weather-0~20151125.gitccaa1eb/po/update.js	2015-12-09 21:55:47.000000000 +0100
@@ -4,9 +4,11 @@
  *
  *  PO Updater for GNOME Shell Extension Weather
  *
- * Copyright (C) 2012 -2014
+ * Copyright (C) 2012 -2013
  *     Christian METZLER <neroth@xeked.com>
  *     Jens Lody <jens@jenslody.de>,
+ * Copyright (C) 2014 -2015
+ *     Jens Lody <jens@jenslody.de>,
  *
  *
  * This file is part of gnome-shell-extension-openweather.
@@ -29,7 +31,7 @@
 Gio = imports.gi.Gio;
 
 print("Generate gnome-shell-extension-openweather.pot");
-var xgettext = Seed.spawn("xgettext -o gnome-shell-extension-openweather.pot -L python --from-code=utf-8 --keyword=_ -f POTFILES.in");
+var xgettext = Seed.spawn("xgettext -o gnome-shell-extension-openweather.pot --from-code=utf-8 --keyword=_ --keyword=translatable -f POTFILES.in");
 
 if (xgettext.stderr)
     print(xgettext.stderr);
diff -Nru --exclude '*.pot' --exclude '*.po' gnome-shell-extension-weather-0~20140924.git7e28508/README.md gnome-shell-extension-weather-0~20151125.gitccaa1eb/README.md
--- gnome-shell-extension-weather-0~20140924.git7e28508/README.md	2014-09-24 20:18:58.000000000 +0200
+++ gnome-shell-extension-weather-0~20151125.gitccaa1eb/README.md	2015-12-09 21:55:47.000000000 +0100
@@ -2,7 +2,10 @@
 
 *gnome-shell-extension-openweather* is a simple extension for displaying weather conditions and forecasts in GNOME Shell, featuring support for multiple locations, no need for WOEID, a symmetrical layout and a settings panel through *gnome-shell-extension-prefs*.
 
-Currently, the weather data, including forecasts for up to ten days, is fetched from [OpenWeatherMap](http://openweathermap.org/).
+The weather data is fetched from [OpenWeatherMap](https://openweathermap.org/) (including forecasts for up to ten days) or [forecast.io](https://forecast.io) (including forecasts for up to eight days).
+
+#### Note: since version 29 this extensions uses coordinates to store the locations and makes the names editable to support multiple weather-providers!
+#### If you update from versions prior to 29 to 29 or greater (with forecast.io - support) you have to recreate your locations.
 
 ----
 
@@ -31,19 +34,7 @@
 
 ### [Fedora](https://fedoraproject.org/)
 
-You can install the extension from [my repo](http://rpm.jenslody.de/).
-I have packages for Fedora 18, 19 and 20.
-
-To install my repo download and install [this rpm](http://rpm.jenslody.de/fedora-jenslody.de-0.1-2.fc17.noarch.rpm).
-
-If it is not installed automatically, just run:
-
-    sudo yum localinstall --nogpgcheck http://rpm.jenslody.de/fedora-jenslody.de-0.1-2.fc17.noarch.rpm
-
-Now you can install the extension, either via your favourite package-manager or on a console:
-
-    sudo yum install gnome-shell-extension-openweather
-
+You can install the extension from the official Fedora repos.
 
 ## Generic (Local installation)
 
@@ -63,7 +54,7 @@
 Run the following commands:
 
 	cd ~ && git clone git://github.com/jenslody/gnome-shell-extension-openweather.git
-	cd ~/gnome-shell-extension-weather
+	cd ~/gnome-shell-extension-openweather
 	./autogen.sh && make local-install
 
 ----
@@ -76,19 +67,15 @@
 
 You can also use *dconf-editor* or *gsettings* to configure the extension through the command line.
 
-If you switch from old openweathermap to the new master ( or openweathermap), you can load the settings with
-
-    dconf dump /org/gnome/shell/extensions/weather/ | dconf load /org/gnome/shell/extensions/openweather/
-
-This can also work for most locations, if you switch from old yahoo-based master-branch (now yahoo) to the new master-branch (openweathermap-based).
+On [OpenWeatherMap](https://openweathermap.org/) you can either use the extensions default-key or register to get a [personal API key](http://openweathermap.org/appid). This key has to be added in the preferences dialog. Don't forget to switch the a appropriate switch in the dialog to "off" in this case.
 
-The [OpenWeatherMap](http://openweathermap.org/) maintainers recommend to use an [API key](http://openweathermap.org/appid). This key can be added in the preferences dialog.
+To use [Forecast.io](https://forecast.io) you also need to [register](https://developer.forecast.io/register) and get an API key. With this key you can make 1000 requests per day for free. This should be enough for this extension in any normal use case. Do not add billing information, otherwise you might have to pay for the weather-data if something went wrong !
 
 ----
 
 # Licence
 
-Copyright (C) 2011 - 2014
+Copyright (C) 2011 - 2015
 
 * Elad Alfassa <elad@fedoraproject.org>,
 * Mark Benjamin <weather.gnome.Markie1@dfgh.net>,
diff -Nru --exclude '*.pot' --exclude '*.po' gnome-shell-extension-weather-0~20140924.git7e28508/src/extension.js gnome-shell-extension-weather-0~20151125.gitccaa1eb/src/extension.js
--- gnome-shell-extension-weather-0~20140924.git7e28508/src/extension.js	2014-09-24 20:18:58.000000000 +0200
+++ gnome-shell-extension-weather-0~20151125.gitccaa1eb/src/extension.js	2015-12-09 21:55:47.000000000 +0100
@@ -5,7 +5,7 @@
  *  - Displays a small weather information on the top panel.
  *  - On click, gives a popup with details about the weather.
  *
- * Copyright (C) 2011 - 2014
+ * Copyright (C) 2011 - 2013
  *     ecyrbe <ecyrbe+spam@gmail.com>,
  *     Timur Kristof <venemo@msn.com>,
  *     Elad Alfassa <elad@fedoraproject.org>,
@@ -15,6 +15,8 @@
  *     Mattia Meneguzzo odysseus@fedoraproject.org,
  *     Meng Zhuo <mengzhuo1203+spam@gmail.com>,
  *     Jens Lody <jens@jenslody.de>
+ * Copyright (C) 2014 -2015
+ *     Jens Lody <jens@jenslody.de>,
  *
  *
  * This file is part of gnome-shell-extension-openweather.
@@ -38,14 +40,18 @@
 const Me = ExtensionUtils.getCurrentExtension();
 const Config = imports.misc.config;
 const Convenience = Me.imports.convenience;
+const ForecastIo = Me.imports.forecast_io;
+const OpenweathermapOrg = Me.imports.openweathermap_org;
 const Clutter = imports.gi.Clutter;
 const Gettext = imports.gettext.domain('gnome-shell-extension-openweather');
 const Gio = imports.gi.Gio;
 const Gtk = imports.gi.Gtk;
+const GLib = imports.gi.GLib;
 const Lang = imports.lang;
 const Mainloop = imports.mainloop;
 const Soup = imports.gi.Soup;
 const St = imports.gi.St;
+const GnomeSession = imports.misc.gnomeSession;
 const Util = imports.misc.util;
 const _ = Gettext.gettext;
 
@@ -54,34 +60,39 @@
 const PopupMenu = imports.ui.popupMenu;
 
 // Settings
-const WEATHER_SETTINGS_SCHEMA = 'org.gnome.shell.extensions.openweather';
-const WEATHER_UNIT_KEY = 'unit';
-const WEATHER_WIND_SPEED_UNIT_KEY = 'wind-speed-unit';
-const WEATHER_WIND_DIRECTION_KEY = 'wind-direction';
-const WEATHER_PRESSURE_UNIT_KEY = 'pressure-unit';
-const WEATHER_CITY_KEY = 'city';
-const WEATHER_ACTUAL_CITY_KEY = 'actual-city';
-const WEATHER_TRANSLATE_CONDITION_KEY = 'translate-condition';
-const WEATHER_USE_SYMBOLIC_ICONS_KEY = 'use-symbolic-icons';
-const WEATHER_USE_TEXT_ON_BUTTONS_KEY = 'use-text-on-buttons';
-const WEATHER_SHOW_TEXT_IN_PANEL_KEY = 'show-text-in-panel';
-const WEATHER_POSITION_IN_PANEL_KEY = 'position-in-panel';
-const WEATHER_SHOW_COMMENT_IN_PANEL_KEY = 'show-comment-in-panel';
-const WEATHER_REFRESH_INTERVAL_CURRENT = 'refresh-interval-current';
-const WEATHER_REFRESH_INTERVAL_FORECAST = 'refresh-interval-forecast';
-const WEATHER_CENTER_FORECAST_KEY = 'center-forecast';
-const WEATHER_DAYS_FORECAST = 'days-forecast';
-const WEATHER_DECIMAL_PLACES = 'decimal-places';
-const WEATHER_OWM_API_KEY = 'appid';
-
-//URL
-const WEATHER_URL_HOST = 'api.openweathermap.org';
-const WEATHER_URL_PORT = 80;
-const WEATHER_URL_BASE = 'http://' + WEATHER_URL_HOST + '/data/2.5/';
-const WEATHER_URL_CURRENT = WEATHER_URL_BASE + 'weather';
-const WEATHER_URL_FORECAST = WEATHER_URL_BASE + 'forecast/daily';
+const OPENWEATHER_SETTINGS_SCHEMA = 'org.gnome.shell.extensions.openweather';
+const OPENWEATHER_DESKTOP_INTERFACE = 'org.gnome.desktop.interface';
+const OPENWEATHER_PROVIDER_KEY = 'weather-provider';
+const OPENWEATHER_UNIT_KEY = 'unit';
+const OPENWEATHER_WIND_SPEED_UNIT_KEY = 'wind-speed-unit';
+const OPENWEATHER_WIND_DIRECTION_KEY = 'wind-direction';
+const OPENWEATHER_PRESSURE_UNIT_KEY = 'pressure-unit';
+const OPENWEATHER_CITY_KEY = 'city';
+const OPENWEATHER_ACTUAL_CITY_KEY = 'actual-city';
+const OPENWEATHER_TRANSLATE_CONDITION_KEY = 'translate-condition';
+const OPENWEATHER_USE_SYMBOLIC_ICONS_KEY = 'use-symbolic-icons';
+const OPENWEATHER_USE_TEXT_ON_BUTTONS_KEY = 'use-text-on-buttons';
+const OPENWEATHER_SHOW_TEXT_IN_PANEL_KEY = 'show-text-in-panel';
+const OPENWEATHER_POSITION_IN_PANEL_KEY = 'position-in-panel';
+const OPENWEATHER_SHOW_COMMENT_IN_PANEL_KEY = 'show-comment-in-panel';
+const OPENWEATHER_SHOW_COMMENT_IN_FORECAST_KEY = 'show-comment-in-forecast';
+const OPENWEATHER_REFRESH_INTERVAL_CURRENT = 'refresh-interval-current';
+const OPENWEATHER_REFRESH_INTERVAL_FORECAST = 'refresh-interval-forecast';
+const OPENWEATHER_CENTER_FORECAST_KEY = 'center-forecast';
+const OPENWEATHER_DAYS_FORECAST = 'days-forecast';
+const OPENWEATHER_DECIMAL_PLACES = 'decimal-places';
+const OPENWEATHER_USE_DEFAULT_OWM_API_KEY = 'use-default-owm-key';
+const OPENWEATHER_OWM_API_KEY = 'appid';
+const OPENWEATHER_OWM_DEFAULT_API_KEY = 'c93b4a667c8c9d1d1eb941621f899bb8';
+const OPENWEATHER_FC_API_KEY = 'appid-fc';
 
 // Keep enums in sync with GSettings schemas
+const WeatherProvider = {
+    DEFAULT: -1,
+    OPENWEATHERMAP: 0,
+    FORECAST_IO: 1
+};
+
 const WeatherUnits = {
     CELSIUS: 0,
     FAHRENHEIT: 1,
@@ -103,15 +114,16 @@
 };
 
 const WeatherPressureUnits = {
-    hPa: 0,
-    inHg: 1,
-    bar: 2,
-    Pa: 3,
-    kPa: 4,
-    atm: 5,
-    at: 6,
-    Torr: 7,
-    psi: 8
+    HPA: 0,
+    INHG: 1,
+    BAR: 2,
+    PA: 3,
+    KPA: 4,
+    ATM: 5,
+    AT: 6,
+    TORR: 7,
+    PSI: 8,
+    MMHG: 9
 };
 
 const WeatherPosition = {
@@ -120,12 +132,14 @@
     LEFT: 2
 };
 
-const WEATHER_CONV_MPS_IN_MPH = 2.23693629;
-const WEATHER_CONV_MPS_IN_KPH = 3.6;
-const WEATHER_CONV_MPS_IN_KNOTS = 1.94384449;
-const WEATHER_CONV_MPS_IN_FPS = 3.2808399;
+const OPENWEATHER_CONV_MPS_IN_MPH = 2.23693629;
+const OPENWEATHER_CONV_MPS_IN_KPH = 3.6;
+const OPENWEATHER_CONV_MPS_IN_KNOTS = 1.94384449;
+const OPENWEATHER_CONV_MPS_IN_FPS = 3.2808399;
 
 let _httpSession;
+let _currentWeatherCache, _forecastWeatherCache;
+let _timeCacheCurrentWeather, _timeCacheForecastWeather;
 
 const OpenweatherMenuButton = new Lang.Class({
     Name: 'OpenweatherMenuButton',
@@ -133,8 +147,22 @@
     Extends: PanelMenu.Button,
 
     _init: function() {
-        this.currentWeatherCache = undefined;
-        this.forecastWeatherCache = undefined;
+        this.owmCityId = 0;
+
+        // Create user-agent string from uuid and (if present) the version
+        this.user_agent = Me.metadata.uuid;
+        if (Me.metadata.version !== undefined && Me.metadata.version.toString().trim() !== '') {
+            this.user_agent += '/';
+            this.user_agent += Me.metadata.version.toString();
+        }
+        // add trailing space, so libsoup adds its own user-agent
+        this.user_agent += ' ';
+
+        this.oldProvider = this._weather_provider;
+        this.oldUseDefaultOwmKey = this._use_default_owm_key;
+        this.oldTranslateCondition = this._translate_condition;
+        this.switchProvider();
+
         // Load settings
         this.loadConfig();
 
@@ -145,7 +173,7 @@
         });
 
         this._weatherIcon = new St.Icon({
-            icon_name: 'view-refresh' + this.icon_type(),
+            icon_name: 'view-refresh' + this.getIconType(),
             style_class: 'system-status-icon openweather-icon'
         });
 
@@ -186,6 +214,8 @@
         else
             Main.panel._menus.addMenu(this.menu);
 
+        this._session = new GnomeSession.SessionManager();
+
         this._old_position_in_panel = this._position_in_panel;
 
         // Current weather
@@ -201,13 +231,8 @@
             reactive: false
         });
 
-        if (ExtensionUtils.versionCheck(['3.6', '3.8'], Config.PACKAGE_VERSION)) {
-            _itemCurrent.addActor(this._currentWeather);
-            _itemFuture.addActor(this._futureWeather);
-        } else {
-            _itemCurrent.actor.add_actor(this._currentWeather);
-            _itemFuture.actor.add_actor(this._futureWeather);
-        }
+        _itemCurrent.actor.add_actor(this._currentWeather);
+        _itemFuture.actor.add_actor(this._futureWeather);
 
         this.menu.addMenuItem(_itemCurrent);
 
@@ -240,21 +265,49 @@
         this.rebuildCurrentWeatherUi();
         this.rebuildFutureWeatherUi();
 
+        this._idle = false;
+        this._connected = false;
+
         this._network_monitor = Gio.network_monitor_get_default();
 
-        this._connected = false;
+        this._presence = new GnomeSession.Presence(Lang.bind(this, function(proxy, error) {
+            this._onStatusChanged(proxy.status);
+        }));
+        this._presence_connection = this._presence.connectSignal('StatusChanged', Lang.bind(this, function(proxy, senderName, [status]) {
+            this._onStatusChanged(status);
+        }));
+
+        this.currentWeatherCache = _currentWeatherCache;
+        this.forecastWeatherCache = _forecastWeatherCache;
+        if (_timeCacheForecastWeather !== undefined) {
+            let diff = Math.floor(new Date(new Date() - _timeCacheForecastWeather).getTime() / 1000);
+            if (diff < this._refresh_interval_forecast)
+                this.reloadWeatherForecast(this._refresh_interval_forecast - diff);
+        }
+        if (_timeCacheCurrentWeather !== undefined) {
+            let diff = Math.floor(new Date(new Date() - _timeCacheCurrentWeather).getTime() / 1000);
+            if (diff < this._refresh_interval_current)
+                this.reloadWeatherCurrent(this._refresh_interval_current - diff);
+        }
         this._network_monitor_connection = this._network_monitor.connect('network-changed', Lang.bind(this, this._onNetworkStateChanged));
+
         this._checkConnectionState();
 
         this.menu.connect('open-state-changed', Lang.bind(this, this.recalcLayout));
-        if (ExtensionUtils.versionCheck(['3.6', '3.8'], Config.PACKAGE_VERSION)) {
-            this._needsColorUpdate = true;
-            let context = St.ThemeContext.get_for_stage(global.stage);
-            this._globalThemeChangedId = context.connect('changed', Lang.bind(this, function(){this._needsColorUpdate = true;}));
+    },
+
+    _onStatusChanged: function(status) {
+        this._idle = false;
+
+        if (status == GnomeSession.PresenceStatus.IDLE) {
+            this._idle = true;
         }
     },
 
     stop: function() {
+        _forecastWeatherCache = this.forecastWeatherCache;
+        _currentWeatherCache = this.currentWeatherCache;
+
         if (_httpSession !== undefined)
             _httpSession.abort();
 
@@ -270,6 +323,11 @@
 
         this._timeoutForecast = undefined;
 
+        if (this._presence_connection) {
+            this._presence.disconnect(this._presence_connection);
+            this._presence_connection = undefined;
+        }
+
         if (this._network_monitor_connection) {
             this._network_monitor.disconnect(this._network_monitor_connection);
             this._network_monitor_connection = undefined;
@@ -292,30 +350,124 @@
         }
     },
 
+    switchProvider: function() {
+        if (this._weather_provider == WeatherProvider.FORECAST_IO)
+            this.useForecastIo();
+        else
+            this.useOpenweathermapOrg();
+    },
+
+    useOpenweathermapOrg: function() {
+        this.parseWeatherForecast = OpenweathermapOrg.parseWeatherForecast;
+        this.parseWeatherCurrent = OpenweathermapOrg.parseWeatherCurrent;
+        this.getWeatherIcon = OpenweathermapOrg.getWeatherIcon;
+        this.refreshWeatherCurrent = OpenweathermapOrg.refreshWeatherCurrent;
+        this.refreshWeatherForecast = OpenweathermapOrg.refreshWeatherForecast;
+
+        this.weatherProvider = "https://openweathermap.org/";;
+
+        if (this._appid.toString().trim() === '')
+            Main.notify("Openweather", _("Openweathermap.org does not work without an api-key.\nEither set the switch to use the extensions default key in the preferences dialog to on or register at http://openweathermap.org/appid and paste your personal key into the preferences dialog."));
+
+    },
+
+    useForecastIo: function() {
+        this.parseWeatherCurrent = ForecastIo.parseWeatherCurrent;
+        this.parseWeatherForecast = ForecastIo.parseWeatherForecast;
+        this.getWeatherIcon = ForecastIo.getWeatherIcon;
+        this.refreshWeatherCurrent = ForecastIo.refreshWeatherCurrent;
+        this.refreshWeatherForecast = function() {};
+
+        this.weatherProvider = "https://forecast.io/";;
+
+        this.fc_locale = 'en';
+
+        if (this._translate_condition) {
+            let fc_locales = [
+                'ar',
+                'bs',
+                'de',
+                'el',
+                'en',
+                'es',
+                'fr',
+                'hr',
+                'it',
+                'nl',
+                'pl',
+                'pt',
+                'ru',
+                'sk',
+                'sv',
+                'tet',
+                'tr',
+                'uk',
+                'x-pig-latin',
+                'zh',
+                'zh-tw'
+            ];
+            let locale = GLib.get_language_names()[0];
+
+            if (locale.indexOf('_') != -1)
+                locale = locale.split("_")[0];
+
+            if (fc_locales.indexOf(locale) != -1)
+                this.fc_locale = locale;
+        }
+
+        if (this._appid_fc.toString().trim() === '')
+            Main.notify("Openweather", _("Forecast.io does not work without an api-key.\nPlease register at https://developer.forecast.io/register and paste your personal key into the preferences dialog."));
+    },
+
+    getWeatherProviderURL: function() {
+        let url = "";
+        if (this._weather_provider == WeatherProvider.FORECAST_IO) {
+            url = "https://forecast.io/#/f/";;
+            url += this.extractCoord(this._city);
+        } else {
+            url = "https://openweathermap.org";;
+            url += "/city/" + this.owmCityId;
+            if (this._appid)
+                url += "?APPID=" + this._appid;
+        }
+        return url;
+    },
+
     loadConfig: function() {
-        this._settings = Convenience.getSettings(WEATHER_SETTINGS_SCHEMA);
+        this._settings = Convenience.getSettings(OPENWEATHER_SETTINGS_SCHEMA);
+
+        if (this._cities.length === 0)
+            this._cities = "-8.5211767,179.1976747>Vaiaku, Tuvalu>-1";
+
         this._settingsC = this._settings.connect("changed", Lang.bind(this, function() {
+            if (this._cities.length === 0)
+                this._cities = "-8.5211767,179.1976747>Vaiaku, Tuvalu>-1";
             this.rebuildCurrentWeatherUi();
             this.rebuildFutureWeatherUi();
-            this.rebuildButtonMenu();
+            if (this.providerChanged()) {
+                this.switchProvider();
+                this.currentWeatherCache = undefined;
+                this.forecastWeatherCache = undefined;
+            }
             if (this.locationChanged()) {
                 this.currentWeatherCache = undefined;
                 this.forecastWeatherCache = undefined;
             }
+            this.rebuildButtonMenu();
             this.parseWeatherCurrent();
         }));
     },
 
     loadConfigInterface: function() {
-        let schemaInterface = "org.gnome.desktop.interface";
-        if (Gio.Settings.list_schemas().indexOf(schemaInterface) == -1)
-            throw _("Schema \"%s\" not found.").replace("%s", schemaInterface);
-        this._settingsInterface = new Gio.Settings({
-            schema: schemaInterface
-        });
+        this._settingsInterface = Convenience.getSettings(OPENWEATHER_DESKTOP_INTERFACE);
         this._settingsInterfaceC = this._settingsInterface.connect("changed", Lang.bind(this, function() {
             this.rebuildCurrentWeatherUi();
             this.rebuildFutureWeatherUi();
+            if (this.providerChanged()) {
+                this.switchProvider();
+                this.currentWeatherCache = undefined;
+                this.forecastWeatherCache = undefined;
+            }
             if (this.locationChanged()) {
                 this.currentWeatherCache = undefined;
                 this.forecastWeatherCache = undefined;
@@ -329,89 +481,122 @@
     },
 
     _checkConnectionState: function() {
-        this._connected = this._network_monitor.network_available;
-        if (this._connected)
+        let url = this.getWeatherProviderURL();
+        let address = Gio.NetworkAddress.parse_uri(url, 80);
+        let cancellable = Gio.Cancellable.new();
+        this._oldConnected = this._connected;
+        this._connected = false;
+        try {
+            this._network_monitor.can_reach_async(address, cancellable, Lang.bind(this, this._asyncReadyCallback));
+        } catch (err) {
+            let title = _("Can not connect to %s").format(url);
+            log(title + '\n' + err.message);
+        }
+    },
+
+    _asyncReadyCallback: function(nm, res) {
+        this._connected = this._network_monitor.can_reach_finish(res);
+        if (!this._oldConnected && this._connected) {
+            let now = new Date();
+            if (_timeCacheCurrentWeather &&
+                (Math.floor(new Date(now - _timeCacheCurrentWeather).getTime() / 1000) > this._refresh_interval_current))
+                this.currentWeatherCache = undefined;
+            if (_timeCacheForecastWeather &&
+                (Math.floor(new Date(now - _timeCacheForecastWeather).getTime() / 1000) > this._refresh_interval_forecast))
+                this.forecastWeatherCache = undefined;
             this.parseWeatherCurrent();
+        }
     },
 
     locationChanged: function() {
-        let location = this.extractId(this._city);
+        let location = this.extractCoord(this._city);
         if (this.oldLocation != location) {
             return true;
         }
         return false;
     },
 
+    providerChanged: function() {
+        let provider = this._weather_provider;
+        if (this.oldProvider != provider) {
+            this.oldProvider = provider;
+            return true;
+        }
+        if (provider == WeatherProvider.OPENWEATHERMAP) {
+            let useDefaultOwmKey = this._use_default_owm_key;
+            if (this.oldUseDefaultOwmKey != useDefaultOwmKey) {
+                this.oldUseDefaultOwmKey = useDefaultOwmKey;
+                return true;
+            }
+        }
+        if (provider == WeatherProvider.FORECAST_IO) {
+            let translateCondition = this._translate_condition;
+            if (this.oldTranslateCondition != translateCondition) {
+                this.oldTranslateCondition = translateCondition;
+                return true;
+            }
+        }
+        return false;
+    },
+
     get _clockFormat() {
         if (!this._settingsInterface)
             this.loadConfigInterface();
         return this._settingsInterface.get_string("clock-format");
     },
 
-    get _units() {
+    get _weather_provider() {
         if (!this._settings)
             this.loadConfig();
-        return this._settings.get_enum(WEATHER_UNIT_KEY);
-    },
 
-    set _units(v) {
-        if (!this._settings)
-            this.loadConfig();
-        this._settings.set_enum(WEATHER_UNIT_KEY, v);
-    },
+        let provider = this.extractProvider(this._city);
 
-    get _wind_speed_units() {
-        if (!this._settings)
-            this.loadConfig();
-        return this._settings.get_enum(WEATHER_WIND_SPEED_UNIT_KEY);
-    },
+        if (provider == WeatherProvider.DEFAULT)
+            provider = this._settings.get_enum(OPENWEATHER_PROVIDER_KEY);
 
-    set _wind_speed_units(v) {
-        if (!this._settings)
-            this.loadConfig();
-        this._settings.set_enum(WEATHER_WIND_SPEED_UNIT_KEY, v);
+        return provider;
     },
 
-    get _wind_direction() {
+    get _units() {
         if (!this._settings)
             this.loadConfig();
-        return this._settings.get_boolean(WEATHER_WIND_DIRECTION_KEY);
+        return this._settings.get_enum(OPENWEATHER_UNIT_KEY);
     },
 
-    set _wind_direction(v) {
+    get _wind_speed_units() {
         if (!this._settings)
             this.loadConfig();
-        return this._settings.set_boolean(WEATHER_WIND_DIRECTION_KEY, v);
+        return this._settings.get_enum(OPENWEATHER_WIND_SPEED_UNIT_KEY);
     },
 
-    get _pressure_units() {
+    get _wind_direction() {
         if (!this._settings)
             this.loadConfig();
-        return this._settings.get_enum(WEATHER_PRESSURE_UNIT_KEY);
+        return this._settings.get_boolean(OPENWEATHER_WIND_DIRECTION_KEY);
     },
 
-    set _pressure_units(v) {
+    get _pressure_units() {
         if (!this._settings)
             this.loadConfig();
-        this._settings.set_enum(WEATHER_PRESSURE_UNIT_KEY, v);
+        return this._settings.get_enum(OPENWEATHER_PRESSURE_UNIT_KEY);
     },
 
     get _cities() {
         if (!this._settings)
             this.loadConfig();
-        return this._settings.get_string(WEATHER_CITY_KEY);
+        return this._settings.get_string(OPENWEATHER_CITY_KEY);
     },
 
     set _cities(v) {
         if (!this._settings)
             this.loadConfig();
-        this._settings.set_string(WEATHER_CITY_KEY, v);
+        return this._settings.set_string(OPENWEATHER_CITY_KEY, v);
     },
 
     get _actual_city() {
         if (!this._settings)
             this.loadConfig();
-        var a = this._settings.get_int(WEATHER_ACTUAL_CITY_KEY);
+        var a = this._settings.get_int(OPENWEATHER_ACTUAL_CITY_KEY);
         var b = a;
         var cities = this._cities.split(" && ");
 
@@ -451,7 +636,7 @@
         if (a > l)
             a = l;
 
-        this._settings.set_int(WEATHER_ACTUAL_CITY_KEY, a);
+        this._settings.set_int(OPENWEATHER_ACTUAL_CITY_KEY, a);
     },
 
     get _city() {
@@ -465,237 +650,114 @@
         return cities;
     },
 
-    set _city(v) {
-        let cities = this._cities;
-        cities = cities.split(" && ");
-        if (cities && typeof cities == "string")
-            cities = [cities];
-        if (!cities[0])
-            cities = [];
-        cities.splice(this.actual_city, 1, v);
-        cities = cities.join(" && ");
-        if (typeof cities != "string")
-            cities = cities[0];
-        this._cities = cities;
-    },
-
     get _translate_condition() {
         if (!this._settings)
             this.loadConfig();
-        return this._settings.get_boolean(WEATHER_TRANSLATE_CONDITION_KEY);
+        return this._settings.get_boolean(OPENWEATHER_TRANSLATE_CONDITION_KEY);
     },
 
-    set _translate_condition(v) {
+    get _getIconType() {
         if (!this._settings)
             this.loadConfig();
-        this._settings.set_boolean(WEATHER_TRANSLATE_CONDITION_KEY, v);
-    },
-
-    get _icon_type() {
-        if (!this._settings)
-            this.loadConfig();
-        return this._settings.get_boolean(WEATHER_USE_SYMBOLIC_ICONS_KEY) ? 1 : 0;
-    },
-
-    set _icon_type(v) {
-        if (!this._settings)
-            this.loadConfig();
-        this._settings.set_boolean(WEATHER_USE_SYMBOLIC_ICONS_KEY, v);
+        return this._settings.get_boolean(OPENWEATHER_USE_SYMBOLIC_ICONS_KEY) ? 1 : 0;
     },
 
     get _use_text_on_buttons() {
         if (!this._settings)
             this.loadConfig();
-        return this._settings.get_boolean(WEATHER_USE_TEXT_ON_BUTTONS_KEY) ? 1 : 0;
-    },
-
-    set _use_text_on_buttons(v) {
-        if (!this._settings)
-            this.loadConfig();
-        this._settings.set_boolean(WEATHER_USE_TEXT_ON_BUTTONS_KEY, v);
+        return this._settings.get_boolean(OPENWEATHER_USE_TEXT_ON_BUTTONS_KEY) ? 1 : 0;
     },
 
     get _text_in_panel() {
         if (!this._settings)
             this.loadConfig();
-        return this._settings.get_boolean(WEATHER_SHOW_TEXT_IN_PANEL_KEY);
-    },
-
-    set _text_in_panel(v) {
-        if (!this._settings)
-            this.loadConfig();
-        this._settings.set_boolean(WEATHER_SHOW_TEXT_IN_PANEL_KEY, v);
+        return this._settings.get_boolean(OPENWEATHER_SHOW_TEXT_IN_PANEL_KEY);
     },
 
     get _position_in_panel() {
         if (!this._settings)
             this.loadConfig();
-        return this._settings.get_enum(WEATHER_POSITION_IN_PANEL_KEY);
-    },
-
-    set _position_in_panel(v) {
-        if (!this._settings)
-            this.loadConfig();
-        this._settings.set_enum(WEATHER_POSITION_IN_PANEL_KEY, v);
+        return this._settings.get_enum(OPENWEATHER_POSITION_IN_PANEL_KEY);
     },
 
     get _comment_in_panel() {
         if (!this._settings)
             this.loadConfig();
-        return this._settings.get_boolean(WEATHER_SHOW_COMMENT_IN_PANEL_KEY);
+        return this._settings.get_boolean(OPENWEATHER_SHOW_COMMENT_IN_PANEL_KEY);
     },
 
-    set _comment_in_panel(v) {
+    get _comment_in_forecast() {
         if (!this._settings)
             this.loadConfig();
-        this._settings.set_boolean(WEATHER_SHOW_COMMENT_IN_PANEL_KEY, v);
+        return this._settings.get_boolean(OPENWEATHER_SHOW_COMMENT_IN_FORECAST_KEY);
     },
 
     get _refresh_interval_current() {
         if (!this._settings)
             this.loadConfig();
-        let v = this._settings.get_int(WEATHER_REFRESH_INTERVAL_CURRENT);
+        let v = this._settings.get_int(OPENWEATHER_REFRESH_INTERVAL_CURRENT);
         return ((v >= 600) ? v : 600);
     },
 
-    set _refresh_interval_current(v) {
-        if (!this._settings)
-            this.loadConfig();
-        this._settings.set_int(WEATHER_REFRESH_INTERVAL_CURRENT, ((v >= 600) ? v : 600));
-    },
-
     get _refresh_interval_forecast() {
         if (!this._settings)
             this.loadConfig();
-        let v = this._settings.get_int(WEATHER_REFRESH_INTERVAL_FORECAST);
+        let v = this._settings.get_int(OPENWEATHER_REFRESH_INTERVAL_FORECAST);
         return ((v >= 600) ? v : 600);
     },
 
-    set _refresh_interval_forecast(v) {
-        if (!this._settings)
-            this.loadConfig();
-        this._settings.set_int(WEATHER_REFRESH_INTERVAL_FORECAST, ((v >= 600) ? v : 600));
-    },
-
     get _center_forecast() {
         if (!this._settings)
             this.loadConfig();
-        return this._settings.get_boolean(WEATHER_CENTER_FORECAST_KEY);
-    },
-
-    set _center_forecast(v) {
-        if (!this._settings)
-            this.loadConfig();
-        this._settings.set_boolean(WEATHER_CENTER_FORECAST_KEY, v);
+        return this._settings.get_boolean(OPENWEATHER_CENTER_FORECAST_KEY);
     },
 
     get _days_forecast() {
         if (!this._settings)
             this.loadConfig();
-        return this._settings.get_int(WEATHER_DAYS_FORECAST);
-    },
-
-    set _days_forecast(v) {
-        if (!this._settings)
-            this.loadConfig();
-        this._settings.set_int(WEATHER_DAYS_FORECAST, v);
+        return this._settings.get_int(OPENWEATHER_DAYS_FORECAST);
     },
 
     get _decimal_places() {
         if (!this._settings)
             this.loadConfig();
-        return this._settings.get_int(WEATHER_DECIMAL_PLACES);
-    },
-
-    set _decimal_places(v) {
-        if (!this._settings)
-            this.loadConfig();
-        this._settings.set_int(WEATHER_DECIMAL_PLACES, v);
+        return this._settings.get_int(OPENWEATHER_DECIMAL_PLACES);
     },
 
     get _appid() {
         if (!this._settings)
             this.loadConfig();
-        let key = this._settings.get_string(WEATHER_OWM_API_KEY);
+        let key = '';
+        if (this._use_default_owm_key)
+            key = OPENWEATHER_OWM_DEFAULT_API_KEY;
+        else
+            key = this._settings.get_string(OPENWEATHER_OWM_API_KEY);
         return (key.length == 32) ? key : '';
     },
 
-    set _appid(v) {
+    get _use_default_owm_key() {
         if (!this._settings)
             this.loadConfig();
-        this._settings.set_string(WEATHER_OWM_API_KEY, v);
+        return this._settings.get_boolean(OPENWEATHER_USE_DEFAULT_OWM_API_KEY);
     },
 
-    createButton: function(iconName, accessibleName) {
-        let button;
-
-        if (ExtensionUtils.versionCheck(['3.6', '3.8'], Config.PACKAGE_VERSION)) {
-            button = new St.Button({
-                reactive: true,
-                can_focus: true,
-                track_hover: true,
-                accessible_name: accessibleName,
-                style_class: 'popup-menu-item openweather-button'
-            });
-            button.child = new St.Icon({
-                icon_name: iconName
-            });
-            button.connect('notify::hover', Lang.bind(this, this._onButtonHoverChanged));
-        } else
-            button = Main.panel.statusArea.aggregateMenu._system._createActionButton(iconName, accessibleName);
-
-        return button;
-    },
-
-    _onButtonHoverChanged: function(actor, event) {
-        if (actor.hover) {
-            actor.add_style_pseudo_class('hover');
-            actor.set_style(this._button_background_style);
-        } else {
-            actor.remove_style_pseudo_class('hover');
-            actor.set_style('background-color:;');
-            if (actor != this._urlButton)
-                actor.set_style(this._button_border_style);
-            }
-    },
-
-    _updateButtonColors: function() {
-        if (!this._needsColorUpdate)
-            return;
-            this._needsColorUpdate = false;
-        let color;
-        if (ExtensionUtils.versionCheck(['3.6'], Config.PACKAGE_VERSION))
-            color = this._separatorItem._drawingArea.get_theme_node().get_color('-gradient-end');
-        else
-            color = this._separatorItem._separator.actor.get_theme_node().get_color('-gradient-end');
-
-            let alpha = (Math.round(color.alpha / 2.55) / 100);
-
-            if (color.red > 0 && color.green > 0 && color.blue > 0)
-                this._button_border_style = 'border:1px solid rgb(' + Math.round(alpha * color.red) + ',' + Math.round(alpha * color.green) + ',' + Math.round(alpha * color.blue) + ');';
-            else
-                this._button_border_style = 'border:1px solid rgba(' + color.red + ',' + color.green + ',' + color.blue + ',' + alpha + ');';
-
-            this._locationButton.set_style(this._button_border_style);
-            this._reloadButton.set_style(this._button_border_style);
-            this._prefsButton.set_style(this._button_border_style);
-
-            this._buttonMenu.actor.add_style_pseudo_class('active');
-            color = this._buttonMenu.actor.get_theme_node().get_background_color();
-            this._button_background_style = 'background-color:rgba(' + color.red + ',' + color.green + ',' + color.blue + ',' + (Math.round(color.alpha / 2.55) / 100) + ');';
-            this._buttonMenu.actor.remove_style_pseudo_class('active');
+    get _appid_fc() {
+        if (!this._settings)
+            this.loadConfig();
+        let key = this._settings.get_string(OPENWEATHER_FC_API_KEY);
+        return (key.length == 32) ? key : '';
     },
 
     rebuildButtonMenu: function() {
         if (this._buttonBox) {
-        if (this._buttonBox1) {
-            this._buttonBox1.destroy();
-            this._buttonBox1 = undefined;
+            if (this._buttonBox1) {
+                this._buttonBox1.destroy();
+                this._buttonBox1 = undefined;
 
-        }
-        if (this._buttonBox2) {
-            this._buttonBox2.destroy();
-            this._buttonBox2 = undefined;
+            }
+            if (this._buttonBox2) {
+                this._buttonBox2.destroy();
+                this._buttonBox2 = undefined;
             }
             this._buttonMenu.removeActor(this._buttonBox);
             this._buttonBox.destroy();
@@ -711,22 +773,19 @@
             this._buttonBox2 = undefined;
         }
 
-        this._locationButton = this.createButton('find-location-symbolic', _("Locations"));
+        this._locationButton = Main.panel.statusArea.aggregateMenu._system._createActionButton('find-location-symbolic', _("Locations"));
         if (this._use_text_on_buttons)
             this._locationButton.set_label(this._locationButton.get_accessible_name());
 
         this._locationButton.connect('clicked', Lang.bind(this, function() {
-            if (ExtensionUtils.versionCheck(['3.6', '3.8'], Config.PACKAGE_VERSION))
-                this._selectCity.menu.toggle();
-            else
-               this._selectCity._setOpenState(!this._selectCity._getOpenState());
+            this._selectCity._setOpenState(!this._selectCity._getOpenState());
         }));
         this._buttonBox1 = new St.BoxLayout({
             style_class: 'openweather-button-box'
         });
         this._buttonBox1.add_actor(this._locationButton);
 
-        this._reloadButton = this.createButton('view-refresh-symbolic', _("Reload Weather Information"));
+        this._reloadButton = Main.panel.statusArea.aggregateMenu._system._createActionButton('view-refresh-symbolic', _("Reload Weather Information"));
         if (this._use_text_on_buttons)
             this._reloadButton.set_label(this._reloadButton.get_accessible_name());
         this._reloadButton.connect('clicked', Lang.bind(this, function() {
@@ -737,30 +796,17 @@
         }));
         this._buttonBox1.add_actor(this._reloadButton);
 
-
         this._buttonBox2 = new St.BoxLayout({
             style_class: 'openweather-button-box'
         });
 
-        this._urlButton = new St.Button({
-            label: _("Weather data provided by:") + (this._use_text_on_buttons ? "\n" : "  ") + "http://openweathermap.org/";,
-            style_class: 'system-menu-action openweather-provider'
-        });
-        if (ExtensionUtils.versionCheck(['3.6', '3.8'], Config.PACKAGE_VERSION)) {
-            this._urlButton.connect('notify::hover', Lang.bind(this, this._onButtonHoverChanged));
-        }
+        this._urlButton = Main.panel.statusArea.aggregateMenu._system._createActionButton('', _("Weather data provided by:") + (this._use_text_on_buttons ? "\n" : "  ") + this.weatherProvider);
+        this._urlButton.set_label(this._urlButton.get_accessible_name());
+        this._urlButton.style_class += ' openweather-provider';
+
         this._urlButton.connect('clicked', Lang.bind(this, function() {
             this.menu.actor.hide();
-            let cityId = this.extractId(this._city);
-            if (!cityId) {
-                this.updateCities();
-                cityId = this.extractId(this._city);
-            }
-            let url = "http://openweathermap.org";;
-            if (cityId)
-                url += "/city/" + cityId;
-            if (this._appid)
-                url += "?APPID=" + this._appid;
+            let url = this.getWeatherProviderURL();
 
             try {
                 Gtk.show_uri(null, url, global.get_current_time());
@@ -772,28 +818,18 @@
 
         this._buttonBox2.add_actor(this._urlButton);
 
-
-        this._prefsButton = this.createButton('preferences-system-symbolic', _("Weather Settings"));
+        this._prefsButton = Main.panel.statusArea.aggregateMenu._system._createActionButton('preferences-system-symbolic', _("Weather Settings"));
         if (this._use_text_on_buttons)
             this._prefsButton.set_label(this._prefsButton.get_accessible_name());
         this._prefsButton.connect('clicked', Lang.bind(this, this._onPreferencesActivate));
         this._buttonBox2.add_actor(this._prefsButton);
 
-        if (ExtensionUtils.versionCheck(['3.6', '3.8'], Config.PACKAGE_VERSION)) {
-            this._buttonBox = new St.BoxLayout();
-            this._buttonBox1.add_style_class_name('openweather-button-box-38');
-            this._buttonBox2.add_style_class_name('openweather-button-box-38');
-            this._buttonBox.add_actor(this._buttonBox1);
-            this._buttonBox.add_actor(this._buttonBox2);
+        this._buttonMenu.actor.add_actor(this._buttonBox1);
+        this._buttonMenu.actor.add_actor(this._buttonBox2);
 
-            this._buttonMenu.addActor(this._buttonBox);
-            this._needsColorUpdate = true;
-        } else {
-            this._buttonMenu.actor.add_actor(this._buttonBox1);
-            this._buttonMenu.actor.add_actor(this._buttonBox2);
-        }
         this._buttonBox1MinWidth = undefined;
     },
+
     rebuildSelectCityItem: function() {
         this._selectCity.menu.removeAll();
         let item = null;
@@ -809,10 +845,7 @@
             item = new PopupMenu.PopupMenuItem(this.extractLocation(cities[i]));
             item.location = i;
             if (i == this._actual_city) {
-                if (ExtensionUtils.versionCheck(['3.6', '3.8'], Config.PACKAGE_VERSION))
-                    item.setShowDot(true);
-                else
-                    item.setOrnament(PopupMenu.Ornament.DOT);
+                item.setOrnament(PopupMenu.Ornament.DOT);
             }
 
             this._selectCity.menu.addMenuItem(item);
@@ -840,73 +873,28 @@
         return arguments[0].split(">")[1];
     },
 
-    extractCity: function() {
-        if (!arguments[0])
-            return "";
-        let city = this.extractLocation(arguments[0]);
-        if (city.indexOf("(") == -1)
-            return _("Invalid city");
-        return city.split("(")[0].trim();
-    },
+    extractCoord: function() {
+        let coords = 0;
 
-    extractId: function() {
-        if (!arguments[0])
-            return 0;
+        if (arguments[0] && (arguments[0].search(">") != -1))
+            coords = arguments[0].split(">")[0];
 
-        if (arguments[0].search(">") == -1)
+        if ((coords.search(",") == -1) || isNaN(coords.split(",")[0]) || isNaN(coords.split(",")[1])) {
+            Main.notify("Openweather", _("Invalid location! Please try to recreate it."));
             return 0;
-        return arguments[0].split(">")[0];
-    },
-
-    updateCities: function() {
-        let cities = this._cities;
-
-        cities = cities.split(" && ");
-        if (cities && typeof cities == "string")
-            cities = [cities];
-        if (!cities[0])
-            cities = [];
-
-        if (cities.length === 0) {
-            this._cities = "2516479>Eivissa (CA)";
-            this.updateCities();
-            return;
         }
 
-        for (let a in cities) {
-            if (!this.extractCity(cities[a])) {
-                let params = {
-                    q: cities[a],
-                    type: 'like'
-                };
-                if (this._appid)
-                    params.APPID = this._appid;
-
-                this.load_json_async(WEATHER_URL_CURRENT, params, Lang.bind(this, this._updateCitiesCallback));
-                return;
-            } else
-                continue;
-        }
+        return coords;
     },
 
-    _updateCitiesCallback: function() {
-        let city = arguments[0];
-
-        if (Number(city.cod) != 200)
-            return;
-
-        let cityText = city.id + ">" + city.name;
-
-        if (city.sys)
-            cityText += " (" + city.sys.country + ")";
-
-        cities.splice(a, 1, cityText);
-
-        cities = cities.join(" && ");
-        if (typeof cities != "string")
-            cities = cities[0];
-        this._cities = cities;
-        this.updateCities();
+    extractProvider: function() {
+        if (!arguments[0])
+            return -1;
+        if (arguments[0].split(">")[2] === undefined)
+            return -1;
+        if (isNaN(parseInt(arguments[0].split(">")[2])))
+            return -1;
+        return parseInt(arguments[0].split(">")[2]);
     },
 
     _onPreferencesActivate: function() {
@@ -918,8 +906,7 @@
     recalcLayout: function() {
         if (!this.menu.isOpen)
             return;
-        this._updateButtonColors();
-        if(this._buttonBox1MinWidth === undefined)
+        if (this._buttonBox1MinWidth === undefined)
             this._buttonBox1MinWidth = this._buttonBox1.get_width();
         this._buttonBox1.set_width(Math.max(this._buttonBox1MinWidth, this._currentWeather.get_width() - this._buttonBox2.get_width()));
         if (this._forecastScrollBox !== undefined && this._forecastBox !== undefined && this._currentWeather !== undefined) {
@@ -954,240 +941,8 @@
             return '\u00B0C';
     },
 
-    get_weather_icon: function(code) {
-        // see http://bugs.openweathermap.org/projects/api/wiki/Weather_Condition_Codes
-        // fallback icons are: weather-clear-night weather-clear weather-few-clouds-night weather-few-clouds weather-fog weather-overcast weather-severe-alert weather-showers weather-showers-scattered weather-snow weather-storm
-        /*
-weather-clouds-night.png
-weather-freezing-rain.png
-weather-hail.png
-weather-many-clouds.png
-weather-showers-day.png
-weather-showers-night.png
-weather-showers-scattered-day.png
-weather-showers-scattered-night.png
-weather-snow-rain.png
-weather-snow-scattered-day.png
-weather-snow-scattered-night.png
-weather-snow-scattered.png
-weather-storm-day.png
-weather-storm-night.png
-
-weather-severe-alert-symbolic.svg
-
-
-weather-clear-night.png = weather-clear-night-symbolic.svg
-weather-clear.png = weather-clear-symbolic.svg
-weather-clouds.png = weather-overcast-symbolic.svg
-weather-few-clouds-night.png = weather-few-clouds-night-symbolic.svg
-weather-few-clouds.png = weather-few-clouds-symbolic.svg
-weather-mist.png = weather-fog-symbolic.svg
-weather-showers-scattered.png = weather-showers-scattered-symbolic.svg
-weather-showers.png = weather-showers-symbolic.svg
-weather-snow.png = weather-snow-symbolic.svg
-weather-storm.png = weather-storm-symbolic.svg
-
-*/
-        switch (parseInt(code, 10)) {
-            case 200: //thunderstorm with light rain
-            case 201: //thunderstorm with rain
-            case 202: //thunderstorm with heavy rain
-            case 210: //light thunderstorm
-            case 211: //thunderstorm
-            case 212: //heavy thunderstorm
-            case 221: //ragged thunderstorm
-            case 230: //thunderstorm with light drizzle
-            case 231: //thunderstorm with drizzle
-            case 232: //thunderstorm with heavy drizzle
-                return ['weather-storm'];
-            case 300: //light intensity drizzle
-            case 301: //drizzle
-            case 302: //heavy intensity drizzle
-            case 310: //light intensity drizzle rain
-            case 311: //drizzle rain
-            case 312: //heavy intensity drizzle rain
-            case 313: //shower rain and drizzle
-            case 314: //heavy shower rain and drizzle
-            case 321: //shower drizzle
-                return ['weather-showers'];
-            case 500: //light rain
-            case 501: //moderate rain
-            case 502: //heavy intensity rain
-            case 503: //very heavy rain
-            case 504: //extreme rain
-                return ['weather-showers-scattered', 'weather-showers'];
-            case 511: //freezing rain
-                return ['weather-freezing-rain', 'weather-showers'];
-            case 520: //light intensity shower rain
-            case 521: //shower rain
-            case 522: //heavy intensity shower rain
-            case 531: //ragged shower rain
-                return ['weather-showers'];
-            case 600: //light snow
-            case 601: //snow
-            case 602: //heavy snow
-            case 611: //sleet
-            case 612: //shower sleet
-            case 615: //light rain and snow
-            case 616: //rain and snow
-            case 620: //light shower snow
-            case 621: //shower snow
-            case 622: //heavy shower snow
-                return ['weather-snow'];
-            case 701: //mist
-            case 711: //smoke
-            case 721: //haze
-            case 741: //Fog
-                return ['weather-fog'];
-            case 731: //Sand/Dust Whirls
-            case 751: //sand
-            case 761: //dust
-            case 762: //VOLCANIC ASH
-            case 771: //SQUALLS
-            case 781: //TORNADO
-                return ['weather-severe-alert'];
-            case 800: //sky is clear
-                return ['weather-clear'];
-            case 801: //few clouds
-            case 802: //scattered clouds
-                return ['weather-few-clouds'];
-            case 803: //broken clouds
-                return ['weather-many-clouds', 'weather-overcast'];
-            case 804: //overcast clouds
-                return ['weather-overcast'];
-            default:
-                return ['weather-severe-alert'];
-        }
-    },
-
-    get_weather_icon_safely: function(code, night) {
-        let iconname = this.get_weather_icon(code);
-        for (let i = 0; i < iconname.length; i++) {
-            if (night && this.has_icon(iconname[i] + '-night'))
-                return iconname[i] + '-night' + this.icon_type();
-            if (this.has_icon(iconname[i]))
-                return iconname[i] + this.icon_type();
-        }
-        return 'weather-severe-alert' + this.icon_type();
-    },
-
-    has_icon: function(icon) {
-        return Gtk.IconTheme.get_default().has_icon(icon + this.icon_type());
-    },
-
-    get_weather_condition: function(code) {
-        switch (parseInt(code, 10)) {
-            case 200: //thunderstorm with light rain
-                return _('thunderstorm with light rain');
-            case 201: //thunderstorm with rain
-                return _('thunderstorm with rain');
-            case 202: //thunderstorm with heavy rain
-                return _('thunderstorm with heavy rain');
-            case 210: //light thunderstorm
-                return _('light thunderstorm');
-            case 211: //thunderstorm
-                return _('thunderstorm');
-            case 212: //heavy thunderstorm
-                return _('heavy thunderstorm');
-            case 221: //ragged thunderstorm
-                return _('ragged thunderstorm');
-            case 230: //thunderstorm with light drizzle
-                return _('thunderstorm with light drizzle');
-            case 231: //thunderstorm with drizzle
-                return _('thunderstorm with drizzle');
-            case 232: //thunderstorm with heavy drizzle
-                return _('thunderstorm with heavy drizzle');
-            case 300: //light intensity drizzle
-                return _('light intensity drizzle');
-            case 301: //drizzle
-                return _('drizzle');
-            case 302: //heavy intensity drizzle
-                return _('heavy intensity drizzle');
-            case 310: //light intensity drizzle rain
-                return _('light intensity drizzle rain');
-            case 311: //drizzle rain
-                return _('drizzle rain');
-            case 312: //heavy intensity drizzle rain
-                return _('heavy intensity drizzle rain');
-            case 313: //shower rain and drizzle
-                return _('shower rain and drizzle');
-            case 314: //heavy shower rain and drizzle
-                return _('heavy shower rain and drizzle');
-            case 321: //shower drizzle
-                return _('shower drizzle');
-            case 500: //light rain
-                return _('light rain');
-            case 501: //moderate rain
-                return _('moderate rain');
-            case 502: //heavy intensity rain
-                return _('heavy intensity rain');
-            case 503: //very heavy rain
-                return _('very heavy rain');
-            case 504: //extreme rain
-                return _('extreme rain');
-            case 511: //freezing rain
-                return _('freezing rain');
-            case 520: //light intensity shower rain
-                return _('light intensity shower rain');
-            case 521: //shower rain
-                return _('shower rain');
-            case 522: //heavy intensity shower rain
-                return _('heavy intensity shower rain');
-            case 531: //ragged shower rain
-                return _('ragged shower rain');
-            case 600: //light snow
-                return _('light snow');
-            case 601: //snow
-                return _('snow');
-            case 602: //heavy snow
-                return _('heavy snow');
-            case 611: //sleet
-                return _('sleet');
-            case 612: //shower sleet
-                return _('shower sleet');
-            case 615: //light rain and snow
-                return _('light rain and snow');
-            case 616: //rain and snow
-                return _('rain and snow');
-            case 620: //light shower snow
-                return _('light shower snow');
-            case 621: //shower snow
-                return _('shower snow');
-            case 622: //heavy shower snow
-                return _('heavy shower snow');
-            case 701: //mist
-                return _('mist');
-            case 711: //smoke
-                return _('smoke');
-            case 721: //haze
-                return _('haze');
-            case 731: //Sand/Dust Whirls
-                return _('Sand/Dust Whirls');
-            case 741: //Fog
-                return _('Fog');
-            case 751: //sand
-                return _('sand');
-            case 761: //dust
-                return _('dust');
-            case 762: //VOLCANIC ASH
-                return _('VOLCANIC ASH');
-            case 771: //SQUALLS
-                return _('SQUALLS');
-            case 781: //TORNADO
-                return _('TORNADO');
-            case 800: //sky is clear
-                return _('sky is clear');
-            case 801: //few clouds
-                return _('few clouds');
-            case 802: //scattered clouds
-                return _('scattered clouds');
-            case 803: //broken clouds
-                return _('broken clouds');
-            case 804: //overcast clouds
-                return _('overcast clouds');
-            default:
-                return _('Not available');
-        }
+    hasIcon: function(icon) {
+        return Gtk.IconTheme.get_default().has_icon(icon + this.getIconType());
     },
 
     toFahrenheit: function(t) {
@@ -1263,26 +1018,26 @@
             return (!t) ? "12" : "(" + _("Hurricane") + ")";
     },
 
-    get_locale_day: function(abr) {
+    getLocaleDay: function(abr) {
         let days = [_('Sunday'), _('Monday'), _('Tuesday'), _('Wednesday'), _('Thursday'), _('Friday'), _('Saturday')];
         return days[abr];
     },
 
-    get_wind_direction: function(deg) {
+    getWindDirection: function(deg) {
         let arrows = ["\u2193", "\u2199", "\u2190", "\u2196", "\u2191", "\u2197", "\u2192", "\u2198"];
         let letters = [_('N'), _('NE'), _('E'), _('SE'), _('S'), _('SW'), _('W'), _('NW')];
         let idx = Math.round(deg / 45) % arrows.length;
         return (this._wind_direction) ? arrows[idx] : letters[idx];
     },
 
-    icon_type: function(icon_name) {
+    getIconType: function(icon_name) {
         if (!icon_name)
-            if (this._icon_type)
+            if (this._getIconType)
                 return "-symbolic";
             else
                 return "";
 
-        if (this._icon_type)
+        if (this._getIconType)
             if (String(icon_name).search("-symbolic") != -1)
                 return icon_name;
             else
@@ -1296,18 +1051,16 @@
 
     load_json_async: function(url, params, fun) {
         if (_httpSession === undefined) {
-            if (ExtensionUtils.versionCheck(['3.6'], Config.PACKAGE_VERSION)) {
-                // Soup session (see https://bugzilla.gnome.org/show_bug.cgi?id=661323#c64) (Simon Legner)
-                _httpSession = new Soup.SessionAsync();
-                Soup.Session.prototype.add_feature.call(_httpSession, new Soup.ProxyResolverDefault());
-            } else
-                _httpSession = new Soup.Session();
+            _httpSession = new Soup.Session();
+            _httpSession.user_agent = this.user_agent;
+        } else {
+            // abort previous requests.
+            _httpSession.abort();
         }
 
         let message = Soup.form_request_new_from_hash('GET', url, params);
 
         _httpSession.queue_message(message, Lang.bind(this, function(_httpSession, message) {
-
             try {
                 if (!message.response_body.data) {
                     fun.call(this, 0);
@@ -1323,12 +1076,7 @@
         return;
     },
 
-    parseWeatherCurrent: function() {
-        if (this.currentWeatherCache === undefined) {
-            this.refreshWeatherCurrent();
-            return;
-        }
-
+    checkPositionInPanel: function() {
         if (this._old_position_in_panel != this._position_in_panel) {
             switch (this._old_position_in_panel) {
                 case WeatherPosition.LEFT:
@@ -1360,88 +1108,65 @@
             this._old_position_in_panel = this._position_in_panel;
         }
 
-        let json = this.currentWeatherCache;
-        // Refresh current weather
-        let location = this.extractLocation(this._city);
-
-        let comment = json.weather[0].description;
-        if (this._translate_condition)
-            comment = this.get_weather_condition(json.weather[0].id);
-
-        let temperature = json.main.temp;
-        let cloudiness = json.clouds.all;
-        let humidity = json.main.humidity + ' %';
-        let pressure = json.main.pressure;
-        let pressure_unit = 'hPa';
-
-        let wind_direction = this.get_wind_direction(json.wind.deg);
-        let wind = json.wind.speed;
-        let wind_unit = 'm/s';
-
-        let sunrise = new Date(json.sys.sunrise * 1000);
-        let sunset = new Date(json.sys.sunset * 1000);
-        let now = new Date();
-
-        let iconname = this.get_weather_icon_safely(json.weather[0].id, now < sunrise || now > sunset);
-
-        if (this.lastBuildId === undefined)
-            this.lastBuildId = 0;
-
-        if (this.lastBuildDate === undefined)
-            this.lastBuildDate = 0;
-
-        if (this.lastBuildId != json.dt || !this.lastBuildDate) {
-            this.lastBuildId = json.dt;
-            this.lastBuildDate = new Date(this.lastBuildId * 1000);
-        }
+    },
 
+    formatPressure: function(pressure) {
+        let pressure_unit = 'hPa';
         switch (this._pressure_units) {
-            case WeatherPressureUnits.inHg:
+            case WeatherPressureUnits.INHG:
                 pressure = this.toInHg(pressure);
                 pressure_unit = "inHg";
                 break;
 
-            case WeatherPressureUnits.hPa:
+            case WeatherPressureUnits.HPA:
                 pressure = pressure.toFixed(this._decimal_places);
                 pressure_unit = "hPa";
                 break;
 
-            case WeatherPressureUnits.bar:
+            case WeatherPressureUnits.BAR:
                 pressure = (pressure / 1000).toFixed(this._decimal_places);
                 pressure_unit = "bar";
                 break;
 
-            case WeatherPressureUnits.Pa:
+            case WeatherPressureUnits.PA:
                 pressure = (pressure * 100).toFixed(this._decimal_places);
                 pressure_unit = "Pa";
                 break;
 
-            case WeatherPressureUnits.kPa:
+            case WeatherPressureUnits.KPA:
                 pressure = (pressure / 10).toFixed(this._decimal_places);
                 pressure_unit = "kPa";
                 break;
 
-            case WeatherPressureUnits.atm:
+            case WeatherPressureUnits.ATM:
                 pressure = (pressure * 0.000986923267).toFixed(this._decimal_places);
                 pressure_unit = "atm";
                 break;
 
-            case WeatherPressureUnits.at:
+            case WeatherPressureUnits.AT:
                 pressure = (pressure * 0.00101971621298).toFixed(this._decimal_places);
                 pressure_unit = "at";
                 break;
 
-            case WeatherPressureUnits.Torr:
+            case WeatherPressureUnits.TORR:
                 pressure = (pressure * 0.750061683).toFixed(this._decimal_places);
                 pressure_unit = "Torr";
                 break;
 
-            case WeatherPressureUnits.psi:
+            case WeatherPressureUnits.PSI:
                 pressure = (pressure * 0.0145037738).toFixed(this._decimal_places);
                 pressure_unit = "psi";
                 break;
+
+            case WeatherPressureUnits.MMHG:
+                pressure = (pressure * 0.750061683).toFixed(this._decimal_places);
+                pressure_unit = "mmHg";
+                break;
         }
+        return parseFloat(pressure).toLocaleString() + ' ' + pressure_unit;
+    },
 
+    formatTemperature: function(temperature) {
         switch (this._units) {
             case WeatherUnits.FAHRENHEIT:
                 temperature = this.toFahrenheit(temperature);
@@ -1475,266 +1200,77 @@
                 temperature = this.toNewton(temperature);
                 break;
         }
+        return parseFloat(temperature).toLocaleString() + ' ' + this.unit_to_unicode();
+    },
 
-        let lastBuild = '-';
-
-        if (this._clockFormat == "24h") {
-            sunrise = sunrise.toLocaleFormat("%R");
-            sunset = sunset.toLocaleFormat("%R");
-            lastBuild = this.lastBuildDate.toLocaleFormat("%R");
-        } else {
-            sunrise = sunrise.toLocaleFormat("%I:%M %p");
-            sunset = sunset.toLocaleFormat("%I:%M %p");
-            lastBuild = this.lastBuildDate.toLocaleFormat("%I:%M %p");
-        }
-
-        let beginOfDay = new Date(new Date().setHours(0, 0, 0, 0));
-        let d = Math.floor((this.lastBuildDate.getTime() - beginOfDay.getTime()) / 86400000);
-        if (d < 0) {
-            lastBuild = _("Yesterday");
-            if (d < -1)
-                lastBuild = _("%s days ago").replace("%s", -1 * d);
-        }
-
-        this._currentWeatherIcon.icon_name = this._weatherIcon.icon_name = iconname;
-
-        let weatherInfoC = "";
-        let weatherInfoT = "";
-
-        if (this._comment_in_panel)
-            weatherInfoC = comment;
-
-        if (this._text_in_panel)
-            weatherInfoT = parseFloat(temperature).toLocaleString() + ' ' + this.unit_to_unicode();
-
-        this._weatherInfo.text = weatherInfoC + ((weatherInfoC && weatherInfoT) ? ", " : "") + weatherInfoT;
-
-        this._currentWeatherSummary.text = comment + ", " + parseFloat(temperature).toLocaleString() + ' ' + this.unit_to_unicode();
-        this._currentWeatherLocation.text = location;
-        this._currentWeatherTemperature.text = cloudiness + ' %';
-        this._currentWeatherHumidity.text = parseFloat(humidity).toLocaleString() + ' %';
-        this._currentWeatherPressure.text = parseFloat(pressure).toLocaleString() + ' ' + pressure_unit;
-        this._currentWeatherSunrise.text = sunrise;
-        this._currentWeatherSunset.text = sunset;
-        this._currentWeatherBuild.text = lastBuild;
-
-        // Override wind units with our preference
+    formatWind: function(speed, direction) {
+        let unit = 'm/s';
         switch (this._wind_speed_units) {
             case WeatherWindSpeedUnits.MPH:
-                wind = (wind * WEATHER_CONV_MPS_IN_MPH).toFixed(this._decimal_places);
-                wind_unit = 'mph';
+                speed = (speed * OPENWEATHER_CONV_MPS_IN_MPH).toFixed(this._decimal_places);
+                unit = 'mph';
                 break;
 
             case WeatherWindSpeedUnits.KPH:
-                wind = (wind * WEATHER_CONV_MPS_IN_KPH).toFixed(this._decimal_places);
-                wind_unit = 'km/h';
+                speed = (speed * OPENWEATHER_CONV_MPS_IN_KPH).toFixed(this._decimal_places);
+                unit = 'km/h';
                 break;
 
             case WeatherWindSpeedUnits.MPS:
-                wind = wind.toFixed(this._decimal_places);
+                speed = speed.toFixed(this._decimal_places);
                 break;
 
             case WeatherWindSpeedUnits.KNOTS:
-                wind = (wind * WEATHER_CONV_MPS_IN_KNOTS).toFixed(this._decimal_places);
-                wind_unit = 'kn';
+                speed = (speed * OPENWEATHER_CONV_MPS_IN_KNOTS).toFixed(this._decimal_places);
+                unit = 'kn';
                 break;
 
             case WeatherWindSpeedUnits.FPS:
-                wind = (wind * WEATHER_CONV_MPS_IN_FPS).toFixed(this._decimal_places);
-                wind_unit = 'ft/s';
+                speed = (speed * OPENWEATHER_CONV_MPS_IN_FPS).toFixed(this._decimal_places);
+                unit = 'ft/s';
                 break;
 
             case WeatherWindSpeedUnits.BEAUFORT:
-                wind_unit = this.toBeaufort(wind, true);
-                wind = this.toBeaufort(wind);
-        }
-
-        if (!wind)
-            this._currentWeatherWind.text = '\u2013';
-        else if (wind === 0 || !wind_direction)
-            this._currentWeatherWind.text = parseFloat(wind).toLocaleString() + ' ' + wind_unit;
-        else // i.e. wind > 0 && wind_direction
-            this._currentWeatherWind.text = wind_direction + ' ' + parseFloat(wind).toLocaleString() + ' ' + wind_unit;
-
-        this.parseWeatherForecast();
-        this.recalcLayout();
-    },
+                speed = this.toBeaufort(speed);
+                unit = this.toBeaufort(speed, true);
+                break;
 
-    refreshWeatherCurrent: function() {
-        if (!this.extractId(this._city)) {
-            this.updateCities();
-            return;
         }
-        this.oldLocation = this.extractId(this._city);
-
-        let params = {
-            id: this.oldLocation,
-            units: 'metric'
-        };
-        if (this._appid)
-            params.APPID = this._appid;
-
-        this.load_json_async(WEATHER_URL_CURRENT, params, function(json) {
-            if (json && (Number(json.cod) == 200)) {
-
-                if (this.currentWeatherCache != json)
-                    this.currentWeatherCache = json;
 
-                this.rebuildSelectCityItem();
-
-                this.parseWeatherCurrent();
-            } else {
-                // we are connected, but get no (or no correct) data, so invalidate
-                // the shown data and reload after 10 minutes (recommendded by openweathermap.org)
-                this.rebuildCurrentWeatherUi();
-                this.reloadWeatherCurrent(600);
-            }
-        });
-        this.reloadWeatherCurrent(this._refresh_interval_current);
+        if (!speed)
+            return '\u2013';
+        else if (speed === 0 || !direction)
+            return parseFloat(speed).toLocaleString() + ' ' + unit;
+        else // i.e. speed > 0 && direction
+            return direction + ' ' + parseFloat(speed).toLocaleString() + ' ' + unit;
     },
 
     reloadWeatherCurrent: function(interval) {
         if (this._timeoutCurrent) {
             Mainloop.source_remove(this._timeoutCurrent);
+            this._timeoutCurrent = undefined;
         }
+        _timeCacheCurrentWeather = new Date();
         this._timeoutCurrent = Mainloop.timeout_add_seconds(interval, Lang.bind(this, function() {
-            this.currentWeatherCache = undefined;
-            if (this._connected)
-                this.parseWeatherCurrent();
-            else
-                this.rebuildCurrentWeatherUi();
+            // only invalidate cached data, if we can connect the weather-providers server
+            if (this._connected && !this._idle)
+                this.currentWeatherCache = undefined;
+            this.parseWeatherCurrent();
             return true;
         }));
     },
 
-    parseWeatherForecast: function() {
-        if (this.forecastWeatherCache === undefined) {
-            this.refreshWeatherForecast();
-            return;
-        }
-
-        let forecast = this.forecastWeatherCache;
-        let beginOfDay = new Date(new Date().setHours(0, 0, 0, 0));
-
-        // Refresh forecast
-        for (let i = 0; i < this._days_forecast; i++) {
-            let forecastUi = this._forecast[i];
-            let forecastData = forecast[i];
-            if (forecastData === undefined)
-                continue;
-
-            let t_low = forecastData.temp.min;
-            let t_high = forecastData.temp.max;
-
-            switch (this._units) {
-                case WeatherUnits.FAHRENHEIT:
-                    t_low = this.toFahrenheit(t_low);
-                    t_high = this.toFahrenheit(t_high);
-                    break;
-
-                case WeatherUnits.CELSIUS:
-                    t_low = t_low.toFixed(this._decimal_places);
-                    t_high = t_high.toFixed(this._decimal_places);
-                    break;
-
-                case WeatherUnits.KELVIN:
-                    t_low = this.toKelvin(t_low);
-                    t_high = this.toKelvin(t_high);
-                    break;
-
-                case WeatherUnits.RANKINE:
-                    t_low = this.toRankine(t_low);
-                    t_high = this.toRankine(t_high);
-                    break;
-
-                case WeatherUnits.REAUMUR:
-                    t_low = this.toReaumur(t_low);
-                    t_high = this.toReaumur(t_high);
-                    break;
-
-                case WeatherUnits.ROEMER:
-                    t_low = this.toRoemer(t_low);
-                    t_high = this.toRoemer(t_high);
-                    break;
-
-                case WeatherUnits.DELISLE:
-                    t_low = this.toDelisle(t_low);
-                    t_high = this.toDelisle(t_high);
-                    break;
-
-                case WeatherUnits.NEWTON:
-                    t_low = this.toNewton(t_low);
-                    t_high = this.toNewton(t_high);
-                    break;
-            }
-
-            let comment = forecastData.weather[0].description;
-            if (this._translate_condition)
-                comment = this.get_weather_condition(forecastData.weather[0].id);
-
-            let forecastDate = new Date(forecastData.dt * 1000);
-            let dayLeft = Math.floor((forecastDate.getTime() - beginOfDay.getTime()) / 86400000);
-
-            let date_string = _("Today");
-            if (dayLeft == 1)
-                date_string = _("Tomorrow");
-            else if (dayLeft > 1)
-                date_string = _("In %s days").replace("%s", dayLeft);
-            else if (dayLeft == -1)
-                date_string = _("Yesterday");
-            else if (dayLeft < -1)
-                date_string = _("%s days ago").replace("%s", -1 * dayLeft);
-
-            forecastUi.Day.text = date_string + ' (' + this.get_locale_day(forecastDate.getDay()) + ')\n' + forecastDate.toLocaleDateString();
-            forecastUi.Temperature.text = '\u2193 ' + parseFloat(t_low).toLocaleString() + ' ' + this.unit_to_unicode() + '    \u2191 ' + parseFloat(t_high).toLocaleString() + ' ' + this.unit_to_unicode();
-            forecastUi.Summary.text = comment;
-            forecastUi.Icon.icon_name = this.get_weather_icon_safely(forecastData.weather[0].id);
-        }
-    },
-
-    refreshWeatherForecast: function() {
-
-        if (!this.extractId(this._city)) {
-            this.updateCities();
-            return;
-        }
-
-        this.oldLocation = this.extractId(this._city);
-
-        let params = {
-            id: this.oldLocation,
-            units: 'metric',
-            cnt: '13'
-        };
-        if (this._appid)
-            params.APPID = this._appid;
-
-        this.load_json_async(WEATHER_URL_FORECAST, params, function(json) {
-            if (json && (Number(json.cod) == 200)) {
-                if (this.forecastWeatherCache != json.list)
-                    this.forecastWeatherCache = json.list;
-
-                this.parseWeatherForecast();
-            } else {
-                // we are connected, but get no (or no correct) data, so invalidate
-                // the shown data and reload after 10 minutes (recommendded by openweathermap.org)
-                this.rebuildFutureWeatherUi();
-                this.reloadWeatherForecast(600);
-            }
-        });
-        this.reloadWeatherForecast(this._refresh_interval_forecast);
-    },
-
     reloadWeatherForecast: function(interval) {
         if (this._timeoutForecast) {
             Mainloop.source_remove(this._timeoutForecast);
+            this._timeoutForecast = undefined;
         }
+        _timeCacheForecastWeather = new Date();
         this._timeoutForecast = Mainloop.timeout_add_seconds(interval, Lang.bind(this, function() {
-            this.forecastWeatherCache = undefined;
-            if (this._connected)
-                this.parseWeatherForecast();
-            else
-                this.rebuildFutureWeatherUi();
+            // only invalidate cached data, if we can connect the weather-providers server
+            if (this._connected && !this._idle)
+                this.forecastWeatherCache = undefined;
+            this.parseWeatherForecast();
             return true;
         }));
     },
@@ -1750,33 +1286,33 @@
     },
 
     rebuildCurrentWeatherUi: function() {
-        this._weatherInfo.text = _('Loading current weather ...');
-        this._weatherIcon.icon_name = 'view-refresh' + this.icon_type();
+        this._weatherInfo.text = (' ');
+        this._weatherIcon.icon_name = 'view-refresh' + this.getIconType();
 
         this.destroyCurrentWeather();
 
         // This will hold the icon for the current weather
         this._currentWeatherIcon = new St.Icon({
             icon_size: 72,
-            icon_name: 'view-refresh' + this.icon_type(),
-            style_class: 'openweather-current-icon'
+            icon_name: 'view-refresh' + this.getIconType(),
+            style_class: 'system-menu-action openweather-current-icon'
         });
 
         this._sunriseIcon = new St.Icon({
             icon_size: 15,
-            icon_name: 'weather-clear' + this.icon_type(),
+            icon_name: 'weather-clear' + this.getIconType(),
             style_class: 'openweather-sunrise-icon'
         });
 
         this._sunsetIcon = new St.Icon({
             icon_size: 15,
-            icon_name: 'weather-clear-night' + this.icon_type(),
+            icon_name: 'weather-clear-night' + this.getIconType(),
             style_class: 'openweather-sunset-icon'
         });
 
         this._buildIcon = new St.Icon({
             icon_size: 15,
-            icon_name: 'view-refresh' + this.icon_type(),
+            icon_name: 'view-refresh' + this.getIconType(),
             style_class: 'openweather-build-icon'
         });
 
@@ -1791,7 +1327,7 @@
 
         let bb = new St.BoxLayout({
             vertical: true,
-            style_class: 'openweather-current-summarybox'
+            style_class: 'system-menu-action openweather-current-summarybox'
         });
         bb.add_actor(this._currentWeatherLocation);
         bb.add_actor(this._currentWeatherSummary);
@@ -1819,7 +1355,7 @@
         bb.add_actor(ab);
 
         // Other labels
-        this._currentWeatherTemperature = new St.Label({
+        this._currentWeatherCloudiness = new St.Label({
             text: '...'
         });
         this._currentWeatherHumidity = new St.Label({
@@ -1837,11 +1373,11 @@
         });
         let rb_captions = new St.BoxLayout({
             vertical: true,
-            style_class: 'openweather-current-databox-captions'
+            style_class: 'popup-menu-item popup-status-menu-item openweather-current-databox-captions'
         });
         let rb_values = new St.BoxLayout({
             vertical: true,
-            style_class: 'openweather-current-databox-values'
+            style_class: 'system-menu-action openweather-current-databox-values'
         });
         rb.add_actor(rb_captions);
         rb.add_actor(rb_values);
@@ -1849,7 +1385,7 @@
         rb_captions.add_actor(new St.Label({
             text: _('Cloudiness:')
         }));
-        rb_values.add_actor(this._currentWeatherTemperature);
+        rb_values.add_actor(this._currentWeatherCloudiness);
         rb_captions.add_actor(new St.Label({
             text: _('Humidity:')
         }));
@@ -1881,7 +1417,7 @@
         this._forecastScrollBox.hscroll.adjustment.value += delta;
     },
 
-    rebuildFutureWeatherUi: function() {
+    rebuildFutureWeatherUi: function(cnt) {
         this.destroyFutureWeather();
 
         this._forecast = [];
@@ -1919,22 +1455,25 @@
 
         this._futureWeather.set_child(this._forecastScrollBox);
 
-        for (let i = 0; i < this._days_forecast; i++) {
+        if (cnt === undefined)
+            cnt = this._days_forecast;
+        for (let i = 0; i < cnt; i++) {
             let forecastWeather = {};
 
             forecastWeather.Icon = new St.Icon({
                 icon_size: 48,
-                icon_name: 'view-refresh' + this.icon_type(),
-                style_class: 'openweather-forecast-icon'
+                icon_name: 'view-refresh' + this.getIconType(),
+                style_class: 'system-menu-action openweather-forecast-icon'
             });
             forecastWeather.Day = new St.Label({
-                style_class: 'openweather-forecast-day'
+                style_class: 'popup-menu-item popup-status-menu-item openweather-forecast-day'
             });
             forecastWeather.Summary = new St.Label({
-                style_class: 'openweather-forecast-summary'
+                style_class: 'system-menu-action  openweather-forecast-summary'
             });
+            forecastWeather.Summary.clutter_text.line_wrap = true;
             forecastWeather.Temperature = new St.Label({
-                style_class: 'openweather-forecast-temperature'
+                style_class: 'system-menu-action  openweather-forecast-temperature'
             });
 
             let by = new St.BoxLayout({
@@ -1942,7 +1481,8 @@
                 style_class: 'openweather-forecast-databox'
             });
             by.add_actor(forecastWeather.Day);
-            by.add_actor(forecastWeather.Summary);
+            if (this._comment_in_forecast)
+                by.add_actor(forecastWeather.Summary);
             by.add_actor(forecastWeather.Temperature);
 
             let bb = new St.BoxLayout({
diff -Nru --exclude '*.pot' --exclude '*.po' gnome-shell-extension-weather-0~20140924.git7e28508/src/forecast_io.js gnome-shell-extension-weather-0~20151125.gitccaa1eb/src/forecast_io.js
--- gnome-shell-extension-weather-0~20140924.git7e28508/src/forecast_io.js	1970-01-01 01:00:00.000000000 +0100
+++ gnome-shell-extension-weather-0~20151125.gitccaa1eb/src/forecast_io.js	2015-12-09 21:55:47.000000000 +0100
@@ -0,0 +1,284 @@
+/* jshint esnext:true */
+/*
+ *
+ *  Weather extension for GNOME Shell
+ *  - Displays a small weather information on the top panel.
+ *  - On click, gives a popup with details about the weather.
+ *
+ * Copyright (C) 2011 - 2013
+ *     ecyrbe <ecyrbe+spam@gmail.com>,
+ *     Timur Kristof <venemo@msn.com>,
+ *     Elad Alfassa <elad@fedoraproject.org>,
+ *     Simon Legner <Simon.Legner@gmail.com>,
+ *     Christian METZLER <neroth@xeked.com>,
+ *     Mark Benjamin weather.gnome.Markie1@dfgh.net,
+ *     Mattia Meneguzzo odysseus@fedoraproject.org,
+ *     Meng Zhuo <mengzhuo1203+spam@gmail.com>,
+ *     Jens Lody <jens@jenslody.de>
+ * Copyright (C) 2014 -2015
+ *     Jens Lody <jens@jenslody.de>,
+ *
+ *
+ * This file is part of gnome-shell-extension-openweather.
+ *
+ * gnome-shell-extension-openweather 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, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * gnome-shell-extension-openweather 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 gnome-shell-extension-openweather.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+const Gettext = imports.gettext.domain('gnome-shell-extension-openweather');
+const _ = Gettext.gettext;
+const ngettext = Gettext.ngettext;
+
+
+const OPENWEATHER_URL_HOST = 'api.forecast.io';
+const OPENWEATHER_URL_BASE = 'https://' + OPENWEATHER_URL_HOST + '/forecast/';
+
+function getWeatherIcon(icon) {
+    //    clear-day             weather-clear-day
+    //    clear-night           weather-clear-night
+    //    rain                  weather-showers
+    //    snow                  weather-snow
+    //    sleet                 weather-snow
+    //    wind                  weather-storm
+    //    fog                   weather-fog
+    //    cloudy                weather-overcast
+    //    partly-cloudy-day     weather-few-clouds
+    //    partly-cloudy-night   weather-few-clouds-night
+    let iconname = ['weather-severe-alert'];
+    switch (icon) {
+        case 'wind':
+            iconname = ['weather-storm'];
+            break;
+        case 'rain':
+            iconname = ['weather-showers-scattered', 'weather-showers'];
+            break;
+        case 'sleet':
+        case 'snow':
+            iconname = ['weather-snow'];
+            break;
+        case 'fog':
+            iconname = ['weather-fog'];
+            break;
+        case 'clear-day': //sky is clear
+            iconname = ['weather-clear'];
+            break;
+        case 'clear-night': //sky is clear
+            iconname = ['weather-clear-night'];
+            break;
+        case 'partly-cloudy-day':
+            iconname = ['weather-few-clouds'];
+            break;
+        case 'partly-cloudy-night':
+            iconname = ['weather-few-clouds-night'];
+            break;
+        case 'cloudy':
+            iconname = ['weather-overcast'];
+            break;
+    }
+    for (let i = 0; i < iconname.length; i++) {
+        if (this.hasIcon(iconname[i]))
+            return iconname[i] + this.getIconType();
+    }
+    return 'weather-severe-alert' + this.getIconType();
+}
+
+function parseWeatherCurrent() {
+    if (this.currentWeatherCache === undefined) {
+        // this is a reentrency guard, in this times set for both caches,
+        // because they get updated with one call to forecast.io
+        this.currentWeatherCache = "in refresh";
+        // but do it only if the cache has been cleared, otherwise we would
+        // overwrite possibly valid data, that can be kept if the update fails
+        // for some reason
+        if (this.forecastWeatherCache === undefined)
+            this.forecastWeatherCache = "in refresh";
+        this.refreshWeatherCurrent();
+        return;
+    }
+
+    if ((this.forecastWeatherCache == "in refresh") ||
+        (this.currentWeatherCache == "in refresh"))
+        return;
+
+    this.checkPositionInPanel();
+
+    let json = this.currentWeatherCache;
+
+    this.owmCityId = 0;
+    // Refresh current weather
+    let location = this.extractLocation(this._city);
+
+    let comment = json.summary;
+
+    let temperature = this.formatTemperature(json.temperature);
+
+    let now = new Date();
+
+    let iconname = this.getWeatherIcon(json.icon);
+
+    if (this.lastBuildId === undefined)
+        this.lastBuildId = 0;
+
+    if (this.lastBuildDate === undefined)
+        this.lastBuildDate = 0;
+
+    if (this.lastBuildId != json.time || !this.lastBuildDate) {
+        this.lastBuildId = json.time;
+        this.lastBuildDate = new Date(this.lastBuildId * 1000);
+    }
+
+    let lastBuild = '-';
+
+    if (this._clockFormat == "24h")
+        lastBuild = this.lastBuildDate.toLocaleFormat("%R");
+    else
+        lastBuild = this.lastBuildDate.toLocaleFormat("%I:%M %p");
+
+    let beginOfDay = new Date(new Date().setHours(0, 0, 0, 0));
+    let d = Math.floor((this.lastBuildDate.getTime() - beginOfDay.getTime()) / 86400000);
+    if (d < 0) {
+        lastBuild = _("Yesterday");
+        if (d < -1) {
+            d *= -1;
+            lastBuild = ngettext("%d day ago", "%d days ago", d).format(d);
+        }
+    }
+
+    this._currentWeatherIcon.icon_name = this._weatherIcon.icon_name = iconname;
+
+    let weatherInfoC = "";
+    let weatherInfoT = "";
+    if (this._comment_in_panel)
+        weatherInfoC = comment;
+
+    if (this._text_in_panel)
+        weatherInfoT = temperature;
+
+    this._weatherInfo.text = weatherInfoC + ((weatherInfoC && weatherInfoT) ? ", " : "") + weatherInfoT;
+
+    this._currentWeatherSummary.text = comment + ", " + temperature;
+    this._currentWeatherLocation.text = location;
+    this._currentWeatherCloudiness.text = parseInt(json.cloudCover * 100) + ' %';
+    this._currentWeatherHumidity.text = parseInt(json.humidity * 100) + ' %';
+    this._currentWeatherPressure.text = this.formatPressure(json.pressure);
+
+    this._currentWeatherBuild.text = lastBuild;
+
+    this._currentWeatherWind.text = this.formatWind(json.windSpeed, this.getWindDirection(json.windBearing));
+
+    this.parseWeatherForecast();
+    this.recalcLayout();
+}
+
+function refreshWeatherCurrent() {
+    this.oldLocation = this.extractCoord(this._city);
+
+    let params = {
+        exclude: 'minutely,hourly,alerts,flags',
+        lang: this.fc_locale,
+        units: 'si'
+    };
+    let url = OPENWEATHER_URL_BASE + this._appid_fc + '/' + this.oldLocation;
+    this.load_json_async(url, params, function(json) {
+        if (json && json.currently) {
+
+            if (this.currentWeatherCache != json.currently)
+                this.currentWeatherCache = json.currently;
+
+            if (json.daily && json.daily.data) {
+                if (this.forecastWeatherCache != json.daily.data)
+                    this.forecastWeatherCache = json.daily.data;
+            }
+
+            this.rebuildSelectCityItem();
+
+            this.parseWeatherCurrent();
+        } else {
+            this.reloadWeatherCurrent(600);
+        }
+    });
+    this.reloadWeatherCurrent(this._refresh_interval_current);
+}
+
+function parseWeatherForecast() {
+    if ((this.forecastWeatherCache == "in refresh") ||
+        (this.currentWeatherCache == "in refresh"))
+        return;
+
+    if (this.forecastWeatherCache === undefined) {
+        // this is a reentrency guard, in this times set for both caches,
+        // because they get updated with one call to forecast.io
+        this.forecastWeatherCache = "in refresh";
+        // but do it only if the cache has been cleared, otherwise we would
+        // overwrite possibly valid data, that can be kept if the update fails
+        // for some reason
+        if (this.currentWeatherCache === undefined)
+            this.currentWeatherCache = "in refresh";
+        this.refreshWeatherCurrent();
+        return;
+    }
+
+    let forecast = this.forecastWeatherCache;
+    let beginOfDay = new Date(new Date().setHours(0, 0, 0, 0));
+    let cnt = Math.min(this._days_forecast, forecast.length);
+    if (cnt != this._days_forecast)
+        this.rebuildFutureWeatherUi(cnt);
+
+    // Refresh forecast
+    for (let i = 0; i < cnt; i++) {
+        let forecastUi = this._forecast[i];
+        let forecastData = forecast[i];
+        if (forecastData === undefined)
+            continue;
+
+        let t_low = this.formatTemperature(forecastData.temperatureMin);
+        let t_high = this.formatTemperature(forecastData.temperatureMax);
+
+
+        let comment = forecastData.summary;
+        let forecastDate = new Date(forecastData.time * 1000);
+        let dayLeft = Math.floor((forecastDate.getTime() - beginOfDay.getTime()) / 86400000);
+
+        let date_string = _("Today");
+
+        let sunrise = new Date(forecastData.sunriseTime * 1000);
+        let sunset = new Date(forecastData.sunsetTime * 1000);
+
+        if (dayLeft === 0) {
+            if (this._clockFormat == "24h") {
+                sunrise = sunrise.toLocaleFormat("%R");
+                sunset = sunset.toLocaleFormat("%R");
+            } else {
+                sunrise = sunrise.toLocaleFormat("%I:%M %p");
+                sunset = sunset.toLocaleFormat("%I:%M %p");
+            }
+            this._currentWeatherSunrise.text = sunrise;
+            this._currentWeatherSunset.text = sunset;
+        } else if (dayLeft == 1)
+            date_string = _("Tomorrow");
+        else if (dayLeft > 1)
+            date_string = ngettext("In %d day", "In %d days", dayLeft).format(dayLeft);
+        else if (dayLeft == -1)
+            date_string = _("Yesterday");
+        else if (dayLeft < -1) {
+            dayLeft *= -1;
+            date_string = ngettext("%d day ago", "%d days ago", dayLeft).format(dayLeft);
+        }
+
+        forecastUi.Day.text = date_string + ' (' + this.getLocaleDay(forecastDate.getDay()) + ')\n' + forecastDate.toLocaleDateString();
+        forecastUi.Temperature.text = '\u2193 ' + t_low + '    \u2191 ' + t_high;
+        forecastUi.Summary.text = comment;
+        forecastUi.Icon.icon_name = this.getWeatherIcon(forecastData.icon);
+    }
+}
diff -Nru --exclude '*.pot' --exclude '*.po' gnome-shell-extension-weather-0~20140924.git7e28508/src/Makefile.am gnome-shell-extension-weather-0~20151125.gitccaa1eb/src/Makefile.am
--- gnome-shell-extension-weather-0~20140924.git7e28508/src/Makefile.am	2014-09-24 20:18:58.000000000 +0200
+++ gnome-shell-extension-weather-0~20151125.gitccaa1eb/src/Makefile.am	2015-12-09 21:55:47.000000000 +0100
@@ -5,6 +5,6 @@
 
 extensiondir = $(topextensiondir)/$(uuid)
 
-dist_extension_DATA = extension.js convenience.js prefs.js
+dist_extension_DATA = extension.js forecast_io.js openweathermap_org.js convenience.js prefs.js
 
 nodist_extension_DATA = $(EXTRA_EXTENSION)
diff -Nru --exclude '*.pot' --exclude '*.po' gnome-shell-extension-weather-0~20140924.git7e28508/src/openweathermap_org.js gnome-shell-extension-weather-0~20151125.gitccaa1eb/src/openweathermap_org.js
--- gnome-shell-extension-weather-0~20140924.git7e28508/src/openweathermap_org.js	1970-01-01 01:00:00.000000000 +0100
+++ gnome-shell-extension-weather-0~20151125.gitccaa1eb/src/openweathermap_org.js	2015-12-09 21:55:47.000000000 +0100
@@ -0,0 +1,495 @@
+/* jshint esnext:true */
+/*
+ *
+ *  Weather extension for GNOME Shell
+ *  - Displays a small weather information on the top panel.
+ *  - On click, gives a popup with details about the weather.
+ *
+ * Copyright (C) 2011 - 2013
+ *     ecyrbe <ecyrbe+spam@gmail.com>,
+ *     Timur Kristof <venemo@msn.com>,
+ *     Elad Alfassa <elad@fedoraproject.org>,
+ *     Simon Legner <Simon.Legner@gmail.com>,
+ *     Christian METZLER <neroth@xeked.com>,
+ *     Mark Benjamin weather.gnome.Markie1@dfgh.net,
+ *     Mattia Meneguzzo odysseus@fedoraproject.org,
+ *     Meng Zhuo <mengzhuo1203+spam@gmail.com>,
+ *     Jens Lody <jens@jenslody.de>
+ * Copyright (C) 2014 -2015
+ *     Jens Lody <jens@jenslody.de>,
+ *
+ *
+ * This file is part of gnome-shell-extension-openweather.
+ *
+ * gnome-shell-extension-openweather 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, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * gnome-shell-extension-openweather 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 gnome-shell-extension-openweather.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+
+const ExtensionUtils = imports.misc.extensionUtils;
+const Me = ExtensionUtils.getCurrentExtension();
+const OpenweathermapOrg = Me.imports.openweathermap_org;
+const Gettext = imports.gettext.domain('gnome-shell-extension-openweather');
+const _ = Gettext.gettext;
+const ngettext = Gettext.ngettext;
+
+const OPENWEATHER_URL_HOST = 'api.openweathermap.org';
+const OPENWEATHER_URL_BASE = 'http://' + OPENWEATHER_URL_HOST + '/data/2.5/';
+const OPENWEATHER_URL_CURRENT = OPENWEATHER_URL_BASE + 'weather';
+const OPENWEATHER_URL_FORECAST = OPENWEATHER_URL_BASE + 'forecast/daily';
+
+function getWeatherIcon(code, night) {
+
+    let iconname = ['weather-severe-alert'];
+    // see http://bugs.openweathermap.org/projects/api/wiki/Weather_Condition_Codes
+    // fallback icons are: weather-clear-night weather-clear weather-few-clouds-night weather-few-clouds weather-fog weather-overcast weather-severe-alert weather-showers weather-showers-scattered weather-snow weather-storm
+    /*
+weather-clouds-night.png
+weather-freezing-rain.png
+weather-hail.png
+weather-many-clouds.png
+weather-showers-day.png
+weather-showers-night.png
+weather-showers-scattered-day.png
+weather-showers-scattered-night.png
+weather-snow-rain.png
+weather-snow-scattered-day.png
+weather-snow-scattered-night.png
+weather-snow-scattered.png
+weather-storm-day.png
+weather-storm-night.png
+
+weather-severe-alert-symbolic.svg
+
+
+weather-clear-night.png = weather-clear-night-symbolic.svg
+weather-clear.png = weather-clear-symbolic.svg
+weather-clouds.png = weather-overcast-symbolic.svg
+weather-few-clouds-night.png = weather-few-clouds-night-symbolic.svg
+weather-few-clouds.png = weather-few-clouds-symbolic.svg
+weather-mist.png = weather-fog-symbolic.svg
+weather-showers-scattered.png = weather-showers-scattered-symbolic.svg
+weather-showers.png = weather-showers-symbolic.svg
+weather-snow.png = weather-snow-symbolic.svg
+weather-storm.png = weather-storm-symbolic.svg
+
+*/
+    switch (parseInt(code, 10)) {
+        case 200: //thunderstorm with light rain
+        case 201: //thunderstorm with rain
+        case 202: //thunderstorm with heavy rain
+        case 210: //light thunderstorm
+        case 211: //thunderstorm
+        case 212: //heavy thunderstorm
+        case 221: //ragged thunderstorm
+        case 230: //thunderstorm with light drizzle
+        case 231: //thunderstorm with drizzle
+        case 232: //thunderstorm with heavy drizzle
+            iconname = ['weather-storm'];
+            break;
+        case 300: //light intensity drizzle
+        case 301: //drizzle
+        case 302: //heavy intensity drizzle
+        case 310: //light intensity drizzle rain
+        case 311: //drizzle rain
+        case 312: //heavy intensity drizzle rain
+        case 313: //shower rain and drizzle
+        case 314: //heavy shower rain and drizzle
+        case 321: //shower drizzle
+            iconname = ['weather-showers'];
+            break;
+        case 500: //light rain
+        case 501: //moderate rain
+        case 502: //heavy intensity rain
+        case 503: //very heavy rain
+        case 504: //extreme rain
+            iconname = ['weather-showers-scattered', 'weather-showers'];
+            break;
+        case 511: //freezing rain
+            iconname = ['weather-freezing-rain', 'weather-showers'];
+            break;
+        case 520: //light intensity shower rain
+        case 521: //shower rain
+        case 522: //heavy intensity shower rain
+        case 531: //ragged shower rain
+            iconname = ['weather-showers'];
+            break;
+        case 600: //light snow
+        case 601: //snow
+        case 602: //heavy snow
+        case 611: //sleet
+        case 612: //shower sleet
+        case 615: //light rain and snow
+        case 616: //rain and snow
+        case 620: //light shower snow
+        case 621: //shower snow
+        case 622: //heavy shower snow
+            iconname = ['weather-snow'];
+            break;
+        case 701: //mist
+        case 711: //smoke
+        case 721: //haze
+        case 741: //Fog
+            iconname = ['weather-fog'];
+            break;
+        case 731: //Sand/Dust Whirls
+        case 751: //sand
+        case 761: //dust
+        case 762: //VOLCANIC ASH
+        case 771: //SQUALLS
+        case 781: //TORNADO
+            iconname = ['weather-severe-alert'];
+            break;
+        case 800: //sky is clear
+            iconname = ['weather-clear'];
+            break;
+        case 801: //few clouds
+        case 802: //scattered clouds
+            iconname = ['weather-few-clouds'];
+            break;
+        case 803: //broken clouds
+            iconname = ['weather-many-clouds', 'weather-overcast'];
+            break;
+        case 804: //overcast clouds
+            iconname = ['weather-overcast'];
+            break;
+    }
+
+    for (let i = 0; i < iconname.length; i++) {
+        if (night && this.hasIcon(iconname[i] + '-night'))
+            return iconname[i] + '-night' + this.getIconType();
+        if (this.hasIcon(iconname[i]))
+            return iconname[i] + this.getIconType();
+    }
+    return 'weather-severe-alert' + this.getIconType();
+}
+
+function getWeatherCondition(code) {
+    switch (parseInt(code, 10)) {
+        case 200: //thunderstorm with light rain
+            return _('thunderstorm with light rain');
+        case 201: //thunderstorm with rain
+            return _('thunderstorm with rain');
+        case 202: //thunderstorm with heavy rain
+            return _('thunderstorm with heavy rain');
+        case 210: //light thunderstorm
+            return _('light thunderstorm');
+        case 211: //thunderstorm
+            return _('thunderstorm');
+        case 212: //heavy thunderstorm
+            return _('heavy thunderstorm');
+        case 221: //ragged thunderstorm
+            return _('ragged thunderstorm');
+        case 230: //thunderstorm with light drizzle
+            return _('thunderstorm with light drizzle');
+        case 231: //thunderstorm with drizzle
+            return _('thunderstorm with drizzle');
+        case 232: //thunderstorm with heavy drizzle
+            return _('thunderstorm with heavy drizzle');
+        case 300: //light intensity drizzle
+            return _('light intensity drizzle');
+        case 301: //drizzle
+            return _('drizzle');
+        case 302: //heavy intensity drizzle
+            return _('heavy intensity drizzle');
+        case 310: //light intensity drizzle rain
+            return _('light intensity drizzle rain');
+        case 311: //drizzle rain
+            return _('drizzle rain');
+        case 312: //heavy intensity drizzle rain
+            return _('heavy intensity drizzle rain');
+        case 313: //shower rain and drizzle
+            return _('shower rain and drizzle');
+        case 314: //heavy shower rain and drizzle
+            return _('heavy shower rain and drizzle');
+        case 321: //shower drizzle
+            return _('shower drizzle');
+        case 500: //light rain
+            return _('light rain');
+        case 501: //moderate rain
+            return _('moderate rain');
+        case 502: //heavy intensity rain
+            return _('heavy intensity rain');
+        case 503: //very heavy rain
+            return _('very heavy rain');
+        case 504: //extreme rain
+            return _('extreme rain');
+        case 511: //freezing rain
+            return _('freezing rain');
+        case 520: //light intensity shower rain
+            return _('light intensity shower rain');
+        case 521: //shower rain
+            return _('shower rain');
+        case 522: //heavy intensity shower rain
+            return _('heavy intensity shower rain');
+        case 531: //ragged shower rain
+            return _('ragged shower rain');
+        case 600: //light snow
+            return _('light snow');
+        case 601: //snow
+            return _('snow');
+        case 602: //heavy snow
+            return _('heavy snow');
+        case 611: //sleet
+            return _('sleet');
+        case 612: //shower sleet
+            return _('shower sleet');
+        case 615: //light rain and snow
+            return _('light rain and snow');
+        case 616: //rain and snow
+            return _('rain and snow');
+        case 620: //light shower snow
+            return _('light shower snow');
+        case 621: //shower snow
+            return _('shower snow');
+        case 622: //heavy shower snow
+            return _('heavy shower snow');
+        case 701: //mist
+            return _('mist');
+        case 711: //smoke
+            return _('smoke');
+        case 721: //haze
+            return _('haze');
+        case 731: //Sand/Dust Whirls
+            return _('Sand/Dust Whirls');
+        case 741: //Fog
+            return _('Fog');
+        case 751: //sand
+            return _('sand');
+        case 761: //dust
+            return _('dust');
+        case 762: //VOLCANIC ASH
+            return _('VOLCANIC ASH');
+        case 771: //SQUALLS
+            return _('SQUALLS');
+        case 781: //TORNADO
+            return _('TORNADO');
+        case 800: //sky is clear
+            return _('sky is clear');
+        case 801: //few clouds
+            return _('few clouds');
+        case 802: //scattered clouds
+            return _('scattered clouds');
+        case 803: //broken clouds
+            return _('broken clouds');
+        case 804: //overcast clouds
+            return _('overcast clouds');
+        default:
+            return _('Not available');
+    }
+}
+
+function parseWeatherCurrent() {
+    if (this.currentWeatherCache === undefined) {
+        // this is a reentrency guard
+        this.currentWeatherCache = "in refresh";
+        this.refreshWeatherCurrent();
+        return;
+    }
+
+    if (this.currentWeatherCache == "in refresh")
+        return;
+
+    this.checkPositionInPanel();
+
+    let json = this.currentWeatherCache;
+
+    this.owmCityId = json.id;
+    // Refresh current weather
+    let location = this.extractLocation(this._city);
+
+    let comment = json.weather[0].description;
+    if (this._translate_condition)
+        comment = OpenweathermapOrg.getWeatherCondition(json.weather[0].id);
+
+    let temperature = this.formatTemperature(json.main.temp);
+    let sunrise = new Date(json.sys.sunrise * 1000);
+    let sunset = new Date(json.sys.sunset * 1000);
+    let now = new Date();
+
+    let iconname = this.getWeatherIcon(json.weather[0].id, now < sunrise || now > sunset);
+
+    if (this.lastBuildId === undefined)
+        this.lastBuildId = 0;
+
+    if (this.lastBuildDate === undefined)
+        this.lastBuildDate = 0;
+
+    if (this.lastBuildId != json.dt || !this.lastBuildDate) {
+        this.lastBuildId = json.dt;
+        this.lastBuildDate = new Date(this.lastBuildId * 1000);
+    }
+
+    let lastBuild = '-';
+
+    if (this._clockFormat == "24h") {
+        sunrise = sunrise.toLocaleFormat("%R");
+        sunset = sunset.toLocaleFormat("%R");
+        lastBuild = this.lastBuildDate.toLocaleFormat("%R");
+    } else {
+        sunrise = sunrise.toLocaleFormat("%I:%M %p");
+        sunset = sunset.toLocaleFormat("%I:%M %p");
+        lastBuild = this.lastBuildDate.toLocaleFormat("%I:%M %p");
+    }
+
+    let beginOfDay = new Date(new Date().setHours(0, 0, 0, 0));
+    let d = Math.floor((this.lastBuildDate.getTime() - beginOfDay.getTime()) / 86400000);
+    if (d < 0) {
+        lastBuild = _("Yesterday");
+        if (d < -1)
+            lastBuild = ngettext("%d day ago", "%d days ago", -1 * d).format(-1 * d);
+    }
+
+    this._currentWeatherIcon.icon_name = this._weatherIcon.icon_name = iconname;
+
+    let weatherInfoC = "";
+    let weatherInfoT = "";
+
+    if (this._comment_in_panel)
+        weatherInfoC = comment;
+
+    if (this._text_in_panel)
+        weatherInfoT = temperature;
+
+    this._weatherInfo.text = weatherInfoC + ((weatherInfoC && weatherInfoT) ? ", " : "") + weatherInfoT;
+
+    this._currentWeatherSummary.text = comment + ", " + temperature;
+    this._currentWeatherLocation.text = location;
+    this._currentWeatherCloudiness.text = json.clouds.all + ' %';
+    this._currentWeatherHumidity.text = json.main.humidity + ' %';
+    this._currentWeatherPressure.text = this.formatPressure(json.main.pressure);
+    this._currentWeatherSunrise.text = sunrise;
+    this._currentWeatherSunset.text = sunset;
+    this._currentWeatherBuild.text = lastBuild;
+    this._currentWeatherWind.text = this.formatWind(json.wind.speed, this.getWindDirection(json.wind.deg));
+
+    this.parseWeatherForecast();
+    this.recalcLayout();
+}
+
+function refreshWeatherCurrent() {
+    this.oldLocation = this.extractCoord(this._city);
+
+    if (this.oldLocation.search(",") == -1)
+        return;
+
+    let params = {
+        lat: this.oldLocation.split(",")[0],
+        lon: this.oldLocation.split(",")[1],
+        units: 'metric'
+    };
+    if (this._appid)
+        params.APPID = this._appid;
+
+    this.load_json_async(OPENWEATHER_URL_CURRENT, params, function(json) {
+        if (json && (Number(json.cod) == 200)) {
+
+            if (this.currentWeatherCache != json)
+                this.currentWeatherCache = json;
+
+            this.rebuildSelectCityItem();
+
+            this.parseWeatherCurrent();
+        } else {
+            // we are connected, but get no (or no correct) data, so invalidate
+            // the shown data and reload after 10 minutes (recommendded by openweathermap.org)
+            this.rebuildCurrentWeatherUi();
+            this.reloadWeatherCurrent(600);
+        }
+    });
+    this.reloadWeatherCurrent(this._refresh_interval_current);
+}
+
+function parseWeatherForecast() {
+    if (this.forecastWeatherCache === undefined) {
+        // this is a reentrency guard
+        this.forecastWeatherCache = "in refresh";
+        this.refreshWeatherForecast();
+        return;
+    }
+
+    if (this.forecastWeatherCache == "in refresh")
+        return;
+
+    let forecast = this.forecastWeatherCache;
+    let beginOfDay = new Date(new Date().setHours(0, 0, 0, 0));
+
+    // Refresh forecast
+    for (let i = 0; i < this._days_forecast; i++) {
+        let forecastUi = this._forecast[i];
+        let forecastData = forecast[i];
+        if (forecastData === undefined)
+            continue;
+
+        let t_low = this.formatTemperature(forecastData.temp.min);
+        let t_high = this.formatTemperature(forecastData.temp.max);
+
+        let comment = forecastData.weather[0].description;
+        if (this._translate_condition)
+            comment = OpenweathermapOrg.getWeatherCondition(forecastData.weather[0].id);
+
+        let forecastDate = new Date(forecastData.dt * 1000);
+        let dayLeft = Math.floor((forecastDate.getTime() - beginOfDay.getTime()) / 86400000);
+
+        let date_string = _("Today");
+        if (dayLeft == 1)
+            date_string = _("Tomorrow");
+        else if (dayLeft > 1)
+            date_string = ngettext("In %d day", "In %d days", dayLeft).format(dayLeft);
+        else if (dayLeft == -1)
+            date_string = _("Yesterday");
+        else if (dayLeft < -1)
+            date_string = ngettext("%d day ago", "%d days ago", -1 * dayLeft).format(-1 * dayLeft);
+
+        forecastUi.Day.text = date_string + ' (' + this.getLocaleDay(forecastDate.getDay()) + ')\n' + forecastDate.toLocaleDateString();
+        forecastUi.Temperature.text = '\u2193 ' + t_low + '    \u2191 ' + t_high;
+        forecastUi.Summary.text = comment;
+        forecastUi.Icon.icon_name = this.getWeatherIcon(forecastData.weather[0].id);
+    }
+}
+
+function refreshWeatherForecast() {
+
+
+    this.oldLocation = this.extractCoord(this._city);
+
+    if (this.oldLocation.search(",") == -1)
+        return;
+
+    let params = {
+        lat: this.oldLocation.split(",")[0],
+        lon: this.oldLocation.split(",")[1],
+        units: 'metric',
+        cnt: '13'
+    };
+    if (this._appid)
+        params.APPID = this._appid;
+
+    this.load_json_async(OPENWEATHER_URL_FORECAST, params, function(json) {
+        if (json && (Number(json.cod) == 200)) {
+            if (this.forecastWeatherCache != json.list) {
+                this.owmCityId = json.city.id;
+                this.forecastWeatherCache = json.list;
+            }
+
+            this.parseWeatherForecast();
+        } else {
+            // we are connected, but get no (or no correct) data, so invalidate
+            // the shown data and reload after 10 minutes (recommendded by openweathermap.org)
+            this.rebuildFutureWeatherUi();
+            this.reloadWeatherForecast(600);
+        }
+    });
+    this.reloadWeatherForecast(this._refresh_interval_forecast);
+}
diff -Nru --exclude '*.pot' --exclude '*.po' gnome-shell-extension-weather-0~20140924.git7e28508/src/prefs.js gnome-shell-extension-weather-0~20151125.gitccaa1eb/src/prefs.js
--- gnome-shell-extension-weather-0~20140924.git7e28508/src/prefs.js	2014-09-24 20:18:58.000000000 +0200
+++ gnome-shell-extension-weather-0~20151125.gitccaa1eb/src/prefs.js	2015-12-09 21:55:47.000000000 +0100
@@ -4,10 +4,12 @@
  *  Weather extension for GNOME Shell preferences
  *  - Creates a widget to set the preferences of the weather extension
  *
- * Copyright (C) 2012 - 2014
+ * Copyright (C) 2012 - 2013
  *     Canek Peláez <canek@ciencias.unam.mx>,
  *     Christian METZLER <neroth@xeked.com>,
  *     Jens Lody <jens@jenslody.de>,
+ * Copyright (C) 2014 -2015
+ *     Jens Lody <jens@jenslody.de>,
  *
  * This file is part of gnome-shell-extension-openweather.
  *
@@ -28,15 +30,13 @@
  *
  */
 const Gtk = imports.gi.Gtk;
-const Gdk = imports.gi.Gdk;
 const GObject = imports.gi.GObject;
-const GtkBuilder = Gtk.Builder;
-const Gio = imports.gi.Gio;
 const Gettext = imports.gettext.domain('gnome-shell-extension-openweather');
 const _ = Gettext.gettext;
 const Soup = imports.gi.Soup;
 
 const Lang = imports.lang;
+const Mainloop = imports.mainloop;
 const ExtensionUtils = imports.misc.extensionUtils;
 const Me = ExtensionUtils.getCurrentExtension();
 const Config = imports.misc.config;
@@ -44,35 +44,61 @@
 
 const EXTENSIONDIR = Me.dir.get_path();
 
-const WEATHER_SETTINGS_SCHEMA = 'org.gnome.shell.extensions.openweather';
-const WEATHER_UNIT_KEY = 'unit';
-const WEATHER_PRESSURE_UNIT_KEY = 'pressure-unit';
-const WEATHER_WIND_SPEED_UNIT_KEY = 'wind-speed-unit';
-const WEATHER_WIND_DIRECTION_KEY = 'wind-direction';
-const WEATHER_CITY_KEY = 'city';
-const WEATHER_ACTUAL_CITY_KEY = 'actual-city';
-const WEATHER_TRANSLATE_CONDITION_KEY = 'translate-condition';
-const WEATHER_USE_SYMBOLIC_ICONS_KEY = 'use-symbolic-icons';
-const WEATHER_USE_TEXT_ON_BUTTONS_KEY = 'use-text-on-buttons';
-const WEATHER_SHOW_TEXT_IN_PANEL_KEY = 'show-text-in-panel';
-const WEATHER_POSITION_IN_PANEL_KEY = 'position-in-panel';
-const WEATHER_SHOW_COMMENT_IN_PANEL_KEY = 'show-comment-in-panel';
-const WEATHER_REFRESH_INTERVAL_CURRENT = 'refresh-interval-current';
-const WEATHER_REFRESH_INTERVAL_FORECAST = 'refresh-interval-forecast';
-const WEATHER_CENTER_FORECAST_KEY = 'center-forecast';
-const WEATHER_DAYS_FORECAST = 'days-forecast';
-const WEATHER_DECIMAL_PLACES = 'decimal-places';
-const WEATHER_OWM_API_KEY = 'appid';
+const OPENWEATHER_SETTINGS_SCHEMA = 'org.gnome.shell.extensions.openweather';
+const OPENWEATHER_PROVIDER_KEY = 'weather-provider';
+const OPENWEATHER_GEOLOCATION_PROVIDER_KEY = 'geolocation-provider';
+const OPENWEATHER_UNIT_KEY = 'unit';
+const OPENWEATHER_PRESSURE_UNIT_KEY = 'pressure-unit';
+const OPENWEATHER_WIND_SPEED_UNIT_KEY = 'wind-speed-unit';
+const OPENWEATHER_WIND_DIRECTION_KEY = 'wind-direction';
+const OPENWEATHER_CITY_KEY = 'city';
+const OPENWEATHER_ACTUAL_CITY_KEY = 'actual-city';
+const OPENWEATHER_TRANSLATE_CONDITION_KEY = 'translate-condition';
+const OPENWEATHER_USE_SYMBOLIC_ICONS_KEY = 'use-symbolic-icons';
+const OPENWEATHER_USE_TEXT_ON_BUTTONS_KEY = 'use-text-on-buttons';
+const OPENWEATHER_SHOW_TEXT_IN_PANEL_KEY = 'show-text-in-panel';
+const OPENWEATHER_POSITION_IN_PANEL_KEY = 'position-in-panel';
+const OPENWEATHER_SHOW_COMMENT_IN_PANEL_KEY = 'show-comment-in-panel';
+const OPENWEATHER_SHOW_COMMENT_IN_FORECAST_KEY = 'show-comment-in-forecast';
+const OPENWEATHER_REFRESH_INTERVAL_CURRENT = 'refresh-interval-current';
+const OPENWEATHER_REFRESH_INTERVAL_FORECAST = 'refresh-interval-forecast';
+const OPENWEATHER_CENTER_FORECAST_KEY = 'center-forecast';
+const OPENWEATHER_DAYS_FORECAST = 'days-forecast';
+const OPENWEATHER_DECIMAL_PLACES = 'decimal-places';
+const OPENWEATHER_USE_DEFAULT_OWM_API_KEY = 'use-default-owm-key';
+const OPENWEATHER_OWM_API_KEY = 'appid';
+const OPENWEATHER_FC_API_KEY = 'appid-fc';
+const OPENWEATHER_GC_APP_KEY = 'geolocation-appid-mapquest';
 
 //URL
-const WEATHER_URL_BASE = 'http://api.openweathermap.org/data/2.5/';
-const WEATHER_URL_CURRENT = WEATHER_URL_BASE + 'weather';
-const WEATHER_URL_FIND = WEATHER_URL_BASE + 'find';
+const OPENWEATHER_URL_MAPQUEST_BASE = 'https://open.mapquestapi.com/nominatim/v1/';
+const OPENWEATHER_URL_MAPQUEST_FIND = OPENWEATHER_URL_MAPQUEST_BASE + 'search.php';
+const OPENWEATHER_URL_GEOCODE_BASE = 'https://www.geocode.farm/v3/';
+const OPENWEATHER_URL_GEOCODE_FIND = OPENWEATHER_URL_GEOCODE_BASE + 'json/forward';
+const OPENWEATHER_URL_OSM_BASE = 'https://nominatim.openstreetmap.org/';
+const OPENWEATHER_URL_OSM_FIND = OPENWEATHER_URL_OSM_BASE + 'search';
+
+// Keep enums in sync with GSettings schemas
+const WeatherProvider = {
+    DEFAULT: -1,
+    OPENWEATHERMAP: 0,
+    FORECAST_IO: 1
+};
+
+const GeolocationProvider = {
+    OPENSTREETMAPS: 0,
+    GEOCODE: 1,
+    MAPQUEST: 2
+};
 
 let _httpSession;
 
 let mCities = null;
 
+let inRealize = false;
+
+let defaultSize = [-1, -1];
+
 const WeatherPrefsWidget = new GObject.Class({
     Name: 'OpenWeatherExtension.Prefs.Widget',
     GTypeName: 'OpenWeatherExtensionPrefsWidget',
@@ -81,11 +107,37 @@
     _init: function(params) {
         this.parent(params);
 
+        // Create user-agent string from uuid and (if present) the version
+        this.user_agent = Me.metadata.uuid;
+        if (Me.metadata.version !== undefined && Me.metadata.version.toString().trim() !== '') {
+            this.user_agent += '/';
+            this.user_agent += Me.metadata.version.toString();
+        }
+        // add trailing space, so libsoup adds its own user-agent
+        this.user_agent += ' ';
+
         this.initWindow();
 
+        defaultSize = this.MainWidget.get_size_request();
+        var borderWidth = this.MainWidget.get_border_width();
+
+        defaultSize[0] += 2 * borderWidth;
+        defaultSize[1] += 2 * borderWidth;
+
+        this.MainWidget.set_size_request(-1, -1);
+        this.MainWidget.set_border_width(0);
+
         this.refreshUI();
 
         this.add(this.MainWidget);
+        this.MainWidget.connect('realize', Lang.bind(this, function() {
+            if (inRealize)
+                return;
+            inRealize = true;
+
+            this.MainWidget.get_toplevel().resize(defaultSize[0], defaultSize[1]);
+            inRealize = false;
+        }));
     },
 
     Window: new Gtk.Builder(),
@@ -97,24 +149,248 @@
 
         this.MainWidget = this.Window.get_object("main-widget");
         this.treeview = this.Window.get_object("tree-treeview");
-        this.liststore = this.Window.get_object("liststore");
-        this.Iter = this.liststore.get_iter_first();
+        this.liststore = this.Window.get_object("tree-liststore");
+        this.editWidget = this.Window.get_object("edit-widget");
+        this.editName = this.Window.get_object("edit-name");
+        this.editCoord = this.Window.get_object("edit-coord");
+        this.editCombo = this.Window.get_object("edit-combo");
+        this.searchWidget = this.Window.get_object("search-widget");
+        this.searchMenu = this.Window.get_object("search-menu");
+        this.searchName = this.Window.get_object("search-name");
+        this.searchCombo = this.Window.get_object("search-combo");
+        this.spinner = this.Window.get_object("spinner");
+
+        this.searchName.connect("icon-release", Lang.bind(this, this.clearEntry));
+        this.editName.connect("icon-release", Lang.bind(this, this.clearEntry));
+        this.editCoord.connect("icon-release", Lang.bind(this, this.clearEntry));
 
         this.Window.get_object("tree-toolbutton-add").connect("clicked", Lang.bind(this, function() {
-            this.addCity();
+            this.searchWidget.show_all();
         }));
 
-        this.Window.get_object("tree-toolbutton-remove").connect("clicked", Lang.bind(this, function() {
-            this.removeCity();
-        }));
+        this.Window.get_object("tree-toolbutton-remove").connect("clicked", Lang.bind(this, this.removeCity));
+
+        this.Window.get_object("tree-toolbutton-edit").connect("clicked", Lang.bind(this, this.editCity));
 
         this.Window.get_object("treeview-selection").connect("changed", Lang.bind(this, function(selection) {
             this.selectionChanged(selection);
         }));
 
-        this.treeview.set_model(this.liststore);
+        this.Window.get_object("button-edit-cancel").connect("clicked", Lang.bind(this, this.editCancel));
+
+        this.Window.get_object("button-edit-save").connect("clicked", Lang.bind(this, this.editSave));
+
+        this.Window.get_object("button-search-cancel").connect("clicked", Lang.bind(this, function() {
+            this.searchWidget.hide();
+        }));
+
+        this.Window.get_object("button-search-save").connect("clicked", Lang.bind(this, this.searchSave));
+
+        this.Window.get_object("button-search-find").connect("clicked", Lang.bind(this, function() {
+
+            this.clearSearchMenu();
+            let location = this.searchName.get_text().trim();
+            if (location === "")
+                return 0;
+
+            let item = new Gtk.MenuItem();
+            if (this.spinner.get_parent())
+                this.spinner.reparent(item);
+            item.add(this.spinner);
+            this.searchMenu.append(item);
+            this.searchMenu.show_all();
+            this.searchMenu.popup(null, null, Lang.bind(this, this.placeSearchMenu), 0, this.searchName);
+
+            if (this.geolocation_provider == GeolocationProvider.OPENSTREETMAPS) {
+                let params = {
+                    format: 'json',
+                    addressdetails: '1',
+                    q: location
+                };
+
+                this.loadJsonAsync(OPENWEATHER_URL_OSM_FIND, params, Lang.bind(this, function() {
+                    this.clearSearchMenu();
+                    if (!arguments[0]) {
+                        let item = new Gtk.MenuItem({
+                            label: _("Invalid data when searching for \"%s\"").format(location)
+                        });
+                        this.searchMenu.append(item);
+                    } else {
+                        let newCity = arguments[0];
+
+                        if (Number(newCity.length) < 1) {
+                            let item = new Gtk.MenuItem({
+                                label: _("\"%s\" not found").format(location)
+                            });
+                            this.searchMenu.append(item);
+                        } else {
+                            var m = {};
+                            for (var i in newCity) {
+
+                                let cityText = newCity[i].display_name;
+                                let cityCoord = "[" + newCity[i].lat + "," + newCity[i].lon + "]";
+
+                                let item = new Gtk.MenuItem({
+                                    label: cityText + " " + cityCoord
+                                });
+                                item.connect("activate", Lang.bind(this, this.onActivateItem));
+                                this.searchMenu.append(item);
+                            }
+                        }
+                    }
+                    this.searchMenu.show_all();
+                    this.searchMenu.popup(null, null, Lang.bind(this, this.placeSearchMenu), 0, this.searchName);
+                    return 0;
+                }));
+            } else if (this.geolocation_provider == GeolocationProvider.MAPQUEST) {
+                if (this.geolocation_appid_mapquest === '') {
+                    this.clearSearchMenu();
+                    let item = new Gtk.MenuItem({
+                        label: "You need an AppKey to search on openmapquest."
+                    });
+                    this.searchMenu.append(item);
+                    item = new Gtk.MenuItem({
+                        label: "Please visit https://developer.mapquest.com/ ."
+                    });
+                    this.searchMenu.append(item);
+                    this.searchMenu.show_all();
+                    this.searchMenu.popup(null, null, Lang.bind(this, this.placeSearchMenu), 0, this.searchName);
+                    return 0;
+                }
+                let params = {
+                    key: this.geolocation_appid_mapquest,
+                    format: 'json',
+                    addressdetails: '1',
+                    q: location
+                };
+
+                this.loadJsonAsync(OPENWEATHER_URL_MAPQUEST_FIND, params, Lang.bind(this, function() {
+                    this.clearSearchMenu();
+                    if (!arguments[0]) {
+                        let item = new Gtk.MenuItem({
+                            label: _("Invalid data when searching for \"%s\"").format(location)
+                        });
+                        this.searchMenu.append(item);
+                        item = new Gtk.MenuItem({
+                            label: "Do you use a valid AppKey to search on openmapquest ?"
+                        });
+                        this.searchMenu.append(item);
+                        item = new Gtk.MenuItem({
+                            label: "If not, please visit https://developer.mapquest.com/ ."
+                        });
+                        this.searchMenu.append(item);
+                    } else {
+                        let newCity = arguments[0];
+
+                        if (Number(newCity.length) < 1) {
+                            let item = new Gtk.MenuItem({
+                                label: _("\"%s\" not found").format(location)
+                            });
+                            this.searchMenu.append(item);
+                        } else {
+                            var m = {};
+                            for (var i in newCity) {
+
+                                let cityText = newCity[i].display_name;
+                                let cityCoord = "[" + newCity[i].lat + "," + newCity[i].lon + "]";
+
+                                let item = new Gtk.MenuItem({
+                                    label: cityText + " " + cityCoord
+                                });
+                                item.connect("activate", Lang.bind(this, this.onActivateItem));
+                                this.searchMenu.append(item);
+                            }
+                        }
+                    }
+                    this.searchMenu.show_all();
+                    this.searchMenu.popup(null, null, Lang.bind(this, this.placeSearchMenu), 0, this.searchName);
+                    return 0;
+                }));
+            } else if (this.geolocation_provider == GeolocationProvider.GEOCODE) {
+                let params = {
+                    addr: location
+                };
+
+                this.loadJsonAsync(OPENWEATHER_URL_GEOCODE_FIND, params, Lang.bind(this, function() {
+                    this.clearSearchMenu();
+
+                    if (!arguments[0]) {
+                        let item = new Gtk.MenuItem({
+                            label: _("Invalid data when searching for \"%s\"").format(location)
+                        });
+                        this.searchMenu.append(item);
+                    } else {
+                        let newCity = arguments[0].geocoding_results;
+                        if (Number(newCity.length) < 1) {
+                            let item = new Gtk.MenuItem({
+                                label: _("Invalid data when searching for \"%s\"").format(location)
+                            });
+                            this.searchMenu.append(item);
+                        } else {
+                            if (Number(newCity.STATUS.result_count) < 1) {
+                                let item = new Gtk.MenuItem({
+                                    label: _("\"%s\" not found").format(location)
+                                });
+                                this.searchMenu.append(item);
+                            } else {
+                                var m = {};
+                                newCity = newCity.RESULTS;
+                                for (var i in newCity) {
+
+                                    let cityText = newCity[i].formatted_address;
+                                    let cityCoord = "[" + newCity[i].COORDINATES.latitude + "," + newCity[i].COORDINATES.longitude + "]";
+
+                                    let item = new Gtk.MenuItem({
+                                        label: cityText + " " + cityCoord
+                                    });
+                                    item.connect("activate", Lang.bind(this, this.onActivateItem));
+                                    this.searchMenu.append(item);
+                                }
+                            }
+
+                        }
+                    }
+
+                    this.searchMenu.show_all();
+                    this.searchMenu.popup(null, null, Lang.bind(this, this.placeSearchMenu), 0, this.searchName);
+                    return 0;
+                }));
+            }
+            return 0;
+        }));
+
+        this.current_spin = this.Window.get_object("spin-current-refresh");
+        this.current_spin.set_value(this.refresh_interval_current / 60);
+        // prevent from continously updating the value
+        this.currentSpinTimeout = undefined;
+        this.current_spin.connect("value-changed", Lang.bind(this, function(button) {
+
+            if (this.currentSpinTimeout !== undefined)
+                Mainloop.source_remove(this.currentSpinTimeout);
+            this.currentSpinTimeout = Mainloop.timeout_add(250, Lang.bind(this, function() {
+                this.refresh_interval_current = 60 * button.get_value();
+                return false;
+            }));
+
+        }));
+
+        this.forecast_spin = this.Window.get_object("spin-forecast-refresh");
+        this.forecast_spin.set_value(this.refresh_interval_forecast / 60);
+        // prevent from continously updating the value
+        this.forecastSpinTimeout = undefined;
+        this.forecast_spin.connect("value-changed", Lang.bind(this, function(button) {
+
+            if (this.forecastSpinTimeout !== undefined)
+                Mainloop.source_remove(this.forecastSpinTimeout);
+            this.forecastSpinTimeout = Mainloop.timeout_add(250, Lang.bind(this, function() {
+                this.refresh_interval_forecast = 60 * button.get_value();
+                return false;
+            }));
+
+        }));
 
         let column = new Gtk.TreeViewColumn();
+        column.set_title(_("Location"));
         this.treeview.append_column(column);
 
         let renderer = new Gtk.CellRendererText();
@@ -123,45 +399,92 @@
         column.set_cell_data_func(renderer, function() {
             arguments[1].markup = arguments[2].get_value(arguments[3], 0);
         });
+        column = new Gtk.TreeViewColumn();
+        column.set_title(_("Provider"));
+        this.treeview.append_column(column);
+
+        column.pack_start(renderer, null);
+
+        column.set_cell_data_func(renderer, function() {
+            arguments[1].markup = arguments[2].get_value(arguments[3], 1);
+        });
+
+
+        let theObjects = this.Window.get_objects();
+        for (let i in theObjects) {
+            let name = theObjects[i].get_name ? theObjects[i].get_name() : 'dummy';
+            if (this[name] !== undefined) {
+                if (theObjects[i].class_path()[1].indexOf('GtkEntry') != -1)
+                    this.initEntry(theObjects[i]);
+                else if (theObjects[i].class_path()[1].indexOf('GtkComboBoxText') != -1)
+                    this.initComboBox(theObjects[i]);
+                else if (theObjects[i].class_path()[1].indexOf('GtkSwitch') != -1)
+                    this.initSwitch(theObjects[i]);
+                this.configWidgets.push([theObjects[i], name]);
+            }
+        }
+        if (Me.metadata.version !== undefined)
+            this.Window.get_object('version').set_label(Me.metadata.version.toString());
+    },
 
-        this.initConfigWidget();
-        this.addLabel(_("Temperature Unit"));
-        this.addComboBox(["\u00b0C", "\u00b0F", "K", "\u00b0Ra", "\u00b0R\u00E9", "\u00b0R\u00F8", "\u00b0De", "\u00b0N"], "units");
-        this.addLabel(_("Wind Speed Unit"));
-        this.addComboBox(["km/h", "mph", "m/s", "kn", "ft/s", "Beaufort"], "wind_speed_unit");
-        this.addLabel(_("Pressure Unit"));
-        this.addComboBox(["hPa", "inHg", "bar", "Pa", "kPa", "atm", "at", "Torr", "psi"], "pressure_unit");
-        this.addLabel(_("Position in Panel"));
-        this.addComboBox([_("Center"), _("Right"), _("Left")], "position_in_panel");
-        this.addLabel(_("Wind Direction by Arrows"));
-        this.addSwitch("wind_direction");
-        this.addLabel(_("Translate Conditions"));
-        this.addSwitch("translate_condition");
-        this.addLabel(_("Symbolic Icons"));
-        this.addSwitch("icon_type");
-        this.addLabel(_("Text on buttons"));
-        this.addSwitch("use_text_on_buttons");
-        this.addLabel(_("Temperature in Panel"));
-        this.addSwitch("text_in_panel");
-        this.addLabel(_("Conditions in Panel"));
-        this.addSwitch("comment_in_panel");
-        this.addLabel(_("Center forecast"));
-        this.addSwitch("center_forecast");
-        this.addLabel(_("Number of days in forecast"));
-        this.addComboBox(["2", "3", "4", "5", "6", "7", "8", "9", "10"], "days_forecast");
-        this.addLabel(_("Maximal number of digits after the decimal point"));
-        this.addComboBox(["0", "1", "2", "3"], "decimal_places");
-        this.addLabel(_("Personal Api key from openweathermap.org"));
-        this.addAppidEntry(("appid"));
+    clearEntry: function() {
+        arguments[0].set_text("");
+    },
+
+    onActivateItem: function() {
+        this.searchName.set_text(arguments[0].get_label());
+    },
+
+    placeSearchMenu: function() {
+        let[gx, gy, gw, gh] = this.searchName.get_window().get_geometry();
+        let[px, py] = this.searchName.get_window().get_position();
+        return [gx + px, gy + py + this.searchName.get_allocated_height()];
+    },
+
+    clearSearchMenu: function() {
+        let children = this.searchMenu.get_children();
+        for (let i in children) {
+            this.searchMenu.remove(children[i]);
+        }
+    },
+
+    initEntry: function(theEntry) {
+        let name = theEntry.get_name();
+        theEntry.text = this[name];
+        if (this[name].length != 32)
+            theEntry.set_icon_from_icon_name(Gtk.PositionType.LEFT, 'dialog-warning');
+
+        theEntry.connect("notify::text", Lang.bind(this, function() {
+            let key = arguments[0].text;
+            this[name] = key;
+            if (key.length == 32)
+                theEntry.set_icon_from_icon_name(Gtk.PositionType.LEFT, '');
+            else
+                theEntry.set_icon_from_icon_name(Gtk.PositionType.LEFT, 'dialog-warning');
+        }));
+    },
+
+    initComboBox: function(theComboBox) {
+        let name = theComboBox.get_name();
+        theComboBox.connect("changed", Lang.bind(this, function() {
+            this[name] = arguments[0].active;
+        }));
+    },
+
+    initSwitch: function(theSwitch) {
+        let name = theSwitch.get_name();
+        theSwitch.connect("notify::active", Lang.bind(this, function() {
+            this[name] = arguments[0].active;
+        }));
     },
 
     refreshUI: function() {
         this.MainWidget = this.Window.get_object("main-widget");
         this.treeview = this.Window.get_object("tree-treeview");
-        this.liststore = this.Window.get_object("liststore");
-        this.Iter = this.liststore.get_iter_first();
+        this.liststore = this.Window.get_object("tree-liststore");
 
         this.Window.get_object("tree-toolbutton-remove").sensitive = Boolean(this.city.length);
+        this.Window.get_object("tree-toolbutton-edit").sensitive = Boolean(this.city.length);
 
         if (mCities != this.city) {
             if (this.liststore !== undefined)
@@ -178,6 +501,7 @@
                 for (let i in city) {
                     current = this.liststore.append();
                     this.liststore.set_value(current, 0, this.extractLocation(city[i]));
+                    this.liststore.set_value(current, 1, this.getProviderShort(this.extractProvider(city[i])));
                 }
             }
 
@@ -187,109 +511,13 @@
         this.changeSelection();
 
         let config = this.configWidgets;
-        for (let i in config)
+        for (let i in config) {
             if (config[i][0].active != this[config[i][1]])
                 config[i][0].active = this[config[i][1]];
-    },
-
-    initConfigWidget: function() {
-        this.inc(1);
-        let a = this.Window.get_object("right-widget-table");
-        a.visible = 1;
-        a.can_focus = 0;
-        this.right_widget = a;
-    },
-
-    x: [0, 1],
-
-    y: [0, 1],
-
-    configWidgets: [],
-
-    inc: function() {
-        if (arguments[0]) {
-            this.x[0] = 0;
-            this.x[1] = 1;
-            this.y[0] = 0;
-            this.y[1] = 1;
-            return 0;
-        }
-
-        if (this.x[0] == 1) {
-            this.x[0] = 0;
-            this.x[1] = 1;
-            this.y[0] += 1;
-            this.y[1] += 1;
-            return 0;
-        } else {
-            this.x[0] += 1;
-            this.x[1] += 1;
-            return 0;
         }
     },
 
-    addLabel: function(text) {
-        let l = new Gtk.Label({
-            label: text,
-            xalign: 0
-        });
-        l.visible = 1;
-        l.can_focus = 0;
-        this.right_widget.attach(l, this.x[0], this.x[1], this.y[0], this.y[1], 0, 0, 0, 0);
-        this.inc();
-    },
-
-    addComboBox: function(a, b) {
-        let cf = new Gtk.ComboBoxText();
-        this.configWidgets.push([cf, b]);
-        cf.visible = 1;
-        cf.can_focus = 0;
-        cf.width_request = 100;
-        for (let i in a)
-            cf.append_text(a[i]);
-        cf.active = this[b];
-        cf.connect("changed", Lang.bind(this, function() {
-            this[b] = arguments[0].active;
-        }));
-        this.right_widget.attach(cf, this.x[0], this.x[1], this.y[0], this.y[1], 0, 0, 0, 0);
-        this.inc();
-    },
-
-    addSwitch: function(a) {
-        let sw = new Gtk.Switch();
-        this.configWidgets.push([sw, a]);
-        sw.visible = 1;
-        sw.can_focus = 0;
-        sw.active = this[a];
-        sw.connect("notify::active", Lang.bind(this, function() {
-            this[a] = arguments[0].active;
-        }));
-        this.right_widget.attach(sw, this.x[0], this.x[1], this.y[0], this.y[1], 0, 0, 0, 0);
-        this.inc();
-    },
-
-    addAppidEntry: function(a) {
-        let en = new Gtk.Entry();
-        this.configWidgets.push([en, a]);
-        en.visible = 1;
-        en.can_focus = 1;
-        en.set_width_chars(32);
-        en.text = this[a];
-        if (this[a].length != 32)
-            en.set_icon_from_icon_name(Gtk.PositionType.LEFT, 'dialog-warning');
-
-        en.connect("notify::text", Lang.bind(this, function() {
-            let key = arguments[0].text;
-            let rgba = new Gdk.Color();
-            this[a] = key;
-            if (key.length == 32)
-                en.set_icon_from_icon_name(Gtk.PositionType.LEFT, '');
-            else
-                en.set_icon_from_icon_name(Gtk.PositionType.LEFT, 'dialog-warning');
-        }));
-        this.right_widget.attach(en, this.x[0], this.x[1], this.y[0], this.y[1], 0, 0, 0, 0);
-        this.inc();
-    },
+    configWidgets: [],
 
     selectionChanged: function(select) {
         let a = select.get_selected_rows(this.liststore)[0][0];
@@ -299,193 +527,12 @@
                 this.actual_city = parseInt(a.to_string());
     },
 
-    addCity: function() {
-        let textDialog = _("Name of the city");
-
-        let dialog = new Gtk.Dialog({
-            title: ""
-        });
-        let entry = new Gtk.Entry();
-        let completion = new Gtk.EntryCompletion();
-        entry.set_completion(completion);
-        let completionModel = new Gtk.ListStore();
-        completionModel.set_column_types([GObject.TYPE_STRING]);
-        completion.set_model(completionModel);
-        completion.set_text_column(0);
-        completion.set_popup_single_match(true);
-        completion.set_minimum_key_length(1);
-        completion.set_match_func(function(completion, key, iter) {
-            if (iter) {
-                if (completionModel.get_value(iter, 0))
-                    return true;
-            }
-            return false;
-        });
-        entry.margin_top = 12;
-        entry.margin_bottom = 12;
-        let label = new Gtk.Label({
-            label: textDialog
-        });
-
-        dialog.set_border_width(12);
-        dialog.set_modal(1);
-        dialog.set_resizable(0);
-        //dialog.set_transient_for(***** Need parent Window *****);
-
-        dialog.add_button(Gtk.STOCK_CANCEL, 0);
-        let d = dialog.add_button(Gtk.STOCK_OK, 1);
-
-        d.set_can_default(true);
-        d.sensitive = 0;
-
-        dialog.set_default(d);
-        entry.activates_default = true;
-
-        let testLocation = Lang.bind(this, function(location) {
-            if (location.search(/\[/) == -1 || location.search(/\]/) == -1)
-                return 0;
-
-            let id = location.split(/\[/)[1].split(/\]/)[0];
-            if (!id)
-                return 0;
-
-            this.loadJsonAsync(WEATHER_URL_CURRENT, {
-                id: id
-            }, function() {
-                d.sensitive = 0;
-                if (arguments[0] === undefined)
-                    return 0;
-
-                let city = arguments[0];
-
-                if (Number(city.cod) != 200)
-                    return 0;
-
-                if (Number(city.count) === 0)
-                    return 0;
-
-                d.sensitive = 1;
-                return 0;
-            }, "testLocation");
-            return 0;
-        });
-
-        let searchLocation = Lang.bind(this, function() {
-            let location = entry.get_text();
-            let params = {
-                cnt: '30',
-                sort: 'population',
-                type: 'like',
-                units: 'metric',
-                q: location
-            };
-            if (this.appid)
-                params.APPID = this.appid;
-            if (testLocation(location) === 0)
-                this.loadJsonAsync(WEATHER_URL_FIND, params, function() {
-                    if (!arguments[0])
-                        return 0;
-                    let city = arguments[0];
-
-                    if (Number(city.cod) != 200)
-                        return 0;
-
-                    if (Number(city.count) > 0)
-                        city = city.list;
-                    else
-                        return 0;
-
-                    completionModel.clear();
-
-                    let current = this.liststore.get_iter_first();
-
-                    var m = {};
-                    for (var i in city) {
-
-                        current = completionModel.append();
-
-                        let cityText = city[i].name;
-
-                        if (city[i].sys)
-                            cityText += ", " + city[i].sys.country;
-
-                        if (city[i].id)
-                            cityText += " [" + city[i].id + "]";
-
-                        if (m[cityText])
-                            continue;
-                        else
-                            m[cityText] = 1;
-
-                        completionModel.set_value(current, 0, cityText);
-                    }
-
-                    completion.complete();
-                    return 0;
-                }, "getInfo");
-            return 0;
-        });
-
-        entry.connect("changed", searchLocation);
-
-        let dialog_area = dialog.get_content_area();
-        dialog_area.pack_start(label, 0, 0, 0);
-        dialog_area.pack_start(entry, 0, 0, 0);
-        dialog.connect("response", Lang.bind(this, function(w, response_id) {
-            if (response_id) {
-                if (entry.get_text().search(/\[/) == -1 || entry.get_text().search(/\]/) == -1)
-                    return 0;
-
-                let id = entry.get_text().split(/\[/)[1].split(/\]/)[0];
-                if (!id)
-                    return 0;
-
-                let params = {
-                    id: id,
-                    type: 'accurate'
-                };
-                if (this.appid)
-                    params.APPID = this.appid;
-                this.loadJsonAsync(WEATHER_URL_CURRENT, params, Lang.bind(this, function() {
-                    if (!arguments[0])
-                        return 0;
-                    let city = arguments[0];
-
-                    if (Number(city.cod) != 200)
-                        return 0;
-
-                    if (!id)
-                        return 0;
-
-                    if (id != city.id)
-                        return 0;
-
-                    let cityText = entry.get_text().split(/,/)[0];
-
-                    if (city.sys)
-                        cityText += " (" + city.sys.country + ")";
-
-                    if (this.city)
-                        this.city = this.city + " && " + city.id + ">" + cityText;
-                    else
-                        this.city = city.id + ">" + cityText;
-
-                    return 0;
-                }), "lastTest");
-            }
-            dialog.hide();
-            return 0;
-        }));
-
-        dialog.show_all();
-    },
-
     removeCity: function() {
         let city = this.city.split(" && ");
         if (!city.length)
             return 0;
         let ac = this.actual_city;
-        let textDialog = _("Remove %s ?").replace("%s", this.extractLocation(city[ac]));
+        let textDialog = _("Remove %s ?").format(this.extractLocation(city[ac]));
         let dialog = new Gtk.Dialog({
             title: ""
         });
@@ -533,6 +580,64 @@
         return 0;
     },
 
+    editCity: function() {
+        let city = this.city.split(" && ");
+        if (!city.length)
+            return 0;
+        let ac = this.actual_city;
+        this.editName.set_text(this.extractLocation(city[ac]));
+        this.editCoord.set_text(this.extractCoord(city[ac]));
+        this.editCombo.set_active(this.extractProvider(city[ac]) + 1);
+        this.editWidget.show_all();
+        return 0;
+    },
+
+    searchSave: function() {
+        let location = this.searchName.get_text().split(/\[/)[0];
+        let coord = this.searchName.get_text().split(/\[/)[1].split(/\]/)[0];
+        let provider = this.searchCombo.get_active() - 1;
+
+        if (this.city)
+            this.city = this.city + " && " + coord + ">" + location + ">" + provider;
+        else
+            this.city = coord + ">" + location + ">" + provider;
+
+        this.searchWidget.hide();
+        return 0;
+    },
+
+    editSave: function() {
+        let theCity = this.city.split(" && ");
+
+        if (theCity.length === 0)
+            return 0;
+        if (theCity.length > 0 && typeof theCity != "object")
+            theCity = [theCity];
+
+        let ac = this.actual_city;
+        let location = this.editName.get_text();
+        let coord = this.editCoord.get_text();
+        let provider = this.editCombo.get_active() - 1;
+        theCity[ac] = coord + ">" + location + ">" + provider;
+
+        if (theCity.length > 1)
+            this.city = theCity.join(" && ");
+        else if (theCity[0])
+            this.city = theCity[0];
+
+        this.editWidget.hide();
+
+        this.actual_city = ac;
+
+        return 0;
+    },
+
+    editCancel: function() {
+        this.editName.set_text("");
+        this.editCoord.set_text("");
+        this.editWidget.hide();
+    },
+
     changeSelection: function() {
         let path = this.actual_city;
         if (arguments[0])
@@ -543,12 +648,8 @@
 
     loadJsonAsync: function(url, params, fun, id) {
         if (_httpSession === undefined) {
-            if (ExtensionUtils.versionCheck(['3.6'], Config.PACKAGE_VERSION)) {
-                // Soup session (see https://bugzilla.gnome.org/show_bug.cgi?id=661323#c64) (Simon Legner)
-                _httpSession = new Soup.SessionAsync();
-                Soup.Session.prototype.add_feature.call(_httpSession, new Soup.ProxyResolverDefault());
-            } else
-                _httpSession = new Soup.Session();
+            _httpSession = new Soup.Session();
+            _httpSession.user_agent = this.user_agent;
         }
 
         let here = this;
@@ -583,76 +684,100 @@
     },
 
     loadConfig: function() {
-        this.Settings = Convenience.getSettings(WEATHER_SETTINGS_SCHEMA);
+        this.Settings = Convenience.getSettings(OPENWEATHER_SETTINGS_SCHEMA);
         this.Settings.connect("changed", Lang.bind(this, function() {
             this.refreshUI();
         }));
     },
 
+    get weather_provider() {
+        if (!this.Settings)
+            this.loadConfig();
+        return this.Settings.get_enum(OPENWEATHER_PROVIDER_KEY);
+    },
+
+    set weather_provider(v) {
+        if (!this.Settings)
+            this.loadConfig();
+        this.Settings.set_enum(OPENWEATHER_PROVIDER_KEY, v);
+    },
+
+    get geolocation_provider() {
+        if (!this.Settings)
+            this.loadConfig();
+        return this.Settings.get_enum(OPENWEATHER_GEOLOCATION_PROVIDER_KEY);
+    },
+
+    set geolocation_provider(v) {
+        if (!this.Settings)
+            this.loadConfig();
+        this.Settings.set_enum(OPENWEATHER_GEOLOCATION_PROVIDER_KEY, v);
+    },
+
     get units() {
         if (!this.Settings)
             this.loadConfig();
-        return this.Settings.get_enum(WEATHER_UNIT_KEY);
+        return this.Settings.get_enum(OPENWEATHER_UNIT_KEY);
     },
 
     set units(v) {
         if (!this.Settings)
             this.loadConfig();
-        this.Settings.set_enum(WEATHER_UNIT_KEY, v);
+        this.Settings.set_enum(OPENWEATHER_UNIT_KEY, v);
     },
 
     get pressure_unit() {
         if (!this.Settings)
             this.loadConfig();
-        return this.Settings.get_enum(WEATHER_PRESSURE_UNIT_KEY);
+        return this.Settings.get_enum(OPENWEATHER_PRESSURE_UNIT_KEY);
     },
 
     set pressure_unit(v) {
         if (!this.Settings)
             this.loadConfig();
-        this.Settings.set_enum(WEATHER_PRESSURE_UNIT_KEY, v);
+        this.Settings.set_enum(OPENWEATHER_PRESSURE_UNIT_KEY, v);
     },
 
     get wind_speed_unit() {
         if (!this.Settings)
             this.loadConfig();
-        return this.Settings.get_enum(WEATHER_WIND_SPEED_UNIT_KEY);
+        return this.Settings.get_enum(OPENWEATHER_WIND_SPEED_UNIT_KEY);
     },
 
     set wind_speed_unit(v) {
         if (!this.Settings)
             this.loadConfig();
-        this.Settings.set_enum(WEATHER_WIND_SPEED_UNIT_KEY, v);
+        this.Settings.set_enum(OPENWEATHER_WIND_SPEED_UNIT_KEY, v);
     },
 
     get wind_direction() {
         if (!this.Settings)
             this.loadConfig();
-        return this.Settings.get_boolean(WEATHER_WIND_DIRECTION_KEY);
+        return this.Settings.get_boolean(OPENWEATHER_WIND_DIRECTION_KEY);
     },
 
     set wind_direction(v) {
         if (!this.Settings)
             this.loadConfig();
-        return this.Settings.set_boolean(WEATHER_WIND_DIRECTION_KEY, v);
+        return this.Settings.set_boolean(OPENWEATHER_WIND_DIRECTION_KEY, v);
     },
 
     get city() {
         if (!this.Settings)
             this.loadConfig();
-        return this.Settings.get_string(WEATHER_CITY_KEY);
+        return this.Settings.get_string(OPENWEATHER_CITY_KEY);
     },
 
     set city(v) {
         if (!this.Settings)
             this.loadConfig();
-        this.Settings.set_string(WEATHER_CITY_KEY, v);
+        this.Settings.set_string(OPENWEATHER_CITY_KEY, v);
     },
 
     get actual_city() {
         if (!this.Settings)
             this.loadConfig();
-        let a = this.Settings.get_int(WEATHER_ACTUAL_CITY_KEY);
+        let a = this.Settings.get_int(OPENWEATHER_ACTUAL_CITY_KEY);
         let citys = this.city.split(" && ");
 
         if (citys && typeof citys == "string")
@@ -691,165 +816,245 @@
         if (a > l)
             a = l;
 
-        this.Settings.set_int(WEATHER_ACTUAL_CITY_KEY, a);
+        this.Settings.set_int(OPENWEATHER_ACTUAL_CITY_KEY, a);
     },
 
     get translate_condition() {
         if (!this.Settings)
             this.loadConfig();
-        return this.Settings.get_boolean(WEATHER_TRANSLATE_CONDITION_KEY);
+        return this.Settings.get_boolean(OPENWEATHER_TRANSLATE_CONDITION_KEY);
     },
 
     set translate_condition(v) {
         if (!this.Settings)
             this.loadConfig();
-        this.Settings.set_boolean(WEATHER_TRANSLATE_CONDITION_KEY, v);
+        this.Settings.set_boolean(OPENWEATHER_TRANSLATE_CONDITION_KEY, v);
     },
 
     get icon_type() {
         if (!this.Settings)
             this.loadConfig();
-        return this.Settings.get_boolean(WEATHER_USE_SYMBOLIC_ICONS_KEY);
+        return this.Settings.get_boolean(OPENWEATHER_USE_SYMBOLIC_ICONS_KEY);
     },
 
     set icon_type(v) {
         if (!this.Settings)
             this.loadConfig();
-        this.Settings.set_boolean(WEATHER_USE_SYMBOLIC_ICONS_KEY, v);
+        this.Settings.set_boolean(OPENWEATHER_USE_SYMBOLIC_ICONS_KEY, v);
     },
 
     get use_text_on_buttons() {
         if (!this.Settings)
             this.loadConfig();
-        return this.Settings.get_boolean(WEATHER_USE_TEXT_ON_BUTTONS_KEY);
+        return this.Settings.get_boolean(OPENWEATHER_USE_TEXT_ON_BUTTONS_KEY);
     },
 
     set use_text_on_buttons(v) {
         if (!this.Settings)
             this.loadConfig();
-        this.Settings.set_boolean(WEATHER_USE_TEXT_ON_BUTTONS_KEY, v);
+        this.Settings.set_boolean(OPENWEATHER_USE_TEXT_ON_BUTTONS_KEY, v);
     },
 
     get text_in_panel() {
         if (!this.Settings)
             this.loadConfig();
-        return this.Settings.get_boolean(WEATHER_SHOW_TEXT_IN_PANEL_KEY);
+        return this.Settings.get_boolean(OPENWEATHER_SHOW_TEXT_IN_PANEL_KEY);
     },
 
     set text_in_panel(v) {
         if (!this.Settings)
             this.loadConfig();
-        this.Settings.set_boolean(WEATHER_SHOW_TEXT_IN_PANEL_KEY, v);
+        this.Settings.set_boolean(OPENWEATHER_SHOW_TEXT_IN_PANEL_KEY, v);
     },
 
     get position_in_panel() {
         if (!this.Settings)
             this.loadConfig();
-        return this.Settings.get_enum(WEATHER_POSITION_IN_PANEL_KEY);
+        return this.Settings.get_enum(OPENWEATHER_POSITION_IN_PANEL_KEY);
     },
 
     set position_in_panel(v) {
         if (!this.Settings)
             this.loadConfig();
-        this.Settings.set_enum(WEATHER_POSITION_IN_PANEL_KEY, v);
+        this.Settings.set_enum(OPENWEATHER_POSITION_IN_PANEL_KEY, v);
     },
 
     get comment_in_panel() {
         if (!this.Settings)
             this.loadConfig();
-        return this.Settings.get_boolean(WEATHER_SHOW_COMMENT_IN_PANEL_KEY);
+        return this.Settings.get_boolean(OPENWEATHER_SHOW_COMMENT_IN_PANEL_KEY);
     },
 
     set comment_in_panel(v) {
         if (!this.Settings)
             this.loadConfig();
-        this.Settings.set_boolean(WEATHER_SHOW_COMMENT_IN_PANEL_KEY, v);
+        this.Settings.set_boolean(OPENWEATHER_SHOW_COMMENT_IN_PANEL_KEY, v);
+    },
+
+    get comment_in_forecast() {
+        if (!this.Settings)
+            this.loadConfig();
+        return this.Settings.get_boolean(OPENWEATHER_SHOW_COMMENT_IN_FORECAST_KEY);
+    },
+
+    set comment_in_forecast(v) {
+        if (!this.Settings)
+            this.loadConfig();
+        this.Settings.set_boolean(OPENWEATHER_SHOW_COMMENT_IN_FORECAST_KEY, v);
     },
 
     get refresh_interval_current() {
         if (!this.Settings)
             this.loadConfig();
-        let v = this.Settings.get_int(WEATHER_REFRESH_INTERVAL_CURRENT);
+        let v = this.Settings.get_int(OPENWEATHER_REFRESH_INTERVAL_CURRENT);
         return ((v >= 600) ? v : 600);
     },
 
     set refresh_interval_current(v) {
         if (!this.Settings)
             this.loadConfig();
-        this.Settings.set_int(WEATHER_REFRESH_INTERVAL_CURRENT, ((v >= 600) ? v : 600));
+        this.Settings.set_int(OPENWEATHER_REFRESH_INTERVAL_CURRENT, ((v >= 600) ? v : 600));
     },
 
     get refresh_interval_forecast() {
         if (!this.Settings)
             this.loadConfig();
-        let v = this.Settings.get_int(WEATHER_REFRESH_INTERVAL_FORECAST);
+        let v = this.Settings.get_int(OPENWEATHER_REFRESH_INTERVAL_FORECAST);
         return ((v >= 600) ? v : 600);
     },
 
     set refresh_interval_forecast(v) {
         if (!this.Settings)
             this.loadConfig();
-        this.Settings.set_int(WEATHER_REFRESH_INTERVAL_FORECAST, ((v >= 600) ? v : 600));
+        this.Settings.set_int(OPENWEATHER_REFRESH_INTERVAL_FORECAST, ((v >= 600) ? v : 600));
     },
 
     get center_forecast() {
         if (!this.Settings)
             this.loadConfig();
-        return this.Settings.get_boolean(WEATHER_CENTER_FORECAST_KEY);
+        return this.Settings.get_boolean(OPENWEATHER_CENTER_FORECAST_KEY);
     },
 
     set center_forecast(v) {
         if (!this.Settings)
             this.loadConfig();
-        this.Settings.set_boolean(WEATHER_CENTER_FORECAST_KEY, v);
+        this.Settings.set_boolean(OPENWEATHER_CENTER_FORECAST_KEY, v);
     },
 
     get days_forecast() {
         if (!this.Settings)
             this.loadConfig();
-        return this.Settings.get_int(WEATHER_DAYS_FORECAST) - 2;
+        return this.Settings.get_int(OPENWEATHER_DAYS_FORECAST) - 2;
     },
 
     set days_forecast(v) {
         if (!this.Settings)
             this.loadConfig();
-        this.Settings.set_int(WEATHER_DAYS_FORECAST, v + 2);
+        this.Settings.set_int(OPENWEATHER_DAYS_FORECAST, v + 2);
     },
 
     get decimal_places() {
         if (!this.Settings)
             this.loadConfig();
-        return this.Settings.get_int(WEATHER_DECIMAL_PLACES);
+        return this.Settings.get_int(OPENWEATHER_DECIMAL_PLACES);
     },
 
     set decimal_places(v) {
         if (!this.Settings)
             this.loadConfig();
-        this.Settings.set_int(WEATHER_DECIMAL_PLACES, v);
+        this.Settings.set_int(OPENWEATHER_DECIMAL_PLACES, v);
     },
 
     get appid() {
         if (!this.Settings)
             this.loadConfig();
-        return this.Settings.get_string(WEATHER_OWM_API_KEY);
+        return this.Settings.get_string(OPENWEATHER_OWM_API_KEY);
     },
 
     set appid(v) {
         if (!this.Settings)
             this.loadConfig();
-        this.Settings.set_string(WEATHER_OWM_API_KEY, v);
+        this.Settings.set_string(OPENWEATHER_OWM_API_KEY, v);
     },
 
-    extractLocation: function(a) {
-        if (a.search(">") == -1)
+    get use_default_owm_key() {
+        if (!this.Settings)
+            this.loadConfig();
+        return this.Settings.get_boolean(OPENWEATHER_USE_DEFAULT_OWM_API_KEY);
+    },
+
+    set use_default_owm_key(v) {
+        if (!this.Settings)
+            this.loadConfig();
+        this.Settings.set_boolean(OPENWEATHER_USE_DEFAULT_OWM_API_KEY, v);
+    },
+
+    get appid_fc() {
+        if (!this.Settings)
+            this.loadConfig();
+        return this.Settings.get_string(OPENWEATHER_FC_API_KEY);
+    },
+
+    set appid_fc(v) {
+        if (!this.Settings)
+            this.loadConfig();
+        this.Settings.set_string(OPENWEATHER_FC_API_KEY, v);
+    },
+
+    get geolocation_appid_mapquest() {
+        if (!this.Settings)
+            this.loadConfig();
+        return this.Settings.get_string(OPENWEATHER_GC_APP_KEY);
+    },
+
+    set geolocation_appid_mapquest(v) {
+        if (!this.Settings)
+            this.loadConfig();
+        this.Settings.set_string(OPENWEATHER_GC_APP_KEY, v);
+    },
+
+    extractLocation: function() {
+        if (!arguments[0])
+            return "";
+
+        if (arguments[0].search(">") == -1)
             return _("Invalid city");
-        return a.split(">")[1];
+        return arguments[0].split(">")[1];
     },
 
-    extractId: function(a) {
-        if (a.search(">") == -1)
+    extractCoord: function() {
+        if (!arguments[0])
+            return 0;
+
+        if (arguments[0].search(">") == -1)
             return 0;
-        return a.split(">")[0];
+        return arguments[0].split(">")[0];
+    },
+
+    extractProvider: function() {
+        if (!arguments[0])
+            return -1;
+        if (arguments[0].split(">")[2] === undefined)
+            return -1;
+        if (isNaN(parseInt(arguments[0].split(">")[2])))
+            return -1;
+        return parseInt(arguments[0].split(">")[2]);
+    },
+
+    getProviderShort: function() {
+        let provider = arguments[0];
+        if (provider === undefined)
+            provider = this.extractProvider(this.city[this.actual_city]);
+
+        switch (provider) {
+            case WeatherProvider.OPENWEATHERMAP:
+                return "openweathermap.org";
+            case WeatherProvider.FORECAST_IO:
+                return "forecast.io";
+            default:
+            case WeatherProvider.DEFAULT:
+                return _("default");
+        }
     }
 });
 
diff -Nru --exclude '*.pot' --exclude '*.po' gnome-shell-extension-weather-0~20140924.git7e28508/update_revision.sh gnome-shell-extension-weather-0~20151125.gitccaa1eb/update_revision.sh
--- gnome-shell-extension-weather-0~20140924.git7e28508/update_revision.sh	2014-09-24 20:18:58.000000000 +0200
+++ gnome-shell-extension-weather-0~20151125.gitccaa1eb/update_revision.sh	2015-12-09 21:55:47.000000000 +0100
@@ -1,9 +1,37 @@
 #!/bin/sh
+#
+#
+#  Weather extension for GNOME Shell
+#  - generate SPEC-,SOURCES- and SRPM-files from latest git-master and move them
+#    into the appropriate directories
+#  - you need to check the paths and fix the maintainers name
+#
+# Copyright (C) 2012 - 2015
+#     Jens Lody <jens@jenslody.de>,
+#
+# This file is part of gnome-shell-extension-openweather.
+#
+# gnome-shell-extension-openweather 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, either version 3 of the License, or (at your option)
+# any later version.
+#
+# gnome-shell-extension-openweather 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 gnome-shell-extension-openweather.  If not, see
+# <http://www.gnu.org/licenses/>.
+#
+
 
 GITHUB="jenslody-gnome-shell-extension-openweather"
 BASE_URL="https://github.com/jenslody/gnome-shell-extension-openweather/tarball/master/";
-TARBALL_PATH="/home/jens/rpmbuild/SOURCES/"
-SPEC_PATH="/home/jens/rpmbuild/SPECS/"
+TARBALL_PATH="${HOME}/rpmbuild/SOURCES/"
+SPEC_PATH="${HOME}/rpmbuild/SPECS/"
 SPEC_FILE="gnome-shell-extension-openweather.spec"
 
 SCRIPT_DIR=`dirname "$0"`
@@ -38,10 +66,21 @@
 
 echo "Found revision: '${COMMIT}'"
 
-mv ${SPEC_FILE} ${SPEC_FILE}.tmp
-sed "1 s/%global git .*/%global git $COMMIT/" < ${SPEC_FILE}.tmp > ${SPEC_FILE}
-rm -f ${SPEC_FILE}.tmp
+DATE=`date +%Y%m%d`
+
+echo "Use checkout-date: '${DATE}'"
+
+cp ${SPEC_FILE} ${SPEC_FILE}.tmp
+sed -i "s/%global git .*/%global git $COMMIT/"  ${SPEC_FILE}
+sed -i "s/%global checkout_date .*/%global checkout_date $DATE/" ${SPEC_FILE}
+
+rpmdev-bumpspec --comment="Fresh git checkout." --userstring="Jens Lody <fedora@jenslody.de>" ${SPEC_FILE}
+
+vi ${SPEC_FILE}
+
 cp ${SPEC_FILE} ${SPEC_PATH}${SPEC_FILE}
+rm -f ${SPEC_FILE}
+mv ${SPEC_FILE}.tmp ${SPEC_FILE}
 
 rm -f ${TARBALL_PATH}${GITHUB}-*.tar.gz
 wget -c ${BASE_URL}${GITHUB}-${COMMIT}.tar.gz -O ${TARBALL_PATH}${GITHUB}-${COMMIT}.tar.gz

Attachment: signature.asc
Description: PGP signature


Reply to: