← Back to team overview

ubuntu-touch-coreapps-reviewers team mailing list archive

[Merge] lp:ubuntu-weather-app/reboot into lp:ubuntu-weather-app

 

Nicholas Skaggs has proposed merging lp:ubuntu-weather-app/reboot into lp:ubuntu-weather-app.

Requested reviews:
  Ubuntu Weather Developers (ubuntu-weather-dev)

For more details, see:
https://code.launchpad.net/~ubuntu-weather-dev/ubuntu-weather-app/reboot/+merge/267098

This is a test for jenkins. As promised, Andrew wants to get the new jenkins goodness first :-)

If jenkins shows up here, only good things lie ahead.
-- 
Your team Ubuntu Weather Developers is requested to review the proposed merge of lp:ubuntu-weather-app/reboot into lp:ubuntu-weather-app.
=== added file '.bzrignore'
--- .bzrignore	1970-01-01 00:00:00 +0000
+++ .bzrignore	2015-08-05 19:54:56 +0000
@@ -0,0 +1,19 @@
+*.user*
+debian/files
+debian/tmp
+debian/ubuntu-weather-app*
+debian/app-template/
+debian/*.debhelper.log
+debian/*.substvars
+.build
+Makefile
+CMakeCache.txt
+CMakeFiles/
+*.cmake
+*.gmo
+*.mo
+*.desktop
+*.desktop.in
+*.desktop.in.in.h
+.excludes
+ubuntu-weather-app.json

=== renamed file '.bzrignore' => '.bzrignore.moved'
=== added file 'AUTHORS'
--- AUTHORS	1970-01-01 00:00:00 +0000
+++ AUTHORS	2015-08-05 19:54:56 +0000
@@ -0,0 +1,9 @@
+Weather reboot was started in 2015 and has received many contributions from the following people. 
+
+In addition, numerous translations, bug reports and other non-code contributions have been made which are equally valued.
+
+Andrew Hayzen <ahayzen@xxxxxxxxx>
+Daniel Holbach <daniel.holbach@xxxxxxxxxxxxx>
+Martin Borho <martin@xxxxxxxxx>
+Nekhelesh Ramananthan <krnekhelesh@xxxxxxxxx>
+Victor Thompson <victor.thompson@xxxxxxxxx>

=== renamed file 'AUTHORS' => 'AUTHORS.moved'
=== added file 'CMakeLists.txt'
--- CMakeLists.txt	1970-01-01 00:00:00 +0000
+++ CMakeLists.txt	2015-08-05 19:54:56 +0000
@@ -0,0 +1,101 @@
+project(com.ubuntu.weather)
+cmake_minimum_required(VERSION 2.8.9)
+
+find_program(INTLTOOL_MERGE intltool-merge)
+if(NOT INTLTOOL_MERGE)
+    message(FATAL_ERROR "Could not find intltool-merge, please install the intltool package")
+endif()
+find_program(INTLTOOL_EXTRACT intltool-extract)
+if(NOT INTLTOOL_EXTRACT)
+    message(FATAL_ERROR "Could not find intltool-extract, please install the intltool package")
+endif()
+
+set (UBUNTU_MANIFEST_PATH "manifest.json.in" CACHE INTERNAL "Relative path to the manifest file")
+set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -fno-permissive -pedantic -Wall -Wextra")
+
+find_package(Qt5Core REQUIRED)
+find_package(Qt5Qml REQUIRED)
+find_package(Qt5Quick REQUIRED)
+
+# Automatically create moc files
+set(CMAKE_AUTOMOC ON)
+
+option(INSTALL_TESTS "Install the tests on make install" on)
+option(CLICK_MODE "Build as a click package" on)
+
+# Tests
+enable_testing()
+
+# Standard install paths
+include(GNUInstallDirs)
+
+set(APP_NAME weather)
+set(APP_HARDCODE ubuntu-weather-app)
+set(MAIN_QML ${APP_HARDCODE}.qml)
+set(DESKTOP_FILE "${APP_HARDCODE}.desktop")
+set(ICON_FILE weather-app@xxxxxx)
+set(AUTOPILOT_DIR ubuntu_weather_app)
+
+# Set install paths
+if(CLICK_MODE)
+  set(CMAKE_INSTALL_PREFIX "/")
+  set(UBUNTU-WEATHER_APP_DIR "${CMAKE_INSTALL_DATADIR}/qml")
+
+  set(QT_IMPORTS_DIR "${CMAKE_INSTALL_LIBDIR}")
+  set(EXEC "qmlscene $@ ${UBUNTU-WEATHER_APP_DIR}/${MAIN_QML}")
+  set(MODULE_PATH ${QT_IMPORTS_DIR})
+  if(NOT BZR_REVNO)
+    execute_process(
+      COMMAND bzr revno
+              OUTPUT_VARIABLE BZR_REVNO
+              WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
+              OUTPUT_STRIP_TRAILING_WHITESPACE
+      )
+  endif(NOT BZR_REVNO)
+  if(NOT BZR_SOURCE)
+    set(BZR_SOURCE "lp:${APP_HARDCODE}/reboot")
+    message("-- Setting BZR_SOURCE to ${BZR_SOURCE}")
+  endif(NOT BZR_SOURCE)
+else(CLICK_MODE)
+  set(UBUNTU-WEATHER_APP_DIR "${CMAKE_INSTALL_DATADIR}/ubuntu-weather-app")
+  execute_process(
+    COMMAND qmake -query QT_INSTALL_QML
+            OUTPUT_VARIABLE QT_IMPORTS_DIR
+            OUTPUT_STRIP_TRAILING_WHITESPACE
+    )
+  set(MODULE_PATH ${QT_IMPORTS_DIR}/WeatherApp)
+endif(CLICK_MODE)
+
+if(${CLICK_MODE})
+  message("-- Configuring manifest.json")
+
+  configure_file(${UBUNTU_MANIFEST_PATH} ${CMAKE_CURRENT_BINARY_DIR}/manifest.json)
+  install(FILES ${CMAKE_CURRENT_BINARY_DIR}/manifest.json DESTINATION ${CMAKE_INSTALL_PREFIX})
+  install(FILES "${APP_HARDCODE}.apparmor" DESTINATION ${CMAKE_INSTALL_PREFIX})
+else(CLICK_MODE)
+  set(EXEC "qmlscene $@ -I ${MODULE_PATH}  ${CMAKE_INSTALL_PREFIX}/${UBUNTU-WEATHER_APP_DIR}/${MAIN_QML}")
+endif()
+
+
+file(GLOB_RECURSE I18N_SRC_FILES
+    RELATIVE ${CMAKE_CURRENT_SOURCE_DIR}/po
+    *.qml *.js)
+list(APPEND I18N_SRC_FILES ${DESKTOP_FILE}.in.in.h)
+list(SORT I18N_SRC_FILES)
+
+configure_file(${DESKTOP_FILE}.in.in ${DESKTOP_FILE}.in)
+
+add_custom_target(${DESKTOP_FILE} ALL
+    COMMENT "Merging translations into ${DESKTOP_FILE}..."
+    COMMAND LC_ALL=C ${INTLTOOL_MERGE} -d -u ${CMAKE_SOURCE_DIR}/po ${DESKTOP_FILE}.in ${DESKTOP_FILE}
+)
+
+install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${DESKTOP_FILE}
+        DESTINATION ${CMAKE_INSTALL_DATADIR}/applications)
+
+add_subdirectory(app)
+add_subdirectory(po)
+add_subdirectory(tests)
+
+# TODO: Add custom target for autopilot and run.
+

=== renamed file 'CMakeLists.txt' => 'CMakeLists.txt.moved'
=== added file 'COPYING'
--- COPYING	1970-01-01 00:00:00 +0000
+++ COPYING	2015-08-05 19:54:56 +0000
@@ -0,0 +1,674 @@
+                    GNU GENERAL PUBLIC LICENSE
+                       Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+                            Preamble
+
+  The GNU General Public License is a free, copyleft license for
+software and other kinds of works.
+
+  The licenses for most software and other practical works are designed
+to take away your freedom to share and change the works.  By contrast,
+the GNU General Public License is intended to guarantee your freedom to
+share and change all versions of a program--to make sure it remains free
+software for all its users.  We, the Free Software Foundation, use the
+GNU General Public License for most of our software; it applies also to
+any other work released this way by its authors.  You can apply it to
+your programs, too.
+
+  When we speak of free software, we are referring to freedom, not
+price.  Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+them if you wish), that you receive source code or can get it if you
+want it, that you can change the software or use pieces of it in new
+free programs, and that you know you can do these things.
+
+  To protect your rights, we need to prevent others from denying you
+these rights or asking you to surrender the rights.  Therefore, you have
+certain responsibilities if you distribute copies of the software, or if
+you modify it: responsibilities to respect the freedom of others.
+
+  For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must pass on to the recipients the same
+freedoms that you received.  You must make sure that they, too, receive
+or can get the source code.  And you must show them these terms so they
+know their rights.
+
+  Developers that use the GNU GPL protect your rights with two steps:
+(1) assert copyright on the software, and (2) offer you this License
+giving you legal permission to copy, distribute and/or modify it.
+
+  For the developers' and authors' protection, the GPL clearly explains
+that there is no warranty for this free software.  For both users' and
+authors' sake, the GPL requires that modified versions be marked as
+changed, so that their problems will not be attributed erroneously to
+authors of previous versions.
+
+  Some devices are designed to deny users access to install or run
+modified versions of the software inside them, although the manufacturer
+can do so.  This is fundamentally incompatible with the aim of
+protecting users' freedom to change the software.  The systematic
+pattern of such abuse occurs in the area of products for individuals to
+use, which is precisely where it is most unacceptable.  Therefore, we
+have designed this version of the GPL to prohibit the practice for those
+products.  If such problems arise substantially in other domains, we
+stand ready to extend this provision to those domains in future versions
+of the GPL, as needed to protect the freedom of users.
+
+  Finally, every program is threatened constantly by software patents.
+States should not allow patents to restrict development and use of
+software on general-purpose computers, but in those that do, we wish to
+avoid the special danger that patents applied to a free program could
+make it effectively proprietary.  To prevent this, the GPL assures that
+patents cannot be used to render the program non-free.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.
+
+                       TERMS AND CONDITIONS
+
+  0. Definitions.
+
+  "This License" refers to version 3 of the GNU General Public License.
+
+  "Copyright" also means copyright-like laws that apply to other kinds of
+works, such as semiconductor masks.
+
+  "The Program" refers to any copyrightable work licensed under this
+License.  Each licensee is addressed as "you".  "Licensees" and
+"recipients" may be individuals or organizations.
+
+  To "modify" a work means to copy from or adapt all or part of the work
+in a fashion requiring copyright permission, other than the making of an
+exact copy.  The resulting work is called a "modified version" of the
+earlier work or a work "based on" the earlier work.
+
+  A "covered work" means either the unmodified Program or a work based
+on the Program.
+
+  To "propagate" a work means to do anything with it that, without
+permission, would make you directly or secondarily liable for
+infringement under applicable copyright law, except executing it on a
+computer or modifying a private copy.  Propagation includes copying,
+distribution (with or without modification), making available to the
+public, and in some countries other activities as well.
+
+  To "convey" a work means any kind of propagation that enables other
+parties to make or receive copies.  Mere interaction with a user through
+a computer network, with no transfer of a copy, is not conveying.
+
+  An interactive user interface displays "Appropriate Legal Notices"
+to the extent that it includes a convenient and prominently visible
+feature that (1) displays an appropriate copyright notice, and (2)
+tells the user that there is no warranty for the work (except to the
+extent that warranties are provided), that licensees may convey the
+work under this License, and how to view a copy of this License.  If
+the interface presents a list of user commands or options, such as a
+menu, a prominent item in the list meets this criterion.
+
+  1. Source Code.
+
+  The "source code" for a work means the preferred form of the work
+for making modifications to it.  "Object code" means any non-source
+form of a work.
+
+  A "Standard Interface" means an interface that either is an official
+standard defined by a recognized standards body, or, in the case of
+interfaces specified for a particular programming language, one that
+is widely used among developers working in that language.
+
+  The "System Libraries" of an executable work include anything, other
+than the work as a whole, that (a) is included in the normal form of
+packaging a Major Component, but which is not part of that Major
+Component, and (b) serves only to enable use of the work with that
+Major Component, or to implement a Standard Interface for which an
+implementation is available to the public in source code form.  A
+"Major Component", in this context, means a major essential component
+(kernel, window system, and so on) of the specific operating system
+(if any) on which the executable work runs, or a compiler used to
+produce the work, or an object code interpreter used to run it.
+
+  The "Corresponding Source" for a work in object code form means all
+the source code needed to generate, install, and (for an executable
+work) run the object code and to modify the work, including scripts to
+control those activities.  However, it does not include the work's
+System Libraries, or general-purpose tools or generally available free
+programs which are used unmodified in performing those activities but
+which are not part of the work.  For example, Corresponding Source
+includes interface definition files associated with source files for
+the work, and the source code for shared libraries and dynamically
+linked subprograms that the work is specifically designed to require,
+such as by intimate data communication or control flow between those
+subprograms and other parts of the work.
+
+  The Corresponding Source need not include anything that users
+can regenerate automatically from other parts of the Corresponding
+Source.
+
+  The Corresponding Source for a work in source code form is that
+same work.
+
+  2. Basic Permissions.
+
+  All rights granted under this License are granted for the term of
+copyright on the Program, and are irrevocable provided the stated
+conditions are met.  This License explicitly affirms your unlimited
+permission to run the unmodified Program.  The output from running a
+covered work is covered by this License only if the output, given its
+content, constitutes a covered work.  This License acknowledges your
+rights of fair use or other equivalent, as provided by copyright law.
+
+  You may make, run and propagate covered works that you do not
+convey, without conditions so long as your license otherwise remains
+in force.  You may convey covered works to others for the sole purpose
+of having them make modifications exclusively for you, or provide you
+with facilities for running those works, provided that you comply with
+the terms of this License in conveying all material for which you do
+not control copyright.  Those thus making or running the covered works
+for you must do so exclusively on your behalf, under your direction
+and control, on terms that prohibit them from making any copies of
+your copyrighted material outside their relationship with you.
+
+  Conveying under any other circumstances is permitted solely under
+the conditions stated below.  Sublicensing is not allowed; section 10
+makes it unnecessary.
+
+  3. Protecting Users' Legal Rights From Anti-Circumvention Law.
+
+  No covered work shall be deemed part of an effective technological
+measure under any applicable law fulfilling obligations under article
+11 of the WIPO copyright treaty adopted on 20 December 1996, or
+similar laws prohibiting or restricting circumvention of such
+measures.
+
+  When you convey a covered work, you waive any legal power to forbid
+circumvention of technological measures to the extent such circumvention
+is effected by exercising rights under this License with respect to
+the covered work, and you disclaim any intention to limit operation or
+modification of the work as a means of enforcing, against the work's
+users, your or third parties' legal rights to forbid circumvention of
+technological measures.
+
+  4. Conveying Verbatim Copies.
+
+  You may convey verbatim copies of the Program's source code as you
+receive it, in any medium, provided that you conspicuously and
+appropriately publish on each copy an appropriate copyright notice;
+keep intact all notices stating that this License and any
+non-permissive terms added in accord with section 7 apply to the code;
+keep intact all notices of the absence of any warranty; and give all
+recipients a copy of this License along with the Program.
+
+  You may charge any price or no price for each copy that you convey,
+and you may offer support or warranty protection for a fee.
+
+  5. Conveying Modified Source Versions.
+
+  You may convey a work based on the Program, or the modifications to
+produce it from the Program, in the form of source code under the
+terms of section 4, provided that you also meet all of these conditions:
+
+    a) The work must carry prominent notices stating that you modified
+    it, and giving a relevant date.
+
+    b) The work must carry prominent notices stating that it is
+    released under this License and any conditions added under section
+    7.  This requirement modifies the requirement in section 4 to
+    "keep intact all notices".
+
+    c) You must license the entire work, as a whole, under this
+    License to anyone who comes into possession of a copy.  This
+    License will therefore apply, along with any applicable section 7
+    additional terms, to the whole of the work, and all its parts,
+    regardless of how they are packaged.  This License gives no
+    permission to license the work in any other way, but it does not
+    invalidate such permission if you have separately received it.
+
+    d) If the work has interactive user interfaces, each must display
+    Appropriate Legal Notices; however, if the Program has interactive
+    interfaces that do not display Appropriate Legal Notices, your
+    work need not make them do so.
+
+  A compilation of a covered work with other separate and independent
+works, which are not by their nature extensions of the covered work,
+and which are not combined with it such as to form a larger program,
+in or on a volume of a storage or distribution medium, is called an
+"aggregate" if the compilation and its resulting copyright are not
+used to limit the access or legal rights of the compilation's users
+beyond what the individual works permit.  Inclusion of a covered work
+in an aggregate does not cause this License to apply to the other
+parts of the aggregate.
+
+  6. Conveying Non-Source Forms.
+
+  You may convey a covered work in object code form under the terms
+of sections 4 and 5, provided that you also convey the
+machine-readable Corresponding Source under the terms of this License,
+in one of these ways:
+
+    a) Convey the object code in, or embodied in, a physical product
+    (including a physical distribution medium), accompanied by the
+    Corresponding Source fixed on a durable physical medium
+    customarily used for software interchange.
+
+    b) Convey the object code in, or embodied in, a physical product
+    (including a physical distribution medium), accompanied by a
+    written offer, valid for at least three years and valid for as
+    long as you offer spare parts or customer support for that product
+    model, to give anyone who possesses the object code either (1) a
+    copy of the Corresponding Source for all the software in the
+    product that is covered by this License, on a durable physical
+    medium customarily used for software interchange, for a price no
+    more than your reasonable cost of physically performing this
+    conveying of source, or (2) access to copy the
+    Corresponding Source from a network server at no charge.
+
+    c) Convey individual copies of the object code with a copy of the
+    written offer to provide the Corresponding Source.  This
+    alternative is allowed only occasionally and noncommercially, and
+    only if you received the object code with such an offer, in accord
+    with subsection 6b.
+
+    d) Convey the object code by offering access from a designated
+    place (gratis or for a charge), and offer equivalent access to the
+    Corresponding Source in the same way through the same place at no
+    further charge.  You need not require recipients to copy the
+    Corresponding Source along with the object code.  If the place to
+    copy the object code is a network server, the Corresponding Source
+    may be on a different server (operated by you or a third party)
+    that supports equivalent copying facilities, provided you maintain
+    clear directions next to the object code saying where to find the
+    Corresponding Source.  Regardless of what server hosts the
+    Corresponding Source, you remain obligated to ensure that it is
+    available for as long as needed to satisfy these requirements.
+
+    e) Convey the object code using peer-to-peer transmission, provided
+    you inform other peers where the object code and Corresponding
+    Source of the work are being offered to the general public at no
+    charge under subsection 6d.
+
+  A separable portion of the object code, whose source code is excluded
+from the Corresponding Source as a System Library, need not be
+included in conveying the object code work.
+
+  A "User Product" is either (1) a "consumer product", which means any
+tangible personal property which is normally used for personal, family,
+or household purposes, or (2) anything designed or sold for incorporation
+into a dwelling.  In determining whether a product is a consumer product,
+doubtful cases shall be resolved in favor of coverage.  For a particular
+product received by a particular user, "normally used" refers to a
+typical or common use of that class of product, regardless of the status
+of the particular user or of the way in which the particular user
+actually uses, or expects or is expected to use, the product.  A product
+is a consumer product regardless of whether the product has substantial
+commercial, industrial or non-consumer uses, unless such uses represent
+the only significant mode of use of the product.
+
+  "Installation Information" for a User Product means any methods,
+procedures, authorization keys, or other information required to install
+and execute modified versions of a covered work in that User Product from
+a modified version of its Corresponding Source.  The information must
+suffice to ensure that the continued functioning of the modified object
+code is in no case prevented or interfered with solely because
+modification has been made.
+
+  If you convey an object code work under this section in, or with, or
+specifically for use in, a User Product, and the conveying occurs as
+part of a transaction in which the right of possession and use of the
+User Product is transferred to the recipient in perpetuity or for a
+fixed term (regardless of how the transaction is characterized), the
+Corresponding Source conveyed under this section must be accompanied
+by the Installation Information.  But this requirement does not apply
+if neither you nor any third party retains the ability to install
+modified object code on the User Product (for example, the work has
+been installed in ROM).
+
+  The requirement to provide Installation Information does not include a
+requirement to continue to provide support service, warranty, or updates
+for a work that has been modified or installed by the recipient, or for
+the User Product in which it has been modified or installed.  Access to a
+network may be denied when the modification itself materially and
+adversely affects the operation of the network or violates the rules and
+protocols for communication across the network.
+
+  Corresponding Source conveyed, and Installation Information provided,
+in accord with this section must be in a format that is publicly
+documented (and with an implementation available to the public in
+source code form), and must require no special password or key for
+unpacking, reading or copying.
+
+  7. Additional Terms.
+
+  "Additional permissions" are terms that supplement the terms of this
+License by making exceptions from one or more of its conditions.
+Additional permissions that are applicable to the entire Program shall
+be treated as though they were included in this License, to the extent
+that they are valid under applicable law.  If additional permissions
+apply only to part of the Program, that part may be used separately
+under those permissions, but the entire Program remains governed by
+this License without regard to the additional permissions.
+
+  When you convey a copy of a covered work, you may at your option
+remove any additional permissions from that copy, or from any part of
+it.  (Additional permissions may be written to require their own
+removal in certain cases when you modify the work.)  You may place
+additional permissions on material, added by you to a covered work,
+for which you have or can give appropriate copyright permission.
+
+  Notwithstanding any other provision of this License, for material you
+add to a covered work, you may (if authorized by the copyright holders of
+that material) supplement the terms of this License with terms:
+
+    a) Disclaiming warranty or limiting liability differently from the
+    terms of sections 15 and 16 of this License; or
+
+    b) Requiring preservation of specified reasonable legal notices or
+    author attributions in that material or in the Appropriate Legal
+    Notices displayed by works containing it; or
+
+    c) Prohibiting misrepresentation of the origin of that material, or
+    requiring that modified versions of such material be marked in
+    reasonable ways as different from the original version; or
+
+    d) Limiting the use for publicity purposes of names of licensors or
+    authors of the material; or
+
+    e) Declining to grant rights under trademark law for use of some
+    trade names, trademarks, or service marks; or
+
+    f) Requiring indemnification of licensors and authors of that
+    material by anyone who conveys the material (or modified versions of
+    it) with contractual assumptions of liability to the recipient, for
+    any liability that these contractual assumptions directly impose on
+    those licensors and authors.
+
+  All other non-permissive additional terms are considered "further
+restrictions" within the meaning of section 10.  If the Program as you
+received it, or any part of it, contains a notice stating that it is
+governed by this License along with a term that is a further
+restriction, you may remove that term.  If a license document contains
+a further restriction but permits relicensing or conveying under this
+License, you may add to a covered work material governed by the terms
+of that license document, provided that the further restriction does
+not survive such relicensing or conveying.
+
+  If you add terms to a covered work in accord with this section, you
+must place, in the relevant source files, a statement of the
+additional terms that apply to those files, or a notice indicating
+where to find the applicable terms.
+
+  Additional terms, permissive or non-permissive, may be stated in the
+form of a separately written license, or stated as exceptions;
+the above requirements apply either way.
+
+  8. Termination.
+
+  You may not propagate or modify a covered work except as expressly
+provided under this License.  Any attempt otherwise to propagate or
+modify it is void, and will automatically terminate your rights under
+this License (including any patent licenses granted under the third
+paragraph of section 11).
+
+  However, if you cease all violation of this License, then your
+license from a particular copyright holder is reinstated (a)
+provisionally, unless and until the copyright holder explicitly and
+finally terminates your license, and (b) permanently, if the copyright
+holder fails to notify you of the violation by some reasonable means
+prior to 60 days after the cessation.
+
+  Moreover, your license from a particular copyright holder is
+reinstated permanently if the copyright holder notifies you of the
+violation by some reasonable means, this is the first time you have
+received notice of violation of this License (for any work) from that
+copyright holder, and you cure the violation prior to 30 days after
+your receipt of the notice.
+
+  Termination of your rights under this section does not terminate the
+licenses of parties who have received copies or rights from you under
+this License.  If your rights have been terminated and not permanently
+reinstated, you do not qualify to receive new licenses for the same
+material under section 10.
+
+  9. Acceptance Not Required for Having Copies.
+
+  You are not required to accept this License in order to receive or
+run a copy of the Program.  Ancillary propagation of a covered work
+occurring solely as a consequence of using peer-to-peer transmission
+to receive a copy likewise does not require acceptance.  However,
+nothing other than this License grants you permission to propagate or
+modify any covered work.  These actions infringe copyright if you do
+not accept this License.  Therefore, by modifying or propagating a
+covered work, you indicate your acceptance of this License to do so.
+
+  10. Automatic Licensing of Downstream Recipients.
+
+  Each time you convey a covered work, the recipient automatically
+receives a license from the original licensors, to run, modify and
+propagate that work, subject to this License.  You are not responsible
+for enforcing compliance by third parties with this License.
+
+  An "entity transaction" is a transaction transferring control of an
+organization, or substantially all assets of one, or subdividing an
+organization, or merging organizations.  If propagation of a covered
+work results from an entity transaction, each party to that
+transaction who receives a copy of the work also receives whatever
+licenses to the work the party's predecessor in interest had or could
+give under the previous paragraph, plus a right to possession of the
+Corresponding Source of the work from the predecessor in interest, if
+the predecessor has it or can get it with reasonable efforts.
+
+  You may not impose any further restrictions on the exercise of the
+rights granted or affirmed under this License.  For example, you may
+not impose a license fee, royalty, or other charge for exercise of
+rights granted under this License, and you may not initiate litigation
+(including a cross-claim or counterclaim in a lawsuit) alleging that
+any patent claim is infringed by making, using, selling, offering for
+sale, or importing the Program or any portion of it.
+
+  11. Patents.
+
+  A "contributor" is a copyright holder who authorizes use under this
+License of the Program or a work on which the Program is based.  The
+work thus licensed is called the contributor's "contributor version".
+
+  A contributor's "essential patent claims" are all patent claims
+owned or controlled by the contributor, whether already acquired or
+hereafter acquired, that would be infringed by some manner, permitted
+by this License, of making, using, or selling its contributor version,
+but do not include claims that would be infringed only as a
+consequence of further modification of the contributor version.  For
+purposes of this definition, "control" includes the right to grant
+patent sublicenses in a manner consistent with the requirements of
+this License.
+
+  Each contributor grants you a non-exclusive, worldwide, royalty-free
+patent license under the contributor's essential patent claims, to
+make, use, sell, offer for sale, import and otherwise run, modify and
+propagate the contents of its contributor version.
+
+  In the following three paragraphs, a "patent license" is any express
+agreement or commitment, however denominated, not to enforce a patent
+(such as an express permission to practice a patent or covenant not to
+sue for patent infringement).  To "grant" such a patent license to a
+party means to make such an agreement or commitment not to enforce a
+patent against the party.
+
+  If you convey a covered work, knowingly relying on a patent license,
+and the Corresponding Source of the work is not available for anyone
+to copy, free of charge and under the terms of this License, through a
+publicly available network server or other readily accessible means,
+then you must either (1) cause the Corresponding Source to be so
+available, or (2) arrange to deprive yourself of the benefit of the
+patent license for this particular work, or (3) arrange, in a manner
+consistent with the requirements of this License, to extend the patent
+license to downstream recipients.  "Knowingly relying" means you have
+actual knowledge that, but for the patent license, your conveying the
+covered work in a country, or your recipient's use of the covered work
+in a country, would infringe one or more identifiable patents in that
+country that you have reason to believe are valid.
+
+  If, pursuant to or in connection with a single transaction or
+arrangement, you convey, or propagate by procuring conveyance of, a
+covered work, and grant a patent license to some of the parties
+receiving the covered work authorizing them to use, propagate, modify
+or convey a specific copy of the covered work, then the patent license
+you grant is automatically extended to all recipients of the covered
+work and works based on it.
+
+  A patent license is "discriminatory" if it does not include within
+the scope of its coverage, prohibits the exercise of, or is
+conditioned on the non-exercise of one or more of the rights that are
+specifically granted under this License.  You may not convey a covered
+work if you are a party to an arrangement with a third party that is
+in the business of distributing software, under which you make payment
+to the third party based on the extent of your activity of conveying
+the work, and under which the third party grants, to any of the
+parties who would receive the covered work from you, a discriminatory
+patent license (a) in connection with copies of the covered work
+conveyed by you (or copies made from those copies), or (b) primarily
+for and in connection with specific products or compilations that
+contain the covered work, unless you entered into that arrangement,
+or that patent license was granted, prior to 28 March 2007.
+
+  Nothing in this License shall be construed as excluding or limiting
+any implied license or other defenses to infringement that may
+otherwise be available to you under applicable patent law.
+
+  12. No Surrender of Others' Freedom.
+
+  If conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot convey a
+covered work so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you may
+not convey it at all.  For example, if you agree to terms that obligate you
+to collect a royalty for further conveying from those to whom you convey
+the Program, the only way you could satisfy both those terms and this
+License would be to refrain entirely from conveying the Program.
+
+  13. Use with the GNU Affero General Public License.
+
+  Notwithstanding any other provision of this License, you have
+permission to link or combine any covered work with a work licensed
+under version 3 of the GNU Affero General Public License into a single
+combined work, and to convey the resulting work.  The terms of this
+License will continue to apply to the part which is the covered work,
+but the special requirements of the GNU Affero General Public License,
+section 13, concerning interaction through a network will apply to the
+combination as such.
+
+  14. Revised Versions of this License.
+
+  The Free Software Foundation may publish revised and/or new versions of
+the GNU General Public License from time to time.  Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+  Each version is given a distinguishing version number.  If the
+Program specifies that a certain numbered version of the GNU General
+Public License "or any later version" applies to it, you have the
+option of following the terms and conditions either of that numbered
+version or of any later version published by the Free Software
+Foundation.  If the Program does not specify a version number of the
+GNU General Public License, you may choose any version ever published
+by the Free Software Foundation.
+
+  If the Program specifies that a proxy can decide which future
+versions of the GNU General Public License can be used, that proxy's
+public statement of acceptance of a version permanently authorizes you
+to choose that version for the Program.
+
+  Later license versions may give you additional or different
+permissions.  However, no additional obligations are imposed on any
+author or copyright holder as a result of your choosing to follow a
+later version.
+
+  15. Disclaimer of Warranty.
+
+  THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
+APPLICABLE LAW.  EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
+HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
+OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
+THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
+IS WITH YOU.  SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
+ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+  16. Limitation of Liability.
+
+  IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
+THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
+GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
+USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
+DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
+PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
+EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGES.
+
+  17. Interpretation of Sections 15 and 16.
+
+  If the disclaimer of warranty and limitation of liability provided
+above cannot be given local legal effect according to their terms,
+reviewing courts shall apply local law that most closely approximates
+an absolute waiver of all civil liability in connection with the
+Program, unless a warranty or assumption of liability accompanies a
+copy of the Program in return for a fee.
+
+                     END OF TERMS AND CONDITIONS
+
+            How to Apply These Terms to Your New Programs
+
+  If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+  To do so, attach the following notices to the program.  It is safest
+to attach them to the start of each source file to most effectively
+state the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the program's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    This program 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.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+Also add information on how to contact you by electronic and paper mail.
+
+  If the program does terminal interaction, make it output a short
+notice like this when it starts in an interactive mode:
+
+    <program>  Copyright (C) <year>  <name of author>
+    This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+    This is free software, and you are welcome to redistribute it
+    under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License.  Of course, your program's commands
+might be different; for a GUI interface, you would use an "about box".
+
+  You should also get your employer (if you work as a programmer) or school,
+if any, to sign a "copyright disclaimer" for the program, if necessary.
+For more information on this, and how to apply and follow the GNU GPL, see
+<http://www.gnu.org/licenses/>.
+
+  The GNU General Public License does not permit incorporating your program
+into proprietary programs.  If your program is a subroutine library, you
+may consider it more useful to permit linking proprietary applications with
+the library.  If this is what you want to do, use the GNU Lesser General
+Public License instead of this License.  But first, please read
+<http://www.gnu.org/philosophy/why-not-lgpl.html>.

=== renamed file 'COPYING' => 'COPYING.moved'
=== added file 'README'
--- README	1970-01-01 00:00:00 +0000
+++ README	2015-08-05 19:54:56 +0000
@@ -0,0 +1,11 @@
+Weather app for Ubuntu devices
+
+To contribute:
+    https://wiki.ubuntu.com/Touch/CoreApps/Weather
+    https://wiki.ubuntu.com/Touch/CoreApps/DevelopmentGuide
+
+The following essential packages are required to develop this app:
+- ubuntu-sdk (see http://developer.ubuntu.com/start)
+- intltool - run the `sudo apt-get install intltool` command for installation
+
+See the debian/control file for an up-to-date list of dependencies

=== added file 'README.autopilot'
--- README.autopilot	1970-01-01 00:00:00 +0000
+++ README.autopilot	2015-08-05 19:54:56 +0000
@@ -0,0 +1,57 @@
+# Running Autopilot tests
+
+The Weather app follows a test driven development where autopilot tests are run before every merge into trunk. If you are submitting your bugfix/patch to the Weather app, please follow the following steps below to ensure that all tests pass before proposing a merge request.
+
+If you are looking for more info about Autopilot or writing AP tests for the weather app, here are some useful links to help you:
+
+- http://developer.ubuntu.com/start/quality
+- https://developer.ubuntu.com/api/autopilot/python/1.5.0/
+
+For help and options on running tests, see:
+
+- https://developer.ubuntu.com/en/start/platform/guides/running-autopilot-tests/
+
+## Prerequisites
+
+Install the following autopilot packages required to run the tests,
+$ sudo apt-get install python3-autopilot libautopilot-qt ubuntu-ui-toolkit-autopilot python3-autopilot-vis
+
+## Running tests on the desktop
+
+Using terminal:
+
+*  Branch the Weather app code, for example,
+    $ bzr branch lp:ubuntu-weather-app
+    
+*  Navigate to the tests/autopilot directory.
+    $ cd ubuntu-weather-app/tests/autopilot
+
+*  run all tests.
+    $ autopilot3 run -vv ubuntu_weather_app
+
+    to list all tests:
+    $ autopilot3 list ubuntu_weather_app
+
+    To run only one test (for instance: ubuntu_weather_app.tests.test_empty_state.TestEmptyState.test_add_location_button)
+    $ autopilot3 run -vv ubuntu_weather_app.tests.test_empty_state.TestEmptyState.test_add_location_button
+
+    Debugging tests using autopilot vis
+    $ autopilot3 launch -i Qt qmlscene app/ubuntu-weather-app.qml
+    $ autopilot3 vis
+
+
+## Running tests on device or emulator:
+
+Using autopkg:
+
+*  Branch the Weather app code, for example,
+    $ bzr branch lp:ubuntu-weather-app
+
+*  Navigate to the source directory.
+    $ cd ubuntu-weather-app
+
+*  Build a click package
+    $ click-buddy .
+
+*  Run the tests on device (assumes only one click package in the directory)
+    $ adt-run . *.click --- ssh -s adb -- -p <PASSWORD>

=== renamed file 'README' => 'README.moved'
=== added file 'README.translations'
--- README.translations	1970-01-01 00:00:00 +0000
+++ README.translations	2015-08-05 19:54:56 +0000
@@ -0,0 +1,37 @@
+# Updating translations
+
+Translations for the Weather app happen in [Launchpad Translations][] and
+are automatically committed daily on the trunk branch in the po/ folder.
+
+They are then built and installed as part of the package build, so that
+developers don't really need to worry about them.
+
+However, there is one task that needs to be taken care of: exposing new
+translatable messages to translators. So whenever you add new translatable
+messages in the code, make sure to follow these steps:
+
+ 1. Run click-buddy to build the project and generate a new .pot file:
+    `click-buddy --dir .`
+ 2. Commit the generated .pot file:
+    `bzr commit -m"Updated translation template"`
+ 3. Push the branch and send a merge proposal as usual
+
+And that's it, once the branch lands Launchpad should take care of all the rest!
+
+# Behind the scenes
+
+Behind the scenes, whenever the po/*.pot file (also known as translations template)
+is committed to trunk Launchpad reads it and updates the translatable strings
+exposed in the web UI. This will enable translators to work on the new strings.
+The translations template contains all translatable strings that have been
+extracted from the source code files.
+
+Launchpad will then store translations in its database and will commit them daily
+in the form of textual po/*.po files to trunk. The PO files are also usually
+referred to as the translations files. You'll find a translation file for each
+language the app has got at least a translated message available for.
+
+Translations for core apps follow the standard [gettext format].
+
+ [Launchpad Translations]: https://translations.launchpad.net/ubuntu-weather-app
+ [gettext format]: https://www.gnu.org/software/gettext/

=== renamed file 'README.translations' => 'README.translations.moved'
=== added directory 'app'
=== added file 'app/CMakeLists.txt'
--- app/CMakeLists.txt	1970-01-01 00:00:00 +0000
+++ app/CMakeLists.txt	2015-08-05 19:54:56 +0000
@@ -0,0 +1,16 @@
+if(NOT "${CMAKE_CURRENT_SOURCE_DIR}" STREQUAL "${CMAKE_CURRENT_BINARY_DIR}")
+  file(GLOB QML_JS_FILES *.qml *.js)
+  add_custom_target(ubuntu-weather-app_QMlFiles ALL SOURCES ${QML_JS_FILES})
+endif(NOT "${CMAKE_CURRENT_SOURCE_DIR}" STREQUAL "${CMAKE_CURRENT_BINARY_DIR}")
+
+
+set(ICON ${ICON_FILE})
+install(FILES ${ICON} DESTINATION ${CMAKE_INSTALL_PREFIX})
+
+install(FILES ${MAIN_QML} DESTINATION ${UBUNTU-WEATHER_APP_DIR})
+
+add_subdirectory(components)
+add_subdirectory(data)
+add_subdirectory(graphics)
+add_subdirectory(ui)
+

=== added directory 'app/components'
=== added file 'app/components/CMakeLists.txt'
--- app/components/CMakeLists.txt	1970-01-01 00:00:00 +0000
+++ app/components/CMakeLists.txt	2015-08-05 19:54:56 +0000
@@ -0,0 +1,7 @@
+add_subdirectory(ListItemActions)
+
+file(GLOB COMPONENTS_QML_JS_FILES *.qml *.js)
+
+add_custom_target(ubuntu-weather-app_components_QMlFiles ALL SOURCES ${COMPONENTS_QML_JS_FILES})
+
+install(FILES ${COMPONENTS_QML_JS_FILES} DESTINATION ${UBUNTU-WEATHER_APP_DIR}/components)

=== added file 'app/components/CurrentLocation.qml'
--- app/components/CurrentLocation.qml	1970-01-01 00:00:00 +0000
+++ app/components/CurrentLocation.qml	2015-08-05 19:54:56 +0000
@@ -0,0 +1,97 @@
+/*
+ * Copyright (C) 2015 Canonical Ltd
+ *
+ * This file is part of Ubuntu Weather App
+ *
+ * Ubuntu Weather App is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 3 as
+ * published by the Free Software Foundation.
+ *
+ * Ubuntu Weather App is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+import QtLocation 5.3
+import QtPositioning 5.2
+import QtQuick 2.4
+import Ubuntu.Components 1.2
+import "../data/WeatherApi.js" as WeatherApi
+
+
+Item {
+    id: currentLocation
+
+    property string string: "Undefined"
+
+    function searchForLocation(lat, lon) {
+        WeatherApi.sendRequest({
+                                   action: "searchByPoint",
+                                   params: {
+                                       coords: {
+                                           lat: lat,
+                                           lon: lon
+                                       }
+                                   }
+                               }, searchResponseHandler)
+    }
+
+    function searchResponseHandler(msgObject) {
+        if (!msgObject.error && settings.detectCurrentLocation) {
+            console.log("Loc to add:", JSON.stringify(msgObject.result.locations[0]))
+            storage.updateCurrentLocation(msgObject.result.locations[0])
+        }
+    }
+
+
+    PositionSource {
+        id: currentPosition
+        updateInterval: 1000
+        active: settings.detectCurrentLocation
+
+        onPositionChanged: {
+            var coord = currentPosition.position.coordinate
+            if (coord.isValid) {
+                geocodeModel.query = coord
+                geocodeModel.update()
+            }
+        }
+    }
+
+    Plugin {
+        id: osmPlugin
+        name: "osm"
+    }
+
+    GeocodeModel {
+        id: geocodeModel
+        autoUpdate: false
+        plugin: osmPlugin
+
+        onCountChanged: {
+            // Update the currentLocation if one is found and it does not match the stored location
+            if (count > 0 && currentLocation.string !== geocodeModel.get(0).address.city) {
+                search();
+            }
+        }
+
+        function search() {
+            var loc = geocodeModel.get(0)
+            currentLocation.string = loc.address.city
+            searchForLocation(loc.coordinate.latitude, loc.coordinate.longitude)
+        }
+    }
+
+    Connections {
+        target: settings
+        onDetectCurrentLocationChanged: {
+            if (settings.detectCurrentLocation) {
+                geocodeModel.search();
+            }
+        }
+    }
+}

=== added file 'app/components/DayDelegate.qml'
--- app/components/DayDelegate.qml	1970-01-01 00:00:00 +0000
+++ app/components/DayDelegate.qml	2015-08-05 19:54:56 +0000
@@ -0,0 +1,248 @@
+/*
+ * Copyright (C) 2015 Canonical Ltd
+ *
+ * This file is part of Ubuntu Weather App
+ *
+ * Ubuntu Weather App is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 3 as
+ * published by the Free Software Foundation.
+ *
+ * Ubuntu Weather App is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+import QtQuick 2.4
+import Ubuntu.Components 1.2
+
+ListItem {
+    id: dayDelegate
+    height: collapsedHeight
+
+    property int collapsedHeight: units.gu(8)
+    property int expandedHeight: collapsedHeight + units.gu(4) + extraInfoColumn.height
+
+    property alias day: dayLabel.text
+    property alias image: weatherImage.name
+    property alias high: highLabel.text
+    property alias low: lowLabel.text
+
+    property alias condition: conditionForecast.text
+    property alias chanceOfRain: chanceOfRainForecast.value
+    property alias humidity: humidityForecast.value
+    property alias pollen: pollenForecast.value
+    property alias sunrise: sunriseForecast.value
+    property alias sunset: sunsetForecast.value
+    property alias wind: windForecast.value
+    property alias uvIndex: uvIndexForecast.value
+
+    state: "normal"
+    states: [
+        State {
+            name: "normal"
+            PropertyChanges {
+                target: dayDelegate
+                height: collapsedHeight
+            }
+        },
+        State {
+            name: "expanded"
+            PropertyChanges {
+                target: dayDelegate
+                height: expandedHeight
+            }
+            PropertyChanges {
+                target: expandedInfo
+                opacity: 1
+            }
+        }
+    ]
+
+    transitions: [
+        Transition {
+            from: "normal"
+            to: "expanded"
+            SequentialAnimation {
+                NumberAnimation {
+                    easing.type: Easing.InOutQuad
+                    properties: "height"
+                }
+                NumberAnimation {
+                    easing.type: Easing.InOutQuad
+                    properties: "opacity"
+                }
+            }
+        },
+        Transition {
+            from: "expanded"
+            to: "normal"
+            SequentialAnimation {
+                NumberAnimation {
+                    easing.type: Easing.InOutQuad
+                    properties: "opacity"
+                }
+                NumberAnimation {
+                    easing.type: Easing.InOutQuad
+                    properties: "height"
+                }
+            }
+        }
+    ]
+
+    onClicked: {
+        state = state === "normal" ? "expanded" : "normal"
+        locationPages.collapseOtherDelegates(index)
+    }
+
+    Item {
+        id: mainInfo
+
+        height: collapsedHeight
+        anchors {
+            left: parent.left
+            right: parent.right
+            margins: units.gu(2)
+        }
+
+        Label {
+            id: dayLabel
+            anchors {
+                left: parent.left
+                right: weatherImage.left
+                rightMargin: units.gu(1)
+                top: parent.top
+                topMargin: (collapsedHeight - dayLabel.height) / 2
+            }
+            elide: Text.ElideRight
+            font.weight: Font.Light
+            fontSize: "medium"
+        }
+
+        Icon {
+            id: weatherImage
+            anchors {
+                horizontalCenter: parent.horizontalCenter
+                verticalCenter: dayLabel.verticalCenter
+            }
+            height: units.gu(3)
+            width: units.gu(3)
+        }
+
+        Label {
+            id: lowLabel
+            anchors {
+                left: weatherImage.right
+                right: highLabel.left
+                rightMargin: units.gu(1)
+                verticalCenter: dayLabel.verticalCenter
+            }
+            elide: Text.ElideRight
+            font.pixelSize: units.gu(2)
+            font.weight: Font.Light
+            fontSize: "medium"
+            height: units.gu(2)
+            horizontalAlignment: Text.AlignRight
+            verticalAlignment: Text.AlignTop  // AlignTop appears to align bottom?
+        }
+
+        Label {
+            id: highLabel
+            anchors {
+                bottom: lowLabel.bottom
+                right: parent.right
+            }
+            color: UbuntuColors.orange
+            elide: Text.ElideRight
+            font.pixelSize: units.gu(3)
+            font.weight: Font.Normal
+            height: units.gu(3)
+            verticalAlignment: Text.AlignTop  // AlignTop appears to align bottom?
+        }
+    }
+
+    Item {
+        id: expandedInfo
+        anchors {
+            bottom: parent.bottom
+            left: parent.left
+            right: parent.right
+            top: mainInfo.bottom
+            bottomMargin: units.gu(2)
+        }
+        opacity: 0
+        visible: opacity !== 0
+
+        Column {
+            id: extraInfoColumn
+            anchors {
+                centerIn: parent
+            }
+            spacing: units.gu(2)
+
+            // FIXME: extended-infomation_* aren't actually on device
+
+            // Overview text
+            Label {
+                id: conditionForecast
+                color: UbuntuColors.coolGrey
+                fontSize: "x-large"
+                horizontalAlignment: Text.AlignHCenter
+                width: parent.width
+            }
+
+            ForecastDetailsDelegate {
+                id: chanceOfRainForecast
+                forecast: i18n.tr("Chance of rain")
+                imageSource: "../graphics/extended-information_chance-of-rain.svg"
+            }
+
+            ForecastDetailsDelegate {
+                id: windForecast
+                forecast: i18n.tr("Winds")
+                imageSource: "../graphics/extended-information_wind.svg"
+            }
+
+            ForecastDetailsDelegate {
+                id: uvIndexForecast
+                imageSource: "../graphics/extended-information_uv-level.svg"
+                forecast: i18n.tr("UV Index")
+            }
+
+            ForecastDetailsDelegate {
+                id: pollenForecast
+                forecast: i18n.tr("Pollen")
+                // FIXME: need icon
+            }
+
+            ForecastDetailsDelegate {
+                id: humidityForecast
+                forecast: i18n.tr("Humidity")
+                imageSource: "../graphics/extended-information_humidity.svg"
+            }
+
+            ForecastDetailsDelegate {
+                id: sunriseForecast
+                forecast: i18n.tr("Sunrise")
+                imageSource: "../graphics/extended-information_sunrise.svg"
+            }
+
+            ForecastDetailsDelegate {
+                id: sunsetForecast
+                forecast: i18n.tr("Sunset")
+                imageSource: "../graphics/extended-information_sunset.svg"
+            }
+        }
+    }
+
+    Component.onCompleted: {
+        locationPages.collapseOtherDelegates.connect(function(otherIndex) {
+            if (dayDelegate && typeof index !== "undefined" && otherIndex !== index) {
+                state = "normal"
+            }
+        });
+    }
+}

=== added file 'app/components/EmptyStateComponent.qml'
--- app/components/EmptyStateComponent.qml	1970-01-01 00:00:00 +0000
+++ app/components/EmptyStateComponent.qml	2015-08-05 19:54:56 +0000
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2015 Canonical Ltd
+ *
+ * This file is part of Ubuntu Weather App
+ *
+ * Ubuntu Weather App is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 3 as
+ * published by the Free Software Foundation.
+ *
+ * Ubuntu Weather App is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+import QtQuick 2.4
+import Ubuntu.Components 1.2
+import "../components"
+
+
+Item {
+    anchors {
+        fill: parent
+        margins: units.gu(2)
+    }
+
+    SettingsButton {
+        anchors {
+            right: parent.right
+            top: parent.top
+        }
+    }
+
+    Column {
+        anchors {
+            centerIn: parent
+        }
+        spacing: units.gu(4)
+        width: parent.width - units.gu(4)
+
+        Label {
+            id: emptyStateLabel
+            anchors {
+                horizontalCenter: parent.horizontalCenter
+            }
+            horizontalAlignment: Text.AlignHCenter
+            text: settings.detectCurrentLoaction
+                  ? i18n.tr("Searching for current location...")
+                  : i18n.tr("Cannot determine your location")
+            width: parent.width
+            wrapMode: Text.WordWrap
+        }
+
+        Label {
+            anchors {
+                horizontalCenter: parent.horizontalCenter
+            }
+            horizontalAlignment: Text.AlignHCenter
+            text: i18n.tr("Manually add a location by swiping up from the bottom of the display")
+            width: parent.width
+            wrapMode: Text.WordWrap
+        }
+    }
+}

=== added file 'app/components/ExpandableListItem.qml'
--- app/components/ExpandableListItem.qml	1970-01-01 00:00:00 +0000
+++ app/components/ExpandableListItem.qml	2015-08-05 19:54:56 +0000
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 2015 Canonical Ltd
+ *
+ * This file is part of Ubuntu Weather App
+ *
+ * Ubuntu Weather App is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 3 as
+ * published by the Free Software Foundation.
+ *
+ * Ubuntu Weather App is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+import QtQuick 2.4
+import Ubuntu.Components 1.2
+import Ubuntu.Components.ListItems 1.0 as ListItem
+
+/*
+ Component which extends the SDK Expandable list item and provides a easy
+ to use component where the title, subtitle and listview can be displayed. It
+ matches the design specification provided for clock.
+*/
+
+ListItem.Expandable {
+    id: expandableListItem
+
+    property ListModel model
+    property Component delegate
+    property alias text: expandableHeader.text
+    property alias subText: expandableHeader.subText
+    property alias listViewHeight: expandableList.height
+
+    anchors {
+        left: parent.left
+        right: parent.right
+        margins: units.gu(-2)
+    }
+
+    collapseOnClick: true
+    expandedHeight: contentColumn.height + units.gu(1)
+
+    Column {
+        id: contentColumn
+
+        anchors {
+            left: parent.left
+            right: parent.right
+        }
+
+        Item {
+            width: parent.width
+            height: expandableListItem.collapsedHeight
+
+            ListItem.Subtitled {
+                id: expandableHeader
+                onClicked: expandableListItem.expanded = true
+
+                Icon {
+                    id: arrow
+
+                    width: units.gu(2)
+                    height: width
+                    anchors.right: parent.right
+                    anchors.verticalCenter: parent.verticalCenter
+
+                    name: "go-down"
+                    color: "Grey"
+                    rotation: expandableListItem.expanded ? 180 : 0
+
+                    Behavior on rotation {
+                        UbuntuNumberAnimation {}
+                    }
+                }
+            }
+        }
+
+        ListView {
+            id: expandableList
+            width: parent.width
+            interactive: false
+            model: expandableListItem.model
+            delegate: expandableListItem.delegate
+        }
+    }
+}

=== added file 'app/components/FastScroll.js'
--- app/components/FastScroll.js	1970-01-01 00:00:00 +0000
+++ app/components/FastScroll.js	2015-08-05 19:54:56 +0000
@@ -0,0 +1,130 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** Copyright (C) 2014 Canonical Ltda
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@xxxxxxxxx)
+**
+** This file is part of the Qt Components project.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+**   * Redistributions of source code must retain the above copyright
+**     notice, this list of conditions and the following disclaimer.
+**   * Redistributions in binary form must reproduce the above copyright
+**     notice, this list of conditions and the following disclaimer in
+**     the documentation and/or other materials provided with the
+**     distribution.
+**   * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
+**     the names of its contributors may be used to endorse or promote
+**     products derived from this software without specific prior written
+**     permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+// FastScroll.js - this is just SectionScroller.js with a fix for
+// section.criteria == ViewSection.FirstCharacter
+var sectionData = [];
+var _sections = [];
+
+function initialize(list) {
+    initSectionData(list);
+}
+
+function contains(name) {
+    return (_sections.indexOf(name) > -1)
+}
+
+function initSectionData(list) {
+    if (!list || !list.model) return;
+    sectionData = [];
+    _sections = [];
+    var current = "",
+        prop = list.section.property,
+        sectionText;
+
+    if (list.section.criteria === ViewSection.FullString) {
+        for (var i = 0, count = list.model.count; i < count; i++) {
+            sectionText = list.getSectionText(i)
+            if (sectionText !== current) {
+                current = sectionText;
+                _sections.push(current);
+                sectionData.push({ index: i, header: current });
+            }
+        }
+    } else if (list.section.criteria === ViewSection.FirstCharacter) {
+        for (var i = 0, count = list.model.count; i < count; i++) {
+            sectionText = list.getSectionText(i).substring(0, 1)
+            if (sectionText !== current) {
+                current = sectionText
+                _sections.push(sectionText);
+                sectionData.push({ index: i, header: current });
+            }
+        }
+    }
+}
+
+function getSectionPositionString(name) {
+    var val = _sections.indexOf(name);
+    return val === 0 ? "first" :
+           val === _sections.length - 1 ? "last" : false;
+}
+
+function getAt(pos) {
+    return _sections[pos] ? _sections[pos] : "";
+}
+
+function getRelativeSections(current) {
+    var val = _sections.indexOf(current),
+        sect = [],
+        sl = _sections.length;
+
+    val = val < 1 ? 1 : val >= sl-1 ? sl-2 : val;
+    sect = [getAt(val - 1), getAt(val), getAt(val + 1)];
+
+    return sect;
+}
+
+function getClosestSection(pos, down) {
+    var tmp = (_sections.length) * pos;
+    var val = Math.ceil(tmp) // TODO: better algorithm
+    val = val < 2 ? 1 : val;
+    return _sections[val-1];
+}
+
+function getNextSection(current) {
+    var val = _sections.indexOf(current);
+    return (val > -1 ? _sections[(val < _sections.length - 1 ? val + 1 : val)] : _sections[0]) || "";
+}
+
+function getPreviousSection(current) {
+    var val = _sections.indexOf(current);
+    return (val > -1 ? _sections[(val > 0 ? val - 1 : val)] : _sections[0]) || "";
+}
+
+function getIndexFor(sectionName) {
+    var data = sectionData[_sections.indexOf(sectionName)]
+    if (data) {
+        var val = data.index;
+        return val === 0 || val > 0 ? val : -1;
+    } else {
+        return -1
+    }
+}

=== added file 'app/components/FastScroll.qml'
--- app/components/FastScroll.qml	1970-01-01 00:00:00 +0000
+++ app/components/FastScroll.qml	2015-08-05 19:54:56 +0000
@@ -0,0 +1,321 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** Copyright (C) 2014, 2015 Canonical Ltda
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@xxxxxxxxx)
+**
+** This file is part of the Qt Components project.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+**   * Redistributions of source code must retain the above copyright
+**     notice, this list of conditions and the following disclaimer.
+**   * Redistributions in binary form must reproduce the above copyright
+**     notice, this list of conditions and the following disclaimer in
+**     the documentation and/or other materials provided with the
+**     distribution.
+**   * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
+**     the names of its contributors may be used to endorse or promote
+**     products derived from this software without specific prior written
+**     permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+// FastScroll.qml
+import QtQuick 2.4
+import Ubuntu.Components 1.2
+import "FastScroll.js" as Sections
+
+Item {
+    id: root
+
+    property ListView listView
+    property int pinSize: units.gu(2)
+
+    readonly property var letters: ["A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z"]
+    readonly property alias fastScrolling: internal.fastScrolling
+    readonly property bool showing: (rail.opacity !== 0.0)
+    readonly property double minimumHeight: rail.height
+
+    width: units.gu(7)
+    height: rail.height
+
+    onListViewChanged: {
+        if (listView && listView.model) {
+            internal.initDirtyObserver();
+        } else if (listView) {
+            listView.modelChanged.connect(function() {
+                if (listView.model) {
+                    internal.initDirtyObserver();
+                }
+            });
+        }
+    }
+
+    Connections {
+        target: listView
+        onCurrentIndexChanged: {
+            if (currentIndex != -1) {
+                rail.opacity = 0.0
+            }
+        }
+    }
+
+    Rectangle {
+        id: magnified
+
+        color: Theme.palette.normal.overlay
+        radius: height * 0.3
+        height: pinSize * 2
+        width: height
+        opacity: internal.fastScrolling && root.enabled ? 1.0 : 0.0
+        x: -cursor.width - units.gu(3)
+        y: {
+            if (internal.currentItem) {
+                var itemCenterY = rail.y + internal.currentItem.y + (internal.currentItem.height / 2)
+                return (itemCenterY - (magnified.height / 2))
+            } else {
+                return 0
+            }
+        }
+
+        Label {
+            anchors.fill: parent
+            horizontalAlignment: Text.AlignHCenter
+            verticalAlignment: Text.AlignVCenter
+            text: internal.desireSection
+            fontSize: "small"
+        }
+
+        Behavior on opacity {
+            UbuntuNumberAnimation {}
+        }
+    }
+
+    Rectangle {
+        id: cursor
+
+        property bool showLabel: false
+        property string currentSectionName: ""
+
+        radius: pinSize * 0.3
+        height: pinSize
+        width: height
+        color: Theme.palette.normal.foreground
+        opacity: rail.opacity
+        x: rail.x
+        y: {
+            if (internal.currentItem) {
+                var itemCenterY = rail.y + internal.currentItem.y + (internal.currentItem.height / 2)
+                return (itemCenterY - (cursor.height / 2))
+            } else {
+                return 0
+            }
+        }
+        Behavior on y {
+            enabled: !internal.fastScrolling
+            UbuntuNumberAnimation { }
+        }
+    }
+
+    Column {
+        id: rail
+
+        property bool isVisible: root.enabled &&
+                                 (listView.flicking || dragArea.pressed) &&
+                                 (listView.currentIndex == -1)
+        anchors {
+            right: parent.right
+            rightMargin: units.gu(2)
+            left: parent.left
+            leftMargin: units.gu(2)
+            top: parent.top
+        }
+        height: childrenRect.height
+        opacity: 0.0
+        onIsVisibleChanged: {
+            if (isVisible) {
+                rail.opacity = 1.0
+                hideTimer.stop()
+            } else if (!root.enabled) {
+                rail.opacity = 0.0
+            } else {
+                hideTimer.restart()
+            }
+        }
+
+        Behavior on opacity {
+            UbuntuNumberAnimation { }
+        }
+
+        Repeater {
+            id: sectionsRepeater
+
+            model: root.letters
+            Label {
+                id: lbl
+
+                anchors.left: parent.left
+                height: pinSize
+                width: pinSize
+                verticalAlignment: Text.AlignVCenter
+                horizontalAlignment: Text.AlignHCenter
+                text: modelData
+                fontSize: "x-small"
+                color: cursor.y === y ? "white" : Theme.palette.selected.backgroundText
+                opacity: !internal.modelDirty && Sections.contains(text) ? 1.0 : 0.5
+            }
+        }
+
+        Timer {
+            id: hideTimer
+
+            running: false
+            interval: 2000
+            onTriggered: rail.opacity = 0.0
+        }
+    }
+
+    MouseArea {
+        id: dragArea
+
+        anchors {
+            left: parent.left
+            right: parent.right
+        }
+        y: rail.y
+        height: rail.height
+        visible: rail.opacity == 1.0
+
+        preventStealing: true
+        onPressed: {
+            internal.adjustContentPosition(mouseY)
+            dragginTimer.start()
+        }
+
+        onReleased: {
+            dragginTimer.stop()
+            internal.desireSection = ""
+            internal.fastScrolling = false
+        }
+
+        onPositionChanged: internal.adjustContentPosition(mouseY)
+
+        Timer {
+            id: dragginTimer
+
+            running: false
+            interval: 150
+            onTriggered: {
+                internal.fastScrolling = true
+            }
+        }
+    }
+
+    Timer {
+        id: dirtyTimer
+        interval: 500
+        running: false
+        onTriggered: {
+            Sections.initSectionData(listView);
+            internal.modelDirty = false;
+        }
+    }
+
+    Timer {
+        id: timerScroll
+
+        running: false
+        interval: 10
+        onTriggered: {
+            if (internal.desireSection != internal.currentSection) {
+                var idx = Sections.getIndexFor(internal.desireSection)
+                if (idx !== -1) {
+                    listView.cancelFlick()
+                    listView.positionViewAtIndex(idx, ListView.Beginning)
+                }
+            }
+        }
+    }
+
+    QtObject {
+        id: internal
+
+        property string currentSection: listView.currentSection
+        property string desireSection: ""
+        property string targetSection: fastScrolling ? desireSection : currentSection
+        property int oldY: 0
+        property bool modelDirty: false
+        property bool down: true
+        property bool fastScrolling: false
+        property var currentItem: null
+
+        onTargetSectionChanged: moveIndicator(targetSection)
+
+        function initDirtyObserver() {
+            Sections.initialize(listView);
+            function dirtyObserver() {
+                if (!internal.modelDirty) {
+                    internal.modelDirty = true;
+                    dirtyTimer.running = true;
+                }
+            }
+
+            if (listView.model.countChanged)
+                listView.model.countChanged.connect(dirtyObserver);
+
+            if (listView.model.itemsChanged)
+                listView.model.itemsChanged.connect(dirtyObserver);
+
+            if (listView.model.itemsInserted)
+                listView.model.itemsInserted.connect(dirtyObserver);
+
+            if (listView.model.itemsMoved)
+                listView.model.itemsMoved.connect(dirtyObserver);
+
+            if (listView.model.itemsRemoved)
+                listView.model.itemsRemoved.connect(dirtyObserver);
+        }
+
+        function adjustContentPosition(mouseY) {
+            var child = rail.childAt(rail.width / 2, mouseY)
+            if (!child || child.text === "") {
+                return
+            }
+            var section = child.text
+            if (internal.desireSection !== section) {
+                internal.desireSection = section
+                moveIndicator(section)
+                if (dragArea.pressed) {
+                    timerScroll.restart()
+                }
+            }
+        }
+
+        function moveIndicator(section)
+        {
+            var index = root.letters.indexOf(section)
+            if (index != -1) {
+                currentItem = sectionsRepeater.itemAt(index)
+            }
+        }
+    }
+}

=== added file 'app/components/ForecastDetailsDelegate.qml'
--- app/components/ForecastDetailsDelegate.qml	1970-01-01 00:00:00 +0000
+++ app/components/ForecastDetailsDelegate.qml	2015-08-05 19:54:56 +0000
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2015 Canonical Ltd
+ *
+ * This file is part of Ubuntu Weather App
+ *
+ * Ubuntu Weather App is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 3 as
+ * published by the Free Software Foundation.
+ *
+ * Ubuntu Weather App is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+import QtQuick 2.4
+import Ubuntu.Components 1.2
+
+Row {
+    height: icon.height
+    spacing: units.gu(2)
+    visible: value !== ""
+
+    property alias imageName: icon.name
+    property alias imageSource: icon.source
+    property alias forecast: forecastLabel.text
+    property alias value: forecastValue.text
+    
+    Icon {
+        id: icon
+        color: "#000"
+        height: units.gu(2)
+        width: height
+    }
+    
+    Label {
+        id: forecastLabel
+        elide: Text.ElideRight
+        width: units.gu(14)
+    }
+    
+    Label {
+        id: forecastValue
+        width: units.gu(10)
+    }
+}

=== added file 'app/components/HeaderRow.qml'
--- app/components/HeaderRow.qml	1970-01-01 00:00:00 +0000
+++ app/components/HeaderRow.qml	2015-08-05 19:54:56 +0000
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2015 Canonical Ltd
+ *
+ * This file is part of Ubuntu Weather App
+ *
+ * Ubuntu Weather App is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 3 as
+ * published by the Free Software Foundation.
+ *
+ * Ubuntu Weather App is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+import QtQuick 2.4
+import QtQuick.Layouts 1.1
+import Ubuntu.Components 1.2
+
+RowLayout {
+    id: headerRow
+
+    property alias locationName: locationNameLabel.text
+
+    width: parent.width
+
+    Label {
+        id: locationNameLabel
+        color: UbuntuColors.darkGrey
+        elide: Text.ElideRight
+        font.weight: Font.Normal
+        fontSize: "large"
+        height: settingsButton.height
+        Layout.fillWidth: true
+        verticalAlignment: Text.AlignVCenter
+    }
+
+    SettingsButton {
+        id: settingsButton
+    }
+}

=== added file 'app/components/HomeGraphic.qml'
--- app/components/HomeGraphic.qml	1970-01-01 00:00:00 +0000
+++ app/components/HomeGraphic.qml	2015-08-05 19:54:56 +0000
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2015 Canonical Ltd
+ *
+ * This file is part of Ubuntu Weather App
+ *
+ * Ubuntu Weather App is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 3 as
+ * published by the Free Software Foundation.
+ *
+ * Ubuntu Weather App is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+import QtQuick 2.4
+import Ubuntu.Components 1.2
+
+Item {
+    height: units.gu(32)
+    width: parent.width
+
+    property alias icon: iconImage.source
+
+    // TODO: will be on 'rails' (horizontal listview?) to reveal hourly forecast
+    Image {
+        id: iconImage
+        anchors {
+            centerIn: parent
+        }
+        fillMode: Image.PreserveAspectFit
+        height: parent.height
+        width: parent.width
+    }
+}
+

=== added file 'app/components/HomeHourly.qml'
--- app/components/HomeHourly.qml	1970-01-01 00:00:00 +0000
+++ app/components/HomeHourly.qml	2015-08-05 19:54:56 +0000
@@ -0,0 +1,101 @@
+/*
+ * Copyright (C) 2015 Canonical Ltd
+ *
+ * This file is part of Ubuntu Weather App
+ *
+ * Ubuntu Weather App is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 3 as
+ * published by the Free Software Foundation.
+ *
+ * Ubuntu Weather App is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+import QtQuick 2.4
+import Ubuntu.Components 1.2
+
+ListView {
+    id: homeHourly
+
+    clip:true
+    height: parent ? parent.height : undefined
+    width: parent ? parent.width : undefined
+    model: forecasts.length
+    orientation: ListView.Horizontal
+
+    property string currentDate: Qt.formatTime(new Date())
+
+    onVisibleChanged: {
+        if(visible) {
+            ListView.model = forecasts.length
+        }
+    }
+
+    MouseArea {
+        anchors.fill: parent
+        onClicked: {
+            homeGraphic.visible = true
+        }
+    }
+
+    delegate: Item {
+        id: delegate
+
+        property var hourData: forecasts[index]
+
+        height: parent.height
+        width: childrenRect.width
+
+        Column {
+            id: hourColumn
+
+            anchors.verticalCenter: parent.verticalCenter
+            height: childrenRect.height
+            width: units.gu(10)
+
+            Label {
+                anchors.horizontalCenter: parent.horizontalCenter
+                fontSize: "small"
+                font.weight: Font.Light
+                text: currentDate.search(Qt.locale().amText) !== -1 || currentDate.search(Qt.locale().pmText) !== -1 ? "%1 %2".arg(formatTimestamp(hourData.date, 'ddd')).arg(formatTime(hourData.date, 'hap')) : "%1 %2".arg(formatTimestamp(hourData.date, 'ddd')).arg(formatTime(hourData.date, 'h:mm'))
+            }
+
+            Item {
+                anchors.horizontalCenter: parent.horizontalCenter
+                height: units.gu(7)
+                width: units.gu(7)
+
+                Icon {
+                    anchors {
+                        fill: parent
+                        margins: units.gu(0.5)
+                    }
+                    color: UbuntuColors.orange
+                    name: (hourData.icon !== undefined && iconMap[hourData.icon] !== undefined) ? iconMap[hourData.icon] : ""
+                }
+            }
+
+            Label {
+                anchors.horizontalCenter: parent.horizontalCenter
+                font.pixelSize: units.gu(3)
+                font.weight: Font.Light
+                text: Math.round(hourData[tempUnits].temp).toString()+settings.tempScale
+            }
+        }
+
+        Rectangle {
+            anchors.verticalCenter: parent.verticalCenter
+            color: UbuntuColors.darkGrey
+            height: hourColumn.height
+            opacity: 0.2
+            visible: index > 0
+            width: units.gu(0.1)
+        }
+    }
+}
+

=== added file 'app/components/HomeTempInfo.qml'
--- app/components/HomeTempInfo.qml	1970-01-01 00:00:00 +0000
+++ app/components/HomeTempInfo.qml	2015-08-05 19:54:56 +0000
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2015 Canonical Ltd
+ *
+ * This file is part of Ubuntu Weather App
+ *
+ * Ubuntu Weather App is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 3 as
+ * published by the Free Software Foundation.
+ *
+ * Ubuntu Weather App is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+import QtQuick 2.4
+import Ubuntu.Components 1.2
+
+
+Column {
+    anchors {
+        left: parent.left
+        right: parent.right
+    }
+    spacing: units.gu(1)
+
+    property alias description: descriptionLabel.text
+    property alias high: highLabel.text
+    property alias low: lowLabel.text
+    property alias now: nowLabel.text
+
+    Label {
+        font.weight: Font.Light
+        fontSize: "small"
+        text: i18n.tr("Today")
+    }
+
+    Label {
+        id: descriptionLabel
+        font.weight: Font.Normal
+        fontSize: "large"
+    }
+
+    Row {
+        spacing: units.gu(2)
+
+        Label {
+            id: nowLabel
+            color: UbuntuColors.orange
+            font.pixelSize: units.gu(8)
+            font.weight: Font.Light
+            height: units.gu(8)
+            verticalAlignment: Text.AlignBottom  // AlignBottom seems to put it at the top?
+        }
+
+        Column {
+            Label {
+                id: lowLabel
+                font.weight: Font.Light
+                fontSize: "medium"
+            }
+
+            Label {
+                id: highLabel
+                font.weight: Font.Light
+                fontSize: "medium"
+            }
+        }
+    }
+}

=== added directory 'app/components/ListItemActions'
=== added file 'app/components/ListItemActions/CMakeLists.txt'
--- app/components/ListItemActions/CMakeLists.txt	1970-01-01 00:00:00 +0000
+++ app/components/ListItemActions/CMakeLists.txt	2015-08-05 19:54:56 +0000
@@ -0,0 +1,5 @@
+file(GLOB LISTITEMACTIONS_QML_JS_FILES *.qml *.js)
+
+add_custom_target(ubuntu-weather-app_listitemactions_QMlFiles ALL SOURCES ${LISTITEMACTIONS_QML_JS_FILES})
+
+install(FILES ${LISTITEMACTIONS_QML_JS_FILES} DESTINATION ${UBUNTU-WEATHER_APP_DIR}/components/ListItemActions)

=== added file 'app/components/ListItemActions/CheckBox.qml'
--- app/components/ListItemActions/CheckBox.qml	1970-01-01 00:00:00 +0000
+++ app/components/ListItemActions/CheckBox.qml	2015-08-05 19:54:56 +0000
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2012-2014, 2015 Canonical, Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+import QtQuick 2.4
+import Ubuntu.Components 1.2
+
+CheckBox {
+    checked: root.selected
+    width: implicitWidth
+    // disable item mouse area to avoid conflicts with parent mouse area
+    __mouseArea.enabled: false
+}

=== added file 'app/components/ListItemActions/Remove.qml'
--- app/components/ListItemActions/Remove.qml	1970-01-01 00:00:00 +0000
+++ app/components/ListItemActions/Remove.qml	2015-08-05 19:54:56 +0000
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2014, 2015 Andrew Hayzen <ahayzen@xxxxxxxxx>
+ *                    Daniel Holm <d.holmen@xxxxxxxxx>
+ *                    Victor Thompson <victor.thompson@xxxxxxxxx>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+import QtQuick 2.4
+import Ubuntu.Components 1.2
+
+Action {
+    id: removeAction
+    iconName: "delete"
+    objectName: "swipeDeleteAction"
+    text: i18n.tr("Remove")
+}

=== added file 'app/components/ListItemReorderComponent.qml'
--- app/components/ListItemReorderComponent.qml	1970-01-01 00:00:00 +0000
+++ app/components/ListItemReorderComponent.qml	2015-08-05 19:54:56 +0000
@@ -0,0 +1,106 @@
+/*
+ * Copyright (C) 2013, 2014, 2015
+ *      Andrew Hayzen <ahayzen@xxxxxxxxx>
+ *      Nekhelesh Ramananthan <krnekhelesh@xxxxxxxxx>
+ *      Victor Thompson <victor.thompson@xxxxxxxxx>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+import QtQuick 2.4
+import Ubuntu.Components 1.2
+
+
+Item {
+    id: actionReorder
+    width: units.gu(4)
+
+    Icon {
+        anchors {
+            horizontalCenter: parent.horizontalCenter
+            verticalCenter: parent.verticalCenter
+        }
+        name: "navigation-menu"  // TODO: use proper image
+        height: width
+        width: units.gu(3)
+    }
+
+    MouseArea {
+        id: actionReorderMouseArea
+        anchors {
+            fill: parent
+        }
+        property int startY: 0
+        property int startContentY: 0
+
+        onPressed: {
+            root.parent.parent.interactive = false;  // stop scrolling of listview
+            startY = root.y;
+            startContentY = root.parent.parent.contentY;
+            root.z += 10;  // force ontop of other elements
+
+            console.debug("Reorder listitem pressed", root.y)
+        }
+        onMouseYChanged: root.y += mouse.y - (root.height / 2);
+        onReleased: {
+            console.debug("Reorder diff by position", getDiff());
+
+            var diff = getDiff();
+
+            // Remove the height of the actual item if moved down
+            if (diff > 0) {
+                diff -= 1;
+            }
+
+            root.parent.parent.interactive = true;  // reenable scrolling
+
+            if (diff === 0) {
+                // Nothing has changed so reset the item
+                // z index is restored after animation
+                resetListItemYAnimation.start();
+            }
+            else {
+                var newIndex = index + diff;
+
+                if (newIndex < 0) {
+                    newIndex = 0;
+                }
+                else if (newIndex > root.parent.parent.count - 1) {
+                    newIndex = root.parent.parent.count - 1;
+                }
+
+                root.z -= 10;  // restore z index
+                reorder(index, newIndex)
+            }
+        }
+
+        function getDiff() {
+            // Get the amount of items that have been passed over (by centre)
+            return Math.round((((root.y - startY) + (root.parent.parent.contentY - startContentY)) / root.height) + 0.5);
+        }
+    }
+
+    SequentialAnimation {
+        id: resetListItemYAnimation
+        UbuntuNumberAnimation {
+            target: root;
+            property: "y";
+            to: actionReorderMouseArea.startY
+        }
+        ScriptAction {
+            script: {
+                root.z -= 10;  // restore z index
+            }
+        }
+    }
+}

=== added file 'app/components/ListItemWithActions.qml'
--- app/components/ListItemWithActions.qml	1970-01-01 00:00:00 +0000
+++ app/components/ListItemWithActions.qml	2015-08-05 19:54:56 +0000
@@ -0,0 +1,496 @@
+/*
+ * Copyright (C) 2012-2015 Canonical, Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+import QtQuick 2.4
+import Ubuntu.Components 1.2
+import Ubuntu.Components.ListItems 1.0 as ListItem
+
+
+Item {
+    id: root
+    width: parent.width
+
+    property Action leftSideAction: null
+    property list<Action> rightSideActions
+    property double defaultHeight: units.gu(8)
+    property bool locked: false
+    property Action activeAction: null
+    property var activeItem: null
+    property bool triggerActionOnMouseRelease: false
+    property color color: Theme.palette.normal.background
+    property color selectedColor: "#E6E6E6"
+    property bool selected: false
+    property bool selectionMode: false
+    property alias internalAnchors: mainContents.anchors
+    default property alias contents: mainContents.children
+
+    readonly property double actionWidth: units.gu(4)
+    readonly property double leftActionWidth: units.gu(10)
+    readonly property double actionThreshold: actionWidth * 0.4
+    readonly property double threshold: 0.4
+    readonly property string swipeState: main.x == 0 ? "Normal" : main.x > 0 ? "LeftToRight" : "RightToLeft"
+    readonly property alias swipping: mainItemMoving.running
+    readonly property bool _showActions: mouseArea.pressed || swipeState != "Normal" || swipping
+
+    property alias _main: main  // CUSTOM
+    property alias pressed: mouseArea.pressed  // CUSTOM
+
+    /* internal */
+    property var _visibleRightSideActions: filterVisibleActions(rightSideActions)
+
+    signal itemClicked(var mouse)
+    signal itemPressAndHold(var mouse)
+
+    function returnToBoundsRTL(direction)
+    {
+        var actionFullWidth = actionWidth + units.gu(2)
+
+        // go back to normal state if swipping reverse
+        if (direction === "LTR") {
+            updatePosition(0)
+            return
+        } else if (!triggerActionOnMouseRelease) {
+            updatePosition(-rightActionsView.width + units.gu(2))
+            return
+        }
+
+        var xOffset = Math.abs(main.x)
+        var index = Math.min(Math.floor(xOffset / actionFullWidth), _visibleRightSideActions.length)
+        var newX = 0
+
+        if (index === _visibleRightSideActions.length) {
+            newX = -(rightActionsView.width - units.gu(2))
+        } else if (index >= 1) {
+            newX = -(actionFullWidth * index)
+        }
+
+        updatePosition(newX)
+    }
+
+    function returnToBoundsLTR(direction)
+    {
+        var finalX = leftActionWidth
+        if ((direction === "RTL") || (main.x <= (finalX * root.threshold)))
+            finalX = 0
+        updatePosition(finalX)
+    }
+
+    function returnToBounds(direction)
+    {
+        if (main.x < 0) {
+            returnToBoundsRTL(direction)
+        } else if (main.x > 0) {
+            returnToBoundsLTR(direction)
+        } else {
+            updatePosition(0)
+        }
+    }
+
+    function contains(item, point, marginX)
+    {
+        var itemStartX = item.x - marginX
+        var itemEndX = item.x + item.width + marginX
+        return (point.x >= itemStartX) && (point.x <= itemEndX) &&
+               (point.y >= item.y) && (point.y <= (item.y + item.height));
+    }
+
+    function getActionAt(point)
+    {
+        if (leftSideAction && contains(leftActionViewLoader.item, point, 0)) {
+            return leftSideAction
+        } else if (contains(rightActionsView, point, 0)) {
+            var newPoint = root.mapToItem(rightActionsView, point.x, point.y)
+            for (var i = 0; i < rightActionsRepeater.count; i++) {
+                var child = rightActionsRepeater.itemAt(i)
+                if (contains(child, newPoint, units.gu(1))) {
+                    return i
+                }
+            }
+        }
+        return -1
+    }
+
+    function updateActiveAction()
+    {
+        if (triggerActionOnMouseRelease &&
+            (main.x <= -(root.actionWidth + units.gu(2))) &&
+            (main.x > -(rightActionsView.width - units.gu(2)))) {
+            var actionFullWidth = actionWidth + units.gu(2)
+            var xOffset = Math.abs(main.x)
+            var index = Math.min(Math.floor(xOffset / actionFullWidth), _visibleRightSideActions.length)
+            index = index - 1
+            if (index > -1) {
+                root.activeItem = rightActionsRepeater.itemAt(index)
+                root.activeAction = root._visibleRightSideActions[index]
+            }
+        } else {
+            root.activeAction = null
+        }
+    }
+
+    function resetSwipe()
+    {
+        updatePosition(0)
+    }
+
+    function filterVisibleActions(actions)
+    {
+        var visibleActions = []
+        for(var i = 0; i < actions.length; i++) {
+            var action = actions[i]
+            if (action.visible) {
+                visibleActions.push(action)
+            }
+        }
+        return visibleActions
+    }
+
+    function updatePosition(pos)
+    {
+        if (!root.triggerActionOnMouseRelease && (pos !== 0)) {
+            mouseArea.state = pos > 0 ? "RightToLeft" : "LeftToRight"
+        } else {
+            mouseArea.state = ""
+        }
+        main.x = pos
+    }
+
+    // CUSTOM remove animation
+    SequentialAnimation {
+        id: removeAnimation
+
+        property var action
+
+        UbuntuNumberAnimation {
+            target: root
+            duration: UbuntuAnimation.BriskDuration
+            property: "height";
+            to: 0
+        }
+        ScriptAction {
+            script: removeAnimation.action.trigger()
+        }
+    }
+
+    states: [
+        State {
+            name: "select"
+            when: selectionMode || selected
+            PropertyChanges {
+                target: selectionIcon
+                source: Qt.resolvedUrl("ListItemActions/CheckBox.qml")
+                anchors.leftMargin: units.gu(2)
+            }
+            PropertyChanges {
+                target: root
+                locked: true
+            }
+            PropertyChanges {
+                target: main
+                x: 0
+            }
+        }
+    ]
+
+    height: defaultHeight
+    //clip: height !== defaultHeight  // CUSTOM
+
+    Loader {  // CUSTOM
+        id: leftActionViewLoader
+        anchors {
+            top: parent.top
+            bottom: parent.bottom
+            right: main.left
+        }
+        asynchronous: true
+        sourceComponent: leftSideAction ? leftActionViewComponent : undefined
+    }
+
+    Component {  // CUSTOM
+        id: leftActionViewComponent
+
+        Rectangle {
+            id: leftActionView
+            width: root.leftActionWidth + actionThreshold
+            color: UbuntuColors.red
+
+            Icon {
+                id: leftActionIcon
+                anchors {
+                    centerIn: parent
+                    horizontalCenterOffset: actionThreshold / 2
+                }
+                objectName: "swipeDeleteAction"  // CUSTOM
+                name: leftSideAction && _showActions ? leftSideAction.iconName : ""
+                color: Theme.palette.selected.field
+                height: units.gu(3)
+                width: units.gu(3)
+            }
+        }
+    }
+
+    //Rectangle {
+    Item {  // CUSTOM
+       id: rightActionsView
+
+       anchors {
+           top: main.top
+           left: main.right
+           bottom: main.bottom
+       }
+       visible: _visibleRightSideActions.length > 0
+       width: rightActionsRepeater.count > 0 ? rightActionsRepeater.count * (root.actionWidth + units.gu(2)) + root.actionThreshold + units.gu(2) : 0
+       // color: "white"  // CUSTOM
+
+       Row {
+           anchors{
+               top: parent.top
+               left: parent.left
+               leftMargin: units.gu(2)
+               right: parent.right
+               rightMargin: units.gu(2)
+               bottom: parent.bottom
+           }
+           spacing: units.gu(2)
+           Repeater {
+               id: rightActionsRepeater
+
+               model: _showActions ? _visibleRightSideActions : []
+               Item {
+                   property alias image: img
+
+                   height: rightActionsView.height
+                   width: root.actionWidth
+
+                   Icon {
+                       id: img
+
+                       anchors.centerIn: parent
+                       objectName: rightSideActions[index].objectName  // CUSTOM
+                       width: units.gu(3)
+                       height: units.gu(3)
+                       name: modelData.iconName
+                       color: root.activeAction === modelData ? UbuntuColors.orange : UbuntuColors.coolGrey  // CUSTOM
+                   }
+               }
+           }
+       }
+    }
+
+    Rectangle {
+        id: main
+        objectName: "mainItem"
+
+        anchors {
+            top: parent.top
+            bottom: parent.bottom
+        }
+
+        width: parent.width
+        color: root.selected ? root.selectedColor : root.color
+
+        Loader {
+            id: selectionIcon
+
+            anchors {
+                left: main.left
+                verticalCenter: main.verticalCenter
+            }
+            asynchronous: true  // CUSTOM
+            width: (status === Loader.Ready) ? item.implicitWidth : 0
+            visible: (status === Loader.Ready) && (item.width === item.implicitWidth)
+
+            Behavior on width {
+                NumberAnimation {
+                    duration: UbuntuAnimation.SnapDuration
+                }
+            }
+        }
+
+        Item {
+            id: mainContents
+
+            anchors {
+                left: selectionIcon.right
+                //leftMargin: units.gu(2)  // CUSTOM
+                top: parent.top
+                //topMargin: units.gu(1)  // CUSTOM
+                right: parent.right
+                //rightMargin: units.gu(2)  // CUSTOM
+                bottom: parent.bottom
+                //bottomMargin: units.gu(1)  // CUSTOM
+            }
+        }
+
+        Behavior on x {
+            UbuntuNumberAnimation {
+                id: mainItemMoving
+
+                easing.type: Easing.OutElastic
+                duration: UbuntuAnimation.SlowDuration
+            }
+        }
+    }
+
+    SequentialAnimation {
+        id: triggerAction
+
+        property var currentItem: root.activeItem ? root.activeItem.image : null
+
+        running: false
+        ParallelAnimation {
+            UbuntuNumberAnimation {
+                target: triggerAction.currentItem
+                property: "opacity"
+                from: 1.0
+                to: 0.0
+                duration: UbuntuAnimation.SlowDuration
+                easing {type: Easing.InOutBack; }
+            }
+            UbuntuNumberAnimation {
+                target: triggerAction.currentItem
+                properties: "width, height"
+                from: units.gu(3)
+                to: root.actionWidth
+                duration: UbuntuAnimation.SlowDuration
+                easing {type: Easing.InOutBack; }
+            }
+        }
+        PropertyAction {
+            target: triggerAction.currentItem
+            properties: "width, height"
+            value: units.gu(3)
+        }
+        PropertyAction {
+            target: triggerAction.currentItem
+            properties: "opacity"
+            value: 1.0
+        }
+        ScriptAction {
+            script: {
+                root.activeAction.triggered(root)
+                mouseArea.state = ""
+            }
+        }
+        PauseAnimation {
+            duration: 500
+        }
+        UbuntuNumberAnimation {
+            target: main
+            property: "x"
+            to: 0
+        }
+    }
+
+    MouseArea {
+        id: mouseArea
+
+        property bool locked: root.locked || ((root.leftSideAction === null) && (root._visibleRightSideActions.count === 0))  // CUSTOM
+        property bool manual: false
+        property string direction: "None"
+        property real lastX: -1
+
+        anchors.fill: parent
+        drag {
+            target: locked ? null : main
+            axis: Drag.XAxis
+            minimumX: rightActionsView.visible ? -(rightActionsView.width) : 0
+            maximumX: leftSideAction ? leftActionViewLoader.item.width : 0
+            threshold: root.actionThreshold
+        }
+
+        states: [
+            State {
+                name: "LeftToRight"
+                PropertyChanges {
+                    target: mouseArea
+                    drag.maximumX: 0
+                }
+            },
+            State {
+                name: "RightToLeft"
+                PropertyChanges {
+                    target: mouseArea
+                    drag.minimumX: 0
+                }
+            }
+        ]
+
+        onMouseXChanged: {
+            var offset = (lastX - mouseX)
+            if (Math.abs(offset) <= root.actionThreshold) {
+                return
+            }
+            lastX = mouseX
+            direction = offset > 0 ? "RTL" : "LTR";
+        }
+
+        onPressed: {
+            lastX = mouse.x
+        }
+
+        onReleased: {
+            if (root.triggerActionOnMouseRelease && root.activeAction) {
+                triggerAction.start()
+            } else {
+                root.returnToBounds()
+                root.activeAction = null
+            }
+            lastX = -1
+            direction = "None"
+        }
+        onClicked: {
+            if (selectionMode) {  // CUSTOM - selecting a listitem should toggle selection if in selectionMode
+                selected = !selected
+                return
+            } else if (main.x === 0) {
+                root.itemClicked(mouse)
+            } else if (main.x > 0) {
+                var action = getActionAt(Qt.point(mouse.x, mouse.y))
+                if (action && action !== -1) {
+                    //action.triggered(root)
+                    removeAnimation.action = action  // CUSTOM - use our animation instead
+                    removeAnimation.start()  // CUSTOM
+                }
+            } else {
+                var actionIndex = getActionAt(Qt.point(mouse.x, mouse.y))
+
+                if (actionIndex !== -1 && actionIndex !== leftSideAction) {  // CUSTOM - can be leftAction
+                    root.activeItem = rightActionsRepeater.itemAt(actionIndex)
+                    root.activeAction = root.rightSideActions[actionIndex]
+                    triggerAction.start()
+                    return
+                }
+            }
+            root.resetSwipe()
+        }
+
+        onPositionChanged: {
+            if (mouseArea.pressed) {
+                updateActiveAction()
+
+                listItemSwiping(index)  // CUSTOM - tells other listitems to dismiss any swipe
+            }
+        }
+        onPressAndHold: {
+            if (main.x === 0) {
+                root.itemPressAndHold(mouse)
+            }
+        }
+
+        z: -1
+    }
+}

=== added file 'app/components/LoadingIndicator.qml'
--- app/components/LoadingIndicator.qml	1970-01-01 00:00:00 +0000
+++ app/components/LoadingIndicator.qml	2015-08-05 19:54:56 +0000
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 2015 Canonical Ltd
+ *  
+ * This file is part of Ubuntu Weather App
+ *
+ * Ubuntu Weather App is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 3 as
+ * published by the Free Software Foundation.
+ *  
+ * Ubuntu Weather App is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+import QtQuick 2.4
+import Ubuntu.Components 1.2
+
+Rectangle {
+    id: indicator
+    objectName: "processingIndicator"
+    anchors {
+        left: parent.left
+        right: parent.right
+        bottom: parent.bottom
+        bottomMargin: Qt.inputMethod.keyboardRectangle.height
+    }
+    height: units.dp(3)
+    color: "white"
+    opacity: 0
+    visible: opacity > 0
+
+    readonly property bool processing: loading
+
+    Behavior on opacity {
+        UbuntuNumberAnimation { duration: UbuntuAnimation.FastDuration }
+    }
+
+    onProcessingChanged: {
+        if (processing) delay.start();
+        else if (!persist.running) indicator.opacity = 0;
+    }
+
+    Timer {
+        id: delay
+        interval: 200
+        onTriggered: if (indicator.processing) {
+            persist.restart();
+            indicator.opacity = 1;
+        }
+    }
+
+    Timer {
+        id: persist
+        interval: 2 * UbuntuAnimation.SleepyDuration - UbuntuAnimation.FastDuration
+        onTriggered: if (!indicator.processing) indicator.opacity = 0
+    }
+
+    Rectangle {
+        id: orange
+        anchors { top: parent.top;  bottom: parent.bottom }
+        width: parent.width / 4
+        color: UbuntuColors.orange
+
+        SequentialAnimation {
+            running: indicator.visible
+            loops: Animation.Infinite
+            XAnimator {
+                from: -orange.width / 2
+                to: indicator.width - orange.width / 2
+                duration: UbuntuAnimation.SleepyDuration
+                easing.type: Easing.InOutSine
+                target: orange
+            }
+            XAnimator {
+                from: indicator.width - orange.width / 2
+                to: -orange.width / 2
+                duration: UbuntuAnimation.SleepyDuration
+                easing.type: Easing.InOutSine
+                target: orange
+            }
+        }
+    }
+}

=== added file 'app/components/MultiSelectHeadState.qml'
--- app/components/MultiSelectHeadState.qml	1970-01-01 00:00:00 +0000
+++ app/components/MultiSelectHeadState.qml	2015-08-05 19:54:56 +0000
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2015
+ *      Andrew Hayzen <ahayzen@xxxxxxxxx>
+ *      Victor Thompson <victor.thompson@xxxxxxxxx>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+import QtQuick 2.4
+import Ubuntu.Components 1.2
+
+PageHeadState {
+    id: selectionState
+    actions: [
+        Action {
+            iconName: "select"
+            text: i18n.tr("Select All")
+            onTriggered: {
+                if (listview.selectedItems.length === listview.model.count) {
+                    listview.clearSelection()
+                } else {
+                    listview.selectAll()
+                }
+            }
+        },
+        Action {
+            enabled: listview.selectedItems.length > 0
+            iconName: "delete"
+            text: i18n.tr("Delete")
+            visible: removable
+
+            onTriggered: {
+                removed(listview.selectedItems)
+
+                listview.closeSelection()
+            }
+        }
+
+    ]
+    backAction: Action {
+        text: i18n.tr("Cancel selection")
+        iconName: "back"
+        onTriggered: {
+            listview.clearSelection()
+            listview.state = "normal"
+        }
+    }
+    head: thisPage.head
+    name: "selection"
+
+    PropertyChanges {
+        target: thisPage.head
+        backAction: selectionState.backAction
+        actions: selectionState.actions
+    }
+
+    property ListView listview
+    property bool removable: false
+    property Page thisPage
+
+    signal removed(var selectedItems)
+}

=== added file 'app/components/MultiSelectListView.qml'
--- app/components/MultiSelectListView.qml	1970-01-01 00:00:00 +0000
+++ app/components/MultiSelectListView.qml	2015-08-05 19:54:56 +0000
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2013, 2014, 2015
+ *      Andrew Hayzen <ahayzen@xxxxxxxxx>
+ *      Daniel Holm <d.holmen@xxxxxxxxx>
+ *      Victor Thompson <victor.thompson@xxxxxxxxx>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+import QtQuick 2.4
+import Ubuntu.Components 1.2
+
+
+WeatherListView {
+    property var selectedItems: []
+
+    signal clearSelection()
+    signal closeSelection()
+    signal selectAll()
+
+    onClearSelection: selectedItems = []
+    onCloseSelection: {
+        clearSelection()
+        state = "normal"
+    }
+    onSelectAll: {
+        var tmp = selectedItems
+
+        for (var i=0; i < model.count; i++) {
+            if (tmp.indexOf(i) === -1) {
+                tmp.push(i)
+            }
+        }
+
+        selectedItems = tmp
+    }
+    onVisibleChanged: {
+        if (!visible) {
+            closeSelection()
+        }
+    }
+}

=== added file 'app/components/PageWithBottomEdge.qml'
--- app/components/PageWithBottomEdge.qml	1970-01-01 00:00:00 +0000
+++ app/components/PageWithBottomEdge.qml	2015-08-05 19:54:56 +0000
@@ -0,0 +1,411 @@
+/*
+ * Copyright (C) 2014, 2015 Canonical, Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/*
+    Example:
+
+    MainView {
+        objectName: "mainView"
+
+        applicationName: "com.ubuntu.developer.boiko.bottomedge"
+
+        width: units.gu(100)
+        height: units.gu(75)
+
+        Component {
+            id: pageComponent
+
+            PageWithBottomEdge {
+                id: mainPage
+                title: i18n.tr("Main Page")
+
+                Rectangle {
+                    anchors.fill: parent
+                    color: "white"
+                }
+
+                bottomEdgePageComponent: Page {
+                    title: "Contents"
+                    anchors.fill: parent
+                    //anchors.topMargin: contentsPage.flickable.contentY
+
+                    ListView {
+                        anchors.fill: parent
+                        model: 50
+                        delegate: ListItems.Standard {
+                            text: "One Content Item: " + index
+                        }
+                    }
+                }
+                bottomEdgeTitle: i18n.tr("Bottom edge action")
+            }
+        }
+
+        PageStack {
+            id: stack
+            Component.onCompleted: stack.push(pageComponent)
+        }
+    }
+
+*/
+
+import QtQuick 2.4
+import Ubuntu.Components 1.2
+
+Page {
+    id: page
+
+    property alias bottomEdgePageComponent: edgeLoader.sourceComponent
+    property alias bottomEdgePageSource: edgeLoader.source
+    property alias bottomEdgeTitle: tipLabel.text
+    property bool bottomEdgeEnabled: true
+    property int bottomEdgeExpandThreshold: page.height * 0.2
+    property int bottomEdgeExposedArea: bottomEdge.state !== "expanded" ? (page.height - bottomEdge.y - bottomEdge.tipHeight) : _areaWhenExpanded
+    property bool reloadBottomEdgePage: true
+
+    readonly property alias bottomEdgePage: edgeLoader.item
+    readonly property bool isReady: ((bottomEdge.y === 0) && bottomEdgePageLoaded && edgeLoader.item.active)
+    readonly property bool isCollapsed: (bottomEdge.y === page.height)
+    readonly property bool bottomEdgePageLoaded: (edgeLoader.status == Loader.Ready)
+
+    property bool _showEdgePageWhenReady: false
+    property int _areaWhenExpanded: 0
+
+    // CUSTOM properties to allow changing of color
+    property alias tipColor: tip.color
+    property alias tipLabelColor: tipLabel.color
+
+    signal bottomEdgeReleased()
+    signal bottomEdgeDismissed()
+
+
+    function showBottomEdgePage(source, properties)
+    {
+        edgeLoader.setSource(source, properties)
+        _showEdgePageWhenReady = true
+    }
+
+    function setBottomEdgePage(source, properties)
+    {
+        edgeLoader.setSource(source, properties)
+    }
+
+    function _pushPage()
+    {
+        if (edgeLoader.status === Loader.Ready) {
+            edgeLoader.item.active = true
+            page.pageStack.push(edgeLoader.item)
+            if (edgeLoader.item.flickable) {
+                edgeLoader.item.flickable.contentY = -page.header.height
+                edgeLoader.item.flickable.returnToBounds()
+            }
+            if (edgeLoader.item.ready)
+                edgeLoader.item.ready()
+        }
+    }
+
+
+    Component.onCompleted: {
+        // avoid a binding on the expanded height value
+        var expandedHeight = height;
+        _areaWhenExpanded = expandedHeight;
+    }
+
+    onActiveChanged: {
+        if (active) {
+            bottomEdge.state = "collapsed"
+        }
+    }
+
+    onBottomEdgePageLoadedChanged: {
+        if (_showEdgePageWhenReady && bottomEdgePageLoaded) {
+            bottomEdge.state = "expanded"
+            _showEdgePageWhenReady = false
+        }
+    }
+
+    Rectangle {
+        id: bgVisual
+
+        color: "black"
+        anchors.fill: page
+        opacity: 0.7 * ((page.height - bottomEdge.y) / page.height)
+        z: 1
+    }
+
+    UbuntuShape {
+        id: tip
+        objectName: "bottomEdgeTip"
+
+        property bool hidden: (activeFocus === false) || ((bottomEdge.y - units.gu(1)) < tip.y)
+
+        enabled: mouseArea.enabled
+        visible: page.bottomEdgeEnabled
+        anchors {
+            bottom: parent.bottom
+            horizontalCenter: bottomEdge.horizontalCenter
+            bottomMargin: hidden ? - height + units.gu(1) : -units.gu(1)
+            Behavior on bottomMargin {
+                SequentialAnimation {
+                    // wait some msecs in case of the focus change again, to avoid flickering
+                    PauseAnimation {
+                        duration: 300
+                    }
+                    UbuntuNumberAnimation {
+                        duration: UbuntuAnimation.SnapDuration
+                    }
+                }
+            }
+        }
+
+        z: 1
+        width: tipLabel.paintedWidth + units.gu(6)
+        height: bottomEdge.tipHeight + units.gu(1)
+        color: Theme.palette.normal.overlay
+        Label {
+            id: tipLabel
+
+            anchors {
+                top: parent.top
+                left: parent.left
+                right: parent.right
+            }
+            height: bottomEdge.tipHeight
+            verticalAlignment: Text.AlignVCenter
+            horizontalAlignment: Text.AlignHCenter
+            opacity: tip.hidden ? 0.0 : 1.0
+            Behavior on opacity {
+                UbuntuNumberAnimation {
+                    duration: UbuntuAnimation.SnapDuration
+                }
+            }
+        }
+    }
+
+    Rectangle {
+        id: shadow
+
+        anchors {
+            left: parent.left
+            right: parent.right
+            bottom: parent.bottom
+        }
+        height: units.gu(1)
+        z: 1
+        opacity: 0.0
+        gradient: Gradient {
+            GradientStop { position: 0.0; color: "transparent" }
+            GradientStop { position: 1.0; color: Qt.rgba(0, 0, 0, 0.2) }
+        }
+    }
+
+    MouseArea {
+        id: mouseArea
+
+        property real previousY: -1
+        property string dragDirection: "None"
+
+        preventStealing: true
+        drag {
+            axis: Drag.YAxis
+            target: bottomEdge
+            minimumY: bottomEdge.pageStartY
+            maximumY: page.height
+        }
+        enabled: edgeLoader.status == Loader.Ready
+        visible: page.bottomEdgeEnabled
+
+        anchors {
+            left: parent.left
+            right: parent.right
+            bottom: parent.bottom
+
+        }
+        height: bottomEdge.tipHeight
+        z: 1
+
+        onReleased: {
+            page.bottomEdgeReleased()
+            if ((dragDirection === "BottomToTop") &&
+                bottomEdge.y < (page.height - bottomEdgeExpandThreshold - bottomEdge.tipHeight)) {
+                bottomEdge.state = "expanded"
+            } else {
+                bottomEdge.state = "collapsed"
+            }
+            previousY = -1
+            dragDirection = "None"
+        }
+
+        onPressed: {
+            previousY = mouse.y
+            tip.forceActiveFocus()
+        }
+
+        onMouseYChanged: {
+            var yOffset = previousY - mouseY
+            // skip if was a small move
+            if (Math.abs(yOffset) <= units.gu(2)) {
+                return
+            }
+            previousY = mouseY
+            dragDirection = yOffset > 0 ? "BottomToTop" : "TopToBottom"
+        }
+    }
+
+    Rectangle {
+        id: bottomEdge
+        objectName: "bottomEdge"
+
+        readonly property int tipHeight: units.gu(3)
+        readonly property int pageStartY: 0
+
+        z: 1
+        color: Theme.palette.normal.background
+        clip: true
+        anchors {
+            left: parent.left
+            right: parent.right
+        }
+        height: page.height
+        y: height
+        visible: !page.isCollapsed
+        state: "collapsed"
+        states: [
+            State {
+                name: "collapsed"
+                PropertyChanges {
+                    target: bottomEdge
+                    y: bottomEdge.height
+                }
+            },
+            State {
+                name: "expanded"
+                PropertyChanges {
+                    target: bottomEdge
+                    y: bottomEdge.pageStartY
+                }
+            },
+            State {
+                name: "floating"
+                when: mouseArea.drag.active
+                PropertyChanges {
+                    target: shadow
+                    opacity: 1.0
+                }
+            }
+        ]
+
+        transitions: [
+            Transition {
+                to: "expanded"
+                SequentialAnimation {
+                    alwaysRunToEnd: true
+
+                    SmoothedAnimation {
+                        target: bottomEdge
+                        property: "y"
+                        duration: UbuntuAnimation.FastDuration
+                        easing.type: Easing.Linear
+                    }
+                    SmoothedAnimation {
+                        target: edgeLoader
+                        property: "anchors.topMargin"
+                        to: - units.gu(4)
+                        duration: UbuntuAnimation.FastDuration
+                        easing.type: Easing.Linear
+                    }
+                    SmoothedAnimation {
+                        target: edgeLoader
+                        property: "anchors.topMargin"
+                        to: 0
+                        duration: UbuntuAnimation.FastDuration
+                        easing: UbuntuAnimation.StandardEasing
+                    }
+                    ScriptAction {
+                        script: page._pushPage()
+                    }
+                }
+            },
+            Transition {
+                from: "expanded"
+                to: "collapsed"
+                SequentialAnimation {
+                    alwaysRunToEnd: true
+
+                    ScriptAction {
+                        script: {
+                            Qt.inputMethod.hide()
+                            edgeLoader.item.parent = edgeLoader
+                            edgeLoader.item.anchors.fill = edgeLoader
+                            edgeLoader.item.active = false
+                        }
+                    }
+                    SmoothedAnimation {
+                        target: bottomEdge
+                        property: "y"
+                        duration: UbuntuAnimation.SlowDuration
+                    }
+                    ScriptAction {
+                        script: {
+                            // destroy current bottom page
+                            if (page.reloadBottomEdgePage) {
+                                edgeLoader.active = false
+                                // tip will receive focus on page active true
+                            } else {
+                                tip.forceActiveFocus()
+                            }
+
+                            // notify
+                            page.bottomEdgeDismissed()
+
+                            edgeLoader.active = true
+                        }
+                    }
+                }
+            },
+            Transition {
+                from: "floating"
+                to: "collapsed"
+                SmoothedAnimation {
+                    target: bottomEdge
+                    property: "y"
+                    duration: UbuntuAnimation.FastDuration
+                }
+            }
+        ]
+
+        Loader {
+            id: edgeLoader
+
+            asynchronous: true
+            anchors.fill: parent
+            //WORKAROUND: The SDK move the page contents down to allocate space for the header we need to avoid that during the page dragging
+            Binding {
+                target: edgeLoader.status === Loader.Ready ? edgeLoader : null
+                property: "anchors.topMargin"
+                value:  edgeLoader.item && edgeLoader.item.flickable ? edgeLoader.item.flickable.contentY : 0
+                when: !page.isReady
+            }
+
+            onLoaded: {
+                tip.forceActiveFocus()
+                if (page.isReady && edgeLoader.item.active !== true) {
+                    page._pushPage()
+                }
+            }
+        }
+    }
+}

=== added file 'app/components/SettingsButton.qml'
--- app/components/SettingsButton.qml	1970-01-01 00:00:00 +0000
+++ app/components/SettingsButton.qml	2015-08-05 19:54:56 +0000
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2015 Canonical Ltd
+ *
+ * This file is part of Ubuntu Weather App
+ *
+ * Ubuntu Weather App is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 3 as
+ * published by the Free Software Foundation.
+ *
+ * Ubuntu Weather App is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+import QtQuick 2.4
+import Ubuntu.Components 1.2
+
+
+AbstractButton {
+    id: settingsButton
+    height: width
+    width: units.gu(4)
+
+    onClicked: mainPageStack.push(Qt.resolvedUrl("../ui/SettingsPage.qml"))
+
+    Rectangle {
+        anchors.fill: parent
+        color: Theme.palette.selected.background
+        visible: parent.pressed
+    }
+
+    Icon {
+        anchors.centerIn: parent
+        color: UbuntuColors.darkGrey
+        height: width
+        name: "settings"
+        width: units.gu(2.5)
+    }
+}

=== added file 'app/components/StandardListItem.qml'
--- app/components/StandardListItem.qml	1970-01-01 00:00:00 +0000
+++ app/components/StandardListItem.qml	2015-08-05 19:54:56 +0000
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2015 Canonical Ltd
+ *
+ * This file is part of Ubuntu Weather App
+ *
+ * Ubuntu Weather App is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 3 as
+ * published by the Free Software Foundation.
+ *
+ * Ubuntu Weather App is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+import QtQuick 2.4
+import QtQuick.Layouts 1.1
+import Ubuntu.Components 1.2
+
+ListItem {
+    id: listItem
+
+    property alias title: _title.text
+    property alias icon: _icon.name
+    property alias showIcon: _icon.visible
+
+    RowLayout {
+        anchors { left: parent.left; right: parent.right; verticalCenter: parent.verticalCenter; margins: units.gu(2) }
+        height: _icon.height
+        spacing: units.gu(2)
+        
+        Label {
+            id: _title
+            anchors.verticalCenter: _icon.verticalCenter
+            elide: Text.ElideRight
+            Layout.fillWidth: true
+        }
+        
+        Icon {
+            id: _icon
+            height: units.gu(2); width: height
+            name: "go-next"
+        }
+    }
+}

=== added file 'app/components/WeatherListItem.qml'
--- app/components/WeatherListItem.qml	1970-01-01 00:00:00 +0000
+++ app/components/WeatherListItem.qml	2015-08-05 19:54:56 +0000
@@ -0,0 +1,137 @@
+/*
+ * Copyright (C) 2013, 2014, 2015
+ *      Andrew Hayzen <ahayzen@xxxxxxxxx>
+ *      Nekhelesh Ramananthan <krnekhelesh@xxxxxxxxx>
+ *      Victor Thompson <victor.thompson@xxxxxxxxx>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+import QtQuick 2.4
+import Ubuntu.Components 1.2
+
+ListItemWithActions {
+    id: root
+
+    property int listItemIndex: index
+    property bool multiselectable: false
+    property int previousListItemIndex: -1
+    property bool reorderable: false
+
+    signal reorder(int from, int to)
+
+    onItemPressAndHold: {
+        if (multiselectable) {
+            selectionMode = true
+        }
+    }
+
+    onListItemIndexChanged: {
+        var i = parent.parent.selectedItems.lastIndexOf(previousListItemIndex)
+
+        if (i !== -1) {
+            parent.parent.selectedItems[i] = listItemIndex
+        }
+
+        previousListItemIndex = listItemIndex
+    }
+
+    onSelectedChanged: {
+        if (selectionMode) {
+            var tmp = parent.parent.selectedItems
+
+            if (selected) {
+                if (parent.parent.selectedItems.indexOf(listItemIndex) === -1) {
+                    tmp.push(listItemIndex)
+                    parent.parent.selectedItems = tmp
+                }
+            } else {
+                tmp.splice(parent.parent.selectedItems.indexOf(listItemIndex), 1)
+                parent.parent.selectedItems = tmp
+            }
+        }
+    }
+
+    onSelectionModeChanged: {
+        if (reorderable && selectionMode) {
+            resetSwipe()
+        }
+
+        for (var j=0; j < _main.children.length; j++) {
+            if (_main.children[j] !== actionReorderLoader) {
+                _main.children[j].anchors.rightMargin = reorderable && selectionMode ? actionReorderLoader.width + units.gu(2) : 0
+            }
+        }
+
+        parent.parent.state = selectionMode ? "multiselectable" : "normal"
+
+        if (!selectionMode) {
+            selected = false
+        }
+    }
+
+    /* Highlight the listitem on press */
+    Rectangle {
+        id: listItemBrighten
+        color: root.pressed ? UbuntuColors.coolGrey : "transparent"
+        opacity: 0.1
+        height: root.height
+        x: root.x - parent.x  // -parent.x due to selectionIcon in ListItemWithActions
+        width: root.width
+    }
+
+    /* Reorder Component */
+    Loader {
+        id: actionReorderLoader
+        active: reorderable && selectionMode && root.parent.parent.selectedItems.length === 0
+        anchors {
+            bottom: parent.bottom
+            right: parent.right
+            rightMargin: units.gu(1)
+            top: parent.top
+        }
+        asynchronous: true
+        source: "ListItemReorderComponent.qml"
+    }
+
+    Item {
+        Connections {  // Only allow one ListItem to be swiping at any time
+            target: weatherApp
+            onListItemSwiping: {
+                if (i !== index) {
+                    root.resetSwipe();
+                }
+            }
+        }
+
+        Connections {  // Connections from signals in the ListView
+            target: root.parent.parent
+            onClearSelection: selected = false
+            onFlickingChanged: {
+                if (root.parent.parent.flicking) {
+                    root.resetSwipe()
+                }
+            }
+            onSelectAll: selected = true
+            onStateChanged: selectionMode = root.parent.parent.state === "multiselectable"
+        }
+    }
+
+    Component.onCompleted: {  // reload settings as delegates are destroyed
+        if (parent.parent.selectedItems.indexOf(index) !== -1) {
+            selected = true
+        }
+
+        selectionMode = root.parent.parent.state === "multiselectable"
+    }
+}

=== added file 'app/components/WeatherListView.qml'
--- app/components/WeatherListView.qml	1970-01-01 00:00:00 +0000
+++ app/components/WeatherListView.qml	2015-08-05 19:54:56 +0000
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2013, 2014, 2015
+ *      Andrew Hayzen <ahayzen@xxxxxxxxx>
+ *      Daniel Holm <d.holmen@xxxxxxxxx>
+ *      Victor Thompson <victor.thompson@xxxxxxxxx>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+import QtQuick 2.4
+import Ubuntu.Components 1.2
+
+
+ListView {
+    Component.onCompleted: {
+        // FIXME: workaround for qtubuntu not returning values depending on the grid unit definition
+        // for Flickable.maximumFlickVelocity and Flickable.flickDeceleration
+        var scaleFactor = units.gridUnit / 8;
+        maximumFlickVelocity = maximumFlickVelocity * scaleFactor;
+        flickDeceleration = flickDeceleration * scaleFactor;
+    }
+}

=== added directory 'app/data'
=== added file 'app/data/CMakeLists.txt'
--- app/data/CMakeLists.txt	1970-01-01 00:00:00 +0000
+++ app/data/CMakeLists.txt	2015-08-05 19:54:56 +0000
@@ -0,0 +1,5 @@
+file(GLOB DATA_QML_JS_FILES *.qml *.js)
+
+add_custom_target(ubuntu-weather-app_data_QMlFiles ALL SOURCES ${DATA_QML_JS_FILES})
+
+install(FILES ${DATA_QML_JS_FILES} DESTINATION ${UBUNTU-WEATHER_APP_DIR}/data)

=== added file 'app/data/CitiesList.js'
--- app/data/CitiesList.js	1970-01-01 00:00:00 +0000
+++ app/data/CitiesList.js	2015-08-05 19:54:56 +0000
@@ -0,0 +1,65 @@
+.pragma library
+/*
+ * Copyright (C) 2013 Canonical Ltd
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 3 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authored by: Martin Borho <martin@xxxxxxxxx>
+ */
+
+var preList = [
+    {"coord":{"lon":"4.88969","lat":"52.37403"},"timezone":{"gmtOffset":1,"dstOffset":2,"timeZoneId":"Europe/Amsterdam"},"population":741636,"adminName2":"Gemeente Amsterdam","name":"Amsterdam","country":"NL","countryName":"Netherlands","adminName1":"North Holland","adminName3":"","services":{"geonames":2759794},"areaLabel":"North Holland, Netherlands"},
+    {"coord":{"lon":"116.39723","lat":"39.9075"},"timezone":{"gmtOffset":8,"dstOffset":8,"timeZoneId":"Asia/Shanghai"},"population":7480601,"adminName2":"","name":"Beijing","country":"CN","countryName":"China","adminName1":"Beijing","adminName3":"","services":{"geonames":1816670},"areaLabel":"Beijing, China"},
+    {"coord":{"lon":"-74.08175","lat":"4.60971"},"timezone":{"gmtOffset":-5,"dstOffset":-5,"timeZoneId":"America/Bogota"},"population":7674366,"adminName2":"","name":"Bogotá","country":"CO","countryName":"Colombia","adminName1":"Bogota D.C.","adminName3":"","services":{"geonames":3688689},"areaLabel":"Bogota D.C., Colombia"},
+    {"coord":{"lon":"-58.37723","lat":"-34.61315"},"timezone":{"gmtOffset":-3,"dstOffset":-3,"timeZoneId":"America/Argentina/Buenos_Aires"},"population":13076300,"adminName2":"","name":"Buenos Aires","country":"AR","countryName":"Argentina","adminName1":"Buenos Aires F.D.","adminName3":"","services":{"geonames":3435910},"areaLabel":"Buenos Aires F.D., Argentina"},
+    {"coord":{"lon":"31.24967","lat":"30.06263"},"timezone":{"gmtOffset":2,"dstOffset":2,"timeZoneId":"Africa/Cairo"},"population":7734614,"adminName2":"","name":"Cairo","country":"EG","countryName":"Egypt","adminName1":"Al Qāhirah","adminName3":"","services":{"geonames":360630},"areaLabel":"Al Qāhirah, Egypt"},
+    {"coord":{"lon":"-66.87919","lat":"10.48801"},"timezone":{"gmtOffset":-4.5,"dstOffset":-4.5,"timeZoneId":"America/Caracas"},"population":3000000,"adminName2":"Municipio Libertador","name":"Caracas","country":"VE","countryName":"Venezuela","adminName1":"Distrito Federal","adminName3":"","services":{"geonames":3646738},"areaLabel":"Distrito Federal, Venezuela, Bolivarian Republic of"},
+    {"coord":{"lon":"-87.65005","lat":"41.85003"},"timezone":{"gmtOffset":-6,"dstOffset":-5,"timeZoneId":"America/Chicago"},"population":2695598,"adminName2":"Cook County","name":"Chicago","country":"US","countryName":"United States","adminName1":"Illinois","adminName3":"","services":{"geonames":4887398},"areaLabel":"Illinois, United States"},
+    {"coord":{"lon":"77.22897","lat":"28.65381"},"timezone":{"gmtOffset":5.5,"dstOffset":5.5,"timeZoneId":"Asia/Kolkata"},"population":10927986,"adminName2":"","name":"Dehli","country":"IN","countryName":"India","adminName1":"NCT","adminName3":"","services":{"geonames":1273294},"areaLabel":"NCT, India"},
+    {"coord":{"lon":"55.30472","lat":"25.25817"},"timezone":{"gmtOffset":4,"dstOffset":4,"timeZoneId":"Asia/Dubai"},"population":1137347,"adminName2":"","name":"Dubai","country":"AE","countryName":"United Arab Emirates","adminName1":"Dubai","adminName3":"","services":{"geonames":292223},"areaLabel":"Dubai, United Arab Emirates"},
+    {"coord":{"lon":"113.25","lat":"23.11667"},"timezone":{"gmtOffset":8,"dstOffset":8,"timeZoneId":"Asia/Shanghai"},"population":3152825,"adminName2":"","name":"Guangzhou","country":"CN","countryName":"China","adminName1":"Guangdong Province","adminName3":"","services":{"geonames":1809858},"areaLabel":"Guangdong Province, China"},
+    {"coord":{"lon":"10.01534","lat":"53.57532"},"timezone":{"gmtOffset":1,"dstOffset":2,"timeZoneId":"Europe/Berlin"},"population":1739117,"adminName2":"","name":"Hamburg","country":"DE","countryName":"Germany","adminName1":"Hamburg","adminName3":"","services":{"geonames":2911298},"areaLabel":"Hamburg, Germany"},
+    {"coord":{"lon":"-95.36327","lat":"29.76328"},"timezone":{"gmtOffset":-6,"dstOffset":-5,"timeZoneId":"America/Chicago"},"population":2099451,"adminName2":"Harris County","name":"Houston","country":"US","countryName":"United States","adminName1":"Texas","adminName3":"","services":{"geonames":4699066},"areaLabel":"Texas, United States"},
+    {"coord":{"lon":"28.94966","lat":"41.01384"},"timezone":{"gmtOffset":2,"dstOffset":3,"timeZoneId":"Europe/Istanbul"},"population":11174257,"adminName2":"","name":"Istanbul","country":"TR","countryName":"Turkey","adminName1":"Istanbul","adminName3":"","services":{"geonames":745044},"areaLabel":"Istanbul, Turkey"},
+    {"coord":{"lon":"106.84513","lat":"-6.21462"},"timezone":{"gmtOffset":7,"dstOffset":7,"timeZoneId":"Asia/Jakarta"},"population":8540121,"adminName2":"","name":"Jakarta","country":"ID","countryName":"Indonesia","adminName1":"Jakarta Raya","adminName3":"","services":{"geonames":1642911},"areaLabel":"Jakarta Raya, Indonesia"},
+    {"coord":{"lon":"28.04363","lat":"-26.20227"},"timezone":{"gmtOffset":2,"dstOffset":2,"timeZoneId":"Africa/Johannesburg"},"population":2026469,"adminName2":"City of Johannesburg Metropolitan Municipality","name":"Johannesburg","country":"ZA","countryName":"South Africa","adminName1":"Gauteng","adminName3":"City of Johannesburg","services":{"geonames":993800},"areaLabel":"Gauteng, South Africa"},
+    {"coord":{"lon":"67.0822","lat":"24.9056"},"timezone":{"gmtOffset":5,"dstOffset":5,"timeZoneId":"Asia/Karachi"},"population":11624219,"adminName2":"Karāchi District","name":"Karachi","country":"PK","countryName":"Pakistan","adminName1":"Sindh","adminName3":"","services":{"geonames":1174872},"areaLabel":"Sindh, Pakistan"},
+    {"coord":{"lon":"15.30807","lat":"-4.32142"},"timezone":{"gmtOffset":1,"dstOffset":1,"timeZoneId":"Africa/Kinshasa"},"population":7785965,"adminName2":"","name":"Kinshasa","country":"CD","countryName":"Democratic Republic of the Congo","adminName1":"Kinshasa","adminName3":"","services":{"geonames":2314302},"areaLabel":"Kinshasa, Congo, the Democratic Republic of the"},
+    {"coord":{"lon":"88.36304","lat":"22.56263"},"timezone":{"gmtOffset":5.5,"dstOffset":5.5,"timeZoneId":"Asia/Kolkata"},"population":4631392,"adminName2":"","name":"Kolkata","country":"IN","countryName":"India","adminName1":"Bengal","adminName3":"","services":{"geonames":1275004},"areaLabel":"Bengal, India"},
+    {"coord":{"lon":"3.39583","lat":"6.45306"},"timezone":{"gmtOffset":1,"dstOffset":1,"timeZoneId":"Africa/Lagos"},"population":9000000,"adminName2":"","name":"Lagos","country":"NG","countryName":"Nigeria","adminName1":"Lagos","adminName3":"","services":{"geonames":2332459},"areaLabel":"Lagos, Nigeria"},
+    {"coord":{"lon":"-77.02824","lat":"-12.04318"},"timezone":{"gmtOffset":-5,"dstOffset":-5,"timeZoneId":"America/Lima"},"population":7737002,"adminName2":"","name":"Lima","country":"PE","countryName":"Peru","adminName1":"Provincia de Lima","adminName3":"","services":{"geonames":3936456},"areaLabel":"Provincia de Lima, Peru"},
+    {"coord":{"lon":"-0.12574","lat":"51.50853"},"timezone":{"gmtOffset":0,"dstOffset":1,"timeZoneId":"Europe/London"},"population":7556900,"adminName2":"Greater London","name":"London","country":"GB","countryName":"United Kingdom","adminName1":"England","adminName3":"","services":{"geonames":2643743},"areaLabel":"England, Greater London, United Kingdom"},
+    {"coord":{"lon":"-118.24368","lat":"34.05223"},"timezone":{"gmtOffset":-8,"dstOffset":-7,"timeZoneId":"America/Los_Angeles"},"population":3792621,"adminName2":"Los Angeles County","name":"Los Angeles","country":"US","countryName":"United States","adminName1":"California","adminName3":"","services":{"geonames":5368361},"areaLabel":"California, United States"},
+    {"coord":{"lon":"-3.70256","lat":"40.4165"},"timezone":{"gmtOffset":1,"dstOffset":2,"timeZoneId":"Europe/Madrid"},"population":3255944,"adminName2":"Madrid","name":"Madrid","country":"ES","countryName":"Spain","adminName1":"Madrid","adminName3":"Madrid","services":{"geonames":3117735},"areaLabel":"Madrid, Spain"},
+    {"coord":{"lon":"120.9822","lat":"14.6042"},"timezone":{"gmtOffset":8,"dstOffset":8,"timeZoneId":"Asia/Manila"},"population":10444527,"adminName2":"PH.NCR.D9","name":"Manila","country":"PH","countryName":"Philippines","adminName1":"National Capital Region","adminName3":"","services":{"geonames":1701668},"areaLabel":"National Capital, Philippines"},
+    {"coord":{"lon":"-73.58781","lat":"45.50884"},"timezone":{"gmtOffset":-5,"dstOffset":-4,"timeZoneId":"America/Montreal"},"population":3268513,"adminName2":"Montréal","name":"Montreal","country":"CA","countryName":"Canada","adminName1":"Quebec","adminName3":"","services":{"geonames":6077243},"areaLabel":"Quebec, Canada"},
+    {"coord":{"lon":"-99.12766","lat":"19.42847"},"timezone":{"gmtOffset":-6,"dstOffset":-5,"timeZoneId":"America/Mexico_City"},"population":12294193,"adminName2":"","name":"Mexico City","country":"MX","countryName":"Mexico","adminName1":"The Federal District","adminName3":"","services":{"geonames":3530597},"areaLabel":"The Federal District, Mexico"},
+    {"coord":{"lon":"37.61556","lat":"55.75222"},"timezone":{"gmtOffset":4,"dstOffset":4,"timeZoneId":"Europe/Moscow"},"population":10381222,"adminName2":"","name":"Moscow","country":"RU","countryName":"Russia","adminName1":"Moscow","adminName3":"","services":{"geonames":524901},"areaLabel":"Moscow, Russian Federation"},
+    {"coord":{"lon":"72.88261","lat":"19.07283"},"timezone":{"gmtOffset":5.5,"dstOffset":5.5,"timeZoneId":"Asia/Kolkata"},"population":12691836,"adminName2":"Konkan Division","name":"Mumbai","country":"IN","countryName":"India","adminName1":"Mahārāshtra","adminName3":"","services":{"geonames":1275339},"areaLabel":"Mahārāshtra, India"},
+    {"coord":{"lon":"36.81667","lat":"-1.28333"},"timezone":{"gmtOffset":3,"dstOffset":3,"timeZoneId":"Africa/Nairobi"},"population":2750547,"adminName2":"","name":"Nairobi","country":"KE","countryName":"Kenya","adminName1":"Nairobi Area","adminName3":"","services":{"geonames":184745},"areaLabel":"Nairobi Area, Kenya"},
+    {"coord":{"lon":"-74.00597","lat":"40.71427"},"timezone":{"gmtOffset":-5,"dstOffset":-4,"timeZoneId":"America/New_York"},"population":8175133,"adminName2":"","name":"New York City","country":"US","countryName":"United States","adminName1":"New York","adminName3":"","services":{"geonames":5128581},"areaLabel":"New York, United States"},
+    {"coord":{"lon":"135.50218","lat":"34.69374"},"timezone":{"gmtOffset":9,"dstOffset":9,"timeZoneId":"Asia/Tokyo"},"population":2592413,"adminName2":"","name":"Osaka","country":"JP","countryName":"Japan","adminName1":"Ōsaka","adminName3":"","services":{"geonames":1853909},"areaLabel":"Ōsaka, Japan"},
+    {"coord":{"lon":"-43.2075","lat":"-22.90278"},"timezone":{"gmtOffset":-2,"dstOffset":-3,"timeZoneId":"America/Sao_Paulo"},"population":6023699,"adminName2":"Rio de Janeiro","name":"Rio de Janeiro","country":"BR","countryName":"Brazil","adminName1":"Rio de Janeiro","adminName3":"","services":{"geonames":3451190},"areaLabel":"Rio de Janeiro, Brazil"},
+    {"coord":{"lon":"12.4839","lat":"41.89474"},"timezone":{"gmtOffset":1,"dstOffset":2,"timeZoneId":"Europe/Rome"},"population":2563241,"adminName2":"Rome","name":"Rome","country":"IT","countryName":"Italy","adminName1":"Latium","adminName3":"Rome","services":{"geonames":3169070},"areaLabel":"Latium, Italy"},
+    {"coord":{"lon":"126.97783","lat":"37.56826"},"timezone":{"gmtOffset":9,"dstOffset":9,"timeZoneId":"Asia/Seoul"},"population":10349312,"adminName2":"","name":"Seoul","country":"KR","countryName":"South Korea","adminName1":"Seoul","adminName3":"","services":{"geonames":1835848},"areaLabel":"Seoul, Korea, Republic of"},
+    {"coord":{"lon":"-122.41942","lat":"37.77493"},"timezone":{"gmtOffset":-8,"dstOffset":-7,"timeZoneId":"America/Los_Angeles"},"population":805235,"adminName2":"San Francisco County","name":"San Francisco","country":"US","countryName":"United States","adminName1":"California","adminName3":"","services":{"geonames":5391959},"areaLabel":"California, United States"},
+    {"coord":{"lon":"-46.63611","lat":"-23.5475"},"timezone":{"gmtOffset":-2,"dstOffset":-3,"timeZoneId":"America/Sao_Paulo"},"population":10021295,"adminName2":"São Paulo","name":"São Paulo","country":"BR","countryName":"Brazil","adminName1":"São Paulo","adminName3":"","services":{"geonames":3448439},"areaLabel":"São Paulo, Brazil"},
+    {"coord":{"lon":"121.45806","lat":"31.22222"},"timezone":{"gmtOffset":8,"dstOffset":8,"timeZoneId":"Asia/Shanghai"},"population":14608512,"adminName2":"","name":"Shanghai","country":"CN","countryName":"China","adminName1":"Shanghai Shi","adminName3":"","services":{"geonames":1796236},"areaLabel":"Shanghai Shi, China"},
+    {"coord":{"lon":"114.0683","lat":"22.54554"},"timezone":{"gmtOffset":8,"dstOffset":8,"timeZoneId":"Asia/Shanghai"},"population":3000000,"adminName2":"Shenzhen","name":"Shenzhen","country":"CN","countryName":"China","adminName1":"Guangdong Province","adminName3":"","services":{"geonames":1795565},"areaLabel":"Guangdong Province, Shenzhen, China"},
+    {"coord":{"lon":"103.85007","lat":"1.28967"},"timezone":{"gmtOffset":8,"dstOffset":8,"timeZoneId":"Asia/Singapore"},"population":3547809,"adminName2":"","name":"Singapore","country":"SG","countryName":"Singapore","adminName1":"","adminName3":"","services":{"geonames":1880252},"areaLabel":"Singapore"},
+    {"coord":{"lon":"151.20732","lat":"-33.86785"},"timezone":{"gmtOffset":11,"dstOffset":10,"timeZoneId":"Australia/Sydney"},"population":4627345,"adminName2":"City of Sydney","name":"Sydney","country":"AU","countryName":"Australia","adminName1":"New South Wales","adminName3":"","services":{"geonames":2147714},"areaLabel":"New South Wales, Australia"},
+    {"coord":{"lon":"51.42151","lat":"35.69439"},"timezone":{"gmtOffset":3.5,"dstOffset":4.5,"timeZoneId":"Asia/Tehran"},"population":7153309,"adminName2":"","name":"Tehran","country":"IR","countryName":"Iran","adminName1":"Tehrān","adminName3":"","services":{"geonames":112931},"areaLabel":"Tehrān, Iran, Islamic Republic of"},
+    {"coord":{"lon":"117.17667","lat":"39.14222"},"timezone":{"gmtOffset":8,"dstOffset":8,"timeZoneId":"Asia/Shanghai"},"population":3766207,"adminName2":"","name":"Tianjin","country":"CN","countryName":"China","adminName1":"Tianjin Shi","adminName3":"","services":{"geonames":1792947},"areaLabel":"Tianjin Shi, China"},
+    {"coord":{"lon":"139.69171","lat":"35.6895"},"timezone":{"gmtOffset":9,"dstOffset":9,"timeZoneId":"Asia/Tokyo"},"population":8336599,"adminName2":"","name":"Tokyo","country":"JP","countryName":"Japan","adminName1":"Tōkyō","adminName3":"","services":{"geonames":1850147},"areaLabel":"Tōkyō, Japan"},
+    {"coord":{"lon":"-79.4163","lat":"43.70011"},"timezone":{"gmtOffset":-5,"dstOffset":-4,"timeZoneId":"America/Toronto"},"population":4612191,"adminName2":"","name":"Toronto","country":"CA","countryName":"Canada","adminName1":"Ontario","adminName3":"","services":{"geonames":6167865},"areaLabel":"Ontario, Canada"}
+]

=== added file 'app/data/Storage.qml'
--- app/data/Storage.qml	1970-01-01 00:00:00 +0000
+++ app/data/Storage.qml	2015-08-05 19:54:56 +0000
@@ -0,0 +1,214 @@
+/*
+ * Copyright (C) 2013, 2014, 2015 Canonical Ltd
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 3 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authored by: Martin Borho <martin@xxxxxxxxx>
+ */
+import QtQuick.LocalStorage 2.0
+import QtQuick 2.4
+
+Item {
+    property var db: null
+
+    function openDB() {
+        if(db !== null) return;
+
+        db = LocalStorage.openDatabaseSync("com.ubuntu.weather", "", "Default Ubuntu weather app", 100000);
+
+        if (db.version === "") {
+            db.changeVersion("", "0.1",
+                function(tx) {
+                    tx.executeSql('CREATE TABLE IF NOT EXISTS Locations(id INTEGER PRIMARY KEY AUTOINCREMENT, data TEXT, date TEXT)');
+                    console.log('Database created');
+                });
+            // reopen database with new version number
+            db = LocalStorage.openDatabaseSync("com.ubuntu.weather", "", "Default Ubuntu weather app", 100000);
+        }
+
+        if(db.version === "0.1") {
+            db.changeVersion("0.1", "0.2",
+                function(tx) {
+                    tx.executeSql('CREATE TABLE IF NOT EXISTS settings(key TEXT UNIQUE, value TEXT)');
+                    console.log('Settings table added, Database upgraded to v0.2');
+                });
+            // reopen database with new version number
+            db = LocalStorage.openDatabaseSync("com.ubuntu.weather", "", "Default Ubuntu weather app", 100000);
+        }
+
+        if(db.version === "0.2") {
+            db.changeVersion("0.2", "0.3",
+                function(tx) {
+                    tx.executeSql('DELETE FROM Locations WHERE 1');
+                    console.log('Removed old locations, Database upgraded to v0.3');
+                });
+        }
+
+        if (!settings.migrated) {
+            try {  // attempt to read the old settings
+                var oldSettings = {};
+
+                // Load old settings
+                db.readTransaction( function(tx) {
+                    var rs = tx.executeSql("SELECT * FROM settings")
+
+                    for(var i = 0; i < rs.rows.length; i++) {
+                        var row = rs.rows.item(i);
+                        oldSettings[row.key] = row.value;
+                    }
+                });
+
+                console.debug("Migrating old data:", JSON.stringify(oldSettings))
+
+                var metric = Qt.locale().measurementSystem === Locale.MetricSystem
+
+                // Move to new Settings API
+                settings.migrated = true
+                settings.service = oldSettings["service"] === undefined ? "weatherchannel" : oldSettings["service"]
+
+                if (oldSettings["precip_units"] !== undefined) {
+                    settings.precipUnits = oldSettings["precip_units"]
+                } else {
+                    settings.precipUnits = metric ? "mm" : "in"
+                }
+
+                if (oldSettings["units"] !== undefined) {
+                    settings.tempScale = oldSettings["units"] === "metric" ? "°C" : "°F"
+                    settings.units = oldSettings["units"]
+                } else {
+                    settings.tempScale = metric ? "°C" : "°F"
+                    settings.units = metric ? "metric" : "imperial"
+                }
+
+                if (oldSettings["units"] !== undefined) {
+                    // If old wind speed was in "kmh" use "kph" instead
+                    settings.windUnits = oldSettings["wind_units"] === "kmh" ? "kph" : oldSettings["wind_units"]
+                } else {
+                    settings.windUnits = metric ? "kph" : "mph"
+                }
+
+                /*
+                  TODO: uncomment when reboot is ready to replace existing app
+                db.transaction( function(tx) {
+                    tx.executeSql("DROP TABLE IF EXISTS settings")
+                });
+                */
+            } catch (e) {  // likely table did not exist
+                console.debug("No old data to migrate.")
+                settings.migrated = true
+            }
+        }
+    }
+
+    function insertLocation(data) {
+        openDB();
+        var res;
+
+        db.transaction( function(tx){
+            var r = tx.executeSql('INSERT INTO Locations(data, date) VALUES(?, ?)', [JSON.stringify(data), new Date().getTime()]);
+            res = r.insertId;
+        });
+        return res;
+    }
+
+    function insertLocationAtStart(data) {
+        var res = insertLocation(data);
+        reorder(res, 0);
+        return 0;
+    }
+
+    function updateLocation(dbId, data) {
+        openDB();
+        db.transaction( function(tx){
+            var r = tx.executeSql('UPDATE Locations SET data = ?, date=? WHERE id = ?', [JSON.stringify(data), new Date().getTime(), dbId])
+        });
+    }
+
+    function getLocations(callback) {
+        openDB();
+        db.readTransaction(
+            function(tx){
+                var locations = [];
+                var rs = tx.executeSql('SELECT * FROM Locations');
+                for(var i = 0; i < rs.rows.length; i++) {
+                    var row = rs.rows.item(i),
+                        locData = JSON.parse(row.data);
+                    locData["updated"] = parseInt(row.date, 10);
+                    locData["db"] = {id: row.id, updated: new Date(parseInt(row.date, 10))};
+                    locations.push(locData);
+                }
+                callback(locations);
+            }
+        );
+    }
+
+    function clearLocation(location_id) {
+        openDB();
+        db.transaction(function(tx){
+            tx.executeSql('DELETE FROM Locations WHERE id = ?', [location_id]);
+        });
+    }
+
+    function clearMultiLocation(locations) {
+        openDB();
+
+        db.transaction(function (tx) {
+            // Remove all the deleted indexes
+            for (var i=0; i < locations.length; i++) {
+                tx.executeSql('DELETE FROM Locations WHERE id=?;', [locations[i]])
+            }
+
+            // Rebuild locations in order
+            var rs = tx.executeSql('SELECT id FROM Locations ORDER BY id ASC')
+
+            for (i=0; i < rs.rows.length; i++) {
+                tx.executeSql('UPDATE Locations SET id=? WHERE id=?;',
+                              [i, rs.rows.item(i).id])
+            }
+        })
+    }
+
+    function clearDB() { // for dev purposes
+        openDB();
+        db.transaction(function(tx){
+            tx.executeSql('DELETE FROM Locations WHERE 1');
+        });
+    }
+
+    function reorder(from, to) {
+        openDB();
+
+        db.transaction(function(tx) {
+            // Track to move put as -1 for now
+            tx.executeSql('UPDATE Locations SET id=? WHERE id=?;',
+                          [-1, from])
+
+            // Shuffle locations inbetween from->to
+            if (from > to) {
+                for (var i = from-1; i >= to; i--) {
+                    tx.executeSql('UPDATE Locations SET id=? WHERE id=?;',
+                                  [i+1, i])
+                }
+            } else {
+                for (var j = from+1; j <= to; j++) {
+                    tx.executeSql('UPDATE Locations SET id=? WHERE id=?;',
+                                  [j-1, j])
+                }
+            }
+
+            // Switch moving location to its new position
+            tx.executeSql('UPDATE Locations SET id=? WHERE id=?;',
+                          [to, -1])
+        })
+    }
+}

=== added file 'app/data/WeatherApi.js'
--- app/data/WeatherApi.js	1970-01-01 00:00:00 +0000
+++ app/data/WeatherApi.js	2015-08-05 19:54:56 +0000
@@ -0,0 +1,760 @@
+.pragma library
+/*
+ * Copyright (C) 2013 Canonical Ltd
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 3 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authored by: Raúl Yeguas <neokore@xxxxxxxxx>
+ *              Martin Borho <martin@xxxxxxxxx>
+ *              Andrew Starr-Bochicchio <a.starr.b@xxxxxxxxx>
+ */
+
+/**
+*  Version of the response data format.
+*  Increase this number to force a refresh.
+*/
+var RESPONSE_DATA_VERSION = 20150404;
+
+/**
+* Helper functions
+*/
+function debug(obj) {
+    print(JSON.stringify(obj))
+}
+//
+function calcFahrenheit(celsius) {
+        return celsius * 1.8 + 32;
+}
+//
+function calcMph(ms) {
+    return ms*2.24;
+}
+//
+function calcInch(mm) {
+    return mm/25.4;
+}
+//
+function calcKph(ms) {
+    return ms*3.6;
+}
+//
+function convertKphToMph(kph) {
+    return kph*0.621;
+}
+//
+function calcWindDir(degrees) {
+    var direction =  "?";
+    if(degrees >=0 && degrees <= 30){
+        direction = "N";
+    } else if(degrees >30 && degrees <= 60){
+        direction = "NE";
+    } else if(degrees >60 && degrees <= 120){
+        direction = "E";
+    } else if(degrees >120 && degrees <= 150){
+        direction = "SE";
+    } else if(degrees >150 && degrees <= 210){
+        direction = "S";
+    } else if(degrees >210 && degrees <= 240){
+        direction = "SW";
+    } else if(degrees >240 && degrees <= 300){
+        direction = "W";
+    } else if(degrees >300 && degrees <= 330){
+        direction = "NW";
+    } else if(degrees >330 && degrees <= 360){
+        direction = "N";
+    }
+    return direction;
+}
+
+//
+function getLocationTime(tstamp) {
+    var locTime = new Date(tstamp);
+    return {
+        year: locTime.getUTCFullYear(),
+        month: locTime.getUTCMonth(),
+        date: locTime.getUTCDate(),
+        hours: locTime.getUTCHours(),
+        minutes: locTime.getUTCMinutes()
+    }
+}
+// Serialize a JavaScript object to URL parameters
+// E.g. {param1: value1, param2: value2} to "param1=value&param2=value"
+// TODO: it'd be nice to make it work with either passing a single object
+// or several at once
+function parameterize(obj) {
+  var str = [];
+  for(var param in obj) {
+     str.push(encodeURIComponent(param) + "=" + encodeURIComponent(obj[param]));
+  }
+  return str.join("&");
+}
+
+var GeoipApi = (function() {
+    var _baseUrl = "http://geoip.ubuntu.com/lookup";;
+    return {
+        getLatLong: function(params, apiCaller, onSuccess, onError) {
+            var request = { type: "geolookup",url: _baseUrl},
+                resultHandler = (function(request, xmlDoc) {
+                    var coords = {},
+                        childNodes = xmlDoc.childNodes;
+                    for(var i=0;i<childNodes.length;i++) {
+                        if(childNodes[i].nodeName === "Latitude") {
+                            coords.lat = childNodes[i].firstChild.nodeValue;
+                        } else if(childNodes[i].nodeName === "Longitude") {
+                            coords.lon = childNodes[i].firstChild.nodeValue;
+                        }
+                    }
+                    onSuccess(coords);
+                }),
+                retryHandler = (function(err) {
+                    console.log("geolookup retry of "+err.request.url);
+                    apiCaller(request, resultHandler, onError);
+                });
+            apiCaller(request, resultHandler, retryHandler);
+        }
+    }
+})();
+
+var GeonamesApi = (function() {
+    /**
+      provides neccessary methods for requesting and preparing data from Geonames.org
+    */
+    var _baseUrl = "http://api.geonames.org/";;
+    var _username = "uweatherdev"
+    var _addParams = "&maxRows=25&featureClass=P"
+    //
+    function _buildSearchResult(request, data) {
+        var searchResult = { locations: [], request: request };
+        if(data.geonames) {
+            data.geonames.forEach(function(r) {
+               searchResult.locations.push({
+                    name: r.name,
+                    coord: {lat: r.lat, lon: r.lng},
+                    country: r.countryCode,
+                    countryName: r.countryName,
+                    timezone: r.timezone,
+                    adminName1: r.adminName1,
+                    adminName2: r.adminName2,
+                    adminName3: r.adminName3,
+                    population: r.population,
+                    services: {
+                        "geonames": r.geonameId
+                    }
+                });
+            })
+        }
+        return searchResult;
+    }
+    //
+    return {
+        //
+        search: function(mode, params, apiCaller, onSuccess, onError) {
+            var request,
+                retryHandler = (function(err) {
+                        console.log("search retry of "+err.request.url);
+                        apiCaller(request, searchResponseHandler, onError);
+                }),
+                searchResponseHandler = function(request, data) {
+                    onSuccess(_buildSearchResult(request, data));
+                };
+            if(mode === "point") {
+                request = { type: "search",
+                            url: _baseUrl+ "findNearbyPlaceNameJSON?style=full&username="+encodeURIComponent(_username)
+                            +"&lat="+encodeURIComponent(params.coords.lat)+"&lng="+encodeURIComponent(params.coords.lon)
+                            +_addParams}
+            } else {
+                request = { type: "search",
+                            url: _baseUrl+ "searchJSON?style=full&username="+encodeURIComponent(_username)
+                                    +"&name_startsWith="+encodeURIComponent(params.name)+_addParams}
+            }
+            apiCaller(request, searchResponseHandler, retryHandler);
+        }
+    }
+
+})();
+
+var OpenWeatherMapApi = (function() {
+    /**
+      provides neccessary methods for requesting and preparing data from OpenWeatherMap.org
+    */
+    var _baseUrl = "http://api.openweathermap.org/data/2.5/";;
+    //
+    var _serviceName = "openweathermap";
+    //
+    var _icon_map = {
+        "01d": "sun",
+        "01n": "moon",
+        "02d": "cloud_sun",
+        "02n": "cloud_moon",
+        "03d": "cloud_sun",
+        "03n": "cloud_moon",
+        "04d": "cloud",
+        "04n": "cloud",
+        "09d": "rain",
+        "09n": "rain",
+        "10d": "rain",
+        "10n": "rain",
+        "11d": "thunder",
+        "11n": "thunder",
+        "13d": "snow_shower",
+        "13n": "snow_shower",
+        "50d": "fog",
+        "50n": "fog"
+    }    
+    //
+    function _buildDataPoint(date, data) {
+        var result = {
+            timestamp: data.dt,
+            date: date,
+            metric: {
+                temp:data.main.temp,
+                windSpeed: calcKph(data.wind.speed),
+                rain: data.main.rain || ((data.rain) ? data.rain["3h"] : false ) || 0,
+                snow: data.main.snow || ((data.snow) ? data.snow["3h"] : false ) || 0
+            },
+            imperial: {
+                temp: calcFahrenheit(data.main.temp),
+                windSpeed: calcMph(data.wind.speed),
+                rain: calcInch(data.main.rain || ((data.rain) ? data.rain["3h"] : false ) || 0),
+                snow: calcInch(data.main.snow || ((data.snow) ? data.snow["3h"] : false ) ||0)
+            },
+            humidity: data.main.humidity,
+            pressure: data.main.pressure,
+            windDeg: data.wind.deg,
+            windDir: calcWindDir(data.wind.deg),
+            icon: _icon_map[data.weather[0].icon],
+            condition: data.weather[0].main
+        };
+        if(data.id !== undefined) {
+            result["service"] = _serviceName;
+            result["service_id"] =  data.id;
+        }
+        return result;
+    }
+    //
+    function _buildDayFormat(date, data) {
+        var result = {
+            date: date,
+            timestamp: data.dt,
+            metric: {
+                tempMin: data.temp.min,
+                tempMax: data.temp.max,
+                windSpeed: calcKph(data.speed),
+                rain: data.rain || 0,
+                snow: data.snow || 0
+            },
+            imperial: {
+                tempMin: calcFahrenheit(data.temp.min),
+                tempMax: calcFahrenheit(data.temp.max),
+                windSpeed: calcMph(data.speed),
+                rain: calcInch(data.rain || 0),
+                snow: calcInch(data.snow || 0)
+            },
+            pressure: data.pressure,
+            humidity: data.humidity,
+            icon: _icon_map[data.weather[0].icon],
+            condition: data.weather[0].main,
+            windDeg: data.deg,
+            windDir: calcWindDir(data.deg),
+            hourly: []
+        }
+        return result;
+    }
+    //
+    function formatResult(data, location) {
+        var tmpResult = {},
+            result = [],
+            day=null,
+            offset=(location.timezone && location.timezone.gmtOffset) ? location.timezone.gmtOffset*60*60*1000: 0,
+            localNow = getLocationTime(new Date().getTime()+offset),
+            todayDate;        
+        print("["+location.name+"] "+JSON.stringify(localNow))
+        // add openweathermap id for faster responses
+        if(location.services && !location.services[_serviceName] && data["current"].id) {
+            location.services[_serviceName] = data["current"].id
+        }
+        //
+        data["daily"]["list"].forEach(function(dayData) {
+            var date = getLocationTime(((dayData.dt*1000)-1000)+offset), // minus 1 sec to handle +/-12 TZ
+                day = date.year+"-"+date.month+"-"+date.date;
+            if(!todayDate) {
+                if(localNow.year+"-"+localNow.month+"-"+localNow.date > day) {
+                    // skip "yesterday"
+                    return;
+                }
+                todayDate = date;
+            }
+            tmpResult[day] = _buildDayFormat(date, dayData);
+        })
+        //
+        var today = todayDate.year+"-"+todayDate.month+"-"+todayDate.date
+        tmpResult[today]["current"] = _buildDataPoint(todayDate, data["current"]);
+        if(data["forecast"] !== undefined) {
+            data["forecast"]["list"].forEach(function(hourData) {                
+                var dateData = getLocationTime((hourData.dt*1000)+offset),
+                    day = dateData.year+"-"+dateData.month+"-"+dateData.date;
+                if(tmpResult[day]) {
+                    tmpResult[day]["hourly"].push(_buildDataPoint(dateData, hourData));
+                }
+            })
+        }
+        //
+        for(var d in tmpResult) {
+            result.push(tmpResult[d]);
+        }
+        return result;
+    }
+    //
+    function _getUrls(params) {
+        var urls = {
+                current: "",
+                daily: "",
+                forecast: ""
+            },
+            latLongParams = "&lat="+encodeURIComponent(params.location.coord.lat)
+                + "&lon="+encodeURIComponent(params.location.coord.lon);
+        if(params.location.services && params.location.services[_serviceName]) {
+            urls.current = _baseUrl + "weather?units="+params.units+"&id="+params.location.services[_serviceName];
+            urls.daily = _baseUrl + "forecast/daily?id="+params.location.services[_serviceName]+"&cnt=10&units="+params.units
+            urls.forecast = _baseUrl + "forecast?id="+params.location.services[_serviceName]+"&units="+params.units
+
+        } else if (params.location.coord) {
+            urls.current = _baseUrl + "weather?units="+params.units+latLongParams;
+            urls.daily = _baseUrl+"forecast/daily?cnt=10&units="+params.units+latLongParams;
+            urls.forecast = _baseUrl+"forecast?units="+params.units+latLongParams;
+        }
+        return urls;
+    }
+    //
+    return {     
+        //
+        getData: function(params, apiCaller, onSuccess, onError) {
+            var urls = _getUrls(params),
+                handlerMap = {
+                current: { type: "current",url: urls.current},
+                daily: { type: "daily",url: urls.daily},
+                forecast: { type: "forecast", url: urls.forecast}},
+            response = {
+                location: params.location,
+                db: (params.db) ? params.db : null,
+                format: RESPONSE_DATA_VERSION
+            },
+            respData = {},
+            addDataToResponse = (function(request, data) {
+                var formattedResult;
+                respData[request.type] = data;
+                if(respData["current"] !== undefined
+                        && respData["forecast"] !== undefined
+                            && respData["daily"] !== undefined) {
+                    response["data"] = formatResult(respData, params.location)
+                    onSuccess(response);
+                }
+            }),
+            onErrorHandler = (function(err) {
+                onError(err);
+            }),
+            retryHandler = (function(err) {
+                console.log("retry of "+err.request.url);
+                var retryFunc = handlerMap[err.request.type];
+                apiCaller(retryFunc, addDataToResponse, onErrorHandler);
+            });
+            //
+            apiCaller(handlerMap.current, addDataToResponse, retryHandler);
+            apiCaller(handlerMap.forecast, addDataToResponse, retryHandler);
+            apiCaller(handlerMap.daily, addDataToResponse, retryHandler);
+        }
+    }
+
+})();
+
+var WeatherChannelApi = (function() {
+    /**
+      provides neccessary methods for requesting and preparing data from OpenWeatherMap.org
+    */
+    var _baseUrl = "http://wxdata.weather.com/wxdata/";;
+    //
+    var _serviceName = "weatherchannel";
+    //
+    // see http://s.imwx.com/v.20131006.223722/img/wxicon/72/([0-9]+).png
+    var _iconMap = {
+        "0": "thunder", // ??
+        "1": "thunder", // ??
+        "2": "thunder", // ??
+        "3": "thunder", // ??
+        "4": "thunder", //T-Storms
+        "5": "snow_rain", //Rain / Snow
+        "6": "snow_rain", // ??
+        "7": "snow_rain", //Wintry Mix
+        "8": "scattered", //Freezing Drizzle
+        "9": "scattered", //Drizzle
+        "10": "rain", // ??
+        "11": "rain", //Showers
+        "12": "rain", //Rain
+        "13": "snow_shower", // ??
+        "14": "snow_shower", //Snow shower/Light snow
+        "15": "snow_shower", //
+        "16": "snow_shower", //Snow
+        "17": "thunder", // Hail??
+        "18": "snow_rain", // Rain / Snow ??
+        "19": "fog", //Fog ??
+        "20": "fog", //Fog
+        "21": "fog", //Haze
+        "22": "fog", // ??
+        "23": "fog", // Wind ??
+        "24": "overcast", //Partly Cloudy / Wind
+        "25": "overcast", // ??
+        "26": "overcast",//Cloudy
+        "27": "cloud_moon",//Mostly Cloudy
+        "28": "cloud_sun", //Mostly Cloudy
+        "29": "cloud_moon", //Partly Cloudy
+        "30": "cloud_sun", //Partly Cloudy
+        "31": "moon", //Clear
+        "32": "sun", //Sunny
+        "33": "cloud_moon", //Mostly Clear
+        "34": "cloud_sun", //Mostly Sunny
+        "35": "snow_rain", // ??
+        "36": "sun", //Sunny
+        "37": "thunder", //Isolated T-Storms
+        "38": "thunder", //Scattered T-Storms
+        "39": "scattered", //Scattered Showers
+        "40": "rain", // ??
+        "41": "snow", //Scattered Snow Showers
+        "42": "snow_shower", // ??
+        "43": "snow_shower", // ??
+        "44": "fog", // ??
+        "45": "scattered", // ??
+        "46": "snow_shower", //Snow Showers Early
+        "47": "thunder" //Isolated T-Storms
+    };
+    //
+    function _buildDataPoint(date, dataObj) {
+        var data = dataObj["Observation"] || dataObj,
+            result = {
+                timestamp: data.date || data.dateTime,
+                date: date,
+                metric: {
+                    temp: data.temp,
+                    tempFeels: data.feelsLike,
+                    windSpeed: data.wSpeed
+                },
+                imperial: {
+                    temp: calcFahrenheit(data.temp),
+                    tempFeels: calcFahrenheit(data.feelsLike),
+                    windSpeed: convertKphToMph(data.wSpeed)
+                },
+                precipType: (data.precip_type !== undefined) ? data.precip_type : null,
+                propPrecip: (data.pop !== undefined) ? data.pop : null,
+                humidity: data.humid,
+                pressure: data.pressure,
+                windDeg: data.wDir,
+                windDir: data.wDirText,
+                icon: _iconMap[(data.wxIcon||data.icon)],
+                condition: data.text || data.wDesc,
+                uv: data.uv
+        };
+        if(_iconMap[data.wxIcon||data.icon] === undefined) {
+            print("ICON MISSING POINT: "+(data.wxIcon||data.icon)+" "+result.condition)
+        }
+        return result;
+    }
+    //
+    function _buildDayFormat(date, data, now) {
+        var partData = (now > data.validDate || data.day === undefined) ? data.night : data.day,
+            result = {
+            date: date,
+            timestamp: data.validDate,
+            metric: {
+                tempMin: data.minTemp,
+                tempMax: data.maxTemp,
+                windSpeed: partData.wSpeed
+            },
+            imperial: {
+                tempMin: calcFahrenheit(data.minTemp),
+                tempMax: calcFahrenheit(data.maxTemp !== undefined ? data.maxTemp : data.minTemp),
+                windSpeed: convertKphToMph(partData.wSpeed)
+            },
+            precipType: partData.precip_type,
+            propPrecip: partData.pop,
+            pressure: null,
+            humidity: partData.humid,
+            icon: _iconMap[partData.icon],
+            condition: partData.phrase,
+            windDeg: partData.wDir,
+            windDir: partData.wDirText,
+            uv: partData.uv,
+            hourly: []
+        }
+        if(_iconMap[partData.icon] === undefined) {
+            print("ICON MISSING  DAY: "+partData.icon+" "+result.condition)
+        }
+        return result;
+    }
+    //
+    function formatResult(combinedData, location) {
+        var tmpResult = {}, result = [],
+            day=null, todayDate,
+            offset=(location.timezone && location.timezone.gmtOffset) ? location.timezone.gmtOffset*60*60*1000: 0,
+            now = new Date().getTime(),
+            nowMs = parseInt(now/1000),
+            localNow = getLocationTime(now+offset),
+            data = {
+                "location": combinedData[0]["Location"],
+                "daily": combinedData[0]["DailyForecasts"],
+                "forecast": combinedData[0]["HourlyForecasts"],
+                "current": combinedData[0]["StandardObservation"],
+                "sunRiseSet": combinedData[0]["SunRiseSet"],
+            };
+        print("["+location.name+"] "+JSON.stringify(localNow));
+        // add openweathermap id for faster responses
+        if(location.services && !location.services[_serviceName] && data["location"].key) {
+            location.services[_serviceName] = data["location"].key
+        }                
+        // only 5 days of forecast for TWC
+        for(var x=0;x<5;x++) {
+            var dayData = data["daily"][x],
+                date = getLocationTime(((dayData.validDate*1000)-1000)+offset); // minus 1 sec to handle +/-12 TZ
+            var sunRiseSet = data["sunRiseSet"][x];
+            day = date.year+"-"+date.month+"-"+date.date;
+            if(!todayDate) {
+                if(localNow.year+"-"+localNow.month+"-"+localNow.date > day) {
+                    // skip "yesterday"
+                    continue;
+                }
+                todayDate = date;
+            }
+            tmpResult[day] = _buildDayFormat(date, dayData, nowMs);
+            var sunrise = new Date(sunRiseSet.rise*1000);
+            var sunset = new Date(sunRiseSet.set*1000);
+            tmpResult[day].sunrise = sunrise.toLocaleTimeString();
+            tmpResult[day].sunset = sunset.toLocaleTimeString();
+        }
+        //
+        if(data["forecast"] !== undefined) {
+            data["forecast"].forEach(function(hourData) {
+                var dateData = getLocationTime((hourData.dateTime*1000)+offset),
+                    day = dateData.year+"-"+dateData.month+"-"+dateData.date;
+                if(tmpResult[day]) {
+                    tmpResult[day]["hourly"].push(_buildDataPoint(dateData, hourData));
+                }
+            })
+        }
+        //
+        if(data["current"]) {
+            var today = todayDate.year+"-"+todayDate.month+"-"+todayDate.date;
+            tmpResult[today]["current"] = _buildDataPoint(todayDate, data["current"]);
+            // if the icon is missing, use the first from the hourly forecast
+            if(!tmpResult[today]["current"].icon && tmpResult[today]["hourly"] && tmpResult[today]["hourly"].length > 0) {
+                tmpResult[today]["current"].icon = tmpResult[today]["hourly"][0].icon;
+            }
+            // if condition text is missing, use the condition from the first hourly forecast
+            if((tmpResult[today]["current"].condition === "-" || tmpResult[today]["current"].condition === undefined)
+                && (tmpResult[today]["hourly"] && tmpResult[today]["hourly"].length > 0)) {
+                    tmpResult[today]["current"].condition = tmpResult[today]["hourly"][0].condition;
+            }
+        }
+        //
+        for(var d in tmpResult) {
+            result.push(tmpResult[d]);
+        }
+        return result;
+    }
+    //
+    function _getUrl(params) {
+        var url, serviceId,
+            baseParams = {
+                key: params.api_key,
+                units: (params.units === "metric") ? "m" : "e",
+                locale: Qt.locale().name,
+                hours: "48",
+            },
+            commands = {
+                "mobileaggregation": "mobile/mobagg/",
+            };
+        if(params.location.services && params.location.services[_serviceName]) {
+            serviceId = encodeURIComponent(params.location.services[_serviceName]);
+            url = _baseUrl+commands["mobileaggregation"]+serviceId+".js?"+parameterize(baseParams);
+        } else if (params.location.coord) {
+            var coord = {lat: params.location.coord.lat, lng: params.location.coord.lon};
+            url = _baseUrl+commands["mobileaggregation"]+"get.js?"+parameterize(baseParams)+"&"+
+                  parameterize(coord);
+        }
+        return url;
+    }
+    //
+    return {
+        getData: function(params, apiCaller, onSuccess, onError) {
+            var url = _getUrl(params),
+                handlerMap = {
+                    all: { type: "all", url: url}
+                },
+                response = {
+                    location: params.location,
+                    db: (params.db) ? params.db : null,
+                    format: RESPONSE_DATA_VERSION
+                },
+                addDataToResponse = (function(request, data) {
+                    var formattedResult;
+                    response["data"] = formatResult(data, params.location);
+                    onSuccess(response);
+                }),
+                onErrorHandler = (function(err) {
+                    onError(err);
+                });
+            apiCaller(handlerMap.all, addDataToResponse, onErrorHandler);
+        }
+    }
+})();
+
+var WeatherApi = (function(_services) {
+    /**
+      proxy for requesting weather apis, the passed _services are providing the respective api endpoints
+      and formatters to build a uniform response object
+    */
+    function _getService(name) {
+        if(_services[name] !== undefined) {
+            return _services[name];
+        }
+        return _services["weatherchannel"];
+    }
+    //
+    function _sendRequest(request, onSuccess, onError) {
+        var xmlHttp = new XMLHttpRequest();
+        if (xmlHttp) {
+            console.log("Sent request URL: " + request.url);
+            xmlHttp.open('GET', request.url, true);
+            xmlHttp.onreadystatechange = function () {
+                try {
+                    if (xmlHttp.readyState == 4) {
+                        if(xmlHttp.status === 200) {
+                            if(xmlHttp.responseXML) {
+                                onSuccess(request, xmlHttp.responseXML.documentElement);
+                            } else {
+                                var json = JSON.parse(xmlHttp.responseText);
+                                onSuccess(request,json);
+                            }
+                        } else {
+                            onError({
+                                msg: "wrong response http code, got "+xmlHttp.status,
+                                request: request
+                            });
+                        }
+                    }
+                } catch (e) {
+                    print("Exception: "+e)
+                    onError({msg: "wrong response data format", request: request});
+                }
+            };
+            xmlHttp.send(null);
+        }
+    }
+    //
+    return  {
+        //
+        geoLookup: function(params, onSuccess, onError) {
+            var service = _getService('geoip'),
+                geoNameService = _getService('geonames'),
+                lookupHandler = function(data) {
+                    print("Geolookup: "+JSON.stringify(data))
+                    geoNameService.search("point", {coords:data}, _sendRequest, onSuccess, onError);
+                };
+            service.getLatLong(params, _sendRequest, lookupHandler, onError)
+        },
+        //
+        search: function(mode, params, onSuccess, onError) {
+            var service = _getService('geonames');
+            service.search(mode, params, _sendRequest, onSuccess, onError);
+        },
+        //
+        getLocationData: function(params, onSuccess, onError) {
+            var service = _getService(params.service);
+            service.getData(params, _sendRequest, onSuccess, onError);
+        },
+    }
+})({
+    "openweathermap": OpenWeatherMapApi,
+    "weatherchannel": WeatherChannelApi,
+    "geonames": GeonamesApi,
+    "geoip": GeoipApi
+});
+
+var sendRequest = function(message, responseCallback) {
+    // handles the response data
+    var finished = function(result) {
+        // print result to get data for test json files
+        // print(JSON.stringify(result));
+        //WorkerScript.sendMessage({
+        responseCallback({
+            action: message.action,
+            result: result
+        })
+    }
+    // handles errors
+    var onError = function(err) {
+        console.log(JSON.stringify(err, null, true));
+        //WorkerScript.sendMessage({ 'error': err})
+        responseCallback({ 'error': err})
+    }
+    // keep order of locations, sort results
+    var sortDataResults = function(locA, locB) {
+        return locA.db.id - locB.db.id;
+    }
+    // perform the api calls
+    if(message.action === "searchByName") {
+        WeatherApi.search("name", message.params, finished, onError);
+    } else if(message.action === "searchByPoint") {
+        WeatherApi.search("point", message.params, finished, onError);
+    } else if(message.action === "getGeoIp") {
+        WeatherApi.geoLookup(message.params, finished, onError);
+    } else if(message.action === "updateData") {
+        var locLength = message.params.locations.length,
+            locUpdated = 0,
+            result = [],
+            now = new Date().getTime();
+        if(locLength > 0) {
+            message.params.locations.forEach(function(loc) {
+                var updatedHnd = function (newData, cached) {
+                        locUpdated += 1;
+                        if(cached === true) {
+                            newData["save"] = false;
+                        } else {
+                            newData["save"] = true;
+                            newData["updated"] =  new Date().getTime();
+                        }
+                        result.push(newData);
+                        if(locUpdated === locLength) {
+                            result.sort(sortDataResults);
+                            finished(result);
+                        }
+                    },
+                    params = {
+                        location:loc.location,
+                        db: loc.db,
+                        units: 'metric',
+                        service: message.params.service,
+                        api_key: message.params.api_key,
+                        interval: message.params.interval
+                    },
+                    secsFromLastFetch = (now-loc.updated)/1000;
+                if( message.params.force===true || loc.format !== RESPONSE_DATA_VERSION || secsFromLastFetch > params.interval){
+                    // data older than 30min, location is new or data format is deprecated
+                    WeatherApi.getLocationData(params, updatedHnd, onError);
+                } else {
+                    console.log("["+loc.location.name+"] returning cached data, time from last fetch: "+secsFromLastFetch)
+                    updatedHnd(loc, true);
+                }
+            })
+        } else {
+            finished(result);
+        }
+    }
+}

=== added file 'app/data/key.js'
--- app/data/key.js	1970-01-01 00:00:00 +0000
+++ app/data/key.js	2015-08-05 19:54:56 +0000
@@ -0,0 +1,1 @@
+var twcKey = "";

=== added file 'app/data/suncalc.js'
--- app/data/suncalc.js	1970-01-01 00:00:00 +0000
+++ app/data/suncalc.js	2015-08-05 19:54:56 +0000
@@ -0,0 +1,300 @@
+/*
+ (c) 2011-2015, Vladimir Agafonkin
+ SunCalc is a JavaScript library for calculating sun/moon position and light phases.
+ https://github.com/mourner/suncalc
+*/
+
+// shortcuts for easier to read formulas
+
+var PI   = Math.PI,
+    sin  = Math.sin,
+    cos  = Math.cos,
+    tan  = Math.tan,
+    asin = Math.asin,
+    atan = Math.atan2,
+    acos = Math.acos,
+    rad  = PI / 180;
+
+// sun calculations are based on http://aa.quae.nl/en/reken/zonpositie.html formulas
+
+
+// date/time constants and conversions
+
+var dayMs = 1000 * 60 * 60 * 24,
+    J1970 = 2440588,
+    J2000 = 2451545;
+
+function toJulian(date) { return date.valueOf() / dayMs - 0.5 + J1970; }
+function fromJulian(j)  { return new Date((j + 0.5 - J1970) * dayMs); }
+function toDays(date)   { return toJulian(date) - J2000; }
+
+
+// general calculations for position
+
+var e = rad * 23.4397; // obliquity of the Earth
+
+function rightAscension(l, b) { return atan(sin(l) * cos(e) - tan(b) * sin(e), cos(l)); }
+function declination(l, b)    { return asin(sin(b) * cos(e) + cos(b) * sin(e) * sin(l)); }
+
+function azimuth(H, phi, dec)  { return atan(sin(H), cos(H) * sin(phi) - tan(dec) * cos(phi)); }
+function altitude(H, phi, dec) { return asin(sin(phi) * sin(dec) + cos(phi) * cos(dec) * cos(H)); }
+
+function siderealTime(d, lw) { return rad * (280.16 + 360.9856235 * d) - lw; }
+
+
+// general sun calculations
+
+function solarMeanAnomaly(d) { return rad * (357.5291 + 0.98560028 * d); }
+
+function eclipticLongitude(M) {
+
+    var C = rad * (1.9148 * sin(M) + 0.02 * sin(2 * M) + 0.0003 * sin(3 * M)), // equation of center
+        P = rad * 102.9372; // perihelion of the Earth
+
+    return M + C + P + PI;
+}
+
+function sunCoords(d) {
+
+    var M = solarMeanAnomaly(d),
+        L = eclipticLongitude(M);
+
+    return {
+        dec: declination(L, 0),
+        ra: rightAscension(L, 0)
+    };
+}
+
+
+var SunCalc = {};
+
+
+// calculates sun position for a given date and latitude/longitude
+
+SunCalc.getPosition = function (date, lat, lng) {
+
+    var lw  = rad * -lng,
+        phi = rad * lat,
+        d   = toDays(date),
+
+        c  = sunCoords(d),
+        H  = siderealTime(d, lw) - c.ra;
+
+    return {
+        azimuth: azimuth(H, phi, c.dec),
+        altitude: altitude(H, phi, c.dec)
+    };
+};
+
+
+// sun times configuration (angle, morning name, evening name)
+
+var times = SunCalc.times = [
+    [-0.833, 'sunrise',       'sunset'      ],
+    [  -0.3, 'sunriseEnd',    'sunsetStart' ],
+    [    -6, 'dawn',          'dusk'        ],
+    [   -12, 'nauticalDawn',  'nauticalDusk'],
+    [   -18, 'nightEnd',      'night'       ],
+    [     6, 'goldenHourEnd', 'goldenHour'  ]
+];
+
+// adds a custom time to the times config
+
+SunCalc.addTime = function (angle, riseName, setName) {
+    times.push([angle, riseName, setName]);
+};
+
+
+// calculations for sun times
+
+var J0 = 0.0009;
+
+function julianCycle(d, lw) { return Math.round(d - J0 - lw / (2 * PI)); }
+
+function approxTransit(Ht, lw, n) { return J0 + (Ht + lw) / (2 * PI) + n; }
+function solarTransitJ(ds, M, L)  { return J2000 + ds + 0.0053 * sin(M) - 0.0069 * sin(2 * L); }
+
+function hourAngle(h, phi, d) { return acos((sin(h) - sin(phi) * sin(d)) / (cos(phi) * cos(d))); }
+
+// returns set time for the given sun altitude
+function getSetJ(h, lw, phi, dec, n, M, L) {
+
+    var w = hourAngle(h, phi, dec),
+        a = approxTransit(w, lw, n);
+    return solarTransitJ(a, M, L);
+}
+
+
+// calculates sun times for a given date and latitude/longitude
+
+SunCalc.getTimes = function (date, lat, lng) {
+
+    var lw = rad * -lng,
+        phi = rad * lat,
+
+        d = toDays(date),
+        n = julianCycle(d, lw),
+        ds = approxTransit(0, lw, n),
+
+        M = solarMeanAnomaly(ds),
+        L = eclipticLongitude(M),
+        dec = declination(L, 0),
+
+        Jnoon = solarTransitJ(ds, M, L),
+
+        i, len, time, Jset, Jrise;
+
+
+    var result = {
+        solarNoon: fromJulian(Jnoon),
+        nadir: fromJulian(Jnoon - 0.5)
+    };
+
+    for (i = 0, len = times.length; i < len; i += 1) {
+        time = times[i];
+
+        Jset = getSetJ(time[0] * rad, lw, phi, dec, n, M, L);
+        Jrise = Jnoon - (Jset - Jnoon);
+
+        result[time[1]] = fromJulian(Jrise);
+        result[time[2]] = fromJulian(Jset);
+    }
+
+    return result;
+};
+
+
+// moon calculations, based on http://aa.quae.nl/en/reken/hemelpositie.html formulas
+
+function moonCoords(d) { // geocentric ecliptic coordinates of the moon
+
+    var L = rad * (218.316 + 13.176396 * d), // ecliptic longitude
+        M = rad * (134.963 + 13.064993 * d), // mean anomaly
+        F = rad * (93.272 + 13.229350 * d),  // mean distance
+
+        l  = L + rad * 6.289 * sin(M), // longitude
+        b  = rad * 5.128 * sin(F),     // latitude
+        dt = 385001 - 20905 * cos(M);  // distance to the moon in km
+
+    return {
+        ra: rightAscension(l, b),
+        dec: declination(l, b),
+        dist: dt
+    };
+}
+
+SunCalc.getMoonPosition = function (date, lat, lng) {
+
+    var lw  = rad * -lng,
+        phi = rad * lat,
+        d   = toDays(date),
+
+        c = moonCoords(d),
+        H = siderealTime(d, lw) - c.ra,
+        h = altitude(H, phi, c.dec);
+
+    // altitude correction for refraction
+    h = h + rad * 0.017 / tan(h + rad * 10.26 / (h + rad * 5.10));
+
+    return {
+        azimuth: azimuth(H, phi, c.dec),
+        altitude: h,
+        distance: c.dist
+    };
+};
+
+
+// calculations for illumination parameters of the moon,
+// based on http://idlastro.gsfc.nasa.gov/ftp/pro/astro/mphase.pro formulas and
+// Chapter 48 of "Astronomical Algorithms" 2nd edition by Jean Meeus (Willmann-Bell, Richmond) 1998.
+
+SunCalc.getMoonIllumination = function (date) {
+
+    var d = toDays(date),
+        s = sunCoords(d),
+        m = moonCoords(d),
+
+        sdist = 149598000, // distance from Earth to Sun in km
+
+        phi = acos(sin(s.dec) * sin(m.dec) + cos(s.dec) * cos(m.dec) * cos(s.ra - m.ra)),
+        inc = atan(sdist * sin(phi), m.dist - sdist * cos(phi)),
+        angle = atan(cos(s.dec) * sin(s.ra - m.ra), sin(s.dec) * cos(m.dec) -
+                cos(s.dec) * sin(m.dec) * cos(s.ra - m.ra));
+
+    return {
+        fraction: (1 + cos(inc)) / 2,
+        phase: 0.5 + 0.5 * inc * (angle < 0 ? -1 : 1) / Math.PI,
+        angle: angle
+    };
+};
+
+
+function hoursLater(date, h) {
+    return new Date(date.valueOf() + h * dayMs / 24);
+}
+
+// calculations for moon rise/set times are based on http://www.stargazing.net/kepler/moonrise.html article
+
+SunCalc.getMoonTimes = function (date, lat, lng) {
+    var t = new Date(date);
+    t.setHours(0);
+    t.setMinutes(0);
+    t.setSeconds(0);
+    t.setMilliseconds(0);
+
+    var hc = 0.133 * rad,
+        h0 = SunCalc.getMoonPosition(t, lat, lng).altitude - hc,
+        h1, h2, rise, set, a, b, xe, ye, d, roots, x1, x2, dx;
+
+    // go in 2-hour chunks, each time seeing if a 3-point quadratic curve crosses zero (which means rise or set)
+    for (var i = 1; i <= 24; i += 2) {
+        h1 = SunCalc.getMoonPosition(hoursLater(t, i), lat, lng).altitude - hc;
+        h2 = SunCalc.getMoonPosition(hoursLater(t, i + 1), lat, lng).altitude - hc;
+
+        a = (h0 + h2) / 2 - h1;
+        b = (h2 - h0) / 2;
+        xe = -b / (2 * a);
+        ye = (a * xe + b) * xe + h1;
+        d = b * b - 4 * a * h1;
+        roots = 0;
+
+        if (d >= 0) {
+            dx = Math.sqrt(d) / (Math.abs(a) * 2);
+            x1 = xe - dx;
+            x2 = xe + dx;
+            if (Math.abs(x1) <= 1) roots++;
+            if (Math.abs(x2) <= 1) roots++;
+            if (x1 < -1) x1 = x2;
+        }
+
+        if (roots === 1) {
+            if (h0 < 0) rise = i + x1;
+            else set = i + x1;
+
+        } else if (roots === 2) {
+            rise = i + (ye < 0 ? x2 : x1);
+            set = i + (ye < 0 ? x1 : x2);
+        }
+
+        if (rise && set) break;
+
+        h0 = h2;
+    }
+
+    var result = {};
+
+    if (rise) result.rise = hoursLater(t, rise);
+    if (set) result.set = hoursLater(t, set);
+
+    if (!rise && !set) result[ye > 0 ? 'alwaysUp' : 'alwaysDown'] = true;
+
+    return result;
+};
+
+
+// export as AMD module / Node module / browser variable
+//if (typeof define === 'function' && define.amd) define(SunCalc);
+//else if (typeof module !== 'undefined') module.exports = SunCalc;
+//else window.SunCalc = SunCalc;
+
+//}());

=== added directory 'app/graphics'
=== added file 'app/graphics/Big-Rain.png'
Binary files app/graphics/Big-Rain.png	1970-01-01 00:00:00 +0000 and app/graphics/Big-Rain.png	2015-08-05 19:54:56 +0000 differ
=== added file 'app/graphics/CMakeLists.txt'
--- app/graphics/CMakeLists.txt	1970-01-01 00:00:00 +0000
+++ app/graphics/CMakeLists.txt	2015-08-05 19:54:56 +0000
@@ -0,0 +1,5 @@
+file(GLOB IMAGE_FILES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} *.png *.svg)
+
+add_custom_target(ubuntu-weather-app_graphics_IMAGEFiles ALL SOURCES ${IMAGE_FILES})
+
+install(FILES ${IMAGE_FILES} DESTINATION ${UBUNTU-WEATHER_APP_DIR}/graphics)

=== added file 'app/graphics/Cloudy-Circles.png'
Binary files app/graphics/Cloudy-Circles.png	1970-01-01 00:00:00 +0000 and app/graphics/Cloudy-Circles.png	2015-08-05 19:54:56 +0000 differ
=== added file 'app/graphics/Cloudy-Night.png'
Binary files app/graphics/Cloudy-Night.png	1970-01-01 00:00:00 +0000 and app/graphics/Cloudy-Night.png	2015-08-05 19:54:56 +0000 differ
=== added file 'app/graphics/Cloudy-Snow.png'
Binary files app/graphics/Cloudy-Snow.png	1970-01-01 00:00:00 +0000 and app/graphics/Cloudy-Snow.png	2015-08-05 19:54:56 +0000 differ
=== added file 'app/graphics/Cloudy.png'
Binary files app/graphics/Cloudy.png	1970-01-01 00:00:00 +0000 and app/graphics/Cloudy.png	2015-08-05 19:54:56 +0000 differ
=== added file 'app/graphics/Fog.png'
Binary files app/graphics/Fog.png	1970-01-01 00:00:00 +0000 and app/graphics/Fog.png	2015-08-05 19:54:56 +0000 differ
=== added file 'app/graphics/Raindrop.png'
Binary files app/graphics/Raindrop.png	1970-01-01 00:00:00 +0000 and app/graphics/Raindrop.png	2015-08-05 19:54:56 +0000 differ
=== added file 'app/graphics/Showers.png'
Binary files app/graphics/Showers.png	1970-01-01 00:00:00 +0000 and app/graphics/Showers.png	2015-08-05 19:54:56 +0000 differ
=== added file 'app/graphics/Starry-Night.png'
Binary files app/graphics/Starry-Night.png	1970-01-01 00:00:00 +0000 and app/graphics/Starry-Night.png	2015-08-05 19:54:56 +0000 differ
=== added file 'app/graphics/Stormy.png'
Binary files app/graphics/Stormy.png	1970-01-01 00:00:00 +0000 and app/graphics/Stormy.png	2015-08-05 19:54:56 +0000 differ
=== added file 'app/graphics/Sunny.png'
Binary files app/graphics/Sunny.png	1970-01-01 00:00:00 +0000 and app/graphics/Sunny.png	2015-08-05 19:54:56 +0000 differ
=== added file 'app/graphics/Windy-n-Snow.png'
Binary files app/graphics/Windy-n-Snow.png	1970-01-01 00:00:00 +0000 and app/graphics/Windy-n-Snow.png	2015-08-05 19:54:56 +0000 differ
=== added file 'app/graphics/extended-information_chance-of-rain.svg'
--- app/graphics/extended-information_chance-of-rain.svg	1970-01-01 00:00:00 +0000
+++ app/graphics/extended-information_chance-of-rain.svg	2015-08-05 19:54:56 +0000
@@ -0,0 +1,153 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/";
+   xmlns:cc="http://creativecommons.org/ns#";
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#";
+   xmlns:svg="http://www.w3.org/2000/svg";
+   xmlns="http://www.w3.org/2000/svg";
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd";
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape";
+   width="90"
+   height="90"
+   id="svg6138"
+   version="1.1"
+   inkscape:version="0.91pre2 r"
+   viewBox="0 0 90 90.000001"
+   sodipodi:docname="weather-chance-of-rain02.svg">
+  <defs
+     id="defs6140" />
+  <sodipodi:namedview
+     id="base"
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1.0"
+     inkscape:pageopacity="0.0"
+     inkscape:pageshadow="2"
+     inkscape:zoom="5.0931702"
+     inkscape:cx="112.1011"
+     inkscape:cy="19.378885"
+     inkscape:document-units="px"
+     inkscape:current-layer="g6442"
+     showgrid="true"
+     fit-margin-top="0"
+     fit-margin-left="0"
+     fit-margin-right="0"
+     fit-margin-bottom="0"
+     inkscape:snap-global="true"
+     inkscape:snap-bbox="true"
+     inkscape:bbox-paths="true"
+     inkscape:snap-bbox-midpoints="true"
+     inkscape:snap-bbox-edge-midpoints="true"
+     inkscape:bbox-nodes="true"
+     inkscape:object-paths="true"
+     inkscape:snap-intersection-paths="true"
+     inkscape:object-nodes="true"
+     inkscape:snap-smooth-nodes="true"
+     inkscape:snap-midpoints="true"
+     inkscape:snap-others="true"
+     inkscape:snap-object-midpoints="true"
+     inkscape:snap-center="true"
+     showguides="false"
+     inkscape:guide-bbox="true">
+    <inkscape:grid
+       type="xygrid"
+       id="grid6700"
+       empspacing="6" />
+    <sodipodi:guide
+       orientation="0,1"
+       position="90,87"
+       id="guide4064" />
+    <sodipodi:guide
+       orientation="0,1"
+       position="89,84"
+       id="guide4066" />
+    <sodipodi:guide
+       orientation="1,0"
+       position="3,69"
+       id="guide4068" />
+    <sodipodi:guide
+       orientation="1,0"
+       position="6,60"
+       id="guide4070" />
+    <sodipodi:guide
+       orientation="1,0"
+       position="87,58"
+       id="guide4072" />
+    <sodipodi:guide
+       orientation="1,0"
+       position="84,47"
+       id="guide4074" />
+    <sodipodi:guide
+       orientation="0,1"
+       position="77,3"
+       id="guide4076" />
+    <sodipodi:guide
+       orientation="0,1"
+       position="81,6"
+       id="guide4078" />
+    <sodipodi:guide
+       orientation="1,0"
+       position="81,25"
+       id="guide4080" />
+    <sodipodi:guide
+       orientation="0,1"
+       position="78,9"
+       id="guide4082" />
+    <sodipodi:guide
+       orientation="0,1"
+       position="79,81"
+       id="guide4084" />
+    <sodipodi:guide
+       orientation="1,0"
+       position="9,39"
+       id="guide4086" />
+  </sodipodi:namedview>
+  <metadata
+     id="metadata6143">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage"; />
+        <dc:title></dc:title>
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <g
+     inkscape:label="Layer 1"
+     inkscape:groupmode="layer"
+     id="layer1"
+     transform="translate(-283.57144,-358.79068)">
+    <g
+       transform="translate(169.57144,223.42822)"
+       id="g5937"
+       inkscape:export-filename="envelope02.png"
+       inkscape:export-xdpi="90"
+       inkscape:export-ydpi="90" />
+    <g
+       id="g6442"
+       transform="translate(-753.45981,336.4283)">
+      <rect
+         style="fill:none;stroke:none"
+         id="rect1687"
+         width="90"
+         height="90"
+         x="1037.0312"
+         y="22.362379" />
+      <path
+         style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:125%;font-family:Ubuntu;-inkscape-font-specification:Ubuntu;text-align:end;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:end;fill:#808080;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+         d="M 44.929688 12.066406 C 34.037288 12.066406 24.849688 14.943458 17.367188 20.697266 C 9.7896875 26.523909 6 33.624202 6 42 C 7.7011 40.603306 9.6530686 39.474739 11.855469 38.615234 C 14.075869 37.773637 16.4573 37.353516 19 37.353516 C 21.5427 37.353516 23.914587 37.773637 26.117188 38.615234 C 28.337486 39.474739 30.2989 40.603306 32 42 C 33.7011 40.603306 35.653069 39.474739 37.855469 38.615234 C 40.075769 37.773637 42.4573 37.353516 45 37.353516 C 47.5427 37.353516 49.914586 37.773637 52.117188 38.615234 C 54.337487 39.474739 56.2989 40.603306 58 42 L 58.654297 42 C 60.235137 40.784631 62.009869 39.776665 64 39 C 66.2203 38.158403 68.601831 37.738281 71.144531 37.738281 C 73.687231 37.738281 76.059119 38.158403 78.261719 39 C 80.268226 39.776743 82.052173 40.784465 83.634766 42 L 84 42 C 84 33.624202 80.210313 26.523909 72.632812 20.697266 C 65.055613 14.943458 55.822287 12.066406 44.929688 12.066406 z "
+         transform="translate(1037.0313,22.36238)"
+         id="path4181" />
+      <path
+         style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:125%;font-family:Ubuntu;-inkscape-font-specification:Ubuntu;text-indent:0;text-align:end;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:0px;word-spacing:0px;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;baseline-shift:baseline;text-anchor:end;white-space:normal;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#808080;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:6.00000048;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
+         d="m 1079.0312,28.363281 0,66.335938 0.01,0.09766 c 0.015,0.226687 0.022,0.780446 0.022,1.509766 0,1.918939 -0.4328,2.763898 -1.0039,3.289062 l -0.01,0.0059 -0.01,0.0078 c -0.6357,0.592743 -1.5903,1.007813 -3.4297,1.007813 -1.8313,0 -2.8017,-0.41364 -3.461,-1.015626 -0.5541,-0.519673 -0.9882,-1.37472 -0.9882,-3.294921 0,-0.72932 0.01,-1.281931 0.021,-1.501953 l -5.9863,-0.410157 c -0.041,0.598238 -0.035,1.18279 -0.035,1.91211 0,2.983063 0.8627,5.791367 2.9003,7.691407 l 0.01,0.008 0.01,0.006 c 1.9716,1.8129 4.6659,2.60547 7.5332,2.60547 2.8642,0 5.5555,-0.79304 7.5136,-2.61524 2.0532,-1.89396 2.9356,-4.70919 2.9356,-7.695307 0,-0.72932 0.01,-1.312724 -0.033,-1.904297 l 0.01,0.197265 0,-67.236328 -6,1 z"
+         id="path4225"
+         inkscape:connector-curvature="0"
+         sodipodi:nodetypes="cccscccscsccscccscsccccc" />
+    </g>
+  </g>
+</svg>

=== added file 'app/graphics/extended-information_humidity.svg'
--- app/graphics/extended-information_humidity.svg	1970-01-01 00:00:00 +0000
+++ app/graphics/extended-information_humidity.svg	2015-08-05 19:54:56 +0000
@@ -0,0 +1,147 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/";
+   xmlns:cc="http://creativecommons.org/ns#";
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#";
+   xmlns:svg="http://www.w3.org/2000/svg";
+   xmlns="http://www.w3.org/2000/svg";
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd";
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape";
+   width="90"
+   height="90"
+   id="svg6138"
+   version="1.1"
+   inkscape:version="0.91pre2 r"
+   viewBox="0 0 90 90.000001"
+   sodipodi:docname="weather-chance-of-rain.svg">
+  <defs
+     id="defs6140" />
+  <sodipodi:namedview
+     id="base"
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1.0"
+     inkscape:pageopacity="0.0"
+     inkscape:pageshadow="2"
+     inkscape:zoom="4.0745362"
+     inkscape:cx="90.550182"
+     inkscape:cy="25.205316"
+     inkscape:document-units="px"
+     inkscape:current-layer="g6442"
+     showgrid="true"
+     fit-margin-top="0"
+     fit-margin-left="0"
+     fit-margin-right="0"
+     fit-margin-bottom="0"
+     inkscape:snap-global="false"
+     inkscape:snap-bbox="true"
+     inkscape:bbox-paths="true"
+     inkscape:snap-bbox-midpoints="true"
+     inkscape:snap-bbox-edge-midpoints="true"
+     inkscape:bbox-nodes="true"
+     inkscape:object-paths="true"
+     inkscape:snap-intersection-paths="true"
+     inkscape:object-nodes="true"
+     inkscape:snap-smooth-nodes="true"
+     inkscape:snap-midpoints="true"
+     inkscape:snap-others="true"
+     inkscape:snap-object-midpoints="true"
+     inkscape:snap-center="true"
+     showguides="false"
+     inkscape:guide-bbox="true">
+    <inkscape:grid
+       type="xygrid"
+       id="grid6700"
+       empspacing="6" />
+    <sodipodi:guide
+       orientation="0,1"
+       position="90,87"
+       id="guide4064" />
+    <sodipodi:guide
+       orientation="0,1"
+       position="89,84"
+       id="guide4066" />
+    <sodipodi:guide
+       orientation="1,0"
+       position="3,69"
+       id="guide4068" />
+    <sodipodi:guide
+       orientation="1,0"
+       position="6,60"
+       id="guide4070" />
+    <sodipodi:guide
+       orientation="1,0"
+       position="87,58"
+       id="guide4072" />
+    <sodipodi:guide
+       orientation="1,0"
+       position="84,47"
+       id="guide4074" />
+    <sodipodi:guide
+       orientation="0,1"
+       position="77,3"
+       id="guide4076" />
+    <sodipodi:guide
+       orientation="0,1"
+       position="81,6"
+       id="guide4078" />
+    <sodipodi:guide
+       orientation="1,0"
+       position="81,25"
+       id="guide4080" />
+    <sodipodi:guide
+       orientation="0,1"
+       position="78,9"
+       id="guide4082" />
+    <sodipodi:guide
+       orientation="0,1"
+       position="79,81"
+       id="guide4084" />
+    <sodipodi:guide
+       orientation="1,0"
+       position="9,39"
+       id="guide4086" />
+  </sodipodi:namedview>
+  <metadata
+     id="metadata6143">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage"; />
+        <dc:title></dc:title>
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <g
+     inkscape:label="Layer 1"
+     inkscape:groupmode="layer"
+     id="layer1"
+     transform="translate(-283.57144,-358.79068)">
+    <g
+       transform="translate(169.57144,223.42822)"
+       id="g5937"
+       inkscape:export-filename="envelope02.png"
+       inkscape:export-xdpi="90"
+       inkscape:export-ydpi="90" />
+    <g
+       id="g6442"
+       transform="translate(-753.45981,336.4283)">
+      <path
+         style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:#808080;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3;marker:none;enable-background:accumulate"
+         d="M 45.046875 3 C 32.915975 27.594868 24.552722 55.021065 23.982422 56.908203 C 23.901522 57.129789 23.841578 57.361086 23.767578 57.585938 C 23.036878 59.796557 22.623047 62.152027 22.623047 64.607422 C 22.623047 76.973464 32.652638 86.998047 45.023438 86.998047 C 57.372742 86.972595 67.376953 76.959723 67.376953 64.609375 C 67.376953 62.155598 66.975594 59.797236 66.246094 57.587891 C 66.246094 57.587891 58.008075 29.900931 45.046875 3.0390625 L 45.046875 3.03125 L 45.046875 3.0195312 L 45.046875 3.0058594 L 45.046875 3 z M 44.996094 17.728516 C 54.458094 39.650002 60.503906 59.296875 60.503906 59.296875 A 5.9907304 5.9907304 0 0 0 60.558594 59.466797 C 61.095294 61.092212 61.386719 62.80886 61.386719 64.609375 C 61.386719 73.725917 54.126659 80.989079 45.005859 81.005859 C 35.879459 80.996009 28.613281 73.728301 28.613281 64.607422 C 28.613281 62.825026 28.910878 61.113375 29.455078 59.466797 A 5.9907304 5.9907304 0 0 0 29.457031 59.458984 C 29.615031 58.978962 29.665675 58.806709 29.609375 58.960938 A 5.9907304 5.9907304 0 0 0 29.716797 58.638672 C 30.156997 57.182234 36.199294 37.969649 44.996094 17.728516 z "
+         transform="translate(1037.0313,22.36238)"
+         id="path4253" />
+      <rect
+         style="fill:none;stroke:none"
+         id="rect1687"
+         width="90"
+         height="90"
+         x="1037.0312"
+         y="22.362379" />
+    </g>
+  </g>
+</svg>

=== added file 'app/graphics/extended-information_sunrise.svg'
--- app/graphics/extended-information_sunrise.svg	1970-01-01 00:00:00 +0000
+++ app/graphics/extended-information_sunrise.svg	2015-08-05 19:54:56 +0000
@@ -0,0 +1,88 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/";
+   xmlns:cc="http://creativecommons.org/ns#";
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#";
+   xmlns:svg="http://www.w3.org/2000/svg";
+   xmlns="http://www.w3.org/2000/svg";
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd";
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape";
+   width="90"
+   height="90"
+   id="svg3642"
+   version="1.1"
+   inkscape:version="0.91 r13725"
+   viewBox="0 0 90 90"
+   sodipodi:docname="sunrise.svg">
+  <defs
+     id="defs3644" />
+  <sodipodi:namedview
+     id="base"
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1.0"
+     inkscape:pageopacity="0.0"
+     inkscape:pageshadow="2"
+     inkscape:zoom="5.5"
+     inkscape:cx="1.4545455"
+     inkscape:cy="32"
+     inkscape:current-layer="layer1"
+     showgrid="true"
+     inkscape:document-units="px"
+     inkscape:grid-bbox="true"
+     inkscape:window-width="1855"
+     inkscape:window-height="1056"
+     inkscape:window-x="65"
+     inkscape:window-y="24"
+     inkscape:window-maximized="1" />
+  <metadata
+     id="metadata3647">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage"; />
+        <dc:title></dc:title>
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <g
+     id="layer1"
+     inkscape:label="Layer 1"
+     inkscape:groupmode="layer"
+     transform="translate(0,26)">
+    <path
+       style="fill:#808080;fill-opacity:1"
+       d="m 26.78212,5.9887068 -5.382513,-9.3529353 2.093211,-1.1925985 c 1.151271,-0.65592 2.107413,-1.174671 2.124765,-1.152765 0.313155,0.395325 10.541061,18.372014 10.541061,18.527102 0,0.121167 -0.536958,0.524286 -1.193238,0.895824 -0.656289,0.371547 -1.554939,0.889911 -1.99701,1.151919 L 32.164633,15.341641 26.78212,5.9887068 Z"
+       id="path3437"
+       inkscape:connector-curvature="0" />
+    <path
+       style="fill:#808080;fill-opacity:1"
+       d="m 42.749893,0.3532757 0,-10.6823697 2.386485,0 2.386485,0 0,10.6823697 0,10.6823603 -2.386485,0 -2.386485,0 0,-10.6823603 z"
+       id="path3439"
+       inkscape:connector-curvature="0" />
+    <path
+       style="fill:#808080;fill-opacity:1"
+       d="M 56.046025,14.195662 C 55.045972,13.59223 54.130753,13.062283 54.012196,13.018003 53.848144,12.956713 61.28128,-0.2748253 64.150641,-5.02921 l 0.436437,-0.723159 1.979793,1.141956 c 1.088883,0.6280825 2.017233,1.1784505 2.062989,1.2230456 0.08784,0.08559 -10.018844,17.7534264 -10.490561,18.3388854 -0.237942,0.295308 -0.520002,0.193464 -2.093274,-0.755856 z"
+       id="path3441"
+       inkscape:connector-curvature="0" />
+    <path
+       style="fill:#808080;fill-opacity:1"
+       d="M 63.87093,22.143905 C 63.219591,21.005711 62.784261,20.007647 62.893962,19.904048 63.177039,19.63673 81.221725,9.1995467 81.276697,9.2713397 c 0.282537,0.369027 2.389788,4.1043953 2.339028,4.1462363 -0.03753,0.03096 -3.392335,1.976715 -7.455034,4.323898 -4.062708,2.347191 -8.225586,4.759875 -9.250839,5.361516 l -1.864089,1.093905 -1.174833,-2.05299 z"
+       id="path3445"
+       inkscape:connector-curvature="0" />
+    <path
+       style="fill:#808080;fill-opacity:1"
+       d="m 1.8387093,32.887313 0,-2.53251 13.6075957,0 13.607586,0 0.620559,-1.761453 c 2.147886,-6.096807 5.892831,-9.823986 11.166354,-11.11338 2.201751,-0.538335 6.756111,-0.534681 8.727615,0.0072 5.170455,1.420614 9.12609,5.644305 11.040102,11.788227 l 0.407133,1.306881 13.481909,0 13.481911,0 0,2.272842 0,2.272842 -41.673339,0 c -22.920327,0 -42.3019986,0.0657 -43.0703737,0.146025 l -1.397052,0.146016 0,-2.532501 z M 55.616266,29.616128 c -0.413046,-2.094669 -2.175516,-4.507155 -4.292244,-5.875263 -4.577967,-2.958876 -9.971064,-2.49669 -13.914819,1.192491 -1.555938,1.455507 -2.841543,3.616272 -2.841543,4.775895 l 0,0.645552 10.597131,0 10.597131,0 -0.145656,-0.738675 z"
+       id="path3447"
+       inkscape:connector-curvature="0" />
+    <path
+       style="fill:#808080;fill-opacity:1"
+       d="m 15.922288,18.850454 c -5.058325,-2.928024 -9.2259277,-5.40856 -9.2613247,-5.512285 -0.03537,-0.103734 0.459243,-1.078245 1.099215,-2.16558 l 1.163583,-1.9769753 0.719055,0.424107 C 10.038303,9.8529737 14.146156,12.22684 18.7714,14.89498 c 4.625235,2.668132 8.483391,4.91356 8.573679,4.989826 0.09029,0.07623 -0.37359,1.072584 -1.030833,2.214009 l -1.194993,2.075328 -9.196965,-5.323689 z"
+       id="path3449"
+       inkscape:connector-curvature="0" />
+  </g>
+</svg>

=== added file 'app/graphics/extended-information_sunset.svg'
--- app/graphics/extended-information_sunset.svg	1970-01-01 00:00:00 +0000
+++ app/graphics/extended-information_sunset.svg	2015-08-05 19:54:56 +0000
@@ -0,0 +1,88 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/";
+   xmlns:cc="http://creativecommons.org/ns#";
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#";
+   xmlns:svg="http://www.w3.org/2000/svg";
+   xmlns="http://www.w3.org/2000/svg";
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd";
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape";
+   width="90"
+   height="90"
+   id="svg3642"
+   version="1.1"
+   inkscape:version="0.91 r13725"
+   viewBox="0 0 90 90"
+   sodipodi:docname="sunset.svg">
+  <defs
+     id="defs3644" />
+  <sodipodi:namedview
+     id="base"
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1.0"
+     inkscape:pageopacity="0.0"
+     inkscape:pageshadow="2"
+     inkscape:zoom="5.5"
+     inkscape:cx="1.4545455"
+     inkscape:cy="32"
+     inkscape:current-layer="layer1"
+     showgrid="true"
+     inkscape:document-units="px"
+     inkscape:grid-bbox="true"
+     inkscape:window-width="1855"
+     inkscape:window-height="1056"
+     inkscape:window-x="65"
+     inkscape:window-y="24"
+     inkscape:window-maximized="1" />
+  <metadata
+     id="metadata3647">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage"; />
+        <dc:title></dc:title>
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <g
+     id="layer1"
+     inkscape:label="Layer 1"
+     inkscape:groupmode="layer"
+     transform="translate(0,26)">
+    <path
+       style="fill:#808080;fill-opacity:1"
+       d="m 63.036063,25.102202 5.382513,9.352936 -2.093211,1.192598 c -1.151271,0.65592 -2.107413,1.174671 -2.124765,1.152765 -0.313155,-0.395325 -10.541061,-18.372014 -10.541061,-18.527102 0,-0.121167 0.536958,-0.524286 1.193238,-0.895824 0.656289,-0.371547 1.554939,-0.889911 1.99701,-1.151919 l 0.803763,-0.476388 5.382513,9.352934 z"
+       id="path3437"
+       inkscape:connector-curvature="0" />
+    <path
+       style="fill:#808080;fill-opacity:1"
+       d="m 47.06829,30.737633 0,10.68237 -2.386485,0 -2.386485,0 0,-10.68237 0,-10.68236 2.386485,0 2.386485,0 0,10.68236 z"
+       id="path3439"
+       inkscape:connector-curvature="0" />
+    <path
+       style="fill:#808080;fill-opacity:1"
+       d="m 33.772158,16.895247 c 1.000053,0.603432 1.915272,1.133379 2.033829,1.177659 0.164052,0.06129 -7.269084,13.292828 -10.138445,18.047213 l -0.436437,0.723159 -1.979793,-1.141956 c -1.088883,-0.628083 -2.017233,-1.178451 -2.062989,-1.223046 -0.08784,-0.08559 10.018844,-17.753426 10.490561,-18.338885 0.237942,-0.295308 0.520002,-0.193464 2.093274,0.755856 z"
+       id="path3441"
+       inkscape:connector-curvature="0" />
+    <path
+       style="fill:#808080;fill-opacity:1"
+       d="m 25.947253,8.947004 c 0.651339,1.138194 1.086669,2.136258 0.976968,2.239857 -0.283077,0.267318 -18.3277627,10.704501 -18.3827347,10.632708 -0.282537,-0.369027 -2.389788,-4.104395 -2.339028,-4.146236 0.03753,-0.03096 3.392335,-1.976715 7.4550337,-4.323898 4.062708,-2.347191 8.225586,-4.759875 9.250839,-5.361516 l 1.864089,-1.093905 1.174833,2.05299 z"
+       id="path3445"
+       inkscape:connector-curvature="0" />
+    <path
+       style="fill:#808080;fill-opacity:1"
+       d="m 87.979474,-1.796404 0,2.53251 -13.607596,0 -13.607586,0 -0.620559,1.761453 c -2.147886,6.096807 -5.892831,9.823986 -11.166354,11.11338 -2.201751,0.538335 -6.756111,0.534681 -8.727615,-0.0072 C 35.079309,12.183125 31.123674,7.959434 29.209662,1.815512 l -0.407133,-1.306881 -13.481909,0 -13.4819107,0 0,-2.272842 0,-2.272842 41.6733387,0 c 22.920327,0 42.301999,-0.0657 43.070374,-0.146025 l 1.397052,-0.146016 0,2.532501 z M 34.201917,1.474781 c 0.413046,2.094669 2.175516,4.507155 4.292244,5.875263 4.577967,2.958876 9.971064,2.49669 13.914819,-1.192491 1.555938,-1.455507 2.841543,-3.616272 2.841543,-4.775895 l 0,-0.645552 -10.597131,0 -10.597131,0 0.145656,0.738675 z"
+       id="path3447"
+       inkscape:connector-curvature="0" />
+    <path
+       style="fill:#808080;fill-opacity:1"
+       d="m 73.895895,12.240455 c 5.058325,2.928024 9.225928,5.40856 9.261325,5.512285 0.03537,0.103734 -0.459243,1.078245 -1.099215,2.16558 l -1.163583,1.976975 -0.719055,-0.424107 c -0.395487,-0.233253 -4.50334,-2.607119 -9.128584,-5.275259 -4.625235,-2.668132 -8.483391,-4.91356 -8.573679,-4.989826 -0.09029,-0.07623 0.37359,-1.072584 1.030833,-2.214009 l 1.194993,-2.075328 9.196965,5.323689 z"
+       id="path3449"
+       inkscape:connector-curvature="0" />
+  </g>
+</svg>

=== added file 'app/graphics/extended-information_uv-level.svg'
--- app/graphics/extended-information_uv-level.svg	1970-01-01 00:00:00 +0000
+++ app/graphics/extended-information_uv-level.svg	2015-08-05 19:54:56 +0000
@@ -0,0 +1,270 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/";
+   xmlns:cc="http://creativecommons.org/ns#";
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#";
+   xmlns:svg="http://www.w3.org/2000/svg";
+   xmlns="http://www.w3.org/2000/svg";
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd";
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape";
+   width="90"
+   height="90"
+   id="svg6138"
+   version="1.1"
+   inkscape:version="0.91pre2 r"
+   viewBox="0 0 90 90.000001"
+   sodipodi:docname="weather-uv-level.svg">
+  <defs
+     id="defs6140">
+    <linearGradient
+       id="linearGradient3899">
+      <stop
+         id="stop4292"
+         offset="0"
+         style="stop-color:#fbf7e3;stop-opacity:1" />
+      <stop
+         id="stop4294"
+         offset="1"
+         style="stop-color:#c6b386;stop-opacity:1" />
+    </linearGradient>
+  </defs>
+  <sodipodi:namedview
+     id="base"
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1.0"
+     inkscape:pageopacity="0.0"
+     inkscape:pageshadow="2"
+     inkscape:zoom="7.9580785"
+     inkscape:cx="32.979067"
+     inkscape:cy="45.789944"
+     inkscape:document-units="px"
+     inkscape:current-layer="g6442"
+     showgrid="true"
+     fit-margin-top="0"
+     fit-margin-left="0"
+     fit-margin-right="0"
+     fit-margin-bottom="0"
+     inkscape:snap-global="true"
+     inkscape:snap-bbox="true"
+     inkscape:bbox-paths="true"
+     inkscape:snap-bbox-midpoints="true"
+     inkscape:snap-bbox-edge-midpoints="true"
+     inkscape:bbox-nodes="true"
+     inkscape:object-paths="true"
+     inkscape:snap-intersection-paths="true"
+     inkscape:object-nodes="true"
+     inkscape:snap-smooth-nodes="true"
+     inkscape:snap-midpoints="true"
+     inkscape:snap-others="true"
+     inkscape:snap-object-midpoints="true"
+     inkscape:snap-center="true"
+     showguides="true"
+     inkscape:guide-bbox="true">
+    <inkscape:grid
+       type="xygrid"
+       id="grid6700"
+       empspacing="6" />
+    <sodipodi:guide
+       orientation="0,1"
+       position="90,87"
+       id="guide4064" />
+    <sodipodi:guide
+       orientation="0,1"
+       position="89,84"
+       id="guide4066" />
+    <sodipodi:guide
+       orientation="1,0"
+       position="3,69"
+       id="guide4068" />
+    <sodipodi:guide
+       orientation="1,0"
+       position="6,60"
+       id="guide4070" />
+    <sodipodi:guide
+       orientation="1,0"
+       position="87,58"
+       id="guide4072" />
+    <sodipodi:guide
+       orientation="1,0"
+       position="84,47"
+       id="guide4074" />
+    <sodipodi:guide
+       orientation="0,1"
+       position="77,3"
+       id="guide4076" />
+    <sodipodi:guide
+       orientation="0,1"
+       position="81,6"
+       id="guide4078" />
+    <sodipodi:guide
+       orientation="1,0"
+       position="81,25"
+       id="guide4080" />
+    <sodipodi:guide
+       orientation="0,1"
+       position="78,9"
+       id="guide4082" />
+    <sodipodi:guide
+       orientation="0,1"
+       position="79,81"
+       id="guide4084" />
+    <sodipodi:guide
+       orientation="1,0"
+       position="9,39"
+       id="guide4086" />
+  </sodipodi:namedview>
+  <metadata
+     id="metadata6143">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage"; />
+        <dc:title></dc:title>
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <g
+     inkscape:label="Layer 1"
+     inkscape:groupmode="layer"
+     id="layer1"
+     transform="translate(-283.57144,-358.79068)">
+    <g
+       transform="translate(169.57144,223.42822)"
+       id="g5937"
+       inkscape:export-filename="envelope02.png"
+       inkscape:export-xdpi="90"
+       inkscape:export-ydpi="90" />
+    <g
+       id="g6442"
+       transform="translate(-753.45981,336.4283)">
+      <rect
+         style="fill:none;stroke:none"
+         id="rect1687"
+         width="90"
+         height="90"
+         x="1037.0312"
+         y="22.362379" />
+      <path
+         style="color:#000000;fill:#808080;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:6;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+         d="m 1054.1015,75.51863 a 33.872092,33.872092 0 0 0 0.5547,2.339844 33.872092,33.872092 0 0 1 -0.5547,-2.339844 z"
+         id="path4162" />
+      <path
+         style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:#808080;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2.25;marker:none;enable-background:accumulate"
+         d="M 45 12 A 33.00005 33.00005 0 0 0 12 45 A 33.00005 33.00005 0 0 0 45 78 A 33.00005 33.00005 0 0 0 78 45 A 33.00005 33.00005 0 0 0 45 12 z M 45 18 A 27 27 0 0 1 72 45 A 27 27 0 0 1 45 72 A 27 27 0 0 1 18 45 A 27 27 0 0 1 45 18 z "
+         transform="translate(1037.0313,22.36238)"
+         id="path4189" />
+      <path
+         sodipodi:nodetypes="ccsssccc"
+         inkscape:transform-center-y="-37.504247"
+         inkscape:transform-center-x="-0.0125"
+         inkscape:connector-curvature="0"
+         id="path2194-5"
+         d="m 1088.2477,35.36157 c 0,0 -2.5383,-5.872205 -6.1954,-11.007637 0,0 0,0 -0.01,0.0017 0,0 0,0.0017 -0.01,0.0024 0,0 -0.01,0.002 -0.01,0.0026 0,0 -0.01,0.0017 -0.01,0.0017 -3.7738,5.416839 -6.1725,11 -6.1725,11 z"
+         style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:#808080;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3;marker:none;enable-background:accumulate" />
+      <path
+         style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:#808080;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3;marker:none;enable-background:accumulate"
+         d="m 1103.4153,42.757091 c 0,0 0.7378,-6.354629 0.1384,-12.630594 0,0 0,0 -0.01,-0.0035 0,0 -9e-4,0.0015 -0.01,-0.0029 0,0 -0.01,-0.0033 -0.01,-0.0027 0,0 -0.01,-0.0035 -0.01,-0.0035 -5.9767,2.80422 -10.8456,6.440029 -10.8456,6.440029 z"
+         id="path4192"
+         inkscape:connector-curvature="0"
+         inkscape:transform-center-x="-16.197006"
+         inkscape:transform-center-y="-30.926886"
+         sodipodi:nodetypes="ccsssccc" />
+      <path
+         sodipodi:nodetypes="ccsssccc"
+         inkscape:transform-center-y="-16.173909"
+         inkscape:transform-center-x="-30.9307"
+         inkscape:connector-curvature="0"
+         id="path4194"
+         d="m 1112.853,56.745599 c 0,0 3.8163,-5.13437 6.4352,-10.869215 0,0 0,0 -0.01,-0.008 0,0 0,8.49e-4 -0.01,-0.0075 0,0 -0.01,-0.0079 -0.01,-0.0073 0,0 -0.01,-0.008 -0.01,-0.008 -6.578,-0.559824 -12.6125,0.154429 -12.6125,0.154429 z"
+         style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:#808080;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3;marker:none;enable-background:accumulate" />
+      <path
+         style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:#808080;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3;marker:none;enable-background:accumulate"
+         d="m 1114.0321,73.578853 c 0,0 5.8722,-2.538345 11.0076,-6.195417 0,0 0,0 0,-0.01193 0,0 -5e-4,7.35e-4 -0.01,-0.0115 0,0 0,-0.01184 0,-0.01132 0,0 0,-0.01193 0,-0.01193 -5.4168,-3.773822 -11,-6.172511 -11,-6.172511 z"
+         id="path4196"
+         inkscape:connector-curvature="0"
+         inkscape:transform-center-x="-37.50345"
+         inkscape:transform-center-y="0.0091698086"
+         sodipodi:nodetypes="ccsssccc" />
+      <path
+         sodipodi:nodetypes="ccsssccc"
+         inkscape:transform-center-y="16.194334"
+         inkscape:transform-center-x="-30.9356"
+         inkscape:connector-curvature="0"
+         id="path4198"
+         d="m 1106.6366,88.746428 c 0,0 6.3546,0.737829 12.6305,0.138412 0,0 0,0 0.01,-0.01033 0,0 -8e-4,3.87e-4 0,-0.01496 0,0 0.01,-0.01025 0.01,-0.0098 0,0 0.01,-0.01033 0.01,-0.01033 -2.8042,-5.976626 -6.44,-10.845552 -6.44,-10.845552 z"
+         style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:#808080;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3;marker:none;enable-background:accumulate" />
+      <path
+         style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:#808080;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3;marker:none;enable-background:accumulate"
+         d="m 1092.6481,98.184183 c 0,0 5.1343,3.816277 10.8691,6.435117 0,0 0,0 0.014,-0.004 0,0 -8e-4,-7e-5 0.01,-0.013 0,0 0.014,-0.004 0.014,-0.003 0,0 0.014,-0.004 0.014,-0.004 0.5598,-6.578013 -0.1544,-12.612527 -0.1544,-12.612527 z"
+         id="path4200"
+         inkscape:connector-curvature="0"
+         inkscape:transform-center-x="-16.184519"
+         inkscape:transform-center-y="30.938658"
+         sodipodi:nodetypes="ccsssccc" />
+      <path
+         sodipodi:nodetypes="ccsssccc"
+         inkscape:transform-center-y="37.507651"
+         inkscape:transform-center-x="0.003949878"
+         inkscape:connector-curvature="0"
+         id="path4202"
+         d="m 1075.8148,99.363269 c 0,0 2.5383,5.872141 6.1954,11.007521 0,0 0,0 0.014,0.004 0,0 -7e-4,-4.6e-4 0.015,-0.006 0,0 0.014,0.004 0.014,0.004 0,0 0.014,0.004 0.014,0.004 3.7738,-5.41683 6.1726,-10.999969 6.1726,-10.999969 z"
+         style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:#808080;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3;marker:none;enable-background:accumulate" />
+      <path
+         style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:#808080;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3;marker:none;enable-background:accumulate"
+         d="m 1060.6472,91.967738 c 0,0 -0.7378,6.354573 -0.1384,12.630492 0,0 0,0 0.01,0.0105 0,0 -3e-4,-7.4e-4 0.016,0.002 0,0 0.01,0.0105 0.01,0.0105 0,0 0.01,0.0105 0.01,0.0105 5.9766,-2.80422 10.8456,-6.439956 10.8456,-6.439956 z"
+         id="path4204"
+         inkscape:connector-curvature="0"
+         inkscape:transform-center-x="16.194006"
+         inkscape:transform-center-y="30.937355"
+         sodipodi:nodetypes="ccsssccc" />
+      <path
+         sodipodi:nodetypes="ccsssccc"
+         inkscape:transform-center-y="16.184506"
+         inkscape:transform-center-x="30.94415"
+         inkscape:connector-curvature="0"
+         id="path4206"
+         d="m 1051.2094,77.97922 c 0,0 -3.8162,5.134322 -6.4351,10.869127 0,0 0,0 0,0.01409 0,0 2e-4,-7.9e-4 0.013,0.0097 0,0 0,0.01409 0,0.01409 0,0 0,0.01409 0,0.01409 6.578,0.559774 12.6126,-0.154365 12.6126,-0.154365 z"
+         style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:#808080;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3;marker:none;enable-background:accumulate" />
+      <path
+         style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:#808080;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3;marker:none;enable-background:accumulate"
+         d="m 1050.0303,61.145908 c 0,0 -5.8721,2.538353 -11.0075,6.19539 0,0 0,0 -0.01,0.0122 0,0 5e-4,-5.85e-4 0.01,0.0149 0,0 -0.01,0.0122 -0.01,0.0122 0,0 -0.01,0.0122 -0.01,0.0122 5.4168,3.773778 11,6.172616 11,6.172616 z"
+         id="path4208"
+         inkscape:connector-curvature="0"
+         inkscape:transform-center-x="37.5147"
+         inkscape:transform-center-y="-0.0067180911"
+         sodipodi:nodetypes="ccsssccc" />
+      <path
+         sodipodi:nodetypes="ccsssccc"
+         inkscape:transform-center-y="-16.199665"
+         inkscape:transform-center-x="30.94315"
+         inkscape:connector-curvature="0"
+         id="path4210"
+         d="m 1057.4258,45.978282 c 0,0 -6.3545,-0.737771 -12.6304,-0.138384 0,0 0,0 -0.015,0.0056 0,0 7e-4,-2.57e-4 0,0.0179 0,0 -0.015,0.0056 -0.015,0.0056 0,0 -0.015,0.0056 -0.015,0.0056 2.8042,5.976587 6.44,10.845642 6.44,10.845642 z"
+         style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:#808080;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3;marker:none;enable-background:accumulate" />
+      <path
+         style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:#808080;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3;marker:none;enable-background:accumulate"
+         d="m 1071.4144,36.540483 c 0,0 -5.1343,-3.816179 -10.8691,-6.435044 0,0 0,0 -0.016,-0.0026 0,0 7e-4,1.27e-4 -0.01,0.0155 0,0 -0.016,-0.0026 -0.016,-0.0026 0,0 -0.016,-0.0026 -0.016,-0.0026 -0.5598,6.577976 0.1544,12.612601 0.1544,12.612601 z"
+         id="path4212"
+         inkscape:connector-curvature="0"
+         inkscape:transform-center-x="16.187519"
+         inkscape:transform-center-y="-30.94809"
+         sodipodi:nodetypes="ccsssccc" />
+      <text
+         xml:space="preserve"
+         style="font-style:normal;font-variant:normal;font-weight:500;font-stretch:normal;font-size:31.51123047px;line-height:125%;font-family:Ubuntu;-inkscape-font-specification:'Ubuntu Medium';text-align:end;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:end;fill:#808080;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+         x="1103.2705"
+         y="79.316757"
+         id="text4214"
+         sodipodi:linespacing="125%"><tspan
+           sodipodi:role="line"
+           id="tspan4216"
+           x="1103.2705"
+           y="79.316757">UV</tspan></text>
+    </g>
+  </g>
+</svg>

=== added file 'app/graphics/extended-information_wind.svg'
--- app/graphics/extended-information_wind.svg	1970-01-01 00:00:00 +0000
+++ app/graphics/extended-information_wind.svg	2015-08-05 19:54:56 +0000
@@ -0,0 +1,155 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/";
+   xmlns:cc="http://creativecommons.org/ns#";
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#";
+   xmlns:svg="http://www.w3.org/2000/svg";
+   xmlns="http://www.w3.org/2000/svg";
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd";
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape";
+   width="90"
+   height="90"
+   id="svg6138"
+   version="1.1"
+   inkscape:version="0.91pre2 r"
+   viewBox="0 0 90 90.000001"
+   sodipodi:docname="weather-chance-of-wind02.svg">
+  <defs
+     id="defs6140" />
+  <sodipodi:namedview
+     id="base"
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1.0"
+     inkscape:pageopacity="0.0"
+     inkscape:pageshadow="2"
+     inkscape:zoom="3.2596289"
+     inkscape:cx="81.435648"
+     inkscape:cy="24.842587"
+     inkscape:document-units="px"
+     inkscape:current-layer="g6442"
+     showgrid="true"
+     fit-margin-top="0"
+     fit-margin-left="0"
+     fit-margin-right="0"
+     fit-margin-bottom="0"
+     inkscape:snap-global="true"
+     inkscape:snap-bbox="true"
+     inkscape:bbox-paths="true"
+     inkscape:snap-bbox-midpoints="true"
+     inkscape:snap-bbox-edge-midpoints="true"
+     inkscape:bbox-nodes="true"
+     inkscape:object-paths="true"
+     inkscape:snap-intersection-paths="true"
+     inkscape:object-nodes="true"
+     inkscape:snap-smooth-nodes="true"
+     inkscape:snap-midpoints="true"
+     inkscape:snap-others="true"
+     inkscape:snap-object-midpoints="true"
+     inkscape:snap-center="true"
+     showguides="false"
+     inkscape:guide-bbox="true">
+    <inkscape:grid
+       type="xygrid"
+       id="grid6700"
+       empspacing="6" />
+    <sodipodi:guide
+       orientation="0,1"
+       position="90,87"
+       id="guide4064" />
+    <sodipodi:guide
+       orientation="0,1"
+       position="89,84"
+       id="guide4066" />
+    <sodipodi:guide
+       orientation="1,0"
+       position="3,69"
+       id="guide4068" />
+    <sodipodi:guide
+       orientation="1,0"
+       position="6,60"
+       id="guide4070" />
+    <sodipodi:guide
+       orientation="1,0"
+       position="87,58"
+       id="guide4072" />
+    <sodipodi:guide
+       orientation="1,0"
+       position="84,47"
+       id="guide4074" />
+    <sodipodi:guide
+       orientation="0,1"
+       position="77,3"
+       id="guide4076" />
+    <sodipodi:guide
+       orientation="0,1"
+       position="81,6"
+       id="guide4078" />
+    <sodipodi:guide
+       orientation="1,0"
+       position="81,25"
+       id="guide4080" />
+    <sodipodi:guide
+       orientation="0,1"
+       position="78,9"
+       id="guide4082" />
+    <sodipodi:guide
+       orientation="0,1"
+       position="79,81"
+       id="guide4084" />
+    <sodipodi:guide
+       orientation="1,0"
+       position="9,39"
+       id="guide4086" />
+  </sodipodi:namedview>
+  <metadata
+     id="metadata6143">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage"; />
+        <dc:title></dc:title>
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <g
+     inkscape:label="Layer 1"
+     inkscape:groupmode="layer"
+     id="layer1"
+     transform="translate(-283.57144,-358.79068)">
+    <g
+       transform="translate(169.57144,223.42822)"
+       id="g5937"
+       inkscape:export-filename="envelope02.png"
+       inkscape:export-xdpi="90"
+       inkscape:export-ydpi="90" />
+    <g
+       id="g6442"
+       transform="translate(-753.45981,336.4283)">
+      <rect
+         style="fill:none;stroke:none"
+         id="rect1687"
+         width="90"
+         height="90"
+         x="1037.0312"
+         y="22.362379" />
+      <path
+         style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:125%;font-family:Ubuntu;-inkscape-font-specification:Ubuntu;text-indent:0;text-align:end;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:0px;word-spacing:0px;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;baseline-shift:baseline;text-anchor:end;white-space:normal;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#808080;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:6;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
+         d="m 75.279297,28.75 c -1.0334,0 -2.070116,0.17314 -3.103516,0.517578 -1.0332,0.301421 -1.957037,0.799407 -2.773437,1.488281 -0.7749,0.645859 -1.426106,1.497766 -1.941406,2.574219 -0.193801,0.386934 -0.311535,0.83777 -0.427735,1.285156 l 4.048828,2.333985 c 0.066,-0.47516 0.09082,-0.97049 0.265625,-1.34961 0.2583,-0.516687 0.599203,-0.93497 1.033203,-1.236328 0.4327,-0.344501 0.877363,-0.575907 1.351563,-0.705078 0.5166,-0.172251 1.013028,-0.253906 1.486328,-0.253906 0.9909,0 1.914591,0.365704 2.775391,1.097656 0.9043,0.688938 1.349609,1.71392 1.349609,3.091797 0,1.463904 -0.463956,2.57267 -1.410156,3.304688 -0.9054,0.731951 -2.2137,1.097656 -3.9375,1.097656 l -0.90625,0 -5.109375,0 -2.976563,0 -53.367237,0 0,0.0039 c -1.118972,8.07e-4 -2.232917,0.175074 -3.2753908,0.546875 -1.0812,0.374449 -2.0898969,0.990457 -2.9042969,1.802734 -0.8511,0.837684 -1.4685875,1.874775 -1.8671875,2.980469 -0.422,1.158702 -0.5898438,2.388837 -0.5898438,3.673828 0,1.287641 0.1681907,2.523171 0.5878907,3.6875 l 0,0.0059 0,0.0078 c 0.4008,1.096658 1.0169625,2.124759 1.8515625,2.960938 l 0.011719,0.01172 0.011719,0.01172 c 0.8122,0.795376 1.8055406,1.402256 2.8691406,1.785156 l 0.023437,0.0059 0.019531,0.0078 c 1.041,0.357709 2.145119,0.521485 3.261719,0.521485 l 0,0.002 41.3438,0 2.980469,0 5.115234,0 0.908203,0 c 1.7259,0 3.034806,0.36677 3.941406,1.099609 0.9473,0.732906 1.414063,1.842913 1.414063,3.308594 0,1.379548 -0.446163,2.403976 -1.351563,3.09375 -0.8619,0.73284 -1.787297,1.099609 -2.779297,1.099609 -0.4739,0 -0.970981,-0.08145 -1.488281,-0.253906 -0.4746,-0.129329 -0.920316,-0.362111 -1.353515,-0.707031 -0.434501,-0.301723 -0.776457,-0.720967 -1.035157,-1.238282 -0.1741,-0.379579 -0.200625,-0.873874 -0.265625,-1.349609 l -4.052734,2.335938 c 0.1164,0.44793 0.231781,0.899706 0.425781,1.287109 0.5159,1.07776 1.169413,1.931483 1.945313,2.578125 0.8175,0.689709 1.742843,1.188446 2.777343,1.490234 1.0347,0.344855 2.072722,0.517579 3.107422,0.517579 0.7758,0 1.660344,-0.153292 2.652344,-0.455079 1.0346,-0.258658 1.998997,-0.75733 2.904297,-1.490234 0.906,-0.68971 1.658365,-1.634709 2.259766,-2.841797 0.605199,-1.163958 0.910156,-2.648384 0.910156,-4.458984 l 0.0039,0 C 72,60.363013 70.961878,57.768642 68.892578,56.259766 66.823378,54.750954 63.956869,54 60.292969,54 l -48.6563,0 0,0.0098 c -0.5345,0 -0.948916,-0.07592 -1.291016,-0.191407 -0.2996,-0.111208 -0.4927686,-0.23897 -0.6679686,-0.408203 -0.1552,-0.158288 -0.3061656,-0.371439 -0.4472656,-0.751953 l 0,-0.0039 c -0.1279,-0.355148 -0.2324219,-0.897858 -0.2324219,-1.650391 0,-0.752625 0.1039625,-1.28965 0.2265625,-1.625 l 0,-0.0059 0,-0.0078 c 0.1465,-0.406946 0.2963938,-0.609758 0.4335938,-0.74414 l 0.011719,-0.01172 0.011719,-0.01172 c 0.1749,-0.175302 0.3458723,-0.286102 0.6386723,-0.386718 l 0.01953,-0.0078 0.02148,-0.0078 C 10.695178,48.075095 11.107669,48 11.636669,48 l 60.669972,0 c 3.6595,0 6.523043,-0.750829 8.589843,-2.257812 C 82.963184,44.23514 84,41.644264 84,37.984375 l -0.0039,0 c 0,-1.808407 -0.303703,-3.290578 -0.908203,-4.453125 -0.6007,-1.205626 -1.352913,-2.149016 -2.257813,-2.837891 -0.9043,-0.732015 -1.86719,-1.229936 -2.90039,-1.488281 C 76.938787,28.903658 76.054197,28.75 75.279297,28.75 Z"
+         transform="translate(1037.0313,22.36238)"
+         id="path4178"
+         inkscape:connector-curvature="0"
+         sodipodi:nodetypes="sccccccccscscsccccccccsccccccccccccccscscsccccccccscccccssccccccscccccccccssccccccs" />
+      <path
+         sodipodi:nodetypes="ccccsccccccccscscscccccsscc"
+         inkscape:connector-curvature="0"
+         id="path4171"
+         d="m 1091.0274,48.500103 c 0,-1.780677 -0.2989,-3.239878 -0.8941,-4.384599 -0.5915,-1.187139 -1.3323,-2.116397 -2.2233,-2.794708 -0.8904,-0.720792 -1.8392,-1.211305 -2.8567,-1.465688 -0.9756,-0.2968 -1.8456,-0.44714 -2.6087,-0.44714 -1.0176,0 -2.0383,0.170054 -3.0558,0.50921 -1.0175,0.2968 -1.9269,0.787377 -2.7308,1.465687 -0.7631,0.635956 -1.4055,1.473955 -1.9129,2.533903 -0.1908,0.381001 -0.3053,0.826425 -0.4198,1.266952 l 3.9862,2.297899 c 0.064,-0.467873 0.089,-0.955778 0.2607,-1.329084 0.2544,-0.508765 0.5915,-0.920483 1.0188,-1.21722 0.4261,-0.339219 0.8637,-0.568417 1.3305,-0.695608 0.5087,-0.16961 0.9978,-0.248405 1.4639,-0.248405 0.9756,0 1.885,0.359888 2.7327,1.080617 0.8904,0.678374 1.3292,1.686427 1.3292,3.043176 0,1.441458 -0.4579,2.533521 -1.3896,3.254314 -0.8916,0.720728 -2.1794,1.080616 -3.8768,1.080616 l -0.8929,0 -5.031,0 -2.9311,0 -17.2945,0 0,5.912355 24.4865,0 c 3.6033,0 6.4232,-0.739426 8.4582,-2.223302 2.0351,-1.48394 3.0552,-4.035204 3.0552,-7.638975 z"
+         style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:125%;font-family:Ubuntu;-inkscape-font-specification:Ubuntu;text-align:end;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:end;fill:#808080;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
+    </g>
+  </g>
+</svg>

=== added file 'app/ubuntu-weather-app.qml'
--- app/ubuntu-weather-app.qml	1970-01-01 00:00:00 +0000
+++ app/ubuntu-weather-app.qml	2015-08-05 19:54:56 +0000
@@ -0,0 +1,292 @@
+/*
+ * Copyright (C) 2015 Canonical Ltd
+ *
+ * This file is part of Ubuntu Weather App
+ *
+ * Ubuntu Weather App is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 3 as
+ * published by the Free Software Foundation.
+ *
+ * Ubuntu Weather App is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+import QtQuick 2.4
+import Qt.labs.settings 1.0
+import Ubuntu.Components 1.2
+import "components"
+import "data" as Data
+import "data/WeatherApi.js" as WeatherApi
+import "data/key.js" as Key
+import "ui"
+
+MainView {
+    id: weatherApp
+
+    objectName: "weather"
+
+    applicationName: "com.ubuntu.weather"
+
+    automaticOrientation: false
+
+    width: units.gu(40)
+    height: units.gu(70)
+
+    backgroundColor: "#F5F5F5"
+
+    anchorToKeyboard: true
+
+    signal listItemSwiping(int i)
+
+    /*
+      List of locations and their data, accessible through index
+    */
+    property var locationsList: []    
+
+    /*
+      Index of Location before a refresh, to go back after
+    */
+    property int indexAtRefresh: -1
+
+    /*
+      Is the app loading?
+    */
+    property bool loading: false
+
+    /*
+      (re)load the pages on completion
+    */
+    Component.onCompleted: {
+        storage.getLocations(fillPages);
+        refreshData();
+    }
+
+    /*
+      Handle response data from data backend. Checks if a location
+      was updated and has to be stored again.
+    */
+    function responseDataHandler(messageObject) {
+         if(!messageObject.error) {
+             if(messageObject.action === "updateData") {
+                 messageObject.result.forEach(function(loc) {
+                     // replace location data in cache with refreshed values
+                     if(loc["save"] === true) {
+                         storage.updateLocation(loc.db.id, loc);
+                     }
+                 });
+                 //print(JSON.stringify(messageObject.result));
+                 fillPages(messageObject.result);
+             }
+         } else {
+             console.log(messageObject.error.msg+" / "+messageObject.error.request.url)
+             // TODO error handling
+         }
+     }
+
+    /* Fill the location pages with their data. */
+    function fillPages(locations) {
+        locationsList = []
+        locationsList = locations;
+    }
+
+    /*
+      Refresh data, either directly from storage or by checking against
+      API instead.
+    */
+    function refreshData(from_storage, force_refresh) {
+        from_storage = from_storage || false
+        force_refresh = force_refresh || false
+        loading = true
+        if(from_storage === true && force_refresh !== true) {
+            storage.getLocations(fillPages);
+        } else {
+            storage.getLocations(function(locations) {
+                WeatherApi.sendRequest({
+                    action: "updateData",
+                    params: {
+                        locations: locations,
+                        force: force_refresh,
+                        service: settings.service,
+                        api_key: Key.twcKey,
+                        interval: settings.refreshInterval
+                    }
+                }, responseDataHandler)
+            });
+        }
+    }
+
+    CurrentLocation {
+        id: currentLocation
+    }
+
+    Settings {
+        id: settings
+        category: "weatherSettings"
+        /*
+          Index of the current locationList of locations and their data, accessible through index
+        */
+        property int current: 0
+
+        property bool detectCurrentLocation: true
+        property int refreshInterval: 1800
+        property string precipUnits
+        property string service
+        property string tempScale
+        property string units
+        property string windUnits
+
+        property bool addedCurrentLocation: false
+        property bool migrated: false
+
+        onDetectCurrentLocationChanged: {
+            if (!detectCurrentLocation) {
+                if (addedCurrentLocation) {
+                    storage.removeLocation(-1);  // indexes are increased by 1
+                    addedCurrentLocation = false;
+                }
+
+                refreshData();
+            }
+        }
+
+        Component.onCompleted: {
+            if (units === "") {  // No settings so load defaults
+                console.debug("No settings, using defaults")
+                var metric = Qt.locale().measurementSystem === Locale.MetricSystem
+
+                precipUnits = metric ? "mm" : "in"
+                service = "weatherchannel"
+                tempScale = "°" + (metric ? "C" : "F")
+                units = metric ? "metric" : "imperial"
+                windUnits = metric ? "kph" : "mph"
+            }
+
+            if (Key.twcKey === "") {  // No API key for TWC, so use OWM
+                service = "openweathermap"
+            }
+        }
+    }
+
+    Data.Storage {
+        id: storage
+
+        // Add or replace the current locaiton to the storage and refresh the
+        // locationList
+        function updateCurrentLocation(location) {
+            if (!settings.addedCurrentLocation || locationsList == null || locationsList.length == 0) {
+                storage.insertLocationAtStart({location: location});
+                settings.addedCurrentLocation = true;
+            } else {
+                storage.updateLocation(locationsList[0].db.id, {location: location});
+            }
+
+            refreshData(false, true);
+        }
+
+        // Add the location to the storage and refresh the locationList
+        // Return true if a location is added
+        function addLocation(location) {
+            var exists = checkLocationExists(location)
+
+            if(!exists) {
+                if(location.dbId === undefined || location.dbId === 0) {
+                    storage.insertLocation({location: location});
+                }
+                refreshData();
+            }
+
+            return !exists;
+        }
+
+        // Return true if the location given is already in the locationsList, and is not the same
+        // as the current location.
+        function checkLocationExists(location) {
+            var exists = false;
+
+            for (var i=0; !exists && i < locationsList.length; i++) {
+                var loc = locationsList[i].location;
+
+                if (loc.services.geonames && (loc.services.geonames === location.services.geonames) && !(settings.addedCurrentLocation && i === 0)) {
+                    exists = true;
+                }
+            }
+
+            return exists;
+        }
+
+        function moveLocation(from, to) {
+            // Indexes are offset by 1 to account for current location
+            if (settings.addedCurrentLocation) {
+                from += 1
+                to += 1
+            }
+
+            // Update settings to respect new changes
+            if (from === settings.current) {
+                settings.current = to;
+            } else if (from < settings.current && to >= settings.current) {
+                settings.current -= 1;
+            } else if (from > settings.current && to <= settings.current) {
+                settings.current += 1;
+            }
+
+            storage.reorder(locationsList[from].db.id, locationsList[to].db.id);
+
+            refreshData(true, false);
+        }
+
+        // Remove a location from the list
+        function removeLocation(index) {
+            // Indexes are offset by 1 to account for current location
+            if (settings.addedCurrentLocation) {
+                index += 1
+            }
+
+            if (settings.current >= index) {  // Update settings to respect new changes
+                settings.current -= settings.current;
+            }
+
+            storage.clearLocation(locationsList[index].db.id);
+
+            refreshData(true, false);
+        }
+
+        function removeMultiLocations(indexes) {
+            var i;
+
+            // Sort the item indexes as loops below assume *numeric* sort
+            indexes.sort(function(a,b) { return a - b })
+
+            for (i=0; i < indexes.length; i++) {
+                if (settings.current >= indexes[i] + 1) {  // Update settings to respect new changes
+                    settings.current -= settings.current;
+                }
+            }
+
+            // Get location db ids to remove
+            var locations = []
+
+            for (i=0; i < indexes.length; i++) {
+                if (settings.addedCurrentLocation) {
+                    locations.push(locationsList[indexes[i] + 1].db.id)
+                } else {
+                    locations.push(locationsList[indexes[i]].db.id)
+                }
+            }
+
+            storage.clearMultiLocation(locations);
+
+            refreshData(true, false);
+        }
+    }
+
+    PageStack {
+        id: mainPageStack
+        Component.onCompleted: mainPageStack.push(Qt.resolvedUrl("ui/HomePage.qml"))
+    }
+}

=== added directory 'app/ui'
=== added file 'app/ui/AddLocationPage.qml'
--- app/ui/AddLocationPage.qml	1970-01-01 00:00:00 +0000
+++ app/ui/AddLocationPage.qml	2015-08-05 19:54:56 +0000
@@ -0,0 +1,310 @@
+/*
+ * Copyright (C) 2015 Canonical Ltd
+ *
+ * This file is part of Ubuntu Weather App
+ *
+ * Ubuntu Weather App is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 3 as
+ * published by the Free Software Foundation.
+ *
+ * Ubuntu Weather App is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+import QtQuick 2.4
+import Ubuntu.Components 1.2
+import Ubuntu.Components.Popups 1.0
+import "../components"
+import "../data/CitiesList.js" as Cities
+import "../data/WeatherApi.js" as WeatherApi
+
+Page {
+    id: addLocationPage
+    objectName: "addLocationPage"
+    title: i18n.tr("Select a city")
+    visible: false
+
+    /*
+      Flickable is set to null to stop page header from hiding since the fast
+      scroll component hides top anchor margin is incorrect.
+    */
+    flickable: null
+
+    state: "default"
+    states: [
+        PageHeadState {
+            name: "default"
+            head: addLocationPage.head
+            backAction: Action {
+                iconName: "back"
+                text: i18n.tr("Back")
+                onTriggered: mainPageStack.pop()
+            }
+            actions: [
+                Action {
+                    iconName: "search"
+                    text: i18n.tr("City")
+                    onTriggered: {
+                        addLocationPage.state = "search"
+                        searchComponentLoader.sourceComponent = searchComponent
+                        searchComponentLoader.item.forceActiveFocus()
+                    }
+                }
+            ]
+        },
+
+        PageHeadState {
+            name: "search"
+            head: addLocationPage.head
+            backAction: Action {
+                iconName: "back"
+                text: i18n.tr("Back")
+                onTriggered: {
+                    locationList.forceActiveFocus()
+                    searchComponentLoader.item.text = ""
+                    addLocationPage.state = "default"
+                    searchComponentLoader.sourceComponent = undefined
+                }
+            }
+
+            contents: Loader {
+                id: searchComponentLoader
+                anchors {
+                    left: parent ? parent.left : undefined
+                    right: parent ? parent.right : undefined
+                    rightMargin: units.gu(2)
+                }
+            }
+        }
+    ]
+
+    Component {
+        id: searchComponent
+        TextField {
+            id: searchField
+            objectName: "searchField"
+
+            inputMethodHints: Qt.ImhNoPredictiveText
+            placeholderText: i18n.tr("Search city")
+            hasClearButton: true
+
+            onTextChanged: {
+                if (text.trim() === "") {
+                    loadEmpty()
+                } else {
+                    loadFromProvider(text)
+                }
+            }
+        }
+    }
+
+    // Builds a area label for the location, depending on the uniqueness of name, adminName1 and country
+     function buildAreaLabel(loc, a1Counts) {
+         var label = "";
+         label += ((loc.adminName1) ? loc.adminName1.replace(/ Region$/,''):"");
+         if (loc.adminName2 && a1Counts[loc.name+loc.adminName1] > 1) {
+             // even name and adminName1 are multiple, add adminName2
+             label += ", "+loc.adminName2;
+         }
+         label += ((label !== "") ? ", " : "") + loc.countryName
+         return label;
+     }
+
+     function appendCities(list) {
+         var a1Counts = {};
+         // count occurrences of name+adminName1 and name+country
+         list.forEach(function(loc) {
+             a1Counts[loc.name+loc.adminName1] = (!a1Counts[loc.name+loc.adminName1]) ? 1 : a1Counts[loc.name+loc.adminName1]+1;
+         });
+         // add locations to listmodel
+         list.forEach(function(loc) {
+             loc.areaLabel = buildAreaLabel(loc, a1Counts)
+             citiesModel.append(loc);
+         })
+     }
+
+    function clearModelForLoading() {
+        citiesModel.clear()
+        citiesModel.loading = true
+        citiesModel.httpError = false
+    }
+
+    function loadEmpty() {
+        clearModelForLoading()
+
+        appendCities(Cities.preList)
+
+        citiesModel.loading = false
+    }
+
+    function loadFromProvider(search) {
+        clearModelForLoading()
+
+        WeatherApi.sendRequest({
+                                   action: "searchByName",
+                                   params: {
+                                       name: search,
+                                       units: "metric"
+                                   }
+                               }, searchResponseHandler)
+    }
+
+    function searchResponseHandler(msgObject) {
+        if (!msgObject.error) {
+            appendCities(msgObject.result.locations)
+        } else {
+            citiesModel.httpError = true
+        }
+
+        citiesModel.loading = false
+    }
+
+    ListView {
+        id: locationList
+
+        clip: true
+        currentIndex: -1
+        anchors.fill: parent
+        anchors.rightMargin: fastScroll.showing ? fastScroll.width - units.gu(1)
+                                                : 0
+
+        function getSectionText(index) {
+            return citiesModel.get(index).name.substring(0,1)
+        }
+
+        onFlickStarted: {
+            forceActiveFocus()
+        }
+
+        section.property: "name"
+        section.criteria: ViewSection.FirstCharacter
+        section.labelPositioning: ViewSection.InlineLabels
+
+        section.delegate: ListItem {
+            height: headerText.implicitHeight + units.gu(1)
+            Label {
+                id: headerText
+                text: section
+                anchors { left: parent.left; right: parent.right; margins: units.gu(2) }
+                font.weight: Font.DemiBold
+            }
+        }
+
+        model: ListModel {
+            id: citiesModel
+
+            property bool loading: true
+            property bool httpError: false
+
+            onRowsAboutToBeInserted: loading = false
+        }
+
+        delegate: ListItem {
+            divider.visible: false
+            Column {
+                anchors {
+                    left: parent.left
+                    leftMargin: units.gu(2)
+                    right: parent.right
+                    rightMargin: units.gu(2)
+                    verticalCenter: parent.verticalCenter
+                }
+
+                Label {
+                    color: UbuntuColors.darkGrey
+                    elide: Text.ElideRight
+                    fontSize: "medium"
+                    text: name
+                }
+
+                Label {
+                    color: UbuntuColors.lightGrey
+                    elide: Text.ElideRight
+                    fontSize: "xx-small"
+                    text: areaLabel
+                }
+            }
+
+            onClicked: {
+                if (storage.addLocation(citiesModel.get(index))) {
+                    mainPageStack.pop()
+                } else {
+                    PopupUtils.open(locationExistsComponent, addLocationPage)
+                }
+            }
+        }
+
+        Component.onCompleted: loadEmpty()
+
+        Behavior on anchors.rightMargin {
+            UbuntuNumberAnimation {}
+        }
+    }
+
+    FastScroll {
+        id: fastScroll
+
+        listView: locationList
+
+        enabled: (locationList.contentHeight > (locationList.height * 2)) &&
+                 (locationList.height >= minimumHeight)
+
+        anchors {
+            top: locationList.top
+            topMargin: units.gu(1.5)
+            bottom: locationList.bottom
+            right: parent.right
+        }
+    }
+
+    ActivityIndicator {
+        anchors {
+            centerIn: parent
+        }
+        running: visible
+        visible: citiesModel.loading
+    }
+
+    Label {
+        id: noCity
+        anchors {
+            centerIn: parent
+        }
+        text: i18n.tr("No city found")
+        visible: citiesModel.count === 0 && !citiesModel.loading
+    }
+
+    Label {
+        id: httpFail
+        anchors {
+            left: parent.left
+            margins: units.gu(1)
+            right: parent.right
+            top: noCity.bottom
+        }
+        horizontalAlignment: Text.AlignHCenter
+        text: i18n.tr("Couldn't load weather data, please try later again!")
+        visible: citiesModel.httpError
+        wrapMode: Text.WordWrap
+    }
+
+    Component {
+        id: locationExistsComponent
+
+        Dialog {
+            id: locationExists
+            title: i18n.tr("Location already added.")
+
+            Button {
+                text: i18n.tr("OK")
+                onClicked: PopupUtils.close(locationExists)
+            }
+        }
+    }
+
+}

=== added file 'app/ui/CMakeLists.txt'
--- app/ui/CMakeLists.txt	1970-01-01 00:00:00 +0000
+++ app/ui/CMakeLists.txt	2015-08-05 19:54:56 +0000
@@ -0,0 +1,7 @@
+add_subdirectory(settings)
+
+file(GLOB UI_QML_JS_FILES *.qml *.js)
+
+add_custom_target(ubuntu-weather-app_ui_QMlFiles ALL SOURCES ${UI_QML_JS_FILES})
+
+install(FILES ${UI_QML_JS_FILES} DESTINATION ${UBUNTU-WEATHER_APP_DIR}/ui)

=== added file 'app/ui/HomePage.qml'
--- app/ui/HomePage.qml	1970-01-01 00:00:00 +0000
+++ app/ui/HomePage.qml	2015-08-05 19:54:56 +0000
@@ -0,0 +1,198 @@
+/*
+ * Copyright (C) 2015 Canonical Ltd
+ *
+ * This file is part of Ubuntu Weather App
+ *
+ * Ubuntu Weather App is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 3 as
+ * published by the Free Software Foundation.
+ *
+ * Ubuntu Weather App is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+import QtQuick 2.4
+import Ubuntu.Components 1.2
+import "../components"
+
+
+PageWithBottomEdge {
+    // Set to null otherwise the header is shown (but blank) over the top of the listview
+    id: locationPage
+    objectName: "homePage"
+    flickable: null
+
+    bottomEdgePageSource: Qt.resolvedUrl("LocationsPage.qml")
+    bottomEdgeTitle: i18n.tr("Locations")
+    tipColor: UbuntuColors.orange
+    tipLabelColor: "#FFF"
+
+    property var iconMap: {
+        "sun": "weather-clear-symbolic",
+        "moon": "weather-clear-night-symbolic",
+        "cloud_sun": "weather-few-clouds-symbolic",
+        "cloud_moon": "weather-few-clouds-night-symbolic",
+        "cloud": "weather-clouds-symbolic",
+        "rain": "weather-showers-symbolic",
+        "thunder": "weather-storm-symbolic",
+        "snow_shower": "weather-snow-symbolic",
+        "fog": "weather-fog-symbolic",
+        "snow_rain": "weather-snow-symbolic",
+        "scattered": "weather-showers-scattered-symbolic",
+        "overcast": "weather-overcast-symbolic"
+    }
+
+    property var imageMap: {
+        "sun": Qt.resolvedUrl("../graphics/Sunny.png"),
+        "moon": Qt.resolvedUrl("../graphics/Starry-Night.png"),
+        "cloud_sun": Qt.resolvedUrl("../graphics/Cloudy-Circles.png"),
+        "cloud_moon": Qt.resolvedUrl("../graphics/Cloudy-Night.png"),
+        "cloud": Qt.resolvedUrl("../graphics/Cloudy.png"),
+        "rain": Qt.resolvedUrl("../graphics/Big-Rain.png"),
+        "thunder": Qt.resolvedUrl("../graphics/Stormy.png"),
+        "snow_shower": Qt.resolvedUrl("../graphics/Cloudy-Snow.png"),
+        "fog": Qt.resolvedUrl("../graphics/Fog.png"),
+        "snow_rain": Qt.resolvedUrl("../graphics/Cloudy-Snow.png"),
+        "scattered": Qt.resolvedUrl("../graphics/Showers.png"),
+        "overcast": Qt.resolvedUrl("../graphics/Cloudy.png")
+    }
+
+    /*
+      Format date object by given format.
+    */
+    function formatTimestamp(dateData, format) {
+        return Qt.formatDate(getDate(dateData), i18n.tr(format))
+    }
+
+    /*
+      Format time object by given format.
+    */
+    function formatTime(dateData, format) {
+        return Qt.formatTime(getDate(dateData), i18n.tr(format))
+    }
+
+    /*
+      Get Date object from dateData.
+    */
+    function getDate(dateData) {
+        return new Date(dateData.year, dateData.month, dateData.date, dateData.hours, dateData.minutes)
+    }
+
+    /*
+      Background for the PageWithBottomEdge
+    */
+    Rectangle {
+        id: pageBackground
+        anchors.fill: parent
+        color: "white"
+    }
+
+    /*
+      Flickable to scroll the location vertically.
+      The respective contentHeight gets calculated after the Location is filled with data.
+    */
+    Flickable {
+        id: locationFlickable
+        width: parent.width
+        height: parent.height
+
+        // FIXME: not sure where the 3GU comes from, PullToRefresh or something in HomePage?
+        contentHeight: locationPages.currentItem ? locationPages.currentItem.childrenRect.height + units.gu(3) : 0
+        contentWidth: parent.width
+
+        Behavior on contentHeight {
+            NumberAnimation {
+
+            }
+        }
+
+        PullToRefresh {
+            id: pullToRefresh
+            parent: locationFlickable
+            refreshing: false
+            onRefresh: {
+                locationPages.loaded = false
+                refreshing = true
+                refreshData(false, true)
+            }
+        }
+
+        /*
+          ListView for locations with snap-scrolling horizontally.
+        */
+        ListView {
+            id: locationPages
+            objectName: "locationPages"
+            anchors.fill: parent
+            currentIndex: settings.current
+            delegate: LocationPane {}
+            height: childrenRect.height
+            highlightRangeMode: ListView.StrictlyEnforceRange
+            model: weatherApp.locationsList.length
+            orientation: ListView.Horizontal
+            // TODO with snapMode, currentIndex is not properly set and setting currentIndex fails
+            //snapMode: ListView.SnapOneItem
+            width: parent.width
+
+            property bool loaded: false
+
+            signal collapseOtherDelegates(int index)
+
+            onCurrentIndexChanged: {
+                if (loaded) {
+                    // FIXME: when a model is reloaded this causes the currentIndex to be lost
+                    settings.current = currentIndex
+
+                    collapseOtherDelegates(-1)  // collapse all
+                }
+            }
+            onModelChanged: {
+                currentIndex = settings.current
+
+                if (model > 0) {
+                    pullToRefresh.refreshing = false
+                    loading = false
+                    loaded = true
+                }
+            }
+            onVisibleChanged: {
+                if (!visible && loaded) {
+                    collapseOtherDelegates(-1)  // collapse all
+                }
+            }
+
+            // TODO: workaround for not being able to use snapMode property
+            Component.onCompleted: {
+                var scaleFactor = units.gridUnit * 10;
+                maximumFlickVelocity = maximumFlickVelocity * scaleFactor;
+                flickDeceleration = flickDeceleration * scaleFactor;
+            }
+
+            Connections {
+                target: settings
+                onCurrentChanged: {
+                    locationPages.currentIndex = settings.current
+                }
+            }
+        }
+    }
+
+    LoadingIndicator {
+        id: loadingIndicator
+    }
+
+    Loader {
+        active: (locationsList === null || locationsList.length === 0) && mainPageStack.depth === 1
+        anchors {
+            fill: parent
+        }
+        asynchronous: true
+        source: "../components/EmptyStateComponent.qml"
+        visible: status === Loader.Ready && active
+    }
+}

=== added file 'app/ui/LocationPane.qml'
--- app/ui/LocationPane.qml	1970-01-01 00:00:00 +0000
+++ app/ui/LocationPane.qml	2015-08-05 19:54:56 +0000
@@ -0,0 +1,200 @@
+/*
+ * Copyright (C) 2015 Canonical Ltd
+ *
+ * This file is part of Ubuntu Weather App
+ *
+ * Ubuntu Weather App is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 3 as
+ * published by the Free Software Foundation.
+ *
+ * Ubuntu Weather App is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+import QtQuick 2.4
+import Ubuntu.Components 1.2
+import Ubuntu.Components.ListItems 0.1 as ListItem
+import "../components"
+import "../data/suncalc.js" as SunCalc
+
+Item {
+    id: locationItem
+    /*
+      Data properties
+    */
+    property string name
+    property string conditionText
+    property string currentTemp
+    property string todayMaxTemp
+    property string todayMinTemp
+    property string icon
+    property string iconName
+
+    Component.onCompleted: renderData(index)
+
+    width: locationPage.width
+    height: childrenRect.height
+    anchors.fill: parent.fill
+
+    function emptyIfUndefined(variable, append) {
+        if (append === undefined) {
+            append = ""
+        }
+
+        return variable === undefined ? "" : variable + append
+    }
+
+    /*
+      Extracts values from the location weather data and puts them into the appropriate components
+      to display them.
+
+      Attention: Data access happens through "weatherApp.locationList[]" by index, since complex
+      data in models will lead to type problems.
+    */
+    function renderData(index) {
+        var data = weatherApp.locationsList[index],
+                current = data.data[0].current,
+                forecasts = data.data,
+                forecastsLength = forecasts.length,
+                today = forecasts[0],
+                hourlyForecasts = [];
+
+        var tempUnits = settings.tempScale === "°C" ? "metric" : "imperial"
+
+        // set general location data
+        name = data.location.name;
+
+        // set current temps and condition
+        iconName = (current.icon) ? current.icon : "";
+        icon = (imageMap[iconName] !== undefined) ? imageMap[iconName] : "";
+        conditionText = (current.condition !== undefined) ? current.condition : "";
+        todayMaxTemp = (today[tempUnits].tempMax !== undefined) ? Math.round(today[tempUnits].tempMax).toString() + settings.tempScale: "";
+        todayMinTemp = Math.round(today[tempUnits].tempMin).toString() + settings.tempScale;
+        currentTemp = Math.round(current[tempUnits].temp).toString() + String("°");
+
+        // reset days list
+        mainPageWeekdayListView.model.clear()
+
+        // set daily forecasts
+        if(forecastsLength > 0) {
+            for(var x=0;x<forecastsLength;x++) {
+                // collect hourly forecasts if available
+                if(forecasts[x].hourly !== undefined && forecasts[x].hourly.length > 0) {
+                    hourlyForecasts = hourlyForecasts.concat(forecasts[x].hourly)
+                }
+                if(x === 0) {
+                    // skip todays daydata
+                    continue;
+                }
+
+                // set daydata
+                var dayData = {
+                    day: formatTimestamp(forecasts[x].date, 'dddd'),
+                    low: Math.round(forecasts[x][tempUnits].tempMin).toString() + settings.tempScale,
+                    high: (forecasts[x][tempUnits].tempMax !== undefined) ? Math.round(forecasts[x][tempUnits].tempMax).toString() + settings.tempScale : "",
+                    image: (forecasts[x].icon !== undefined && iconMap[forecasts[x].icon] !== undefined) ? iconMap[forecasts[x].icon] : "",
+                    condition: emptyIfUndefined(forecasts[x].condition),
+                    chanceOfRain: emptyIfUndefined(forecasts[x].propPrecip, "%"),
+                    humidity: emptyIfUndefined(forecasts[x].humidity, "%"),
+                    sunrise: forecasts[x].sunrise || SunCalc.SunCalc.getTimes(getDate(forecasts[x].date), data.location.coord.lat, data.location.coord.lon).sunrise.toLocaleTimeString(),
+                    sunset: forecasts[x].sunset || SunCalc.SunCalc.getTimes(getDate(forecasts[x].date), data.location.coord.lat, data.location.coord.lon).sunset.toLocaleTimeString(),
+                    uvIndex: emptyIfUndefined(forecasts[x].uv),
+                    wind: forecasts[x][tempUnits].windSpeed === undefined || forecasts[x].windDir === undefined
+                                ? "" : Math.round(forecasts[x][tempUnits].windSpeed) + settings.windUnits + " " + forecasts[x].windDir
+                }
+                mainPageWeekdayListView.model.append(dayData);
+            }
+        }        
+
+        // set data for hourly forecasts
+        if(hourlyForecasts.length > 0) {
+            homeHourlyLoader.forecasts = hourlyForecasts;
+            homeHourlyLoader.tempUnits = tempUnits;
+        }
+    }
+
+    Column {
+        id: locationTop
+
+        anchors {
+            top: parent.top
+            left: parent.left
+            right: parent.right
+            margins: units.gu(2)
+        }
+        spacing: units.gu(1)
+
+        HeaderRow {
+            id: headerRow
+            locationName: locationItem.name
+        }
+
+        HomeGraphic {
+            id: homeGraphic
+            icon: locationItem.icon
+            MouseArea {
+                anchors.fill: parent
+                onClicked: {
+                    homeGraphic.visible = false;
+                }
+            }
+        }
+
+        Loader {
+            id: homeHourlyLoader
+            active: !homeGraphic.visible
+            asynchronous: true
+            height: units.gu(32)
+            source: "../components/HomeHourly.qml"
+            visible: active
+            width: parent.width
+
+            property var forecasts: []
+            property string tempUnits: ""
+        }
+
+        HomeTempInfo {
+            id: homeTempInfo
+            description: conditionText
+            high: locationItem.todayMaxTemp
+            low: locationItem.todayMinTemp
+            now: locationItem.currentTemp
+        }
+
+        // TODO: Migrate this to using the new SDK list item when possible.
+        ListItem.ThinDivider { anchors { leftMargin: units.gu(-2); rightMargin: units.gu(-2) } }
+    }
+    Column {
+        id: weekdayColumn
+
+        anchors.top: locationTop.bottom
+        height: childrenRect.height
+        width: parent.width
+
+        Repeater {
+            id: mainPageWeekdayListView
+            model: ListModel{}
+            delegate: DayDelegate {
+                day: model.day
+                high: model.high
+                image: model.image
+                low: model.low
+
+                condition: model.condition
+                chanceOfRain: model.chanceOfRain
+                humidity: model.humidity
+                // TODO: extra from API
+                //pollen: model.pollen
+                sunrise: model.sunrise
+                sunset: model.sunset
+                wind: model.wind
+                uvIndex: model.uvIndex
+            }
+        }
+    }
+}

=== added file 'app/ui/LocationsPage.qml'
--- app/ui/LocationsPage.qml	1970-01-01 00:00:00 +0000
+++ app/ui/LocationsPage.qml	2015-08-05 19:54:56 +0000
@@ -0,0 +1,281 @@
+/*
+ * Copyright (C) 2015 Canonical Ltd
+ *
+ * This file is part of Ubuntu Weather App
+ *
+ * Ubuntu Weather App is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 3 as
+ * published by the Free Software Foundation.
+ *
+ * Ubuntu Weather App is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+import QtQuick 2.4
+import Ubuntu.Components 1.2
+import Ubuntu.Components.ListItems 0.1 as ListItem
+import "../components"
+import "../components/ListItemActions"
+
+
+Page {
+    id: locationsPage
+    objectName: "locationsPage"
+    // Set to null otherwise the first delegate appears +header.height down the page
+    flickable: null
+    title: i18n.tr("Locations")
+
+    state: locationsListView.state === "multiselectable" ? "selection" : "default"
+    states: [
+        PageHeadState {
+            id: defaultState
+            name: "default"
+            actions: [
+                Action {
+                    iconName: "add"
+                    onTriggered: mainPageStack.push(Qt.resolvedUrl("AddLocationPage.qml"))
+                }
+            ]
+            PropertyChanges {
+                target: locationsPage.head
+                actions: defaultState.actions
+            }
+        },
+        MultiSelectHeadState {
+            listview: locationsListView
+            removable: true
+            thisPage: locationsPage
+
+            onRemoved: storage.removeMultiLocations(selectedItems.slice());
+        }
+    ]
+
+    ListModel {
+        id: currentLocationModel
+    }
+
+    MultiSelectListView {
+        id: locationsListView
+        anchors {
+            fill: parent
+        }
+        model: ListModel {
+            id: locationsModel
+        }
+        header: MultiSelectListView {
+            id: currentLocationListView
+            anchors {
+                left: parent.left
+                right: parent.right
+            }
+            height: settings.addedCurrentLocation && settings.detectCurrentLocation ? units.gu(8) : units.gu(0)
+            interactive: false
+            model: currentLocationModel
+            delegate: WeatherListItem {
+                id: currentLocationListItem
+
+                onItemClicked: {
+                    settings.current = index;
+                    pageStack.pop()
+                }
+
+                Column {
+                    anchors {
+                        left: parent.left
+                        right: currentWeatherImage.left
+                        rightMargin: units.gu(1)
+                        verticalCenter: parent.verticalCenter
+                    }
+
+                    Label {
+                        id: currentLocationName
+
+                        anchors {
+                            left: parent.left
+                            leftMargin: units.gu(2)
+                        }
+
+                        elide: Text.ElideRight
+                        fontSize: "medium"
+                        text: i18n.tr("Current Location")
+                    }
+                    Label {
+                        id: currentLocationName2
+
+                        anchors {
+                            left: parent.left
+                            leftMargin: units.gu(2)
+                        }
+
+                        color: UbuntuColors.lightGrey
+                        elide: Text.ElideRight
+                        fontSize: "small"
+                        font.weight: Font.Light
+                        text: name + ", " + (adminName1 == name ? countryName : adminName1)
+                    }
+                }
+
+                Icon {
+                    id: currentWeatherImage
+                    anchors {
+                        right: parent.right
+                        rightMargin: units.gu(14)
+                        verticalCenter: parent.verticalCenter
+                    }
+                    name: icon
+                    height: units.gu(3)
+                    width: units.gu(3)
+                }
+
+                Label {
+                    id: currentTemperatureLabel
+                    anchors {
+                        left: currentWeatherImage.right
+                        leftMargin: units.gu(1)
+                        right: parent.right
+                        rightMargin: units.gu(2)
+                        verticalCenter: parent.verticalCenter
+                    }
+                    color: UbuntuColors.orange
+                    elide: Text.ElideRight
+                    font.pixelSize: units.gu(4)
+                    font.weight: Font.Light
+                    horizontalAlignment: Text.AlignRight
+                    text: temp + settings.tempScale
+                }
+            }
+        }
+
+        delegate: WeatherListItem {
+            id: locationsListItem
+            leftSideAction: Remove {
+                onTriggered: storage.removeLocation(index)
+            }
+            multiselectable: true
+            reorderable: true
+
+            onItemClicked: {
+                settings.current = index + 1;
+
+                pageStack.pop()
+            }
+            onReorder: {
+                console.debug("Move: ", from, to);
+
+                storage.moveLocation(from, to);
+            }
+
+            ListItem.ThinDivider {
+                anchors {
+                    top: parent.top
+                }
+                visible: index == 0
+            }
+
+            Item {
+                anchors {
+                    fill: parent
+                    leftMargin: units.gu(2)
+                    rightMargin: units.gu(2)
+                }
+
+                Column {
+                    anchors {
+                        left: parent.left
+                        right: weatherImage.visible ? weatherImage.left : parent.right
+                        rightMargin: units.gu(1)
+                        verticalCenter: parent.verticalCenter
+                    }
+
+                    Label {
+                        id: locationName
+                        elide: Text.ElideRight
+                        fontSize: "medium"
+                        text: name
+                    }
+                    Label {
+                        id: locationName2
+                        color: UbuntuColors.lightGrey
+                        elide: Text.ElideRight
+                        fontSize: "small"
+                        font.weight: Font.Light
+                        text: adminName1 == name ? countryName : adminName1
+                    }
+                }
+
+                Icon {
+                    id: weatherImage
+                    anchors {
+                        right: parent.right
+                        rightMargin: units.gu(12)
+                        verticalCenter: parent.verticalCenter
+                    }
+                    name: icon
+                    height: units.gu(3)
+                    width: units.gu(3)
+                    visible: locationsPage.state === "default"
+                }
+
+                Label {
+                    id: temperatureLabel
+                    anchors {
+                        left: weatherImage.right
+                        leftMargin: units.gu(1)
+                        right: parent.right
+                        verticalCenter: parent.verticalCenter
+                    }
+                    color: UbuntuColors.orange
+                    elide: Text.ElideRight
+                    font.pixelSize: units.gu(4)
+                    font.weight: Font.Light
+                    horizontalAlignment: Text.AlignRight
+                    text: temp + settings.tempScale
+                    visible: locationsPage.state === "default"
+                }
+            }
+
+            ListItem.ThinDivider {
+                anchors {
+                    bottom: parent.bottom
+                }
+            }
+        }
+    }
+
+    function populateLocationsModel() {
+        currentLocationModel.clear()
+        locationsModel.clear()
+        var loc = {}, data = {},
+            tempUnits = settings.tempScale === "°C" ? "metric" : "imperial";
+
+        for (var i=0; i < weatherApp.locationsList.length; i++) {
+            data = weatherApp.locationsList[i];
+            loc = {
+                "name": data.location.name,
+                "adminName1": data.location.adminName1,
+                "areaLabel": data.location.areaLabel,
+                "countryName": data.location.countryName,
+                "temp": Math.round(data.data[0].current[tempUnits].temp).toString(),
+                "icon": iconMap[data.data[0].current.icon]
+            }
+
+            if (!settings.addedCurrentLocation || i > 0) {
+                locationsModel.append(loc)
+            } else {
+                currentLocationModel.append(loc)
+            }
+        }
+    }
+
+    Connections {
+        target: weatherApp
+        onLocationsListChanged: populateLocationsModel()
+    }
+
+    Component.onCompleted: populateLocationsModel()
+}

=== added file 'app/ui/SettingsPage.qml'
--- app/ui/SettingsPage.qml	1970-01-01 00:00:00 +0000
+++ app/ui/SettingsPage.qml	2015-08-05 19:54:56 +0000
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2015 Canonical Ltd
+ *
+ * This file is part of Ubuntu Weather App
+ *
+ * Ubuntu Weather App is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 3 as
+ * published by the Free Software Foundation.
+ *
+ * Ubuntu Weather App is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+import QtQuick 2.4
+import Ubuntu.Components 1.2
+import "../components"
+
+Page {
+    title: i18n.tr("Settings")
+
+    Column {
+        id: settingsColumn
+
+        anchors.fill: parent
+
+        StandardListItem {
+            title: i18n.tr("Units")
+            onClicked: mainPageStack.push(Qt.resolvedUrl("settings/UnitsPage.qml"))
+        }
+
+        StandardListItem {
+            title: i18n.tr("Data Provider")
+            onClicked: mainPageStack.push(Qt.resolvedUrl("settings/DataProviderPage.qml"))
+        }
+
+        StandardListItem {
+            title: i18n.tr("Refresh Interval")
+            onClicked: mainPageStack.push(Qt.resolvedUrl("settings/RefreshIntervalPage.qml"))
+        }
+
+        StandardListItem {
+            title: i18n.tr("Location")
+            onClicked: mainPageStack.push(Qt.resolvedUrl("settings/LocationPage.qml"))
+        }
+    }
+}

=== added directory 'app/ui/settings'
=== added file 'app/ui/settings/CMakeLists.txt'
--- app/ui/settings/CMakeLists.txt	1970-01-01 00:00:00 +0000
+++ app/ui/settings/CMakeLists.txt	2015-08-05 19:54:56 +0000
@@ -0,0 +1,5 @@
+file(GLOB UI_SETTINGS_QML_JS_FILES *.qml *.js)
+
+add_custom_target(ubuntu-weather-app_ui_settings_QMlFiles ALL SOURCES ${UI_SETTINGS_QML_JS_FILES})
+
+install(FILES ${UI_SETTINGS_QML_JS_FILES} DESTINATION ${UBUNTU-WEATHER_APP_DIR}/ui/settings)

=== added file 'app/ui/settings/DataProviderPage.qml'
--- app/ui/settings/DataProviderPage.qml	1970-01-01 00:00:00 +0000
+++ app/ui/settings/DataProviderPage.qml	2015-08-05 19:54:56 +0000
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2015 Canonical Ltd
+ *
+ * This file is part of Ubuntu Weather App
+ *
+ * Ubuntu Weather App is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 3 as
+ * published by the Free Software Foundation.
+ *
+ * Ubuntu Weather App is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+import QtQuick 2.4
+import Ubuntu.Components 1.2
+import "../../components"
+import "../../data/key.js" as Key
+
+Page {
+    title: i18n.tr("Data Provider")
+
+    ListModel {
+        id: dataProviderModel
+        ListElement { text: "OpenWeatherMap" }
+    }
+
+    ExpandableListItem {
+        id: dataProviderSetting
+
+        listViewHeight: dataProviderModel.count*units.gu(7) - units.gu(1)
+        model: dataProviderModel
+        text: i18n.tr("Provider")
+        subText: settings.service === "weatherchannel" ? "The Weather Channel" : "OpenWeatherMap"
+
+        delegate: StandardListItem {
+            title: model.text
+            icon: "ok"
+            showIcon: dataProviderSetting.subText === model.text
+            onClicked: {
+                if (model.text === "The Weather Channel") {
+                    settings.service = "weatherchannel"
+                } else {
+                    settings.service = "openweathermap"
+                }
+                refreshData(false, true)
+            }
+        }
+    }
+
+    Component.onCompleted: {
+        // If the key file for TWC is not blank, add the service to the model
+        if (Key.twcKey !== "") {
+            dataProviderModel.append({ text: "The Weather Channel" })
+        }
+    }
+}

=== added file 'app/ui/settings/LocationPage.qml'
--- app/ui/settings/LocationPage.qml	1970-01-01 00:00:00 +0000
+++ app/ui/settings/LocationPage.qml	2015-08-05 19:54:56 +0000
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2015 Canonical Ltd
+ *
+ * This file is part of Ubuntu Weather App
+ *
+ * Ubuntu Weather App is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 3 as
+ * published by the Free Software Foundation.
+ *
+ * Ubuntu Weather App is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+import QtQuick 2.4
+import Ubuntu.Components 1.2
+import Ubuntu.Components.ListItems 1.0 as ListItem
+
+Page {
+    title: i18n.tr("Location")
+
+    ListItem.Standard {
+        control: CheckBox {
+            checked: settings.detectCurrentLocation
+
+            onCheckedChanged: settings.detectCurrentLocation = checked;
+        }
+        text: i18n.tr("Detect current location")
+
+        onClicked: control.checked = !control.checked
+    }
+}

=== added file 'app/ui/settings/RefreshIntervalPage.qml'
--- app/ui/settings/RefreshIntervalPage.qml	1970-01-01 00:00:00 +0000
+++ app/ui/settings/RefreshIntervalPage.qml	2015-08-05 19:54:56 +0000
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2015 Canonical Ltd
+ *
+ * This file is part of Ubuntu Weather App
+ *
+ * Ubuntu Weather App is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 3 as
+ * published by the Free Software Foundation.
+ *
+ * Ubuntu Weather App is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+import QtQuick 2.4
+import Ubuntu.Components 1.2
+import "../../components"
+
+Page {
+    title: i18n.tr("Refresh Interval")
+
+    ListModel {
+        id: refreshModel
+        Component.onCompleted: initialize()
+        function initialize() {
+            refreshModel.append({"interval": 600, "text": i18n.tr("%1 minute", "%1 minutes", 10).arg(10)})
+            refreshModel.append({"interval": 900, "text": i18n.tr("%1 minute", "%1 minutes", 15).arg(15)})
+            refreshModel.append({"interval": 1800, "text": i18n.tr("%1 minute", "%1 minutes", 30).arg(30)})
+            refreshModel.append({"interval": 3600, "text": i18n.tr("%1 minute", "%1 minutes", 60).arg(60)})
+        }
+    }
+
+    ExpandableListItem {
+        id: dataProviderSetting
+
+        listViewHeight: refreshModel.count*units.gu(7) - units.gu(1)
+        model: refreshModel
+        text: i18n.tr("Interval")
+        subText: i18n.tr("%1 minute", "%1 minutes", Math.floor(settings.refreshInterval / 60).toString()).arg(Math.floor(settings.refreshInterval / 60).toString())
+
+        delegate: StandardListItem {
+            title: model.text
+            icon: "ok"
+            showIcon: settings.refreshInterval === model.interval
+            onClicked: {
+                settings.refreshInterval = model.interval
+                refreshData(false, true)
+            }
+        }
+    }
+}

=== added file 'app/ui/settings/UnitsPage.qml'
--- app/ui/settings/UnitsPage.qml	1970-01-01 00:00:00 +0000
+++ app/ui/settings/UnitsPage.qml	2015-08-05 19:54:56 +0000
@@ -0,0 +1,111 @@
+/*
+ * Copyright (C) 2015 Canonical Ltd
+ *
+ * This file is part of Ubuntu Weather App
+ *
+ * Ubuntu Weather App is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 3 as
+ * published by the Free Software Foundation.
+ *
+ * Ubuntu Weather App is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+import QtQuick 2.4
+import Ubuntu.Components 1.2
+import "../../components"
+
+Page {
+    title: i18n.tr("Units")
+
+    flickable: null
+
+    Flickable {
+        clip: true
+        anchors.fill: parent
+        height: parent.height
+        contentHeight: unitsColumn.childrenRect.height
+
+        ListModel {
+            id: temperatureModel
+            Component.onCompleted: initialize()
+            function initialize() {
+                // TRANSLATORS: The strings are standard measurement units
+                // of temperature in Celcius and are shown in the settings page.
+                // Only the abbreviated form of Celcius should be used.
+                temperatureModel.append({"text": i18n.tr("°C"), "value": "°C"})
+
+                // TRANSLATORS: The strings are standard measurement units
+                // of temperature in Fahrenheit and are shown in the settings page.
+                // Only the abbreviated form of Fahrenheit should be used.
+                temperatureModel.append({"text": i18n.tr("°F"), "value": "°F"})
+            }
+        }
+
+        ListModel {
+            id: windSpeedModel
+            Component.onCompleted: initialize()
+            function initialize() {
+                // TRANSLATORS: The strings are standard measurement units
+                // of wind speed in kilometers per hour and are shown in the settings page.
+                // Only the abbreviated form of kilometers per hour should be used.
+                windSpeedModel.append({"text": i18n.tr("kph"), "value": "kph"})
+
+                // TRANSLATORS: The strings are standard measurement units
+                // of wind speed in miles per hour and are shown in the settings page.
+                // Only the abbreviated form of miles per hour should be used.
+                windSpeedModel.append({"text": i18n.tr("mph"), "value": "mph"})
+            }
+        }
+
+        Column {
+            id: unitsColumn
+            anchors.fill: parent
+
+            ExpandableListItem {
+                id: temperatureSetting
+
+                listViewHeight: temperatureModel.count*units.gu(7) - units.gu(1)
+                model: temperatureModel
+                text: i18n.tr("Temperature")
+                subText: settings.tempScale === "°C" ? i18n.tr("°C")
+                                                     : i18n.tr("°F")
+
+                delegate: StandardListItem {
+                    title: model.text
+                    icon: "ok"
+                    showIcon: settings.tempScale === model.value
+                    onClicked: {
+                        settings.tempScale = model.value
+                        refreshData(true)
+                    }
+                }
+            }
+
+            ExpandableListItem {
+                id: windSetting
+
+                listViewHeight: windSpeedModel.count*units.gu(7) - units.gu(1)
+                model: windSpeedModel
+                text: i18n.tr("Wind Speed")
+                subText: settings.windUnits === "kph" ? i18n.tr("kph")
+                                                      : i18n.tr("mph")
+
+                delegate: StandardListItem {
+                    title: model.text
+                    icon: "ok"
+                    showIcon: settings.windUnits === model.value
+                    onClicked: {
+                        settings.windUnits = model.value
+                        refreshData(true)
+                    }
+                }
+            }
+        }
+    }
+}

=== added file 'app/weather-app@xxxxxx'
Binary files app/weather-app@xxxxxx	1970-01-01 00:00:00 +0000 and app/weather-app@xxxxxx	2015-08-05 19:54:56 +0000 differ
=== added directory 'debian'
=== renamed directory 'debian' => 'debian.moved'
=== added file 'debian/changelog'
--- debian/changelog	1970-01-01 00:00:00 +0000
+++ debian/changelog	2015-08-05 19:54:56 +0000
@@ -0,0 +1,197 @@
+ubuntu-weather-app (3.0) UNRELEASED; urgency=medium
+
+  [ Victor Thompson ]
+  * Sync debian version with click version.
+  * Use sunrise/sunset from API if available, otherwise use calculated times
+  * Allow adding the current location as a duplicate to the Locations List.
+  * Add chance of rain
+  * Add conditions text to day delegate. 
+  * Default to OWM if the key file for TWC is blank.
+  * Add sunrise and sunset icons from the spec
+
+  [ Andrew Hayzen ]
+  * Add mocked locations for autopilot and add a test using the data
+  * Add setting to disable auto detecting location
+  * When running under autopilot do not auto detect location
+  * Fix for console error on startup if there are no locations
+  * Show settings button on empty state page
+  * Fix empty state page so that bottom edge animation is ontop
+  * Remove add location button
+  * Change phrasing of manual add location
+  * Conditionally show "searching for current location" depending on the detectCurrentLocation setting
+
+ -- Victor Thompson <victor.thompson@xxxxxxxxx>  Mon, 01 Jun 2015 20:11:23 -0500
+
+ubuntu-weather-app (2.1) UNRELEASED; urgency=medium
+
+  * Update packaging to reflect reboot changes.
+
+ -- Daniel Holbach <daniel.holbach@xxxxxxxxxx>  Wed, 04 Feb 2015 11:25:02 +0100
+
+ubuntu-weather-app (2.0) utopic; urgency=low
+
+  [ Andrew Hayzen ]
+  * Initial version of reboot
+
+ -- Andrew Hayzen <ahayzen@xxxxxxxxx>  Mon, 02 Feb 2014 15:10:00 +0000
+
+ubuntu-weather-app (1.8.3ubuntu1) utopic; urgency=low
+
+  [ Dan Chapman ]
+  * Add timezone c++ extension plugin
+
+ -- Dan Chapman <dpniel@xxxxxxxxxx>  Thu, 25 Sep 2014 10:46:29 +0100
+
+ubuntu-weather-app (1.8.3) raring; urgency=low
+
+  [ Martin Borho ]
+  * updated icons for rain and snow
+  * bug fixes and optimizations
+
+  [ Alan Pope ]
+  * Update click framework and apparmor profile version (LP: #1315318) 
+
+ -- Alan Pope <popey@xxxxxxxxxx>  Fri, 02 May 2014 13:51:57 +0100
+
+ubuntu-weather-app (1.8.1ubuntu1) UNRELEASED; urgency=low
+
+  * added missing icon
+
+ -- Martin Borho <martin@xxxxxxxxx>  Sun, 23 Mar 2014 13:06:17 +0000
+
+ubuntu-weather-app (1.8ubuntu1) UNRELEASED; urgency=low
+
+  [Leo Arias]
+  * Port to autopilot 1.4.
+  * Set the objectNames for the settings options.
+
+  [Nicholas Skaggs]
+  * Fixed test_del_add_bug test, simplify tests, re-enable disabled tests.
+  * Redo create blank db, ensure it's being used across all tests.
+  * Add cmake build.
+  * Set revno to match store.
+  * Updated tests to use more emulator standards.
+  * Tweaked activity indicator handling.
+
+  [Dennis O'Flaherty]
+  * Load weather for the selected city when clicking the OWM logo instead of loading for London.
+
+  [Raul Yeguas]
+  * Added an modified logo for OpenWeatherMap (have mercy on me, christina-li and michal) and an action to open its website on click.
+  * Added animations for daily and houly forecast scroll.
+  * Improved animation speed by reducing image size.
+  * Removes SideStage hint, fixes related to the sizes of the current weather data display on tablets.
+
+  [Victor Thompson]
+  * Added unit of measure for main temperature value.
+  * Fixed conversion of wind speed data for TWC data.
+  * Prevent predictive text in search bar.
+
+  [Arash Badie Modiri]
+  * Changed a translation string into something a little bit more general.
+
+  [Martin Borho]
+  * Optimized and added haptic effect to hourly scrolling .
+  * Added The Weather Channel as default weather data provider.
+  * Added keyboard shortcuts.
+  * Initial tablet design of the Weather app.
+  * Refactored all width:parent.width and height:parent.height through corresponding anchors
+  * Fixed edit dialog to fill window on N7 2013 landscape
+  * Fixed weather AP tests to not assume tablet mode
+  * Fixed content sticking to the top, when height was changed in phone mode
+  * Fixed StateNotFoundError failures in image 206
+  * Removed WorkerScriptfor API calls
+  * New icon names used in API clients
+  * Using the current condition icon for the current day
+
+  [David Planella]
+  * Fixed the rule to generate a .pot template after the migration to cmake.
+  * Minor improvements on the weather API: added parameterize(), added locale parameters to TWC calls
+  * Fixes empty TWC URL if locale is not supported.
+  * Adds documentation for the The Weather Channel API.
+  * Makes the provider footer to be full width in order for it to make it look good on a Nexus 7.
+  * Fixes the shorter length header on the N7 using anchors instead of widths.
+
+  [Alan Pope]
+  * New icon.
+
+ -- Martin Borho <martin@xxxxxxxxx>  Fri, 21 Mar 2014 11:26:17 +0000
+
+ubuntu-weather-app (1.0ubuntu1) UNRELEASED; urgency=medium
+
+  * New icon 
+
+ -- Alan Pope <alan.pope@xxxxxxxxxxxxx>  Tue, 18 Feb 2014 21:26:17 +0000
+
+ubuntu-weather-app (1.0) saucy; urgency=low
+
+  [Andrew Starr-Bochicchio]
+  * Use the system locale to determine both the default units and the display of time.
+  * Add predictive search for locations. (LP: #1218910)
+  * Increase visibility of ActivityIndicator (LP: #1218904)
+
+  [David Planella]
+  * Updated translatable strings, a couple of small fixes to ease translations
+
+  [Dennis O'Flaherty]
+  * Fixes for precipitation values.
+
+  [Martin Borho]
+  * Removing a location add adding a new one fails. (LP: #1230297)
+  * Added location lookup via geoip and geonames.org with test (LP: #1187312, #1188726)
+  * Added fixes for new removable ListItem and the changed LocalStorage path. (LP: #1234544)
+  * Added setting for precipitation unit, mm or in.
+  * Location search now via geonames.org. (LP: #1230153)
+  * Updated predefined cities list.
+  * Added component for notifications.
+  * Added bottom margin to scrolling area in tabs and moved warm colors up the gradient color scheme.
+  * Visual improvements and fixes to LocationManagerSheet and AddLocationSheet. (LP: #1198541, #1221734)
+  * Added updated label, removed years from date labels. (LP: #1219200, #1221149, #1221162)
+  * Improved scrolling, added slow/fast scrolling for day/hour scrolling distinction. (LP:# 1221169)
+  * Added option in settings to change the wind speed unit. (LP: #1214934, #1190784)
+  * Dynamic gradient backgrounds according to the visual design.
+  * Added missing localstorage dependency.
+
+  [Nicholas Skaags]
+  * Add support for testing via click packages.
+
+  [Raúl Yeguas]
+  * Updated colors in GradientsMap.js. (LP: #1226746)
+  * Returns the last element to primary information screen and skip animation. (LP: #1227150)
+  * improved CurrentTemp text size
+  * UbuntuAnimations should be used (LP: #1218805)
+  * Replaced ValueSelector with new OptionSelector in Settings.
+  * Implemented a new scrolling.
+  * Added pressure data and modified the transition animation.
+  * Font color should be always white, with drop shadow.
+
+  [Sergio Schvezov]
+  * changing applicationName to com.ubuntu.weather to write in the unconfined areas
+  * cleaning up python code
+  * add the click data into the package and added apparmor rules (LP: #121839)
+
+ -- Martin Borho <martin@xxxxxxxxx>  Tue, 8 Oct 2013 22:42:00 +0200
+
+ubuntu-weather-app (0.3) raring; urgency=low
+  
+  * LocationManager-Sheet added
+  * Settings-Sheet added
+  * Autopilot tests
+  * Data-provider calls now in WorkerScript
+  * ActivityIndicators while loading
+  * Suru theme added
+  * Displaying more weather data for every location
+
+ -- Martin Borho <martin@xxxxxxxxx>  Tue, 13 Aug 2013 21:33:33 +0200
+
+ubuntu-weather-app (0.2) raring; urgency=low
+
+  * Added support for packaging and installing translations 
+
+ -- David Planella <david.planella@xxxxxxxxxx>  Tue, 28 May 2013 14:21:33 +0200
+
+ubuntu-weather-app (0.1) raring; urgency=low
+
+  * Initial release
+
+ -- Michael Hall <mhall119@xxxxxxxxxx>  Mon, 11 Feb 2013 16:04:00 -0500

=== added file 'debian/compat'
--- debian/compat	1970-01-01 00:00:00 +0000
+++ debian/compat	2015-08-05 19:54:56 +0000
@@ -0,0 +1,1 @@
+9

=== added file 'debian/control'
--- debian/control	1970-01-01 00:00:00 +0000
+++ debian/control	2015-08-05 19:54:56 +0000
@@ -0,0 +1,41 @@
+Source: ubuntu-weather-app
+Priority: extra
+Maintainer: Ubuntu App Cats <ubuntu-touch-coreapps@xxxxxxxxxxxxxxxxxxx>
+Build-Depends: cmake,
+               debhelper (>= 9),
+               gettext,
+               intltool,
+               python3 | python-all | python3-dev | python3-all-dev,
+               python3-minimal,
+               qtbase5-dev,
+               qtbase5-dev-tools,
+               qtdeclarative5-dev,
+               qtdeclarative5-dev-tools,
+               qtdeclarative5-ubuntu-ui-toolkit-plugin,
+Standards-Version: 3.9.6
+Section: misc
+Homepage: https://launchpad.net/ubuntu-weather-app
+Vcs-Bzr: https://code.launchpad.net/~ubuntu-weather-dev/ubuntu-weather-app/trunk
+
+Package: ubuntu-weather-app
+Architecture: all
+Depends: qmlscene,
+         qtdeclarative5-localstorage-plugin,
+         qml-module-qt-labs-settings,
+         qtdeclarative5-qtquick2-plugin,
+         qtdeclarative5-ubuntu-ui-toolkit-plugin | qt-components-ubuntu,
+         suru-icon-theme | ubuntu-mobile-icons,
+         ${misc:Depends}
+Description: Weather application
+ Core Weather application
+
+Package: ubuntu-weather-app-autopilot
+Architecture: all
+Depends: libautopilot-qt (>= 1.4),
+         libqt5test5,
+         libqt5widgets5,
+         ubuntu-ui-toolkit-autopilot,
+         ubuntu-weather-app (>= ${source:Version}),
+         ${misc:Depends}
+Description: Test package for the weather app
+ Autopilot tests for the weather app package

=== added file 'debian/copyright'
--- debian/copyright	1970-01-01 00:00:00 +0000
+++ debian/copyright	2015-08-05 19:54:56 +0000
@@ -0,0 +1,79 @@
+Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
+Upstream-Name: ubuntu-weather-app
+Source: https://launchpad.net/ubuntu-weather-app
+
+Files: *
+Copyright: 2013 Canonical Ltd.
+           2013 Jakub <jakub@xxxxxxxxxxx>
+           2013 Martin Borho <martin@xxxxxxxxx>
+           2013 Nekhelesh Ramananthan <krnekhelesh@xxxxxxxxx>
+           2013 Omer Akram <om26er@xxxxxxxxxx>
+           2013 Raúl Yeguas <neokore@xxxxxxxxx>
+           2013 Riccardo Padovani <rpadovani@xxxxxxxxxxxxx>
+           2013 Zonov Roman <roman2861@xxxxxxxxx>
+           2015 Andrew Hayzen <ahayzen@xxxxxxxxx>
+           2015 Victor Thompson <victor.thompson@xxxxxxxxx>
+License: GPL-3
+
+Files: app/data/suncalc.js
+Copyright: 2014 Vladimir Agafonkin
+License: BSD-2-clause
+
+Files: debian/*
+Copyright: 2013 Canonical Ltd.
+License: LGPL-3
+
+License: BSD-2-clause
+ Redistribution and use in source and binary forms, with or without modification, are
+ permitted provided that the following conditions are met:
+ .
+    1. Redistributions of source code must retain the above copyright notice, this list of
+       conditions and the following disclaimer.
+ .
+    2. Redistributions in binary form must reproduce the above copyright notice, this list
+       of conditions and the following disclaimer in the documentation and/or other materials
+       provided with the distribution.
+ .
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
+ EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
+ TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+License: GPL-3
+ This package is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public
+ License as published by the Free Software Foundation; either
+ version 3 of the License.
+ .
+ This package is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ General Public License for more details.
+ .
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+ .
+ On Debian systems, the complete text of the GNU General
+ Public License can be found in "/usr/share/common-licenses/GPL-3".
+
+License: LGPL-3
+ This package is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 3 of the License.
+ .
+ This package is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ Lesser General Public License for more details.
+ .
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+ .
+ On Debian systems, the complete text of the GNU Lesser General
+ Public License can be found in "/usr/share/common-licenses/LGPL-3".

=== added file 'debian/rules'
--- debian/rules	1970-01-01 00:00:00 +0000
+++ debian/rules	2015-08-05 19:54:56 +0000
@@ -0,0 +1,14 @@
+#!/usr/bin/make -f
+# -*- makefile -*-
+
+# Uncomment this to turn on verbose mode.
+#export DH_VERBOSE=1
+
+%:
+	dh $@
+
+override_dh_auto_configure:
+	dh_auto_configure -- -DCLICK_MODE=OFF
+
+override_dh_install:
+	dh_install --list-missing

=== added directory 'debian/source'
=== added file 'debian/source/format'
--- debian/source/format	1970-01-01 00:00:00 +0000
+++ debian/source/format	2015-08-05 19:54:56 +0000
@@ -0,0 +1,1 @@
+1.0

=== added file 'debian/ubuntu-weather-app-autopilot.install'
--- debian/ubuntu-weather-app-autopilot.install	1970-01-01 00:00:00 +0000
+++ debian/ubuntu-weather-app-autopilot.install	2015-08-05 19:54:56 +0000
@@ -0,0 +1,1 @@
+usr/lib

=== added file 'debian/ubuntu-weather-app.install'
--- debian/ubuntu-weather-app.install	1970-01-01 00:00:00 +0000
+++ debian/ubuntu-weather-app.install	2015-08-05 19:54:56 +0000
@@ -0,0 +1,1 @@
+usr/share

=== added file 'manifest.json.in'
--- manifest.json.in	1970-01-01 00:00:00 +0000
+++ manifest.json.in	2015-08-05 19:54:56 +0000
@@ -0,0 +1,23 @@
+{
+    "architecture": "all",
+    "description": "A weather forecast application for Ubuntu with support for multiple online weather data sources",
+    "framework": "ubuntu-sdk-15.04-qml",
+    "hooks": {
+        "weather": {
+            "apparmor": "ubuntu-weather-app.apparmor",
+            "desktop": "@CMAKE_INSTALL_DATADIR@/applications/ubuntu-weather-app.desktop"
+        }
+    },
+    "icon": "@ICON@",
+    "maintainer": "Ubuntu App Cats <ubuntu-touch-coreapps@xxxxxxxxxxxxxxxxxxx>",
+    "name": "@PROJECT_NAME@",
+    "title": "Weather",
+    "version": "3.0.@BZR_REVNO@",
+    "x-source": {
+        "vcs-bzr": "@BZR_SOURCE@",
+        "vcs-bzr-revno": "@BZR_REVNO@"
+    },
+    "x-test": {
+        "autopilot": "@AUTOPILOT_DIR@"
+    }
+}

=== added directory 'po'
=== renamed directory 'po' => 'po.moved'
=== added file 'po/CMakeLists.txt'
--- po/CMakeLists.txt	1970-01-01 00:00:00 +0000
+++ po/CMakeLists.txt	2015-08-05 19:54:56 +0000
@@ -0,0 +1,33 @@
+include(FindGettext)
+find_program(GETTEXT_XGETTEXT_EXECUTABLE xgettext)
+
+set(DOMAIN ${PROJECT_NAME})
+set(POT_FILE ${DOMAIN}.pot)
+file(GLOB PO_FILES *.po)
+
+# Creates the .pot file containing the translations template
+add_custom_target(${POT_FILE} ALL
+    COMMENT "Generating translation template"
+    COMMAND ${INTLTOOL_EXTRACT} --update --type=gettext/ini
+        --srcdir=${CMAKE_SOURCE_DIR} ${DESKTOP_FILE}.in.in
+    COMMAND ${GETTEXT_XGETTEXT_EXECUTABLE} -o ${POT_FILE}
+        -D ${CMAKE_CURRENT_SOURCE_DIR}
+        -D ${CMAKE_CURRENT_BINARY_DIR}
+        --from-code=UTF-8
+        --c++ --qt --add-comments=TRANSLATORS
+        --keyword=tr --keyword=tr:1,2 --keyword=N_
+        --package-name='${APP_HARDCODE}'
+        --copyright-holder='Canonical Ltd.'
+        ${I18N_SRC_FILES}
+    COMMAND ${CMAKE_COMMAND} -E copy ${POT_FILE} ${CMAKE_CURRENT_SOURCE_DIR})
+
+# Builds the binary translations catalog for each language
+# it finds source translations (*.po) for
+foreach(PO_FILE ${PO_FILES})
+    get_filename_component(LANG ${PO_FILE} NAME_WE)
+    gettext_process_po_files(${LANG} ALL PO_FILES ${PO_FILE})
+    set(INSTALL_DIR ${CMAKE_INSTALL_LOCALEDIR}/${LANG}/LC_MESSAGES)
+    install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${LANG}.gmo
+            DESTINATION ${INSTALL_DIR}
+            RENAME ${DOMAIN}.mo)
+endforeach(PO_FILE)

=== added file 'po/com.ubuntu.weather.pot'
--- po/com.ubuntu.weather.pot	1970-01-01 00:00:00 +0000
+++ po/com.ubuntu.weather.pot	2015-08-05 19:54:56 +0000
@@ -0,0 +1,212 @@
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR Canonical Ltd.
+# This file is distributed under the same license as the PACKAGE package.
+# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
+#
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: ubuntu-weather-app\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2015-07-29 21:25+0100\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
+"Language-Team: LANGUAGE <LL@xxxxxx>\n"
+"Language: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n"
+
+#: ../app/components/DayDelegate.qml:199
+msgid "Chance of rain"
+msgstr ""
+
+#: ../app/components/DayDelegate.qml:205
+msgid "Winds"
+msgstr ""
+
+#: ../app/components/DayDelegate.qml:212
+msgid "UV Index"
+msgstr ""
+
+#: ../app/components/DayDelegate.qml:217
+msgid "Pollen"
+msgstr ""
+
+#: ../app/components/DayDelegate.qml:223
+msgid "Humidity"
+msgstr ""
+
+#: ../app/components/DayDelegate.qml:229
+msgid "Sunrise"
+msgstr ""
+
+#: ../app/components/DayDelegate.qml:235
+msgid "Sunset"
+msgstr ""
+
+#: ../app/components/EmptyStateComponent.qml:51
+msgid "Searching for current location..."
+msgstr ""
+
+#: ../app/components/EmptyStateComponent.qml:52
+msgid "Cannot determine your location"
+msgstr ""
+
+#: ../app/components/EmptyStateComponent.qml:62
+msgid "Manually add a location by swiping up from the bottom of the display"
+msgstr ""
+
+#: ../app/components/HomeTempInfo.qml:38
+msgid "Today"
+msgstr ""
+
+#: ../app/components/ListItemActions/Remove.qml:26
+msgid "Remove"
+msgstr ""
+
+#: ../app/components/MultiSelectHeadState.qml:27
+msgid "Select All"
+msgstr ""
+
+#: ../app/components/MultiSelectHeadState.qml:39
+msgid "Delete"
+msgstr ""
+
+#: ../app/components/MultiSelectHeadState.qml:51
+msgid "Cancel selection"
+msgstr ""
+
+#: ../app/ui/AddLocationPage.qml:29
+msgid "Select a city"
+msgstr ""
+
+#: ../app/ui/AddLocationPage.qml:45 ../app/ui/AddLocationPage.qml:66
+msgid "Back"
+msgstr ""
+
+#: ../app/ui/AddLocationPage.qml:51
+msgid "City"
+msgstr ""
+
+#: ../app/ui/AddLocationPage.qml:93
+msgid "Search city"
+msgstr ""
+
+#: ../app/ui/AddLocationPage.qml:278
+msgid "No city found"
+msgstr ""
+
+#: ../app/ui/AddLocationPage.qml:291
+msgid "Couldn't load weather data, please try later again!"
+msgstr ""
+
+#: ../app/ui/AddLocationPage.qml:301
+msgid "Location already added."
+msgstr ""
+
+#: ../app/ui/AddLocationPage.qml:304
+msgid "OK"
+msgstr ""
+
+#: ../app/ui/HomePage.qml:31 ../app/ui/LocationsPage.qml:30
+msgid "Locations"
+msgstr ""
+
+#: ../app/ui/LocationsPage.qml:104
+msgid "Current Location"
+msgstr ""
+
+#: ../app/ui/SettingsPage.qml:24
+msgid "Settings"
+msgstr ""
+
+#: ../app/ui/SettingsPage.qml:32 ../app/ui/settings/UnitsPage.qml:24
+msgid "Units"
+msgstr ""
+
+#: ../app/ui/SettingsPage.qml:37 ../app/ui/settings/DataProviderPage.qml:25
+msgid "Data Provider"
+msgstr ""
+
+#: ../app/ui/SettingsPage.qml:42 ../app/ui/settings/RefreshIntervalPage.qml:24
+msgid "Refresh Interval"
+msgstr ""
+
+#: ../app/ui/SettingsPage.qml:47 ../app/ui/settings/LocationPage.qml:24
+msgid "Location"
+msgstr ""
+
+#: ../app/ui/settings/DataProviderPage.qml:37
+msgid "Provider"
+msgstr ""
+
+#: ../app/ui/settings/LocationPage.qml:32
+msgid "Detect current location"
+msgstr ""
+
+#: ../app/ui/settings/RefreshIntervalPage.qml:30
+#: ../app/ui/settings/RefreshIntervalPage.qml:31
+#: ../app/ui/settings/RefreshIntervalPage.qml:32
+#: ../app/ui/settings/RefreshIntervalPage.qml:33
+#: ../app/ui/settings/RefreshIntervalPage.qml:43
+#, qt-format
+msgid "%1 minute"
+msgid_plural "%1 minutes"
+msgstr[0] ""
+msgstr[1] ""
+
+#: ../app/ui/settings/RefreshIntervalPage.qml:42
+msgid "Interval"
+msgstr ""
+
+#. TRANSLATORS: The strings are standard measurement units
+#. of temperature in Celcius and are shown in the settings page.
+#. Only the abbreviated form of Celcius should be used.
+#: ../app/ui/settings/UnitsPage.qml:41 ../app/ui/settings/UnitsPage.qml:76
+msgid "°C"
+msgstr ""
+
+#. TRANSLATORS: The strings are standard measurement units
+#. of temperature in Fahrenheit and are shown in the settings page.
+#. Only the abbreviated form of Fahrenheit should be used.
+#: ../app/ui/settings/UnitsPage.qml:46 ../app/ui/settings/UnitsPage.qml:77
+msgid "°F"
+msgstr ""
+
+#. TRANSLATORS: The strings are standard measurement units
+#. of wind speed in kilometers per hour and are shown in the settings page.
+#. Only the abbreviated form of kilometers per hour should be used.
+#: ../app/ui/settings/UnitsPage.qml:57 ../app/ui/settings/UnitsPage.qml:96
+msgid "kph"
+msgstr ""
+
+#. TRANSLATORS: The strings are standard measurement units
+#. of wind speed in miles per hour and are shown in the settings page.
+#. Only the abbreviated form of miles per hour should be used.
+#: ../app/ui/settings/UnitsPage.qml:62 ../app/ui/settings/UnitsPage.qml:97
+msgid "mph"
+msgstr ""
+
+#: ../app/ui/settings/UnitsPage.qml:75
+msgid "Temperature"
+msgstr ""
+
+#: ../app/ui/settings/UnitsPage.qml:95
+msgid "Wind Speed"
+msgstr ""
+
+#: ubuntu-weather-app.desktop.in.in.h:1
+msgid "Weather"
+msgstr ""
+
+#: ubuntu-weather-app.desktop.in.in.h:2
+msgid ""
+"A weather forecast application for Ubuntu with support for multiple online "
+"weather data sources"
+msgstr ""
+
+#: ubuntu-weather-app.desktop.in.in.h:3
+msgid "weather;forecast;twc;openweathermap;the weather channel;"
+msgstr ""

=== added file 'po/de.po'
--- po/de.po	1970-01-01 00:00:00 +0000
+++ po/de.po	2015-08-05 19:54:56 +0000
@@ -0,0 +1,216 @@
+# German translation for ubuntu-weather-app
+# Copyright (c) 2015 Rosetta Contributors and Canonical Ltd 2015
+# This file is distributed under the same license as the ubuntu-weather-app package.
+# FIRST AUTHOR <EMAIL@ADDRESS>, 2015.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: ubuntu-weather-app\n"
+"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
+"POT-Creation-Date: 2015-07-29 21:25+0100\n"
+"PO-Revision-Date: 2015-07-29 20:39+0000\n"
+"Last-Translator: Phillip Sz <Unknown>\n"
+"Language-Team: German <de@xxxxxx>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=n != 1;\n"
+"X-Launchpad-Export-Date: 2015-07-31 05:44+0000\n"
+"X-Generator: Launchpad (build 17656)\n"
+
+#: ../app/components/DayDelegate.qml:199
+msgid "Chance of rain"
+msgstr "Regen möglich"
+
+#: ../app/components/DayDelegate.qml:205
+msgid "Winds"
+msgstr "Wind"
+
+#: ../app/components/DayDelegate.qml:212
+msgid "UV Index"
+msgstr "UV-Index"
+
+#: ../app/components/DayDelegate.qml:217
+msgid "Pollen"
+msgstr "Pollen"
+
+#: ../app/components/DayDelegate.qml:223
+msgid "Humidity"
+msgstr "Luftfeuchtigkeit"
+
+#: ../app/components/DayDelegate.qml:229
+msgid "Sunrise"
+msgstr "Sonnenaufgang"
+
+#: ../app/components/DayDelegate.qml:235
+msgid "Sunset"
+msgstr "Sonnenuntergang"
+
+#: ../app/components/EmptyStateComponent.qml:51
+msgid "Searching for current location..."
+msgstr "Suche nach aktuellem Standort …"
+
+#: ../app/components/EmptyStateComponent.qml:52
+msgid "Cannot determine your location"
+msgstr ""
+
+#: ../app/components/EmptyStateComponent.qml:62
+msgid "Manually add a location by swiping up from the bottom of the display"
+msgstr ""
+
+#: ../app/components/HomeTempInfo.qml:38
+msgid "Today"
+msgstr "Heute"
+
+#: ../app/components/ListItemActions/Remove.qml:26
+msgid "Remove"
+msgstr "Entfernen"
+
+#: ../app/components/MultiSelectHeadState.qml:27
+msgid "Select All"
+msgstr "Alle auswählen"
+
+#: ../app/components/MultiSelectHeadState.qml:39
+msgid "Delete"
+msgstr "Löschen"
+
+#: ../app/components/MultiSelectHeadState.qml:51
+msgid "Cancel selection"
+msgstr "Auswahl abbrechen"
+
+#: ../app/ui/AddLocationPage.qml:29
+msgid "Select a city"
+msgstr "Eine Stadt auswählen"
+
+#: ../app/ui/AddLocationPage.qml:45 ../app/ui/AddLocationPage.qml:66
+msgid "Back"
+msgstr "Zurück"
+
+#: ../app/ui/AddLocationPage.qml:51
+msgid "City"
+msgstr "Ort"
+
+#: ../app/ui/AddLocationPage.qml:93
+msgid "Search city"
+msgstr "Ort suchen"
+
+#: ../app/ui/AddLocationPage.qml:278
+msgid "No city found"
+msgstr "Keinen Ort gefunden"
+
+#: ../app/ui/AddLocationPage.qml:291
+msgid "Couldn't load weather data, please try later again!"
+msgstr ""
+"Wetterdaten konnten nicht geladen werden, bitte versuchen Sie es später noch "
+"einmal!"
+
+#: ../app/ui/AddLocationPage.qml:301
+msgid "Location already added."
+msgstr "Ort wurde schon hinzugefügt."
+
+#: ../app/ui/AddLocationPage.qml:304
+msgid "OK"
+msgstr "OK"
+
+#: ../app/ui/HomePage.qml:31 ../app/ui/LocationsPage.qml:30
+msgid "Locations"
+msgstr "Standorte"
+
+#: ../app/ui/LocationsPage.qml:104
+msgid "Current Location"
+msgstr "Aktueller Standort"
+
+#: ../app/ui/SettingsPage.qml:24
+msgid "Settings"
+msgstr "Einstellungen"
+
+#: ../app/ui/SettingsPage.qml:32 ../app/ui/settings/UnitsPage.qml:24
+msgid "Units"
+msgstr "Einheiten"
+
+#: ../app/ui/SettingsPage.qml:37 ../app/ui/settings/DataProviderPage.qml:25
+msgid "Data Provider"
+msgstr "Anbieter der Daten"
+
+#: ../app/ui/SettingsPage.qml:42 ../app/ui/settings/RefreshIntervalPage.qml:24
+msgid "Refresh Interval"
+msgstr "Aktualisierungsintervall"
+
+#: ../app/ui/SettingsPage.qml:47 ../app/ui/settings/LocationPage.qml:24
+msgid "Location"
+msgstr "Ort"
+
+#: ../app/ui/settings/DataProviderPage.qml:37
+msgid "Provider"
+msgstr "Anbieter"
+
+#: ../app/ui/settings/LocationPage.qml:32
+msgid "Detect current location"
+msgstr "Den aktuellen Standort feststellen"
+
+#: ../app/ui/settings/RefreshIntervalPage.qml:30
+#: ../app/ui/settings/RefreshIntervalPage.qml:31
+#: ../app/ui/settings/RefreshIntervalPage.qml:32
+#: ../app/ui/settings/RefreshIntervalPage.qml:33
+#: ../app/ui/settings/RefreshIntervalPage.qml:43
+#, qt-format
+msgid "%1 minute"
+msgid_plural "%1 minutes"
+msgstr[0] "%1 Minute"
+msgstr[1] "%1 Minuten"
+
+#: ../app/ui/settings/RefreshIntervalPage.qml:42
+msgid "Interval"
+msgstr "Intervall"
+
+#. TRANSLATORS: The strings are standard measurement units
+#. of temperature in Celcius and are shown in the settings page.
+#. Only the abbreviated form of Celcius should be used.
+#: ../app/ui/settings/UnitsPage.qml:41 ../app/ui/settings/UnitsPage.qml:76
+msgid "°C"
+msgstr "°C"
+
+#. TRANSLATORS: The strings are standard measurement units
+#. of temperature in Fahrenheit and are shown in the settings page.
+#. Only the abbreviated form of Fahrenheit should be used.
+#: ../app/ui/settings/UnitsPage.qml:46 ../app/ui/settings/UnitsPage.qml:77
+msgid "°F"
+msgstr "°F"
+
+#. TRANSLATORS: The strings are standard measurement units
+#. of wind speed in kilometers per hour and are shown in the settings page.
+#. Only the abbreviated form of kilometers per hour should be used.
+#: ../app/ui/settings/UnitsPage.qml:57 ../app/ui/settings/UnitsPage.qml:96
+msgid "kph"
+msgstr "km/h"
+
+#. TRANSLATORS: The strings are standard measurement units
+#. of wind speed in miles per hour and are shown in the settings page.
+#. Only the abbreviated form of miles per hour should be used.
+#: ../app/ui/settings/UnitsPage.qml:62 ../app/ui/settings/UnitsPage.qml:97
+msgid "mph"
+msgstr "Meilen/h"
+
+#: ../app/ui/settings/UnitsPage.qml:75
+msgid "Temperature"
+msgstr "Temperatur"
+
+#: ../app/ui/settings/UnitsPage.qml:95
+msgid "Wind Speed"
+msgstr "Windgeschwindigkeit"
+
+#: ubuntu-weather-app.desktop.in.in.h:1
+msgid "Weather"
+msgstr "Wetter"
+
+#: ubuntu-weather-app.desktop.in.in.h:2
+msgid ""
+"A weather forecast application for Ubuntu with support for multiple online "
+"weather data sources"
+msgstr ""
+"Eine Wettervorhersagen-App für Ubuntu mit Unterstützung für viele Online-"
+"Wetterdatenquellen"
+
+#: ubuntu-weather-app.desktop.in.in.h:3
+msgid "weather;forecast;twc;openweathermap;the weather channel;"
+msgstr "Wetter;Vorhersage;openweathermap;the weather channel;"

=== added file 'po/en_GB.po'
--- po/en_GB.po	1970-01-01 00:00:00 +0000
+++ po/en_GB.po	2015-08-05 19:54:56 +0000
@@ -0,0 +1,214 @@
+# English (United Kingdom) translation for ubuntu-weather-app
+# Copyright (c) 2015 Rosetta Contributors and Canonical Ltd 2015
+# This file is distributed under the same license as the ubuntu-weather-app package.
+# FIRST AUTHOR <EMAIL@ADDRESS>, 2015.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: ubuntu-weather-app\n"
+"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
+"POT-Creation-Date: 2015-07-29 21:25+0100\n"
+"PO-Revision-Date: 2015-07-27 17:54+0000\n"
+"Last-Translator: Bartosz Kosiorek <Unknown>\n"
+"Language-Team: English (United Kingdom) <en_GB@xxxxxx>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=n != 1;\n"
+"X-Launchpad-Export-Date: 2015-07-31 05:44+0000\n"
+"X-Generator: Launchpad (build 17656)\n"
+
+#: ../app/components/DayDelegate.qml:199
+msgid "Chance of rain"
+msgstr "Chance of rain"
+
+#: ../app/components/DayDelegate.qml:205
+msgid "Winds"
+msgstr "Winds"
+
+#: ../app/components/DayDelegate.qml:212
+msgid "UV Index"
+msgstr "UV Index"
+
+#: ../app/components/DayDelegate.qml:217
+msgid "Pollen"
+msgstr "Pollen"
+
+#: ../app/components/DayDelegate.qml:223
+msgid "Humidity"
+msgstr "Humidity"
+
+#: ../app/components/DayDelegate.qml:229
+msgid "Sunrise"
+msgstr "Sunrise"
+
+#: ../app/components/DayDelegate.qml:235
+msgid "Sunset"
+msgstr "Sunset"
+
+#: ../app/components/EmptyStateComponent.qml:51
+msgid "Searching for current location..."
+msgstr "Searching for current location..."
+
+#: ../app/components/EmptyStateComponent.qml:52
+msgid "Cannot determine your location"
+msgstr ""
+
+#: ../app/components/EmptyStateComponent.qml:62
+msgid "Manually add a location by swiping up from the bottom of the display"
+msgstr ""
+
+#: ../app/components/HomeTempInfo.qml:38
+msgid "Today"
+msgstr "Today"
+
+#: ../app/components/ListItemActions/Remove.qml:26
+msgid "Remove"
+msgstr "Remove"
+
+#: ../app/components/MultiSelectHeadState.qml:27
+msgid "Select All"
+msgstr "Select All"
+
+#: ../app/components/MultiSelectHeadState.qml:39
+msgid "Delete"
+msgstr "Delete"
+
+#: ../app/components/MultiSelectHeadState.qml:51
+msgid "Cancel selection"
+msgstr "Cancel selection"
+
+#: ../app/ui/AddLocationPage.qml:29
+msgid "Select a city"
+msgstr "Select a city"
+
+#: ../app/ui/AddLocationPage.qml:45 ../app/ui/AddLocationPage.qml:66
+msgid "Back"
+msgstr "Back"
+
+#: ../app/ui/AddLocationPage.qml:51
+msgid "City"
+msgstr "City"
+
+#: ../app/ui/AddLocationPage.qml:93
+msgid "Search city"
+msgstr "Search city"
+
+#: ../app/ui/AddLocationPage.qml:278
+msgid "No city found"
+msgstr "No city found"
+
+#: ../app/ui/AddLocationPage.qml:291
+msgid "Couldn't load weather data, please try later again!"
+msgstr "Couldn't load weather data, please try later again!"
+
+#: ../app/ui/AddLocationPage.qml:301
+msgid "Location already added."
+msgstr "Location already added."
+
+#: ../app/ui/AddLocationPage.qml:304
+msgid "OK"
+msgstr "OK"
+
+#: ../app/ui/HomePage.qml:31 ../app/ui/LocationsPage.qml:30
+msgid "Locations"
+msgstr "Locations"
+
+#: ../app/ui/LocationsPage.qml:104
+msgid "Current Location"
+msgstr "Current Location"
+
+#: ../app/ui/SettingsPage.qml:24
+msgid "Settings"
+msgstr "Settings"
+
+#: ../app/ui/SettingsPage.qml:32 ../app/ui/settings/UnitsPage.qml:24
+msgid "Units"
+msgstr "Units"
+
+#: ../app/ui/SettingsPage.qml:37 ../app/ui/settings/DataProviderPage.qml:25
+msgid "Data Provider"
+msgstr "Data Provider"
+
+#: ../app/ui/SettingsPage.qml:42 ../app/ui/settings/RefreshIntervalPage.qml:24
+msgid "Refresh Interval"
+msgstr "Refresh Interval"
+
+#: ../app/ui/SettingsPage.qml:47 ../app/ui/settings/LocationPage.qml:24
+msgid "Location"
+msgstr "Location"
+
+#: ../app/ui/settings/DataProviderPage.qml:37
+msgid "Provider"
+msgstr "Provider"
+
+#: ../app/ui/settings/LocationPage.qml:32
+msgid "Detect current location"
+msgstr "Detect current location"
+
+#: ../app/ui/settings/RefreshIntervalPage.qml:30
+#: ../app/ui/settings/RefreshIntervalPage.qml:31
+#: ../app/ui/settings/RefreshIntervalPage.qml:32
+#: ../app/ui/settings/RefreshIntervalPage.qml:33
+#: ../app/ui/settings/RefreshIntervalPage.qml:43
+#, qt-format
+msgid "%1 minute"
+msgid_plural "%1 minutes"
+msgstr[0] "%1 minute"
+msgstr[1] "%1 minutes"
+
+#: ../app/ui/settings/RefreshIntervalPage.qml:42
+msgid "Interval"
+msgstr "Interval"
+
+#. TRANSLATORS: The strings are standard measurement units
+#. of temperature in Celcius and are shown in the settings page.
+#. Only the abbreviated form of Celcius should be used.
+#: ../app/ui/settings/UnitsPage.qml:41 ../app/ui/settings/UnitsPage.qml:76
+msgid "°C"
+msgstr "°C"
+
+#. TRANSLATORS: The strings are standard measurement units
+#. of temperature in Fahrenheit and are shown in the settings page.
+#. Only the abbreviated form of Fahrenheit should be used.
+#: ../app/ui/settings/UnitsPage.qml:46 ../app/ui/settings/UnitsPage.qml:77
+msgid "°F"
+msgstr "°F"
+
+#. TRANSLATORS: The strings are standard measurement units
+#. of wind speed in kilometers per hour and are shown in the settings page.
+#. Only the abbreviated form of kilometers per hour should be used.
+#: ../app/ui/settings/UnitsPage.qml:57 ../app/ui/settings/UnitsPage.qml:96
+msgid "kph"
+msgstr "kph"
+
+#. TRANSLATORS: The strings are standard measurement units
+#. of wind speed in miles per hour and are shown in the settings page.
+#. Only the abbreviated form of miles per hour should be used.
+#: ../app/ui/settings/UnitsPage.qml:62 ../app/ui/settings/UnitsPage.qml:97
+msgid "mph"
+msgstr "mph"
+
+#: ../app/ui/settings/UnitsPage.qml:75
+msgid "Temperature"
+msgstr "Temperature"
+
+#: ../app/ui/settings/UnitsPage.qml:95
+msgid "Wind Speed"
+msgstr "Wind Speed"
+
+#: ubuntu-weather-app.desktop.in.in.h:1
+msgid "Weather"
+msgstr "Weather"
+
+#: ubuntu-weather-app.desktop.in.in.h:2
+msgid ""
+"A weather forecast application for Ubuntu with support for multiple online "
+"weather data sources"
+msgstr ""
+"A weather forecast application for Ubuntu with support for multiple online "
+"weather data sources"
+
+#: ubuntu-weather-app.desktop.in.in.h:3
+msgid "weather;forecast;twc;openweathermap;the weather channel;"
+msgstr "weather;forecast;twc;openweathermap;the weather channel;"

=== added file 'po/fr.po'
--- po/fr.po	1970-01-01 00:00:00 +0000
+++ po/fr.po	2015-08-05 19:54:56 +0000
@@ -0,0 +1,216 @@
+# French translation for ubuntu-weather-app
+# Copyright (c) 2015 Rosetta Contributors and Canonical Ltd 2015
+# This file is distributed under the same license as the ubuntu-weather-app package.
+# FIRST AUTHOR <EMAIL@ADDRESS>, 2015.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: ubuntu-weather-app\n"
+"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
+"POT-Creation-Date: 2015-07-29 21:25+0100\n"
+"PO-Revision-Date: 2015-07-27 17:26+0000\n"
+"Last-Translator: Anne <anneonyme017@xxxxxxxxx>\n"
+"Language-Team: French <fr@xxxxxx>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=n > 1;\n"
+"X-Launchpad-Export-Date: 2015-07-31 05:44+0000\n"
+"X-Generator: Launchpad (build 17656)\n"
+
+#: ../app/components/DayDelegate.qml:199
+msgid "Chance of rain"
+msgstr "Risque de pluie"
+
+#: ../app/components/DayDelegate.qml:205
+msgid "Winds"
+msgstr "Vents"
+
+#: ../app/components/DayDelegate.qml:212
+msgid "UV Index"
+msgstr "Indice UV"
+
+#: ../app/components/DayDelegate.qml:217
+msgid "Pollen"
+msgstr "Pollen"
+
+#: ../app/components/DayDelegate.qml:223
+msgid "Humidity"
+msgstr "Humidité"
+
+#: ../app/components/DayDelegate.qml:229
+msgid "Sunrise"
+msgstr "Lever du soleil"
+
+#: ../app/components/DayDelegate.qml:235
+msgid "Sunset"
+msgstr "Coucher du soleil"
+
+#: ../app/components/EmptyStateComponent.qml:51
+msgid "Searching for current location..."
+msgstr "Recherche de la position actuelle..."
+
+#: ../app/components/EmptyStateComponent.qml:52
+msgid "Cannot determine your location"
+msgstr ""
+
+#: ../app/components/EmptyStateComponent.qml:62
+msgid "Manually add a location by swiping up from the bottom of the display"
+msgstr ""
+
+#: ../app/components/HomeTempInfo.qml:38
+msgid "Today"
+msgstr "Aujourd'hui"
+
+#: ../app/components/ListItemActions/Remove.qml:26
+msgid "Remove"
+msgstr "Supprimer"
+
+#: ../app/components/MultiSelectHeadState.qml:27
+msgid "Select All"
+msgstr "Tout sélectionner"
+
+#: ../app/components/MultiSelectHeadState.qml:39
+msgid "Delete"
+msgstr "Supprimer"
+
+#: ../app/components/MultiSelectHeadState.qml:51
+msgid "Cancel selection"
+msgstr "Annuler la sélection"
+
+#: ../app/ui/AddLocationPage.qml:29
+msgid "Select a city"
+msgstr "Sélectionner une ville"
+
+#: ../app/ui/AddLocationPage.qml:45 ../app/ui/AddLocationPage.qml:66
+msgid "Back"
+msgstr "Précédent"
+
+#: ../app/ui/AddLocationPage.qml:51
+msgid "City"
+msgstr "Ville"
+
+#: ../app/ui/AddLocationPage.qml:93
+msgid "Search city"
+msgstr "Rechercher une ville"
+
+#: ../app/ui/AddLocationPage.qml:278
+msgid "No city found"
+msgstr "Aucune ville trouvée"
+
+#: ../app/ui/AddLocationPage.qml:291
+msgid "Couldn't load weather data, please try later again!"
+msgstr ""
+"Impossible de récupérer les données météorologiques, veuillez réessayer plus "
+"tard !"
+
+#: ../app/ui/AddLocationPage.qml:301
+msgid "Location already added."
+msgstr "Emplacement déjà ajouté."
+
+#: ../app/ui/AddLocationPage.qml:304
+msgid "OK"
+msgstr "OK"
+
+#: ../app/ui/HomePage.qml:31 ../app/ui/LocationsPage.qml:30
+msgid "Locations"
+msgstr "Emplacements"
+
+#: ../app/ui/LocationsPage.qml:104
+msgid "Current Location"
+msgstr "Emplacement actuel"
+
+#: ../app/ui/SettingsPage.qml:24
+msgid "Settings"
+msgstr "Paramètres"
+
+#: ../app/ui/SettingsPage.qml:32 ../app/ui/settings/UnitsPage.qml:24
+msgid "Units"
+msgstr "Unités"
+
+#: ../app/ui/SettingsPage.qml:37 ../app/ui/settings/DataProviderPage.qml:25
+msgid "Data Provider"
+msgstr "Fournisseur de données"
+
+#: ../app/ui/SettingsPage.qml:42 ../app/ui/settings/RefreshIntervalPage.qml:24
+msgid "Refresh Interval"
+msgstr "Intervalle d'actualisation"
+
+#: ../app/ui/SettingsPage.qml:47 ../app/ui/settings/LocationPage.qml:24
+msgid "Location"
+msgstr "Emplacement"
+
+#: ../app/ui/settings/DataProviderPage.qml:37
+msgid "Provider"
+msgstr "Fournisseur"
+
+#: ../app/ui/settings/LocationPage.qml:32
+msgid "Detect current location"
+msgstr "Détecter l'emplacement actuel"
+
+#: ../app/ui/settings/RefreshIntervalPage.qml:30
+#: ../app/ui/settings/RefreshIntervalPage.qml:31
+#: ../app/ui/settings/RefreshIntervalPage.qml:32
+#: ../app/ui/settings/RefreshIntervalPage.qml:33
+#: ../app/ui/settings/RefreshIntervalPage.qml:43
+#, qt-format
+msgid "%1 minute"
+msgid_plural "%1 minutes"
+msgstr[0] "%1 minute"
+msgstr[1] "%1 minutes"
+
+#: ../app/ui/settings/RefreshIntervalPage.qml:42
+msgid "Interval"
+msgstr "Intervalle"
+
+#. TRANSLATORS: The strings are standard measurement units
+#. of temperature in Celcius and are shown in the settings page.
+#. Only the abbreviated form of Celcius should be used.
+#: ../app/ui/settings/UnitsPage.qml:41 ../app/ui/settings/UnitsPage.qml:76
+msgid "°C"
+msgstr "°C"
+
+#. TRANSLATORS: The strings are standard measurement units
+#. of temperature in Fahrenheit and are shown in the settings page.
+#. Only the abbreviated form of Fahrenheit should be used.
+#: ../app/ui/settings/UnitsPage.qml:46 ../app/ui/settings/UnitsPage.qml:77
+msgid "°F"
+msgstr "°F"
+
+#. TRANSLATORS: The strings are standard measurement units
+#. of wind speed in kilometers per hour and are shown in the settings page.
+#. Only the abbreviated form of kilometers per hour should be used.
+#: ../app/ui/settings/UnitsPage.qml:57 ../app/ui/settings/UnitsPage.qml:96
+msgid "kph"
+msgstr "km/h"
+
+#. TRANSLATORS: The strings are standard measurement units
+#. of wind speed in miles per hour and are shown in the settings page.
+#. Only the abbreviated form of miles per hour should be used.
+#: ../app/ui/settings/UnitsPage.qml:62 ../app/ui/settings/UnitsPage.qml:97
+msgid "mph"
+msgstr "mph"
+
+#: ../app/ui/settings/UnitsPage.qml:75
+msgid "Temperature"
+msgstr "Température"
+
+#: ../app/ui/settings/UnitsPage.qml:95
+msgid "Wind Speed"
+msgstr "Vitesse du vent"
+
+#: ubuntu-weather-app.desktop.in.in.h:1
+msgid "Weather"
+msgstr "Météo"
+
+#: ubuntu-weather-app.desktop.in.in.h:2
+msgid ""
+"A weather forecast application for Ubuntu with support for multiple online "
+"weather data sources"
+msgstr ""
+"Une application de prévisions météo pour Ubuntu avec prise en charge de "
+"plusieurs sources de données météorologiques en ligne"
+
+#: ubuntu-weather-app.desktop.in.in.h:3
+msgid "weather;forecast;twc;openweathermap;the weather channel;"
+msgstr "météo;temps;prévisions;twc;openweathermap;the weather channel;"

=== added file 'po/gl.po'
--- po/gl.po	1970-01-01 00:00:00 +0000
+++ po/gl.po	2015-08-05 19:54:56 +0000
@@ -0,0 +1,214 @@
+# Galician translation for ubuntu-weather-app
+# Copyright (c) 2015 Rosetta Contributors and Canonical Ltd 2015
+# This file is distributed under the same license as the ubuntu-weather-app package.
+# FIRST AUTHOR <EMAIL@ADDRESS>, 2015.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: ubuntu-weather-app\n"
+"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
+"POT-Creation-Date: 2015-07-29 21:25+0100\n"
+"PO-Revision-Date: 2015-07-31 01:15+0000\n"
+"Last-Translator: Marcos Lans <Unknown>\n"
+"Language-Team: Galician <gl@xxxxxx>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=n != 1;\n"
+"X-Launchpad-Export-Date: 2015-08-01 05:49+0000\n"
+"X-Generator: Launchpad (build 17656)\n"
+
+#: ../app/components/DayDelegate.qml:199
+msgid "Chance of rain"
+msgstr "Posibilidade de choiva"
+
+#: ../app/components/DayDelegate.qml:205
+msgid "Winds"
+msgstr "Ventos"
+
+#: ../app/components/DayDelegate.qml:212
+msgid "UV Index"
+msgstr "Índice UV"
+
+#: ../app/components/DayDelegate.qml:217
+msgid "Pollen"
+msgstr "Polen"
+
+#: ../app/components/DayDelegate.qml:223
+msgid "Humidity"
+msgstr "Humidade"
+
+#: ../app/components/DayDelegate.qml:229
+msgid "Sunrise"
+msgstr "Abrente"
+
+#: ../app/components/DayDelegate.qml:235
+msgid "Sunset"
+msgstr "Solpor"
+
+#: ../app/components/EmptyStateComponent.qml:51
+msgid "Searching for current location..."
+msgstr "Buscando a localización..."
+
+#: ../app/components/EmptyStateComponent.qml:52
+msgid "Cannot determine your location"
+msgstr "Non foi posíbel determinar a súa localización"
+
+#: ../app/components/EmptyStateComponent.qml:62
+msgid "Manually add a location by swiping up from the bottom of the display"
+msgstr "Engada unha localización esvarando o dedo desde o fondo da pantalla"
+
+#: ../app/components/HomeTempInfo.qml:38
+msgid "Today"
+msgstr "Hoxe"
+
+#: ../app/components/ListItemActions/Remove.qml:26
+msgid "Remove"
+msgstr "Eliminar"
+
+#: ../app/components/MultiSelectHeadState.qml:27
+msgid "Select All"
+msgstr "Seleccionar todo"
+
+#: ../app/components/MultiSelectHeadState.qml:39
+msgid "Delete"
+msgstr "Eliminar"
+
+#: ../app/components/MultiSelectHeadState.qml:51
+msgid "Cancel selection"
+msgstr "Cancelar selección"
+
+#: ../app/ui/AddLocationPage.qml:29
+msgid "Select a city"
+msgstr "Seleccionar cidade"
+
+#: ../app/ui/AddLocationPage.qml:45 ../app/ui/AddLocationPage.qml:66
+msgid "Back"
+msgstr "Volver"
+
+#: ../app/ui/AddLocationPage.qml:51
+msgid "City"
+msgstr "Cidade"
+
+#: ../app/ui/AddLocationPage.qml:93
+msgid "Search city"
+msgstr "Buscar a cidade"
+
+#: ../app/ui/AddLocationPage.qml:278
+msgid "No city found"
+msgstr "Non se atopou a cidade"
+
+#: ../app/ui/AddLocationPage.qml:291
+msgid "Couldn't load weather data, please try later again!"
+msgstr "Non se cargaron os datos do tempo, ténteo máis tarde."
+
+#: ../app/ui/AddLocationPage.qml:301
+msgid "Location already added."
+msgstr "A localización xa se engadiu."
+
+#: ../app/ui/AddLocationPage.qml:304
+msgid "OK"
+msgstr "Aceptar"
+
+#: ../app/ui/HomePage.qml:31 ../app/ui/LocationsPage.qml:30
+msgid "Locations"
+msgstr "Localizacións"
+
+#: ../app/ui/LocationsPage.qml:104
+msgid "Current Location"
+msgstr "Localización actual"
+
+#: ../app/ui/SettingsPage.qml:24
+msgid "Settings"
+msgstr "Axustes"
+
+#: ../app/ui/SettingsPage.qml:32 ../app/ui/settings/UnitsPage.qml:24
+msgid "Units"
+msgstr "Unidades"
+
+#: ../app/ui/SettingsPage.qml:37 ../app/ui/settings/DataProviderPage.qml:25
+msgid "Data Provider"
+msgstr "Fornecedor dos datos"
+
+#: ../app/ui/SettingsPage.qml:42 ../app/ui/settings/RefreshIntervalPage.qml:24
+msgid "Refresh Interval"
+msgstr "Intervalo de actualización"
+
+#: ../app/ui/SettingsPage.qml:47 ../app/ui/settings/LocationPage.qml:24
+msgid "Location"
+msgstr "Localización"
+
+#: ../app/ui/settings/DataProviderPage.qml:37
+msgid "Provider"
+msgstr "Fornecedor"
+
+#: ../app/ui/settings/LocationPage.qml:32
+msgid "Detect current location"
+msgstr "Detectar a localización"
+
+#: ../app/ui/settings/RefreshIntervalPage.qml:30
+#: ../app/ui/settings/RefreshIntervalPage.qml:31
+#: ../app/ui/settings/RefreshIntervalPage.qml:32
+#: ../app/ui/settings/RefreshIntervalPage.qml:33
+#: ../app/ui/settings/RefreshIntervalPage.qml:43
+#, qt-format
+msgid "%1 minute"
+msgid_plural "%1 minutes"
+msgstr[0] "%1 minuto"
+msgstr[1] "%1 minutos"
+
+#: ../app/ui/settings/RefreshIntervalPage.qml:42
+msgid "Interval"
+msgstr "Intervalo"
+
+#. TRANSLATORS: The strings are standard measurement units
+#. of temperature in Celcius and are shown in the settings page.
+#. Only the abbreviated form of Celcius should be used.
+#: ../app/ui/settings/UnitsPage.qml:41 ../app/ui/settings/UnitsPage.qml:76
+msgid "°C"
+msgstr "°C"
+
+#. TRANSLATORS: The strings are standard measurement units
+#. of temperature in Fahrenheit and are shown in the settings page.
+#. Only the abbreviated form of Fahrenheit should be used.
+#: ../app/ui/settings/UnitsPage.qml:46 ../app/ui/settings/UnitsPage.qml:77
+msgid "°F"
+msgstr "°F"
+
+#. TRANSLATORS: The strings are standard measurement units
+#. of wind speed in kilometers per hour and are shown in the settings page.
+#. Only the abbreviated form of kilometers per hour should be used.
+#: ../app/ui/settings/UnitsPage.qml:57 ../app/ui/settings/UnitsPage.qml:96
+msgid "kph"
+msgstr "km/h"
+
+#. TRANSLATORS: The strings are standard measurement units
+#. of wind speed in miles per hour and are shown in the settings page.
+#. Only the abbreviated form of miles per hour should be used.
+#: ../app/ui/settings/UnitsPage.qml:62 ../app/ui/settings/UnitsPage.qml:97
+msgid "mph"
+msgstr "m/h"
+
+#: ../app/ui/settings/UnitsPage.qml:75
+msgid "Temperature"
+msgstr "Temperatura"
+
+#: ../app/ui/settings/UnitsPage.qml:95
+msgid "Wind Speed"
+msgstr "Velocidade do vento"
+
+#: ubuntu-weather-app.desktop.in.in.h:1
+msgid "Weather"
+msgstr "O Tempo"
+
+#: ubuntu-weather-app.desktop.in.in.h:2
+msgid ""
+"A weather forecast application for Ubuntu with support for multiple online "
+"weather data sources"
+msgstr ""
+"Previsión meteorolóxica para Ubuntu con compatibilidade para múltiples "
+"orixes de datos en liña"
+
+#: ubuntu-weather-app.desktop.in.in.h:3
+msgid "weather;forecast;twc;openweathermap;the weather channel;"
+msgstr "tempo;clima;weather channel;previsión;prognóstico;openweathermap;"

=== added file 'po/hu.po'
--- po/hu.po	1970-01-01 00:00:00 +0000
+++ po/hu.po	2015-08-05 19:54:56 +0000
@@ -0,0 +1,213 @@
+# Hungarian translation for ubuntu-weather-app
+# Copyright (c) 2015 Rosetta Contributors and Canonical Ltd 2015
+# This file is distributed under the same license as the ubuntu-weather-app package.
+# FIRST AUTHOR <EMAIL@ADDRESS>, 2015.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: ubuntu-weather-app\n"
+"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
+"POT-Creation-Date: 2015-07-29 21:25+0100\n"
+"PO-Revision-Date: 2015-07-27 20:27+0000\n"
+"Last-Translator: Richard Somlói <ricsipontaz@xxxxxxxxx>\n"
+"Language-Team: Hungarian <hu@xxxxxx>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=n != 1;\n"
+"X-Launchpad-Export-Date: 2015-07-31 05:44+0000\n"
+"X-Generator: Launchpad (build 17656)\n"
+
+#: ../app/components/DayDelegate.qml:199
+msgid "Chance of rain"
+msgstr "Eső esélye"
+
+#: ../app/components/DayDelegate.qml:205
+msgid "Winds"
+msgstr "Szél"
+
+#: ../app/components/DayDelegate.qml:212
+msgid "UV Index"
+msgstr "UV Index"
+
+#: ../app/components/DayDelegate.qml:217
+msgid "Pollen"
+msgstr "Pollen"
+
+#: ../app/components/DayDelegate.qml:223
+msgid "Humidity"
+msgstr "Páratartalom"
+
+#: ../app/components/DayDelegate.qml:229
+msgid "Sunrise"
+msgstr "Napkelte"
+
+#: ../app/components/DayDelegate.qml:235
+msgid "Sunset"
+msgstr "Napnyugta"
+
+#: ../app/components/EmptyStateComponent.qml:51
+msgid "Searching for current location..."
+msgstr "Jelenlegi helyzet meghatározása…"
+
+#: ../app/components/EmptyStateComponent.qml:52
+msgid "Cannot determine your location"
+msgstr ""
+
+#: ../app/components/EmptyStateComponent.qml:62
+msgid "Manually add a location by swiping up from the bottom of the display"
+msgstr ""
+
+#: ../app/components/HomeTempInfo.qml:38
+msgid "Today"
+msgstr "Ma"
+
+#: ../app/components/ListItemActions/Remove.qml:26
+msgid "Remove"
+msgstr "Eltávolítás"
+
+#: ../app/components/MultiSelectHeadState.qml:27
+msgid "Select All"
+msgstr "Összes kijelölése"
+
+#: ../app/components/MultiSelectHeadState.qml:39
+msgid "Delete"
+msgstr "Törlés"
+
+#: ../app/components/MultiSelectHeadState.qml:51
+msgid "Cancel selection"
+msgstr "Kijelölés megszüntetése"
+
+#: ../app/ui/AddLocationPage.qml:29
+msgid "Select a city"
+msgstr "Város kiválasztása"
+
+#: ../app/ui/AddLocationPage.qml:45 ../app/ui/AddLocationPage.qml:66
+msgid "Back"
+msgstr "Vissza"
+
+#: ../app/ui/AddLocationPage.qml:51
+msgid "City"
+msgstr "Város"
+
+#: ../app/ui/AddLocationPage.qml:93
+msgid "Search city"
+msgstr "Város keresése"
+
+#: ../app/ui/AddLocationPage.qml:278
+msgid "No city found"
+msgstr "Nincs találat"
+
+#: ../app/ui/AddLocationPage.qml:291
+msgid "Couldn't load weather data, please try later again!"
+msgstr "Nem sikerült betölteni az időjárásadatokat, próbálja újra később!"
+
+#: ../app/ui/AddLocationPage.qml:301
+msgid "Location already added."
+msgstr "A hely korábban már hozzá lett adva."
+
+#: ../app/ui/AddLocationPage.qml:304
+msgid "OK"
+msgstr "OK"
+
+#: ../app/ui/HomePage.qml:31 ../app/ui/LocationsPage.qml:30
+msgid "Locations"
+msgstr "Helyek"
+
+#: ../app/ui/LocationsPage.qml:104
+msgid "Current Location"
+msgstr "Jelenlegi hely"
+
+#: ../app/ui/SettingsPage.qml:24
+msgid "Settings"
+msgstr "Beállítások"
+
+#: ../app/ui/SettingsPage.qml:32 ../app/ui/settings/UnitsPage.qml:24
+msgid "Units"
+msgstr "Mértékegységek"
+
+#: ../app/ui/SettingsPage.qml:37 ../app/ui/settings/DataProviderPage.qml:25
+msgid "Data Provider"
+msgstr "Adatszolgáltató"
+
+#: ../app/ui/SettingsPage.qml:42 ../app/ui/settings/RefreshIntervalPage.qml:24
+msgid "Refresh Interval"
+msgstr "Frissítési időköz"
+
+#: ../app/ui/SettingsPage.qml:47 ../app/ui/settings/LocationPage.qml:24
+msgid "Location"
+msgstr "Hely"
+
+#: ../app/ui/settings/DataProviderPage.qml:37
+msgid "Provider"
+msgstr "Szolgáltató"
+
+#: ../app/ui/settings/LocationPage.qml:32
+msgid "Detect current location"
+msgstr "Jelenlegi hely meghatározása"
+
+#: ../app/ui/settings/RefreshIntervalPage.qml:30
+#: ../app/ui/settings/RefreshIntervalPage.qml:31
+#: ../app/ui/settings/RefreshIntervalPage.qml:32
+#: ../app/ui/settings/RefreshIntervalPage.qml:33
+#: ../app/ui/settings/RefreshIntervalPage.qml:43
+#, qt-format
+msgid "%1 minute"
+msgid_plural "%1 minutes"
+msgstr[0] "%1 perc"
+msgstr[1] "%1 perc"
+
+#: ../app/ui/settings/RefreshIntervalPage.qml:42
+msgid "Interval"
+msgstr "Időköz"
+
+#. TRANSLATORS: The strings are standard measurement units
+#. of temperature in Celcius and are shown in the settings page.
+#. Only the abbreviated form of Celcius should be used.
+#: ../app/ui/settings/UnitsPage.qml:41 ../app/ui/settings/UnitsPage.qml:76
+msgid "°C"
+msgstr "°C"
+
+#. TRANSLATORS: The strings are standard measurement units
+#. of temperature in Fahrenheit and are shown in the settings page.
+#. Only the abbreviated form of Fahrenheit should be used.
+#: ../app/ui/settings/UnitsPage.qml:46 ../app/ui/settings/UnitsPage.qml:77
+msgid "°F"
+msgstr "°F"
+
+#. TRANSLATORS: The strings are standard measurement units
+#. of wind speed in kilometers per hour and are shown in the settings page.
+#. Only the abbreviated form of kilometers per hour should be used.
+#: ../app/ui/settings/UnitsPage.qml:57 ../app/ui/settings/UnitsPage.qml:96
+msgid "kph"
+msgstr "kilométer/óra"
+
+#. TRANSLATORS: The strings are standard measurement units
+#. of wind speed in miles per hour and are shown in the settings page.
+#. Only the abbreviated form of miles per hour should be used.
+#: ../app/ui/settings/UnitsPage.qml:62 ../app/ui/settings/UnitsPage.qml:97
+msgid "mph"
+msgstr "mérföld/óra"
+
+#: ../app/ui/settings/UnitsPage.qml:75
+msgid "Temperature"
+msgstr "Hőmérséklet"
+
+#: ../app/ui/settings/UnitsPage.qml:95
+msgid "Wind Speed"
+msgstr "Szélsebesség"
+
+#: ubuntu-weather-app.desktop.in.in.h:1
+msgid "Weather"
+msgstr "Időjárás"
+
+#: ubuntu-weather-app.desktop.in.in.h:2
+msgid ""
+"A weather forecast application for Ubuntu with support for multiple online "
+"weather data sources"
+msgstr ""
+"Időjárás-előrejelzés alkalmazás Ubuntuhoz, mely több forrásból gyűjt adatokat"
+
+#: ubuntu-weather-app.desktop.in.in.h:3
+msgid "weather;forecast;twc;openweathermap;the weather channel;"
+msgstr "időjárás;előrejelzés;twc;openweathermap;the weather channel;"

=== added file 'po/pl.po'
--- po/pl.po	1970-01-01 00:00:00 +0000
+++ po/pl.po	2015-08-05 19:54:56 +0000
@@ -0,0 +1,216 @@
+# Polish translation for ubuntu-weather-app
+# Copyright (c) 2015 Rosetta Contributors and Canonical Ltd 2015
+# This file is distributed under the same license as the ubuntu-weather-app package.
+# FIRST AUTHOR <EMAIL@ADDRESS>, 2015.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: ubuntu-weather-app\n"
+"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
+"POT-Creation-Date: 2015-07-29 21:25+0100\n"
+"PO-Revision-Date: 2015-07-27 17:55+0000\n"
+"Last-Translator: Bartosz Kosiorek <Unknown>\n"
+"Language-Team: Polish <pl@xxxxxx>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=3; plural=n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 "
+"|| n%100>=20) ? 1 : 2;\n"
+"X-Launchpad-Export-Date: 2015-07-31 05:44+0000\n"
+"X-Generator: Launchpad (build 17656)\n"
+
+#: ../app/components/DayDelegate.qml:199
+msgid "Chance of rain"
+msgstr "Możliwy deszcz"
+
+#: ../app/components/DayDelegate.qml:205
+msgid "Winds"
+msgstr "Wiatr"
+
+#: ../app/components/DayDelegate.qml:212
+msgid "UV Index"
+msgstr "Index UV"
+
+#: ../app/components/DayDelegate.qml:217
+msgid "Pollen"
+msgstr "Pylenie"
+
+#: ../app/components/DayDelegate.qml:223
+msgid "Humidity"
+msgstr "Wilgotność"
+
+#: ../app/components/DayDelegate.qml:229
+msgid "Sunrise"
+msgstr "Wschód słońca"
+
+#: ../app/components/DayDelegate.qml:235
+msgid "Sunset"
+msgstr "Zachód słońca"
+
+#: ../app/components/EmptyStateComponent.qml:51
+msgid "Searching for current location..."
+msgstr "Wyszukiwanie bieżącego położenia..."
+
+#: ../app/components/EmptyStateComponent.qml:52
+msgid "Cannot determine your location"
+msgstr ""
+
+#: ../app/components/EmptyStateComponent.qml:62
+msgid "Manually add a location by swiping up from the bottom of the display"
+msgstr ""
+
+#: ../app/components/HomeTempInfo.qml:38
+msgid "Today"
+msgstr "Dzisiaj"
+
+#: ../app/components/ListItemActions/Remove.qml:26
+msgid "Remove"
+msgstr "Usuń"
+
+#: ../app/components/MultiSelectHeadState.qml:27
+msgid "Select All"
+msgstr "Zaznacz wszystko"
+
+#: ../app/components/MultiSelectHeadState.qml:39
+msgid "Delete"
+msgstr "Usuń"
+
+#: ../app/components/MultiSelectHeadState.qml:51
+msgid "Cancel selection"
+msgstr "Anuluj zaznaczenie"
+
+#: ../app/ui/AddLocationPage.qml:29
+msgid "Select a city"
+msgstr "Wybierz miasto"
+
+#: ../app/ui/AddLocationPage.qml:45 ../app/ui/AddLocationPage.qml:66
+msgid "Back"
+msgstr "Wstecz"
+
+#: ../app/ui/AddLocationPage.qml:51
+msgid "City"
+msgstr "Miasto"
+
+#: ../app/ui/AddLocationPage.qml:93
+msgid "Search city"
+msgstr "Wyszukaj miasto"
+
+#: ../app/ui/AddLocationPage.qml:278
+msgid "No city found"
+msgstr "Nie znaleziono miasta"
+
+#: ../app/ui/AddLocationPage.qml:291
+msgid "Couldn't load weather data, please try later again!"
+msgstr "Nie udało się załadować danych pogodowych. Spróbuj ponownie później."
+
+#: ../app/ui/AddLocationPage.qml:301
+msgid "Location already added."
+msgstr "Lokalizacja została już dodana."
+
+#: ../app/ui/AddLocationPage.qml:304
+msgid "OK"
+msgstr "OK"
+
+#: ../app/ui/HomePage.qml:31 ../app/ui/LocationsPage.qml:30
+msgid "Locations"
+msgstr "Położenia"
+
+#: ../app/ui/LocationsPage.qml:104
+msgid "Current Location"
+msgstr "Obecne położenie"
+
+#: ../app/ui/SettingsPage.qml:24
+msgid "Settings"
+msgstr "Ustawienia"
+
+#: ../app/ui/SettingsPage.qml:32 ../app/ui/settings/UnitsPage.qml:24
+msgid "Units"
+msgstr "Jednostki"
+
+#: ../app/ui/SettingsPage.qml:37 ../app/ui/settings/DataProviderPage.qml:25
+msgid "Data Provider"
+msgstr "Dostawca danych"
+
+#: ../app/ui/SettingsPage.qml:42 ../app/ui/settings/RefreshIntervalPage.qml:24
+msgid "Refresh Interval"
+msgstr "Częstość odświeżania"
+
+#: ../app/ui/SettingsPage.qml:47 ../app/ui/settings/LocationPage.qml:24
+msgid "Location"
+msgstr "Położenie"
+
+#: ../app/ui/settings/DataProviderPage.qml:37
+msgid "Provider"
+msgstr "Dostawca"
+
+#: ../app/ui/settings/LocationPage.qml:32
+msgid "Detect current location"
+msgstr "Wykryj bieżące położenie"
+
+#: ../app/ui/settings/RefreshIntervalPage.qml:30
+#: ../app/ui/settings/RefreshIntervalPage.qml:31
+#: ../app/ui/settings/RefreshIntervalPage.qml:32
+#: ../app/ui/settings/RefreshIntervalPage.qml:33
+#: ../app/ui/settings/RefreshIntervalPage.qml:43
+#, qt-format
+msgid "%1 minute"
+msgid_plural "%1 minutes"
+msgstr[0] "%1 minuta"
+msgstr[1] "%1 minuty"
+msgstr[2] "%1 minut"
+
+#: ../app/ui/settings/RefreshIntervalPage.qml:42
+msgid "Interval"
+msgstr "Okres"
+
+#. TRANSLATORS: The strings are standard measurement units
+#. of temperature in Celcius and are shown in the settings page.
+#. Only the abbreviated form of Celcius should be used.
+#: ../app/ui/settings/UnitsPage.qml:41 ../app/ui/settings/UnitsPage.qml:76
+msgid "°C"
+msgstr "°C"
+
+#. TRANSLATORS: The strings are standard measurement units
+#. of temperature in Fahrenheit and are shown in the settings page.
+#. Only the abbreviated form of Fahrenheit should be used.
+#: ../app/ui/settings/UnitsPage.qml:46 ../app/ui/settings/UnitsPage.qml:77
+msgid "°F"
+msgstr "°F"
+
+#. TRANSLATORS: The strings are standard measurement units
+#. of wind speed in kilometers per hour and are shown in the settings page.
+#. Only the abbreviated form of kilometers per hour should be used.
+#: ../app/ui/settings/UnitsPage.qml:57 ../app/ui/settings/UnitsPage.qml:96
+msgid "kph"
+msgstr "km/h"
+
+#. TRANSLATORS: The strings are standard measurement units
+#. of wind speed in miles per hour and are shown in the settings page.
+#. Only the abbreviated form of miles per hour should be used.
+#: ../app/ui/settings/UnitsPage.qml:62 ../app/ui/settings/UnitsPage.qml:97
+msgid "mph"
+msgstr "mile/h"
+
+#: ../app/ui/settings/UnitsPage.qml:75
+msgid "Temperature"
+msgstr "Temperatura"
+
+#: ../app/ui/settings/UnitsPage.qml:95
+msgid "Wind Speed"
+msgstr "Prędkość wiatru"
+
+#: ubuntu-weather-app.desktop.in.in.h:1
+msgid "Weather"
+msgstr "Pogoda"
+
+#: ubuntu-weather-app.desktop.in.in.h:2
+msgid ""
+"A weather forecast application for Ubuntu with support for multiple online "
+"weather data sources"
+msgstr ""
+"Aplikacja prognozy pogody dla Ubuntu z obsługą wielu internetowych danych "
+"pogodowych"
+
+#: ubuntu-weather-app.desktop.in.in.h:3
+msgid "weather;forecast;twc;openweathermap;the weather channel;"
+msgstr "pogoda;prognoza;twc;openweathermap;kanał z prognozą pogody;"

=== added file 'po/pt.po'
--- po/pt.po	1970-01-01 00:00:00 +0000
+++ po/pt.po	2015-08-05 19:54:56 +0000
@@ -0,0 +1,213 @@
+# Portuguese translation for ubuntu-weather-app
+# Copyright (c) 2015 Rosetta Contributors and Canonical Ltd 2015
+# This file is distributed under the same license as the ubuntu-weather-app package.
+# FIRST AUTHOR <EMAIL@ADDRESS>, 2015.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: ubuntu-weather-app\n"
+"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
+"POT-Creation-Date: 2015-07-29 21:25+0100\n"
+"PO-Revision-Date: 2015-07-28 17:38+0000\n"
+"Last-Translator: Ivo Xavier <ivofernandes12@xxxxxxxxx>\n"
+"Language-Team: Portuguese <pt@xxxxxx>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=n != 1;\n"
+"X-Launchpad-Export-Date: 2015-07-31 05:44+0000\n"
+"X-Generator: Launchpad (build 17656)\n"
+
+#: ../app/components/DayDelegate.qml:199
+msgid "Chance of rain"
+msgstr "Possibilidade de chuva"
+
+#: ../app/components/DayDelegate.qml:205
+msgid "Winds"
+msgstr "Ventos"
+
+#: ../app/components/DayDelegate.qml:212
+msgid "UV Index"
+msgstr "índice UV"
+
+#: ../app/components/DayDelegate.qml:217
+msgid "Pollen"
+msgstr "Pólen"
+
+#: ../app/components/DayDelegate.qml:223
+msgid "Humidity"
+msgstr "Umidade"
+
+#: ../app/components/DayDelegate.qml:229
+msgid "Sunrise"
+msgstr "Amanhecer"
+
+#: ../app/components/DayDelegate.qml:235
+msgid "Sunset"
+msgstr "Pôr do sol"
+
+#: ../app/components/EmptyStateComponent.qml:51
+msgid "Searching for current location..."
+msgstr "A procurar localização atual..."
+
+#: ../app/components/EmptyStateComponent.qml:52
+msgid "Cannot determine your location"
+msgstr ""
+
+#: ../app/components/EmptyStateComponent.qml:62
+msgid "Manually add a location by swiping up from the bottom of the display"
+msgstr ""
+
+#: ../app/components/HomeTempInfo.qml:38
+msgid "Today"
+msgstr "Hoje"
+
+#: ../app/components/ListItemActions/Remove.qml:26
+msgid "Remove"
+msgstr "Remover"
+
+#: ../app/components/MultiSelectHeadState.qml:27
+msgid "Select All"
+msgstr "Selecionar todas"
+
+#: ../app/components/MultiSelectHeadState.qml:39
+msgid "Delete"
+msgstr "Eliminar"
+
+#: ../app/components/MultiSelectHeadState.qml:51
+msgid "Cancel selection"
+msgstr "Cancelar seleção"
+
+#: ../app/ui/AddLocationPage.qml:29
+msgid "Select a city"
+msgstr "Selecione uma cidade"
+
+#: ../app/ui/AddLocationPage.qml:45 ../app/ui/AddLocationPage.qml:66
+msgid "Back"
+msgstr "Anterior"
+
+#: ../app/ui/AddLocationPage.qml:51
+msgid "City"
+msgstr "Cidade"
+
+#: ../app/ui/AddLocationPage.qml:93
+msgid "Search city"
+msgstr "Procurar cidade"
+
+#: ../app/ui/AddLocationPage.qml:278
+msgid "No city found"
+msgstr "Sem cidade encontrada"
+
+#: ../app/ui/AddLocationPage.qml:291
+msgid "Couldn't load weather data, please try later again!"
+msgstr "Informação do tempo não carregada, por favor tente mais tarde!"
+
+#: ../app/ui/AddLocationPage.qml:301
+msgid "Location already added."
+msgstr "Localização já adicionada."
+
+#: ../app/ui/AddLocationPage.qml:304
+msgid "OK"
+msgstr "OK"
+
+#: ../app/ui/HomePage.qml:31 ../app/ui/LocationsPage.qml:30
+msgid "Locations"
+msgstr "Locais"
+
+#: ../app/ui/LocationsPage.qml:104
+msgid "Current Location"
+msgstr "Localização atual"
+
+#: ../app/ui/SettingsPage.qml:24
+msgid "Settings"
+msgstr "Definições"
+
+#: ../app/ui/SettingsPage.qml:32 ../app/ui/settings/UnitsPage.qml:24
+msgid "Units"
+msgstr "Unidades"
+
+#: ../app/ui/SettingsPage.qml:37 ../app/ui/settings/DataProviderPage.qml:25
+msgid "Data Provider"
+msgstr "Fornecedor de dados"
+
+#: ../app/ui/SettingsPage.qml:42 ../app/ui/settings/RefreshIntervalPage.qml:24
+msgid "Refresh Interval"
+msgstr "Intervalo de atualização"
+
+#: ../app/ui/SettingsPage.qml:47 ../app/ui/settings/LocationPage.qml:24
+msgid "Location"
+msgstr "Localização"
+
+#: ../app/ui/settings/DataProviderPage.qml:37
+msgid "Provider"
+msgstr "Fornecedor"
+
+#: ../app/ui/settings/LocationPage.qml:32
+msgid "Detect current location"
+msgstr "Detetar localização atual"
+
+#: ../app/ui/settings/RefreshIntervalPage.qml:30
+#: ../app/ui/settings/RefreshIntervalPage.qml:31
+#: ../app/ui/settings/RefreshIntervalPage.qml:32
+#: ../app/ui/settings/RefreshIntervalPage.qml:33
+#: ../app/ui/settings/RefreshIntervalPage.qml:43
+#, qt-format
+msgid "%1 minute"
+msgid_plural "%1 minutes"
+msgstr[0] "%1 minuto"
+msgstr[1] "%1 minutos"
+
+#: ../app/ui/settings/RefreshIntervalPage.qml:42
+msgid "Interval"
+msgstr "Intervalo"
+
+#. TRANSLATORS: The strings are standard measurement units
+#. of temperature in Celcius and are shown in the settings page.
+#. Only the abbreviated form of Celcius should be used.
+#: ../app/ui/settings/UnitsPage.qml:41 ../app/ui/settings/UnitsPage.qml:76
+msgid "°C"
+msgstr "°C"
+
+#. TRANSLATORS: The strings are standard measurement units
+#. of temperature in Fahrenheit and are shown in the settings page.
+#. Only the abbreviated form of Fahrenheit should be used.
+#: ../app/ui/settings/UnitsPage.qml:46 ../app/ui/settings/UnitsPage.qml:77
+msgid "°F"
+msgstr "°F"
+
+#. TRANSLATORS: The strings are standard measurement units
+#. of wind speed in kilometers per hour and are shown in the settings page.
+#. Only the abbreviated form of kilometers per hour should be used.
+#: ../app/ui/settings/UnitsPage.qml:57 ../app/ui/settings/UnitsPage.qml:96
+msgid "kph"
+msgstr "kph"
+
+#. TRANSLATORS: The strings are standard measurement units
+#. of wind speed in miles per hour and are shown in the settings page.
+#. Only the abbreviated form of miles per hour should be used.
+#: ../app/ui/settings/UnitsPage.qml:62 ../app/ui/settings/UnitsPage.qml:97
+msgid "mph"
+msgstr "mph"
+
+#: ../app/ui/settings/UnitsPage.qml:75
+msgid "Temperature"
+msgstr "Temperatura"
+
+#: ../app/ui/settings/UnitsPage.qml:95
+msgid "Wind Speed"
+msgstr "Velocidade do vento"
+
+#: ubuntu-weather-app.desktop.in.in.h:1
+msgid "Weather"
+msgstr "Meteorologia"
+
+#: ubuntu-weather-app.desktop.in.in.h:2
+msgid ""
+"A weather forecast application for Ubuntu with support for multiple online "
+"weather data sources"
+msgstr ""
+"Uma app de meteorologia para o Ubuntu com suporte múltiplo a fontes online"
+
+#: ubuntu-weather-app.desktop.in.in.h:3
+msgid "weather;forecast;twc;openweathermap;the weather channel;"
+msgstr "meteorologia;previsão;twc;openweathermap;o canal do tempo;"

=== added file 'po/ru.po'
--- po/ru.po	1970-01-01 00:00:00 +0000
+++ po/ru.po	2015-08-05 19:54:56 +0000
@@ -0,0 +1,213 @@
+# Russian translation for ubuntu-weather-app
+# Copyright (c) 2015 Rosetta Contributors and Canonical Ltd 2015
+# This file is distributed under the same license as the ubuntu-weather-app package.
+# FIRST AUTHOR <EMAIL@ADDRESS>, 2015.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: ubuntu-weather-app\n"
+"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
+"POT-Creation-Date: 2015-07-29 21:25+0100\n"
+"PO-Revision-Date: 2015-07-25 18:35+0000\n"
+"Last-Translator: Bartosz Kosiorek <Unknown>\n"
+"Language-Team: Russian <ru@xxxxxx>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && "
+"n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n"
+"X-Launchpad-Export-Date: 2015-07-31 05:44+0000\n"
+"X-Generator: Launchpad (build 17656)\n"
+
+#: ../app/components/DayDelegate.qml:199
+msgid "Chance of rain"
+msgstr ""
+
+#: ../app/components/DayDelegate.qml:205
+msgid "Winds"
+msgstr ""
+
+#: ../app/components/DayDelegate.qml:212
+msgid "UV Index"
+msgstr ""
+
+#: ../app/components/DayDelegate.qml:217
+msgid "Pollen"
+msgstr ""
+
+#: ../app/components/DayDelegate.qml:223
+msgid "Humidity"
+msgstr ""
+
+#: ../app/components/DayDelegate.qml:229
+msgid "Sunrise"
+msgstr "Восход"
+
+#: ../app/components/DayDelegate.qml:235
+msgid "Sunset"
+msgstr "Заход"
+
+#: ../app/components/EmptyStateComponent.qml:51
+msgid "Searching for current location..."
+msgstr ""
+
+#: ../app/components/EmptyStateComponent.qml:52
+msgid "Cannot determine your location"
+msgstr ""
+
+#: ../app/components/EmptyStateComponent.qml:62
+msgid "Manually add a location by swiping up from the bottom of the display"
+msgstr ""
+
+#: ../app/components/HomeTempInfo.qml:38
+msgid "Today"
+msgstr ""
+
+#: ../app/components/ListItemActions/Remove.qml:26
+msgid "Remove"
+msgstr ""
+
+#: ../app/components/MultiSelectHeadState.qml:27
+msgid "Select All"
+msgstr ""
+
+#: ../app/components/MultiSelectHeadState.qml:39
+msgid "Delete"
+msgstr ""
+
+#: ../app/components/MultiSelectHeadState.qml:51
+msgid "Cancel selection"
+msgstr ""
+
+#: ../app/ui/AddLocationPage.qml:29
+msgid "Select a city"
+msgstr ""
+
+#: ../app/ui/AddLocationPage.qml:45 ../app/ui/AddLocationPage.qml:66
+msgid "Back"
+msgstr ""
+
+#: ../app/ui/AddLocationPage.qml:51
+msgid "City"
+msgstr ""
+
+#: ../app/ui/AddLocationPage.qml:93
+msgid "Search city"
+msgstr ""
+
+#: ../app/ui/AddLocationPage.qml:278
+msgid "No city found"
+msgstr ""
+
+#: ../app/ui/AddLocationPage.qml:291
+msgid "Couldn't load weather data, please try later again!"
+msgstr ""
+
+#: ../app/ui/AddLocationPage.qml:301
+msgid "Location already added."
+msgstr ""
+
+#: ../app/ui/AddLocationPage.qml:304
+msgid "OK"
+msgstr ""
+
+#: ../app/ui/HomePage.qml:31 ../app/ui/LocationsPage.qml:30
+msgid "Locations"
+msgstr ""
+
+#: ../app/ui/LocationsPage.qml:104
+msgid "Current Location"
+msgstr ""
+
+#: ../app/ui/SettingsPage.qml:24
+msgid "Settings"
+msgstr ""
+
+#: ../app/ui/SettingsPage.qml:32 ../app/ui/settings/UnitsPage.qml:24
+msgid "Units"
+msgstr ""
+
+#: ../app/ui/SettingsPage.qml:37 ../app/ui/settings/DataProviderPage.qml:25
+msgid "Data Provider"
+msgstr ""
+
+#: ../app/ui/SettingsPage.qml:42 ../app/ui/settings/RefreshIntervalPage.qml:24
+msgid "Refresh Interval"
+msgstr ""
+
+#: ../app/ui/SettingsPage.qml:47 ../app/ui/settings/LocationPage.qml:24
+msgid "Location"
+msgstr ""
+
+#: ../app/ui/settings/DataProviderPage.qml:37
+msgid "Provider"
+msgstr ""
+
+#: ../app/ui/settings/LocationPage.qml:32
+msgid "Detect current location"
+msgstr ""
+
+#: ../app/ui/settings/RefreshIntervalPage.qml:30
+#: ../app/ui/settings/RefreshIntervalPage.qml:31
+#: ../app/ui/settings/RefreshIntervalPage.qml:32
+#: ../app/ui/settings/RefreshIntervalPage.qml:33
+#: ../app/ui/settings/RefreshIntervalPage.qml:43
+#, qt-format
+msgid "%1 minute"
+msgid_plural "%1 minutes"
+msgstr[0] ""
+msgstr[1] ""
+
+#: ../app/ui/settings/RefreshIntervalPage.qml:42
+msgid "Interval"
+msgstr ""
+
+#. TRANSLATORS: The strings are standard measurement units
+#. of temperature in Celcius and are shown in the settings page.
+#. Only the abbreviated form of Celcius should be used.
+#: ../app/ui/settings/UnitsPage.qml:41 ../app/ui/settings/UnitsPage.qml:76
+msgid "°C"
+msgstr ""
+
+#. TRANSLATORS: The strings are standard measurement units
+#. of temperature in Fahrenheit and are shown in the settings page.
+#. Only the abbreviated form of Fahrenheit should be used.
+#: ../app/ui/settings/UnitsPage.qml:46 ../app/ui/settings/UnitsPage.qml:77
+msgid "°F"
+msgstr ""
+
+#. TRANSLATORS: The strings are standard measurement units
+#. of wind speed in kilometers per hour and are shown in the settings page.
+#. Only the abbreviated form of kilometers per hour should be used.
+#: ../app/ui/settings/UnitsPage.qml:57 ../app/ui/settings/UnitsPage.qml:96
+msgid "kph"
+msgstr ""
+
+#. TRANSLATORS: The strings are standard measurement units
+#. of wind speed in miles per hour and are shown in the settings page.
+#. Only the abbreviated form of miles per hour should be used.
+#: ../app/ui/settings/UnitsPage.qml:62 ../app/ui/settings/UnitsPage.qml:97
+msgid "mph"
+msgstr ""
+
+#: ../app/ui/settings/UnitsPage.qml:75
+msgid "Temperature"
+msgstr ""
+
+#: ../app/ui/settings/UnitsPage.qml:95
+msgid "Wind Speed"
+msgstr ""
+
+#: ubuntu-weather-app.desktop.in.in.h:1
+msgid "Weather"
+msgstr ""
+
+#: ubuntu-weather-app.desktop.in.in.h:2
+msgid ""
+"A weather forecast application for Ubuntu with support for multiple online "
+"weather data sources"
+msgstr ""
+
+#: ubuntu-weather-app.desktop.in.in.h:3
+msgid "weather;forecast;twc;openweathermap;the weather channel;"
+msgstr ""

=== added file 'po/sv.po'
--- po/sv.po	1970-01-01 00:00:00 +0000
+++ po/sv.po	2015-08-05 19:54:56 +0000
@@ -0,0 +1,212 @@
+# Swedish translation for ubuntu-weather-app
+# Copyright (c) 2015 Rosetta Contributors and Canonical Ltd 2015
+# This file is distributed under the same license as the ubuntu-weather-app package.
+# FIRST AUTHOR <EMAIL@ADDRESS>, 2015.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: ubuntu-weather-app\n"
+"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
+"POT-Creation-Date: 2015-07-29 21:25+0100\n"
+"PO-Revision-Date: 2015-07-29 11:31+0000\n"
+"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
+"Language-Team: Swedish <sv@xxxxxx>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=n != 1;\n"
+"X-Launchpad-Export-Date: 2015-07-31 05:44+0000\n"
+"X-Generator: Launchpad (build 17656)\n"
+
+#: ../app/components/DayDelegate.qml:199
+msgid "Chance of rain"
+msgstr ""
+
+#: ../app/components/DayDelegate.qml:205
+msgid "Winds"
+msgstr ""
+
+#: ../app/components/DayDelegate.qml:212
+msgid "UV Index"
+msgstr ""
+
+#: ../app/components/DayDelegate.qml:217
+msgid "Pollen"
+msgstr ""
+
+#: ../app/components/DayDelegate.qml:223
+msgid "Humidity"
+msgstr ""
+
+#: ../app/components/DayDelegate.qml:229
+msgid "Sunrise"
+msgstr ""
+
+#: ../app/components/DayDelegate.qml:235
+msgid "Sunset"
+msgstr ""
+
+#: ../app/components/EmptyStateComponent.qml:51
+msgid "Searching for current location..."
+msgstr ""
+
+#: ../app/components/EmptyStateComponent.qml:52
+msgid "Cannot determine your location"
+msgstr ""
+
+#: ../app/components/EmptyStateComponent.qml:62
+msgid "Manually add a location by swiping up from the bottom of the display"
+msgstr ""
+
+#: ../app/components/HomeTempInfo.qml:38
+msgid "Today"
+msgstr ""
+
+#: ../app/components/ListItemActions/Remove.qml:26
+msgid "Remove"
+msgstr ""
+
+#: ../app/components/MultiSelectHeadState.qml:27
+msgid "Select All"
+msgstr ""
+
+#: ../app/components/MultiSelectHeadState.qml:39
+msgid "Delete"
+msgstr ""
+
+#: ../app/components/MultiSelectHeadState.qml:51
+msgid "Cancel selection"
+msgstr ""
+
+#: ../app/ui/AddLocationPage.qml:29
+msgid "Select a city"
+msgstr ""
+
+#: ../app/ui/AddLocationPage.qml:45 ../app/ui/AddLocationPage.qml:66
+msgid "Back"
+msgstr ""
+
+#: ../app/ui/AddLocationPage.qml:51
+msgid "City"
+msgstr ""
+
+#: ../app/ui/AddLocationPage.qml:93
+msgid "Search city"
+msgstr ""
+
+#: ../app/ui/AddLocationPage.qml:278
+msgid "No city found"
+msgstr ""
+
+#: ../app/ui/AddLocationPage.qml:291
+msgid "Couldn't load weather data, please try later again!"
+msgstr ""
+
+#: ../app/ui/AddLocationPage.qml:301
+msgid "Location already added."
+msgstr ""
+
+#: ../app/ui/AddLocationPage.qml:304
+msgid "OK"
+msgstr ""
+
+#: ../app/ui/HomePage.qml:31 ../app/ui/LocationsPage.qml:30
+msgid "Locations"
+msgstr ""
+
+#: ../app/ui/LocationsPage.qml:104
+msgid "Current Location"
+msgstr ""
+
+#: ../app/ui/SettingsPage.qml:24
+msgid "Settings"
+msgstr ""
+
+#: ../app/ui/SettingsPage.qml:32 ../app/ui/settings/UnitsPage.qml:24
+msgid "Units"
+msgstr ""
+
+#: ../app/ui/SettingsPage.qml:37 ../app/ui/settings/DataProviderPage.qml:25
+msgid "Data Provider"
+msgstr ""
+
+#: ../app/ui/SettingsPage.qml:42 ../app/ui/settings/RefreshIntervalPage.qml:24
+msgid "Refresh Interval"
+msgstr ""
+
+#: ../app/ui/SettingsPage.qml:47 ../app/ui/settings/LocationPage.qml:24
+msgid "Location"
+msgstr ""
+
+#: ../app/ui/settings/DataProviderPage.qml:37
+msgid "Provider"
+msgstr ""
+
+#: ../app/ui/settings/LocationPage.qml:32
+msgid "Detect current location"
+msgstr ""
+
+#: ../app/ui/settings/RefreshIntervalPage.qml:30
+#: ../app/ui/settings/RefreshIntervalPage.qml:31
+#: ../app/ui/settings/RefreshIntervalPage.qml:32
+#: ../app/ui/settings/RefreshIntervalPage.qml:33
+#: ../app/ui/settings/RefreshIntervalPage.qml:43
+#, qt-format
+msgid "%1 minute"
+msgid_plural "%1 minutes"
+msgstr[0] ""
+msgstr[1] ""
+
+#: ../app/ui/settings/RefreshIntervalPage.qml:42
+msgid "Interval"
+msgstr ""
+
+#. TRANSLATORS: The strings are standard measurement units
+#. of temperature in Celcius and are shown in the settings page.
+#. Only the abbreviated form of Celcius should be used.
+#: ../app/ui/settings/UnitsPage.qml:41 ../app/ui/settings/UnitsPage.qml:76
+msgid "°C"
+msgstr ""
+
+#. TRANSLATORS: The strings are standard measurement units
+#. of temperature in Fahrenheit and are shown in the settings page.
+#. Only the abbreviated form of Fahrenheit should be used.
+#: ../app/ui/settings/UnitsPage.qml:46 ../app/ui/settings/UnitsPage.qml:77
+msgid "°F"
+msgstr ""
+
+#. TRANSLATORS: The strings are standard measurement units
+#. of wind speed in kilometers per hour and are shown in the settings page.
+#. Only the abbreviated form of kilometers per hour should be used.
+#: ../app/ui/settings/UnitsPage.qml:57 ../app/ui/settings/UnitsPage.qml:96
+msgid "kph"
+msgstr ""
+
+#. TRANSLATORS: The strings are standard measurement units
+#. of wind speed in miles per hour and are shown in the settings page.
+#. Only the abbreviated form of miles per hour should be used.
+#: ../app/ui/settings/UnitsPage.qml:62 ../app/ui/settings/UnitsPage.qml:97
+msgid "mph"
+msgstr ""
+
+#: ../app/ui/settings/UnitsPage.qml:75
+msgid "Temperature"
+msgstr ""
+
+#: ../app/ui/settings/UnitsPage.qml:95
+msgid "Wind Speed"
+msgstr ""
+
+#: ubuntu-weather-app.desktop.in.in.h:1
+msgid "Weather"
+msgstr ""
+
+#: ubuntu-weather-app.desktop.in.in.h:2
+msgid ""
+"A weather forecast application for Ubuntu with support for multiple online "
+"weather data sources"
+msgstr ""
+
+#: ubuntu-weather-app.desktop.in.in.h:3
+msgid "weather;forecast;twc;openweathermap;the weather channel;"
+msgstr ""

=== added file 'po/zh_TW.po'
--- po/zh_TW.po	1970-01-01 00:00:00 +0000
+++ po/zh_TW.po	2015-08-05 19:54:56 +0000
@@ -0,0 +1,212 @@
+# Chinese (Traditional) translation for ubuntu-weather-app
+# Copyright (c) 2015 Rosetta Contributors and Canonical Ltd 2015
+# This file is distributed under the same license as the ubuntu-weather-app package.
+# FIRST AUTHOR <EMAIL@ADDRESS>, 2015.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: ubuntu-weather-app\n"
+"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
+"POT-Creation-Date: 2015-07-29 21:25+0100\n"
+"PO-Revision-Date: 2015-07-30 02:49+0000\n"
+"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
+"Language-Team: Chinese (Traditional) <zh_TW@xxxxxx>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=1; plural=0;\n"
+"X-Launchpad-Export-Date: 2015-07-31 05:44+0000\n"
+"X-Generator: Launchpad (build 17656)\n"
+
+#: ../app/components/DayDelegate.qml:199
+msgid "Chance of rain"
+msgstr ""
+
+#: ../app/components/DayDelegate.qml:205
+msgid "Winds"
+msgstr ""
+
+#: ../app/components/DayDelegate.qml:212
+msgid "UV Index"
+msgstr ""
+
+#: ../app/components/DayDelegate.qml:217
+msgid "Pollen"
+msgstr ""
+
+#: ../app/components/DayDelegate.qml:223
+msgid "Humidity"
+msgstr ""
+
+#: ../app/components/DayDelegate.qml:229
+msgid "Sunrise"
+msgstr ""
+
+#: ../app/components/DayDelegate.qml:235
+msgid "Sunset"
+msgstr ""
+
+#: ../app/components/EmptyStateComponent.qml:51
+msgid "Searching for current location..."
+msgstr ""
+
+#: ../app/components/EmptyStateComponent.qml:52
+msgid "Cannot determine your location"
+msgstr ""
+
+#: ../app/components/EmptyStateComponent.qml:62
+msgid "Manually add a location by swiping up from the bottom of the display"
+msgstr ""
+
+#: ../app/components/HomeTempInfo.qml:38
+msgid "Today"
+msgstr ""
+
+#: ../app/components/ListItemActions/Remove.qml:26
+msgid "Remove"
+msgstr ""
+
+#: ../app/components/MultiSelectHeadState.qml:27
+msgid "Select All"
+msgstr ""
+
+#: ../app/components/MultiSelectHeadState.qml:39
+msgid "Delete"
+msgstr ""
+
+#: ../app/components/MultiSelectHeadState.qml:51
+msgid "Cancel selection"
+msgstr ""
+
+#: ../app/ui/AddLocationPage.qml:29
+msgid "Select a city"
+msgstr ""
+
+#: ../app/ui/AddLocationPage.qml:45 ../app/ui/AddLocationPage.qml:66
+msgid "Back"
+msgstr ""
+
+#: ../app/ui/AddLocationPage.qml:51
+msgid "City"
+msgstr ""
+
+#: ../app/ui/AddLocationPage.qml:93
+msgid "Search city"
+msgstr ""
+
+#: ../app/ui/AddLocationPage.qml:278
+msgid "No city found"
+msgstr ""
+
+#: ../app/ui/AddLocationPage.qml:291
+msgid "Couldn't load weather data, please try later again!"
+msgstr ""
+
+#: ../app/ui/AddLocationPage.qml:301
+msgid "Location already added."
+msgstr ""
+
+#: ../app/ui/AddLocationPage.qml:304
+msgid "OK"
+msgstr ""
+
+#: ../app/ui/HomePage.qml:31 ../app/ui/LocationsPage.qml:30
+msgid "Locations"
+msgstr ""
+
+#: ../app/ui/LocationsPage.qml:104
+msgid "Current Location"
+msgstr ""
+
+#: ../app/ui/SettingsPage.qml:24
+msgid "Settings"
+msgstr ""
+
+#: ../app/ui/SettingsPage.qml:32 ../app/ui/settings/UnitsPage.qml:24
+msgid "Units"
+msgstr ""
+
+#: ../app/ui/SettingsPage.qml:37 ../app/ui/settings/DataProviderPage.qml:25
+msgid "Data Provider"
+msgstr ""
+
+#: ../app/ui/SettingsPage.qml:42 ../app/ui/settings/RefreshIntervalPage.qml:24
+msgid "Refresh Interval"
+msgstr ""
+
+#: ../app/ui/SettingsPage.qml:47 ../app/ui/settings/LocationPage.qml:24
+msgid "Location"
+msgstr ""
+
+#: ../app/ui/settings/DataProviderPage.qml:37
+msgid "Provider"
+msgstr ""
+
+#: ../app/ui/settings/LocationPage.qml:32
+msgid "Detect current location"
+msgstr ""
+
+#: ../app/ui/settings/RefreshIntervalPage.qml:30
+#: ../app/ui/settings/RefreshIntervalPage.qml:31
+#: ../app/ui/settings/RefreshIntervalPage.qml:32
+#: ../app/ui/settings/RefreshIntervalPage.qml:33
+#: ../app/ui/settings/RefreshIntervalPage.qml:43
+#, qt-format
+msgid "%1 minute"
+msgid_plural "%1 minutes"
+msgstr[0] ""
+msgstr[1] ""
+
+#: ../app/ui/settings/RefreshIntervalPage.qml:42
+msgid "Interval"
+msgstr ""
+
+#. TRANSLATORS: The strings are standard measurement units
+#. of temperature in Celcius and are shown in the settings page.
+#. Only the abbreviated form of Celcius should be used.
+#: ../app/ui/settings/UnitsPage.qml:41 ../app/ui/settings/UnitsPage.qml:76
+msgid "°C"
+msgstr ""
+
+#. TRANSLATORS: The strings are standard measurement units
+#. of temperature in Fahrenheit and are shown in the settings page.
+#. Only the abbreviated form of Fahrenheit should be used.
+#: ../app/ui/settings/UnitsPage.qml:46 ../app/ui/settings/UnitsPage.qml:77
+msgid "°F"
+msgstr ""
+
+#. TRANSLATORS: The strings are standard measurement units
+#. of wind speed in kilometers per hour and are shown in the settings page.
+#. Only the abbreviated form of kilometers per hour should be used.
+#: ../app/ui/settings/UnitsPage.qml:57 ../app/ui/settings/UnitsPage.qml:96
+msgid "kph"
+msgstr ""
+
+#. TRANSLATORS: The strings are standard measurement units
+#. of wind speed in miles per hour and are shown in the settings page.
+#. Only the abbreviated form of miles per hour should be used.
+#: ../app/ui/settings/UnitsPage.qml:62 ../app/ui/settings/UnitsPage.qml:97
+msgid "mph"
+msgstr ""
+
+#: ../app/ui/settings/UnitsPage.qml:75
+msgid "Temperature"
+msgstr ""
+
+#: ../app/ui/settings/UnitsPage.qml:95
+msgid "Wind Speed"
+msgstr ""
+
+#: ubuntu-weather-app.desktop.in.in.h:1
+msgid "Weather"
+msgstr ""
+
+#: ubuntu-weather-app.desktop.in.in.h:2
+msgid ""
+"A weather forecast application for Ubuntu with support for multiple online "
+"weather data sources"
+msgstr ""
+
+#: ubuntu-weather-app.desktop.in.in.h:3
+msgid "weather;forecast;twc;openweathermap;the weather channel;"
+msgstr ""

=== added directory 'tests'
=== renamed directory 'tests' => 'tests.moved'
=== added file 'tests/CMakeLists.txt'
--- tests/CMakeLists.txt	1970-01-01 00:00:00 +0000
+++ tests/CMakeLists.txt	2015-08-05 19:54:56 +0000
@@ -0,0 +1,1 @@
+add_subdirectory(autopilot)

=== added directory 'tests/autopilot'
=== added file 'tests/autopilot/CMakeLists.txt'
--- tests/autopilot/CMakeLists.txt	1970-01-01 00:00:00 +0000
+++ tests/autopilot/CMakeLists.txt	2015-08-05 19:54:56 +0000
@@ -0,0 +1,10 @@
+if(INSTALL_TESTS)
+execute_process(COMMAND python3 -c "from distutils.sysconfig import get_python_lib; print(get_python_lib())"
+    OUTPUT_VARIABLE PYTHON_PACKAGE_DIR OUTPUT_STRIP_TRAILING_WHITESPACE)
+
+install(DIRECTORY ${AUTOPILOT_DIR}
+    DESTINATION ${PYTHON_PACKAGE_DIR}
+    )
+endif(INSTALL_TESTS)
+
+add_subdirectory(ubuntu_weather_app)

=== added directory 'tests/autopilot/ubuntu_weather_app'
=== added file 'tests/autopilot/ubuntu_weather_app/CMakeLists.txt'
--- tests/autopilot/ubuntu_weather_app/CMakeLists.txt	1970-01-01 00:00:00 +0000
+++ tests/autopilot/ubuntu_weather_app/CMakeLists.txt	2015-08-05 19:54:56 +0000
@@ -0,0 +1,10 @@
+add_subdirectory(databases)
+add_subdirectory(files)
+add_subdirectory(tests)
+
+# make the emulator files visible on qtcreator
+file(GLOB PYTHON_EMULATOR_FILES
+     RELATIVE ${CMAKE_CURRENT_SOURCE_DIR}
+     *.py)
+
+add_custom_target(ubuntu-weather-app_PYTHONEMULATORFiles ALL SOURCES ${PYTHON_EMULATOR_FILES})

=== added file 'tests/autopilot/ubuntu_weather_app/__init__.py'
--- tests/autopilot/ubuntu_weather_app/__init__.py	1970-01-01 00:00:00 +0000
+++ tests/autopilot/ubuntu_weather_app/__init__.py	2015-08-05 19:54:56 +0000
@@ -0,0 +1,113 @@
+# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*-
+# Copyright 2013, 2014, 2015 Canonical
+#
+# This program is free software: you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 3, as published
+# by the Free Software Foundation.
+
+"""ubuntu-weather-app tests and emulators - top level package."""
+from autopilot.introspection import dbus
+import logging
+from ubuntuuitoolkit import MainView, UbuntuUIToolkitCustomProxyObjectBase
+
+
+logger = logging.getLogger(__name__)
+
+
+class UbuntuWeatherAppException(Exception):
+    """Exception raised when there's an error in the Weather App."""
+
+
+def click_object(func):
+    """Wrapper which clicks the returned object"""
+    def func_wrapper(self, *args, **kwargs):
+        return self.pointing_device.click_object(func(self, *args, **kwargs))
+
+    return func_wrapper
+
+
+class UbuntuWeatherApp(object):
+    """Autopilot helper object for the Weather application."""
+
+    def __init__(self, app_proxy):
+        self.app = app_proxy
+
+        # FIXME: Select by objectName due to it being MainView12 not MainView
+        # pad.lv/1350532
+        self.main_view = self.app.wait_select_single(objectName="weather")
+
+    def get_add_location_page(self):
+        return self.main_view.wait_select_single(
+            AddLocationPage, objectName="addLocationPage")
+
+    def get_home_page(self):
+        return self.main_view.wait_select_single(
+            HomePage, objectName="homePage")
+
+    def get_locations_page(self):
+        return self.main_view.wait_select_single(
+            LocationsPage, objectName="locationsPage")
+
+
+class Page(UbuntuUIToolkitCustomProxyObjectBase):
+    """Autopilot helper for Pages."""
+    def __init__(self, *args):
+        super(Page, self).__init__(*args)
+
+
+class PageWithBottomEdge(Page):
+    """Autopilot helper for PageWithBottomEdge."""
+    def __init__(self, *args):
+        super(PageWithBottomEdge, self).__init__(*args)
+
+    def reveal_bottom_edge_page(self):
+        """Bring the bottom edge page to the screen"""
+
+        self.bottomEdgePageLoaded.wait_for(True)
+
+        try:
+            action_item = self.wait_select_single(objectName='bottomEdgeTip')
+            action_item.visible.wait_for(True)
+            start_x = (action_item.globalRect.x +
+                       (action_item.globalRect.width * 0.5))
+            start_y = (action_item.globalRect.y +
+                       (action_item.height * 0.5))
+            stop_y = start_y - (self.height * 0.7)
+
+            self.pointing_device.drag(start_x, start_y,
+                                      start_x, stop_y, rate=2)
+            self.isReady.wait_for(True)
+        except dbus.StateNotFoundError:
+            logger.error('BottomEdge element not found.')
+            raise
+
+
+class AddLocationPage(Page):
+    """Autopilot helper for AddLocationPage."""
+    def __init__(self, *args):
+        super(AddLocationPage, self).__init__(*args)
+
+
+class HomePage(PageWithBottomEdge):
+    """Autopilot helper for HomePage."""
+    def __init__(self, *args):
+        super(HomePage, self).__init__(*args)
+
+    def get_location_count(self):
+        return self.wait_select_single(
+            "QQuickListView", objectName="locationPages").count
+
+
+class LocationsPage(Page):
+    """Autopilot helper for LocationsPage."""
+    def __init__(self, *args, **kwargs):
+        super(LocationsPage, self).__init__(*args, **kwargs)
+
+
+class MainView(MainView):
+    """Autopilot custom proxy object for the MainView."""
+    retry_delay = 0.2
+
+    def __init__(self, *args):
+        super(MainView, self).__init__(*args)
+        self.visible.wait_for(True)

=== added directory 'tests/autopilot/ubuntu_weather_app/databases'
=== added file 'tests/autopilot/ubuntu_weather_app/databases/34e1e542f2f083ff18f537b07a380071.ini'
--- tests/autopilot/ubuntu_weather_app/databases/34e1e542f2f083ff18f537b07a380071.ini	1970-01-01 00:00:00 +0000
+++ tests/autopilot/ubuntu_weather_app/databases/34e1e542f2f083ff18f537b07a380071.ini	2015-08-05 19:54:56 +0000
@@ -0,0 +1,6 @@
+[General]
+Description=Default Ubuntu weather app
+Driver=QSQLITE
+EstimatedSize=100000
+Name=com.ubuntu.weather
+Version=0.3

=== added file 'tests/autopilot/ubuntu_weather_app/databases/34e1e542f2f083ff18f537b07a380071.sqlite'
Binary files tests/autopilot/ubuntu_weather_app/databases/34e1e542f2f083ff18f537b07a380071.sqlite	1970-01-01 00:00:00 +0000 and tests/autopilot/ubuntu_weather_app/databases/34e1e542f2f083ff18f537b07a380071.sqlite	2015-08-05 19:54:56 +0000 differ
=== added file 'tests/autopilot/ubuntu_weather_app/databases/CMakeLists.txt'
--- tests/autopilot/ubuntu_weather_app/databases/CMakeLists.txt	1970-01-01 00:00:00 +0000
+++ tests/autopilot/ubuntu_weather_app/databases/CMakeLists.txt	2015-08-05 19:54:56 +0000
@@ -0,0 +1,6 @@
+# make the database files visible on qtcreator
+file(GLOB PYTHON_TEST_DATABASE_FILES
+     RELATIVE ${CMAKE_CURRENT_SOURCE_DIR}
+     *.ini *.conf)
+
+add_custom_target(ubuntu-weather-app_PYTHONTestDatabaseFiles ALL SOURCES ${PYTHON_TEST_DATABASE_FILES})

=== added file 'tests/autopilot/ubuntu_weather_app/databases/location_added.conf'
--- tests/autopilot/ubuntu_weather_app/databases/location_added.conf	1970-01-01 00:00:00 +0000
+++ tests/autopilot/ubuntu_weather_app/databases/location_added.conf	2015-08-05 19:54:56 +0000
@@ -0,0 +1,3 @@
+[weatherSettings]
+detectCurrentLocation=false
+migrated=true

=== added directory 'tests/autopilot/ubuntu_weather_app/files'
=== added file 'tests/autopilot/ubuntu_weather_app/files/1.json'
--- tests/autopilot/ubuntu_weather_app/files/1.json	1970-01-01 00:00:00 +0000
+++ tests/autopilot/ubuntu_weather_app/files/1.json	2015-08-05 19:54:56 +0000
@@ -0,0 +1,1509 @@
+{
+   "db":{
+      "id":4,
+      "updated":"2015-07-18T17:07:53.668Z"
+   },
+   "format":20150404,
+   "location":{
+      "objectName":"",
+      "adminName1":"England",
+      "adminName2":"Greater London",
+      "adminName3":"",
+      "areaLabel":"England, Greater London, United Kingdom",
+      "coord":{
+         "lat":"51.50853",
+         "lon":"-0.12574"
+      },
+      "country":"GB",
+      "countryName":"United Kingdom",
+      "name":"London",
+      "population":7556900,
+      "services":{
+         "geonames":2643743,
+         "openweathermap":2643743
+      },
+      "timezone":{
+         "dstOffset":1,
+         "gmtOffset":0,
+         "timeZoneId":"Europe/London"
+      }
+   },
+   "data":[
+      {
+         "condition":"Clouds",
+         "date":{
+            "date":18,
+            "hours":11,
+            "minutes":59,
+            "month":6,
+            "year":2015
+         },
+         "hourly":[
+            {
+               "condition":"Clouds",
+               "date":{
+                  "date":18,
+                  "hours":18,
+                  "minutes":0,
+                  "month":6,
+                  "year":2015
+               },
+               "humidity":45,
+               "icon":"cloud",
+               "imperial":{
+                  "rain":0,
+                  "snow":0,
+                  "temp":71.006,
+                  "windSpeed":6.0704
+               },
+               "metric":{
+                  "rain":0,
+                  "snow":0,
+                  "temp":21.67,
+                  "windSpeed":9.756
+               },
+               "pressure":1020.88,
+               "timestamp":1437242400,
+               "windDeg":233.508,
+               "windDir":"SW"
+            },
+            {
+               "condition":"Clouds",
+               "date":{
+                  "date":18,
+                  "hours":21,
+                  "minutes":0,
+                  "month":6,
+                  "year":2015
+               },
+               "humidity":49,
+               "icon":"cloud",
+               "imperial":{
+                  "rain":0,
+                  "snow":0,
+                  "temp":65.84,
+                  "windSpeed":5.0624
+               },
+               "metric":{
+                  "rain":0,
+                  "snow":0,
+                  "temp":18.8,
+                  "windSpeed":8.136
+               },
+               "pressure":1020.14,
+               "timestamp":1437253200,
+               "windDeg":211.004,
+               "windDir":"SW"
+            }
+         ],
+         "humidity":63,
+         "icon":"cloud_sun",
+         "imperial":{
+            "rain":0,
+            "snow":0,
+            "tempMax":73.724,
+            "tempMin":61.7,
+            "windSpeed":12.4544
+         },
+         "metric":{
+            "rain":0,
+            "snow":0,
+            "tempMax":23.18,
+            "tempMin":16.5,
+            "windSpeed":20.016
+         },
+         "pressure":1022.45,
+         "timestamp":1437220800,
+         "windDeg":247,
+         "windDir":"W",
+         "current":{
+            "condition":"Clouds",
+            "date":{
+               "date":18,
+               "hours":11,
+               "minutes":59,
+               "month":6,
+               "year":2015
+            },
+            "humidity":31,
+            "icon":"cloud",
+            "imperial":{
+               "rain":0,
+               "snow":0,
+               "temp":73.112,
+               "windSpeed":8.064000000000002
+            },
+            "metric":{
+               "rain":0,
+               "snow":0,
+               "temp":22.84,
+               "windSpeed":12.96
+            },
+            "pressure":1015,
+            "timestamp":1437237984,
+            "windDeg":230,
+            "windDir":"SW",
+            "service":"openweathermap",
+            "service_id":2643743
+         }
+      },
+      {
+         "condition":"Rain",
+         "date":{
+            "date":19,
+            "hours":11,
+            "minutes":59,
+            "month":6,
+            "year":2015
+         },
+         "hourly":[
+            {
+               "condition":"Clouds",
+               "date":{
+                  "date":19,
+                  "hours":0,
+                  "minutes":0,
+                  "month":6,
+                  "year":2015
+               },
+               "humidity":53,
+               "icon":"cloud",
+               "imperial":{
+                  "rain":0,
+                  "snow":0,
+                  "temp":62.654,
+                  "windSpeed":4.412800000000001
+               },
+               "metric":{
+                  "rain":0,
+                  "snow":0,
+                  "temp":17.03,
+                  "windSpeed":7.092
+               },
+               "pressure":1019.63,
+               "timestamp":1437264000,
+               "windDeg":228.006,
+               "windDir":"SW"
+            },
+            {
+               "condition":"Clouds",
+               "date":{
+                  "date":19,
+                  "hours":3,
+                  "minutes":0,
+                  "month":6,
+                  "year":2015
+               },
+               "humidity":53,
+               "icon":"cloud",
+               "imperial":{
+                  "rain":0,
+                  "snow":0,
+                  "temp":60.385999999999996,
+                  "windSpeed":3.1584000000000003
+               },
+               "metric":{
+                  "rain":0,
+                  "snow":0,
+                  "temp":15.77,
+                  "windSpeed":5.076
+               },
+               "pressure":1016.87,
+               "timestamp":1437274800,
+               "windDeg":167.002,
+               "windDir":"S"
+            },
+            {
+               "condition":"Rain",
+               "date":{
+                  "date":19,
+                  "hours":6,
+                  "minutes":0,
+                  "month":6,
+                  "year":2015
+               },
+               "humidity":92,
+               "icon":"rain",
+               "imperial":{
+                  "rain":0.0860236220472441,
+                  "snow":0,
+                  "temp":53.294,
+                  "windSpeed":4.7264
+               },
+               "metric":{
+                  "rain":2.185,
+                  "snow":0,
+                  "temp":11.83,
+                  "windSpeed":7.596
+               },
+               "pressure":1016.41,
+               "timestamp":1437285600,
+               "windDeg":247.002,
+               "windDir":"W"
+            },
+            {
+               "condition":"Rain",
+               "date":{
+                  "date":19,
+                  "hours":9,
+                  "minutes":0,
+                  "month":6,
+                  "year":2015
+               },
+               "humidity":78,
+               "icon":"rain",
+               "imperial":{
+                  "rain":0.055314960629921264,
+                  "snow":0,
+                  "temp":59.414,
+                  "windSpeed":5.734400000000001
+               },
+               "metric":{
+                  "rain":1.405,
+                  "snow":0,
+                  "temp":15.23,
+                  "windSpeed":9.216000000000001
+               },
+               "pressure":1014.95,
+               "timestamp":1437296400,
+               "windDeg":226.5,
+               "windDir":"SW"
+            },
+            {
+               "condition":"Clouds",
+               "date":{
+                  "date":19,
+                  "hours":12,
+                  "minutes":0,
+                  "month":6,
+                  "year":2015
+               },
+               "humidity":66,
+               "icon":"cloud_sun",
+               "imperial":{
+                  "rain":0,
+                  "snow":0,
+                  "temp":67.154,
+                  "windSpeed":10.259200000000002
+               },
+               "metric":{
+                  "rain":0,
+                  "snow":0,
+                  "temp":19.53,
+                  "windSpeed":16.488
+               },
+               "pressure":1014.32,
+               "timestamp":1437307200,
+               "windDeg":247.005,
+               "windDir":"W"
+            },
+            {
+               "condition":"Rain",
+               "date":{
+                  "date":19,
+                  "hours":15,
+                  "minutes":0,
+                  "month":6,
+                  "year":2015
+               },
+               "humidity":59,
+               "icon":"rain",
+               "imperial":{
+                  "rain":0.00019685039370078743,
+                  "snow":0,
+                  "temp":68.45,
+                  "windSpeed":10.886400000000002
+               },
+               "metric":{
+                  "rain":0.005,
+                  "snow":0,
+                  "temp":20.25,
+                  "windSpeed":17.496000000000002
+               },
+               "pressure":1015.06,
+               "timestamp":1437318000,
+               "windDeg":263.001,
+               "windDir":"W"
+            },
+            {
+               "condition":"Clouds",
+               "date":{
+                  "date":19,
+                  "hours":18,
+                  "minutes":0,
+                  "month":6,
+                  "year":2015
+               },
+               "humidity":51,
+               "icon":"cloud_sun",
+               "imperial":{
+                  "rain":0,
+                  "snow":0,
+                  "temp":67.676,
+                  "windSpeed":7.772800000000001
+               },
+               "metric":{
+                  "rain":0,
+                  "snow":0,
+                  "temp":19.82,
+                  "windSpeed":12.492
+               },
+               "pressure":1015.53,
+               "timestamp":1437328800,
+               "windDeg":269.502,
+               "windDir":"W"
+            },
+            {
+               "condition":"Clear",
+               "date":{
+                  "date":19,
+                  "hours":21,
+                  "minutes":0,
+                  "month":6,
+                  "year":2015
+               },
+               "humidity":59,
+               "icon":"moon",
+               "imperial":{
+                  "rain":0,
+                  "snow":0,
+                  "temp":60.494,
+                  "windSpeed":4.9952000000000005
+               },
+               "metric":{
+                  "rain":0,
+                  "snow":0,
+                  "temp":15.83,
+                  "windSpeed":8.028
+               },
+               "pressure":1017.12,
+               "timestamp":1437339600,
+               "windDeg":255.003,
+               "windDir":"W"
+            }
+         ],
+         "humidity":81,
+         "icon":"rain",
+         "imperial":{
+            "rain":0.19173228346456694,
+            "snow":0,
+            "tempMax":67.37,
+            "tempMin":48.74,
+            "windSpeed":19.4432
+         },
+         "metric":{
+            "rain":4.87,
+            "snow":0,
+            "tempMax":19.65,
+            "tempMin":9.3,
+            "windSpeed":31.248
+         },
+         "pressure":1014.57,
+         "timestamp":1437307200,
+         "windDeg":251,
+         "windDir":"W"
+      },
+      {
+         "condition":"Rain",
+         "date":{
+            "date":20,
+            "hours":11,
+            "minutes":59,
+            "month":6,
+            "year":2015
+         },
+         "hourly":[
+            {
+               "condition":"Clear",
+               "date":{
+                  "date":20,
+                  "hours":0,
+                  "minutes":0,
+                  "month":6,
+                  "year":2015
+               },
+               "humidity":78,
+               "icon":"moon",
+               "imperial":{
+                  "rain":0,
+                  "snow":0,
+                  "temp":52.43,
+                  "windSpeed":2.576
+               },
+               "metric":{
+                  "rain":0,
+                  "snow":0,
+                  "temp":11.35,
+                  "windSpeed":4.14
+               },
+               "pressure":1017.21,
+               "timestamp":1437350400,
+               "windDeg":230.008,
+               "windDir":"SW"
+            },
+            {
+               "condition":"Clouds",
+               "date":{
+                  "date":20,
+                  "hours":3,
+                  "minutes":0,
+                  "month":6,
+                  "year":2015
+               },
+               "humidity":88,
+               "icon":"cloud_moon",
+               "imperial":{
+                  "rain":0,
+                  "snow":0,
+                  "temp":47.480000000000004,
+                  "windSpeed":2.3744000000000005
+               },
+               "metric":{
+                  "rain":0,
+                  "snow":0,
+                  "temp":8.6,
+                  "windSpeed":3.8160000000000003
+               },
+               "pressure":1016.59,
+               "timestamp":1437361200,
+               "windDeg":166.004,
+               "windDir":"S"
+            },
+            {
+               "condition":"Rain",
+               "date":{
+                  "date":20,
+                  "hours":6,
+                  "minutes":0,
+                  "month":6,
+                  "year":2015
+               },
+               "humidity":82,
+               "icon":"rain",
+               "imperial":{
+                  "rain":0.001377952755905512,
+                  "snow":0,
+                  "temp":53.69,
+                  "windSpeed":2.6208
+               },
+               "metric":{
+                  "rain":0.035,
+                  "snow":0,
+                  "temp":12.05,
+                  "windSpeed":4.212
+               },
+               "pressure":1016.62,
+               "timestamp":1437372000,
+               "windDeg":141.001,
+               "windDir":"SE"
+            },
+            {
+               "condition":"Rain",
+               "date":{
+                  "date":20,
+                  "hours":9,
+                  "minutes":0,
+                  "month":6,
+                  "year":2015
+               },
+               "humidity":83,
+               "icon":"rain",
+               "imperial":{
+                  "rain":0.010629921259842521,
+                  "snow":0,
+                  "temp":59.36,
+                  "windSpeed":3.4048000000000003
+               },
+               "metric":{
+                  "rain":0.27,
+                  "snow":0,
+                  "temp":15.2,
+                  "windSpeed":5.472
+               },
+               "pressure":1016.18,
+               "timestamp":1437382800,
+               "windDeg":135,
+               "windDir":"SE"
+            },
+            {
+               "condition":"Rain",
+               "date":{
+                  "date":20,
+                  "hours":12,
+                  "minutes":0,
+                  "month":6,
+                  "year":2015
+               },
+               "humidity":72,
+               "icon":"rain",
+               "imperial":{
+                  "rain":0.004330708661417323,
+                  "snow":0,
+                  "temp":66.956,
+                  "windSpeed":5.3984000000000005
+               },
+               "metric":{
+                  "rain":0.11,
+                  "snow":0,
+                  "temp":19.42,
+                  "windSpeed":8.676
+               },
+               "pressure":1015.33,
+               "timestamp":1437393600,
+               "windDeg":167.001,
+               "windDir":"S"
+            },
+            {
+               "condition":"Rain",
+               "date":{
+                  "date":20,
+                  "hours":15,
+                  "minutes":0,
+                  "month":6,
+                  "year":2015
+               },
+               "humidity":68,
+               "icon":"rain",
+               "imperial":{
+                  "rain":0.003149606299212599,
+                  "snow":0,
+                  "temp":72.968,
+                  "windSpeed":9.7664
+               },
+               "metric":{
+                  "rain":0.08,
+                  "snow":0,
+                  "temp":22.76,
+                  "windSpeed":15.696000000000002
+               },
+               "pressure":1014.09,
+               "timestamp":1437404400,
+               "windDeg":220.002,
+               "windDir":"SW"
+            },
+            {
+               "condition":"Rain",
+               "date":{
+                  "date":20,
+                  "hours":18,
+                  "minutes":0,
+                  "month":6,
+                  "year":2015
+               },
+               "humidity":83,
+               "icon":"rain",
+               "imperial":{
+                  "rain":0.03582677165354331,
+                  "snow":0,
+                  "temp":68.036,
+                  "windSpeed":12.118400000000001
+               },
+               "metric":{
+                  "rain":0.91,
+                  "snow":0,
+                  "temp":20.02,
+                  "windSpeed":19.476000000000003
+               },
+               "pressure":1013.88,
+               "timestamp":1437415200,
+               "windDeg":223.502,
+               "windDir":"SW"
+            },
+            {
+               "condition":"Rain",
+               "date":{
+                  "date":20,
+                  "hours":21,
+                  "minutes":0,
+                  "month":6,
+                  "year":2015
+               },
+               "humidity":83,
+               "icon":"rain",
+               "imperial":{
+                  "rain":0.005118110236220473,
+                  "snow":0,
+                  "temp":66.38,
+                  "windSpeed":10.9536
+               },
+               "metric":{
+                  "rain":0.13,
+                  "snow":0,
+                  "temp":19.1,
+                  "windSpeed":17.604
+               },
+               "pressure":1013.72,
+               "timestamp":1437426000,
+               "windDeg":224.006,
+               "windDir":"SW"
+            }
+         ],
+         "humidity":81,
+         "icon":"rain",
+         "imperial":{
+            "rain":0.030708661417322838,
+            "snow":0,
+            "tempMax":71.798,
+            "tempMin":52.519999999999996,
+            "windSpeed":10.2144
+         },
+         "metric":{
+            "rain":0.78,
+            "snow":0,
+            "tempMax":22.11,
+            "tempMin":11.4,
+            "windSpeed":16.416
+         },
+         "pressure":1016.62,
+         "timestamp":1437393600,
+         "windDeg":168,
+         "windDir":"S"
+      },
+      {
+         "condition":"Clouds",
+         "date":{
+            "date":21,
+            "hours":11,
+            "minutes":59,
+            "month":6,
+            "year":2015
+         },
+         "hourly":[
+            {
+               "condition":"Rain",
+               "date":{
+                  "date":21,
+                  "hours":0,
+                  "minutes":0,
+                  "month":6,
+                  "year":2015
+               },
+               "humidity":87,
+               "icon":"rain",
+               "imperial":{
+                  "rain":0.01653543307086614,
+                  "snow":0,
+                  "temp":64.274,
+                  "windSpeed":9.8336
+               },
+               "metric":{
+                  "rain":0.42,
+                  "snow":0,
+                  "temp":17.93,
+                  "windSpeed":15.803999999999998
+               },
+               "pressure":1014.36,
+               "timestamp":1437436800,
+               "windDeg":237.503,
+               "windDir":"SW"
+            },
+            {
+               "condition":"Clear",
+               "date":{
+                  "date":21,
+                  "hours":3,
+                  "minutes":0,
+                  "month":6,
+                  "year":2015
+               },
+               "humidity":82,
+               "icon":"cloud_moon",
+               "imperial":{
+                  "rain":0,
+                  "snow":0,
+                  "temp":59.684,
+                  "windSpeed":7.840000000000001
+               },
+               "metric":{
+                  "rain":0,
+                  "snow":0,
+                  "temp":15.38,
+                  "windSpeed":12.6
+               },
+               "pressure":1015,
+               "timestamp":1437447600,
+               "windDeg":249.502,
+               "windDir":"W"
+            },
+            {
+               "condition":"Clear",
+               "date":{
+                  "date":21,
+                  "hours":6,
+                  "minutes":0,
+                  "month":6,
+                  "year":2015
+               },
+               "humidity":81,
+               "icon":"sun",
+               "imperial":{
+                  "rain":0,
+                  "snow":0,
+                  "temp":58.838,
+                  "windSpeed":7.459200000000001
+               },
+               "metric":{
+                  "rain":0,
+                  "snow":0,
+                  "temp":14.91,
+                  "windSpeed":11.988000000000001
+               },
+               "pressure":1015.87,
+               "timestamp":1437458400,
+               "windDeg":245.502,
+               "windDir":"W"
+            },
+            {
+               "condition":"Clear",
+               "date":{
+                  "date":21,
+                  "hours":9,
+                  "minutes":0,
+                  "month":6,
+                  "year":2015
+               },
+               "humidity":72,
+               "icon":"sun",
+               "imperial":{
+                  "rain":0,
+                  "snow":0,
+                  "temp":64.544,
+                  "windSpeed":8.624
+               },
+               "metric":{
+                  "rain":0,
+                  "snow":0,
+                  "temp":18.08,
+                  "windSpeed":13.860000000000001
+               },
+               "pressure":1016.56,
+               "timestamp":1437469200,
+               "windDeg":234.001,
+               "windDir":"SW"
+            },
+            {
+               "condition":"Clear",
+               "date":{
+                  "date":21,
+                  "hours":12,
+                  "minutes":0,
+                  "month":6,
+                  "year":2015
+               },
+               "humidity":65,
+               "icon":"sun",
+               "imperial":{
+                  "rain":0,
+                  "snow":0,
+                  "temp":69.74600000000001,
+                  "windSpeed":10.4608
+               },
+               "metric":{
+                  "rain":0,
+                  "snow":0,
+                  "temp":20.97,
+                  "windSpeed":16.812
+               },
+               "pressure":1016.62,
+               "timestamp":1437480000,
+               "windDeg":228.508,
+               "windDir":"SW"
+            },
+            {
+               "condition":"Clear",
+               "date":{
+                  "date":21,
+                  "hours":15,
+                  "minutes":0,
+                  "month":6,
+                  "year":2015
+               },
+               "humidity":59,
+               "icon":"sun",
+               "imperial":{
+                  "rain":0,
+                  "snow":0,
+                  "temp":71.564,
+                  "windSpeed":11.6704
+               },
+               "metric":{
+                  "rain":0,
+                  "snow":0,
+                  "temp":21.98,
+                  "windSpeed":18.756
+               },
+               "pressure":1016.46,
+               "timestamp":1437490800,
+               "windDeg":235,
+               "windDir":"SW"
+            },
+            {
+               "condition":"Clouds",
+               "date":{
+                  "date":21,
+                  "hours":18,
+                  "minutes":0,
+                  "month":6,
+                  "year":2015
+               },
+               "humidity":58,
+               "icon":"cloud_sun",
+               "imperial":{
+                  "rain":0,
+                  "snow":0,
+                  "temp":69.29599999999999,
+                  "windSpeed":10.796800000000001
+               },
+               "metric":{
+                  "rain":0,
+                  "snow":0,
+                  "temp":20.72,
+                  "windSpeed":17.352
+               },
+               "pressure":1016.78,
+               "timestamp":1437501600,
+               "windDeg":244.003,
+               "windDir":"W"
+            },
+            {
+               "condition":"Clouds",
+               "date":{
+                  "date":21,
+                  "hours":21,
+                  "minutes":0,
+                  "month":6,
+                  "year":2015
+               },
+               "humidity":68,
+               "icon":"cloud",
+               "imperial":{
+                  "rain":0,
+                  "snow":0,
+                  "temp":65.156,
+                  "windSpeed":8.534400000000002
+               },
+               "metric":{
+                  "rain":0,
+                  "snow":0,
+                  "temp":18.42,
+                  "windSpeed":13.716000000000001
+               },
+               "pressure":1018.15,
+               "timestamp":1437512400,
+               "windDeg":249.501,
+               "windDir":"W"
+            }
+         ],
+         "humidity":73,
+         "icon":"cloud_sun",
+         "imperial":{
+            "rain":0,
+            "snow":0,
+            "tempMax":70.394,
+            "tempMin":57.938,
+            "windSpeed":18.412800000000004
+         },
+         "metric":{
+            "rain":0,
+            "snow":0,
+            "tempMax":21.33,
+            "tempMin":14.41,
+            "windSpeed":29.592000000000002
+         },
+         "pressure":1016.62,
+         "timestamp":1437480000,
+         "windDeg":233,
+         "windDir":"SW"
+      },
+      {
+         "condition":"Rain",
+         "date":{
+            "date":22,
+            "hours":11,
+            "minutes":59,
+            "month":6,
+            "year":2015
+         },
+         "hourly":[
+            {
+               "condition":"Clouds",
+               "date":{
+                  "date":22,
+                  "hours":0,
+                  "minutes":0,
+                  "month":6,
+                  "year":2015
+               },
+               "humidity":71,
+               "icon":"cloud",
+               "imperial":{
+                  "rain":0,
+                  "snow":0,
+                  "temp":62.654,
+                  "windSpeed":7.4144000000000005
+               },
+               "metric":{
+                  "rain":0,
+                  "snow":0,
+                  "temp":17.03,
+                  "windSpeed":11.916
+               },
+               "pressure":1019.51,
+               "timestamp":1437523200,
+               "windDeg":264.503,
+               "windDir":"W"
+            },
+            {
+               "condition":"Clouds",
+               "date":{
+                  "date":22,
+                  "hours":3,
+                  "minutes":0,
+                  "month":6,
+                  "year":2015
+               },
+               "humidity":78,
+               "icon":"cloud_moon",
+               "imperial":{
+                  "rain":0,
+                  "snow":0,
+                  "temp":57.956,
+                  "windSpeed":5.734400000000001
+               },
+               "metric":{
+                  "rain":0,
+                  "snow":0,
+                  "temp":14.42,
+                  "windSpeed":9.216000000000001
+               },
+               "pressure":1020.16,
+               "timestamp":1437534000,
+               "windDeg":265.502,
+               "windDir":"W"
+            },
+            {
+               "condition":"Rain",
+               "date":{
+                  "date":22,
+                  "hours":6,
+                  "minutes":0,
+                  "month":6,
+                  "year":2015
+               },
+               "humidity":79,
+               "icon":"rain",
+               "imperial":{
+                  "rain":0.00039370078740157485,
+                  "snow":0,
+                  "temp":58.964,
+                  "windSpeed":4.1664
+               },
+               "metric":{
+                  "rain":0.01,
+                  "snow":0,
+                  "temp":14.98,
+                  "windSpeed":6.696000000000001
+               },
+               "pressure":1020.7,
+               "timestamp":1437544800,
+               "windDeg":257.008,
+               "windDir":"W"
+            },
+            {
+               "condition":"Rain",
+               "date":{
+                  "date":22,
+                  "hours":9,
+                  "minutes":0,
+                  "month":6,
+                  "year":2015
+               },
+               "humidity":66,
+               "icon":"rain",
+               "imperial":{
+                  "rain":0.0007874015748031497,
+                  "snow":0,
+                  "temp":64.274,
+                  "windSpeed":3.9872000000000005
+               },
+               "metric":{
+                  "rain":0.02,
+                  "snow":0,
+                  "temp":17.93,
+                  "windSpeed":6.408
+               },
+               "pressure":1021.13,
+               "timestamp":1437555600,
+               "windDeg":247.5,
+               "windDir":"W"
+            },
+            {
+               "condition":"Clouds",
+               "date":{
+                  "date":22,
+                  "hours":12,
+                  "minutes":0,
+                  "month":6,
+                  "year":2015
+               },
+               "humidity":61,
+               "icon":"cloud_sun",
+               "imperial":{
+                  "rain":0,
+                  "snow":0,
+                  "temp":68.55799999999999,
+                  "windSpeed":5.510400000000001
+               },
+               "metric":{
+                  "rain":0,
+                  "snow":0,
+                  "temp":20.31,
+                  "windSpeed":8.856
+               },
+               "pressure":1020.74,
+               "timestamp":1437566400,
+               "windDeg":227.501,
+               "windDir":"SW"
+            },
+            {
+               "condition":"Clouds",
+               "date":{
+                  "date":22,
+                  "hours":15,
+                  "minutes":0,
+                  "month":6,
+                  "year":2015
+               },
+               "humidity":56,
+               "icon":"cloud_sun",
+               "imperial":{
+                  "rain":0,
+                  "snow":0,
+                  "temp":69.44,
+                  "windSpeed":7.750400000000001
+               },
+               "metric":{
+                  "rain":0,
+                  "snow":0,
+                  "temp":20.8,
+                  "windSpeed":12.456
+               },
+               "pressure":1019.48,
+               "timestamp":1437577200,
+               "windDeg":236.001,
+               "windDir":"SW"
+            },
+            {
+               "condition":"Clouds",
+               "date":{
+                  "date":22,
+                  "hours":18,
+                  "minutes":0,
+                  "month":6,
+                  "year":2015
+               },
+               "humidity":56,
+               "icon":"cloud",
+               "imperial":{
+                  "rain":0,
+                  "snow":0,
+                  "temp":67.19,
+                  "windSpeed":8.512
+               },
+               "metric":{
+                  "rain":0,
+                  "snow":0,
+                  "temp":19.55,
+                  "windSpeed":13.68
+               },
+               "pressure":1019.42,
+               "timestamp":1437588000,
+               "windDeg":258.502,
+               "windDir":"W"
+            },
+            {
+               "condition":"Rain",
+               "date":{
+                  "date":22,
+                  "hours":21,
+                  "minutes":0,
+                  "month":6,
+                  "year":2015
+               },
+               "humidity":64,
+               "icon":"rain",
+               "imperial":{
+                  "rain":0.0007874015748031497,
+                  "snow":0,
+                  "temp":63.35600000000001,
+                  "windSpeed":5.1968000000000005
+               },
+               "metric":{
+                  "rain":0.02,
+                  "snow":0,
+                  "temp":17.42,
+                  "windSpeed":8.352
+               },
+               "pressure":1020.07,
+               "timestamp":1437598800,
+               "windDeg":261.502,
+               "windDir":"W"
+            }
+         ],
+         "humidity":0,
+         "icon":"rain",
+         "imperial":{
+            "rain":0.07007874015748032,
+            "snow":0,
+            "tempMax":70.80799999999999,
+            "tempMin":58.135999999999996,
+            "windSpeed":8.736
+         },
+         "metric":{
+            "rain":1.78,
+            "snow":0,
+            "tempMax":21.56,
+            "tempMin":14.52,
+            "windSpeed":14.04
+         },
+         "pressure":1023.19,
+         "timestamp":1437566400,
+         "windDeg":219,
+         "windDir":"SW"
+      },
+      {
+         "condition":"Clear",
+         "date":{
+            "date":23,
+            "hours":11,
+            "minutes":59,
+            "month":6,
+            "year":2015
+         },
+         "hourly":[
+            {
+               "condition":"Rain",
+               "date":{
+                  "date":23,
+                  "hours":0,
+                  "minutes":0,
+                  "month":6,
+                  "year":2015
+               },
+               "humidity":74,
+               "icon":"rain",
+               "imperial":{
+                  "rain":0.003149606299212599,
+                  "snow":0,
+                  "temp":60.908,
+                  "windSpeed":3.2704000000000004
+               },
+               "metric":{
+                  "rain":0.08,
+                  "snow":0,
+                  "temp":16.06,
+                  "windSpeed":5.256
+               },
+               "pressure":1020.03,
+               "timestamp":1437609600,
+               "windDeg":253.504,
+               "windDir":"W"
+            },
+            {
+               "condition":"Rain",
+               "date":{
+                  "date":23,
+                  "hours":3,
+                  "minutes":0,
+                  "month":6,
+                  "year":2015
+               },
+               "humidity":83,
+               "icon":"rain",
+               "imperial":{
+                  "rain":0.005905511811023622,
+                  "snow":0,
+                  "temp":59.054,
+                  "windSpeed":3.4048000000000003
+               },
+               "metric":{
+                  "rain":0.15,
+                  "snow":0,
+                  "temp":15.03,
+                  "windSpeed":5.472
+               },
+               "pressure":1019.47,
+               "timestamp":1437620400,
+               "windDeg":251.501,
+               "windDir":"W"
+            },
+            {
+               "condition":"Rain",
+               "date":{
+                  "date":23,
+                  "hours":6,
+                  "minutes":0,
+                  "month":6,
+                  "year":2015
+               },
+               "humidity":88,
+               "icon":"rain",
+               "imperial":{
+                  "rain":0.006692913385826772,
+                  "snow":0,
+                  "temp":59.054,
+                  "windSpeed":3.4048000000000003
+               },
+               "metric":{
+                  "rain":0.17,
+                  "snow":0,
+                  "temp":15.03,
+                  "windSpeed":5.472
+               },
+               "pressure":1019.07,
+               "timestamp":1437631200,
+               "windDeg":165.001,
+               "windDir":"S"
+            },
+            {
+               "condition":"Rain",
+               "date":{
+                  "date":23,
+                  "hours":9,
+                  "minutes":0,
+                  "month":6,
+                  "year":2015
+               },
+               "humidity":77,
+               "icon":"rain",
+               "imperial":{
+                  "rain":0.0024606299212598425,
+                  "snow":0,
+                  "temp":63.212,
+                  "windSpeed":4.972800000000001
+               },
+               "metric":{
+                  "rain":0.0625,
+                  "snow":0,
+                  "temp":17.34,
+                  "windSpeed":7.992000000000001
+               },
+               "pressure":1018.4,
+               "timestamp":1437642000,
+               "windDeg":199.002,
+               "windDir":"S"
+            },
+            {
+               "condition":"Clouds",
+               "date":{
+                  "date":23,
+                  "hours":12,
+                  "minutes":0,
+                  "month":6,
+                  "year":2015
+               },
+               "humidity":64,
+               "icon":"cloud_sun",
+               "imperial":{
+                  "rain":0,
+                  "snow":0,
+                  "temp":68.27,
+                  "windSpeed":6.7424
+               },
+               "metric":{
+                  "rain":0,
+                  "snow":0,
+                  "temp":20.15,
+                  "windSpeed":10.836
+               },
+               "pressure":1017.1,
+               "timestamp":1437652800,
+               "windDeg":224.501,
+               "windDir":"SW"
+            },
+            {
+               "condition":"Rain",
+               "date":{
+                  "date":23,
+                  "hours":15,
+                  "minutes":0,
+                  "month":6,
+                  "year":2015
+               },
+               "humidity":62,
+               "icon":"rain",
+               "imperial":{
+                  "rain":0.0004921259842519686,
+                  "snow":0,
+                  "temp":67.55000000000001,
+                  "windSpeed":8.4224
+               },
+               "metric":{
+                  "rain":0.0125,
+                  "snow":0,
+                  "temp":19.75,
+                  "windSpeed":13.536
+               },
+               "pressure":1016.06,
+               "timestamp":1437663600,
+               "windDeg":231.501,
+               "windDir":"SW"
+            }
+         ],
+         "humidity":0,
+         "icon":"sun",
+         "imperial":{
+            "rain":0,
+            "snow":0,
+            "tempMax":73.328,
+            "tempMin":58.064,
+            "windSpeed":8.601600000000001
+         },
+         "metric":{
+            "rain":0,
+            "snow":0,
+            "tempMax":22.96,
+            "tempMin":14.48,
+            "windSpeed":13.824
+         },
+         "pressure":1023.52,
+         "timestamp":1437652800,
+         "windDeg":239,
+         "windDir":"SW"
+      },
+      {
+         "condition":"Rain",
+         "date":{
+            "date":24,
+            "hours":11,
+            "minutes":59,
+            "month":6,
+            "year":2015
+         },
+         "hourly":[
+
+         ],
+         "humidity":0,
+         "icon":"rain",
+         "imperial":{
+            "rain":0.01968503937007874,
+            "snow":0,
+            "tempMax":79.07,
+            "tempMin":63.068000000000005,
+            "windSpeed":12.1632
+         },
+         "metric":{
+            "rain":0.5,
+            "snow":0,
+            "tempMax":26.15,
+            "tempMin":17.26,
+            "windSpeed":19.548
+         },
+         "pressure":1017.03,
+         "timestamp":1437739200,
+         "windDeg":87,
+         "windDir":"E"
+      },
+      {
+         "condition":"Rain",
+         "date":{
+            "date":25,
+            "hours":11,
+            "minutes":59,
+            "month":6,
+            "year":2015
+         },
+         "hourly":[
+
+         ],
+         "humidity":0,
+         "icon":"rain",
+         "imperial":{
+            "rain":0.010629921259842521,
+            "snow":0,
+            "tempMax":74.084,
+            "tempMin":60.025999999999996,
+            "windSpeed":13.820800000000002
+         },
+         "metric":{
+            "rain":0.27,
+            "snow":0,
+            "tempMax":23.38,
+            "tempMin":15.57,
+            "windSpeed":22.212
+         },
+         "pressure":1015.03,
+         "timestamp":1437825600,
+         "windDeg":228,
+         "windDir":"SW"
+      },
+      {
+         "condition":"Clear",
+         "date":{
+            "date":26,
+            "hours":11,
+            "minutes":59,
+            "month":6,
+            "year":2015
+         },
+         "hourly":[
+
+         ],
+         "humidity":0,
+         "icon":"sun",
+         "imperial":{
+            "rain":0,
+            "snow":0,
+            "tempMax":70.16,
+            "tempMin":58.028000000000006,
+            "windSpeed":17.3824
+         },
+         "metric":{
+            "rain":0,
+            "snow":0,
+            "tempMax":21.2,
+            "tempMin":14.46,
+            "windSpeed":27.936
+         },
+         "pressure":1016.83,
+         "timestamp":1437912000,
+         "windDeg":226,
+         "windDir":"SW"
+      },
+      {
+         "condition":"Rain",
+         "date":{
+            "date":27,
+            "hours":11,
+            "minutes":59,
+            "month":6,
+            "year":2015
+         },
+         "hourly":[
+
+         ],
+         "humidity":0,
+         "icon":"rain",
+         "imperial":{
+            "rain":0.031102362204724412,
+            "snow":0,
+            "tempMax":69.53,
+            "tempMin":56.426,
+            "windSpeed":12.4544
+         },
+         "metric":{
+            "rain":0.79,
+            "snow":0,
+            "tempMax":20.85,
+            "tempMin":13.57,
+            "windSpeed":20.016
+         },
+         "pressure":1017.26,
+         "timestamp":1437998400,
+         "windDeg":245,
+         "windDir":"W"
+      }
+   ],
+   "save":true,
+   "updated":1437239273904
+}

=== added file 'tests/autopilot/ubuntu_weather_app/files/2.json'
--- tests/autopilot/ubuntu_weather_app/files/2.json	1970-01-01 00:00:00 +0000
+++ tests/autopilot/ubuntu_weather_app/files/2.json	2015-08-05 19:54:56 +0000
@@ -0,0 +1,1509 @@
+{
+   "db":{
+      "id":3,
+      "updated":"2015-07-18T17:06:03.228Z"
+   },
+   "format":20150404,
+   "location":{
+      "objectName":"",
+      "adminName1":"Washington, D.C.",
+      "adminName2":"US.DC.001",
+      "adminName3":"",
+      "areaLabel":"Washington, D.C., United States",
+      "coord":{
+         "lat":"38.89511",
+         "lon":"-77.03637"
+      },
+      "country":"US",
+      "countryName":"United States",
+      "name":"Washington",
+      "population":601723,
+      "services":{
+         "geonames":4140963,
+         "openweathermap":4140963
+      },
+      "timezone":{
+         "dstOffset":-4,
+         "gmtOffset":-5,
+         "timeZoneId":"America/New_York"
+      }
+   },
+   "data":[
+      {
+         "condition":"Rain",
+         "date":{
+            "date":18,
+            "hours":11,
+            "minutes":59,
+            "month":6,
+            "year":2015
+         },
+         "hourly":[
+            {
+               "condition":"Clear",
+               "date":{
+                  "date":18,
+                  "hours":13,
+                  "minutes":0,
+                  "month":6,
+                  "year":2015
+               },
+               "humidity":72,
+               "icon":"cloud_sun",
+               "imperial":{
+                  "rain":0,
+                  "snow":0,
+                  "temp":85.136,
+                  "windSpeed":4.9504
+               },
+               "metric":{
+                  "rain":0,
+                  "snow":0,
+                  "temp":29.52,
+                  "windSpeed":7.956
+               },
+               "pressure":1020.23,
+               "timestamp":1437242400,
+               "windDeg":202.008,
+               "windDir":"S"
+            },
+            {
+               "condition":"Clouds",
+               "date":{
+                  "date":18,
+                  "hours":16,
+                  "minutes":0,
+                  "month":6,
+                  "year":2015
+               },
+               "humidity":64,
+               "icon":"cloud_sun",
+               "imperial":{
+                  "rain":0,
+                  "snow":0,
+                  "temp":86.21600000000001,
+                  "windSpeed":6.7424
+               },
+               "metric":{
+                  "rain":0,
+                  "snow":0,
+                  "temp":30.12,
+                  "windSpeed":10.836
+               },
+               "pressure":1018.84,
+               "timestamp":1437253200,
+               "windDeg":213.504,
+               "windDir":"SW"
+            },
+            {
+               "condition":"Rain",
+               "date":{
+                  "date":18,
+                  "hours":19,
+                  "minutes":0,
+                  "month":6,
+                  "year":2015
+               },
+               "humidity":78,
+               "icon":"rain",
+               "imperial":{
+                  "rain":0.17874015748031497,
+                  "snow":0,
+                  "temp":79.7,
+                  "windSpeed":4.1888000000000005
+               },
+               "metric":{
+                  "rain":4.54,
+                  "snow":0,
+                  "temp":26.5,
+                  "windSpeed":6.732
+               },
+               "pressure":1019.47,
+               "timestamp":1437264000,
+               "windDeg":291.506,
+               "windDir":"W"
+            },
+            {
+               "condition":"Rain",
+               "date":{
+                  "date":18,
+                  "hours":22,
+                  "minutes":0,
+                  "month":6,
+                  "year":2015
+               },
+               "humidity":88,
+               "icon":"rain",
+               "imperial":{
+                  "rain":0.017913385826771655,
+                  "snow":0,
+                  "temp":75.938,
+                  "windSpeed":2.9344000000000006
+               },
+               "metric":{
+                  "rain":0.455,
+                  "snow":0,
+                  "temp":24.41,
+                  "windSpeed":4.716
+               },
+               "pressure":1019.87,
+               "timestamp":1437274800,
+               "windDeg":270.502,
+               "windDir":"W"
+            }
+         ],
+         "humidity":72,
+         "icon":"rain",
+         "imperial":{
+            "rain":0.1968503937007874,
+            "snow":0,
+            "tempMax":86.19800000000001,
+            "tempMin":74.35400000000001,
+            "windSpeed":4.9504
+         },
+         "metric":{
+            "rain":5,
+            "snow":0,
+            "tempMax":30.11,
+            "tempMin":23.53,
+            "windSpeed":7.956
+         },
+         "pressure":1020.23,
+         "timestamp":1437238800,
+         "windDeg":202,
+         "windDir":"S",
+         "current":{
+            "condition":"Rain",
+            "date":{
+               "date":18,
+               "hours":11,
+               "minutes":59,
+               "month":6,
+               "year":2015
+            },
+            "humidity":88,
+            "icon":"rain",
+            "imperial":{
+               "rain":0,
+               "snow":0,
+               "temp":78.314,
+               "windSpeed":5.824000000000001
+            },
+            "metric":{
+               "rain":0,
+               "snow":0,
+               "temp":25.73,
+               "windSpeed":9.360000000000001
+            },
+            "pressure":1016,
+            "timestamp":1437236981,
+            "windDeg":270,
+            "windDir":"W",
+            "service":"openweathermap",
+            "service_id":4140963
+         }
+      },
+      {
+         "condition":"Clear",
+         "date":{
+            "date":19,
+            "hours":11,
+            "minutes":59,
+            "month":6,
+            "year":2015
+         },
+         "hourly":[
+            {
+               "condition":"Clear",
+               "date":{
+                  "date":19,
+                  "hours":1,
+                  "minutes":0,
+                  "month":6,
+                  "year":2015
+               },
+               "humidity":95,
+               "icon":"moon",
+               "imperial":{
+                  "rain":0,
+                  "snow":0,
+                  "temp":74.35400000000001,
+                  "windSpeed":2.7104000000000004
+               },
+               "metric":{
+                  "rain":0,
+                  "snow":0,
+                  "temp":23.53,
+                  "windSpeed":4.356
+               },
+               "pressure":1019.41,
+               "timestamp":1437285600,
+               "windDeg":254.502,
+               "windDir":"W"
+            },
+            {
+               "condition":"Clear",
+               "date":{
+                  "date":19,
+                  "hours":4,
+                  "minutes":0,
+                  "month":6,
+                  "year":2015
+               },
+               "humidity":92,
+               "icon":"moon",
+               "imperial":{
+                  "rain":0,
+                  "snow":0,
+                  "temp":73.094,
+                  "windSpeed":2.9344000000000006
+               },
+               "metric":{
+                  "rain":0,
+                  "snow":0,
+                  "temp":22.83,
+                  "windSpeed":4.716
+               },
+               "pressure":1019.25,
+               "timestamp":1437296400,
+               "windDeg":286.5,
+               "windDir":"W"
+            },
+            {
+               "condition":"Clear",
+               "date":{
+                  "date":19,
+                  "hours":7,
+                  "minutes":0,
+                  "month":6,
+                  "year":2015
+               },
+               "humidity":84,
+               "icon":"sun",
+               "imperial":{
+                  "rain":0,
+                  "snow":0,
+                  "temp":80.564,
+                  "windSpeed":5.219200000000001
+               },
+               "metric":{
+                  "rain":0,
+                  "snow":0,
+                  "temp":26.98,
+                  "windSpeed":8.388
+               },
+               "pressure":1019.67,
+               "timestamp":1437307200,
+               "windDeg":311.005,
+               "windDir":"NW"
+            },
+            {
+               "condition":"Clear",
+               "date":{
+                  "date":19,
+                  "hours":10,
+                  "minutes":0,
+                  "month":6,
+                  "year":2015
+               },
+               "humidity":82,
+               "icon":"sun",
+               "imperial":{
+                  "rain":0,
+                  "snow":0,
+                  "temp":87.25999999999999,
+                  "windSpeed":3.9424000000000006
+               },
+               "metric":{
+                  "rain":0,
+                  "snow":0,
+                  "temp":30.7,
+                  "windSpeed":6.336
+               },
+               "pressure":1019.85,
+               "timestamp":1437318000,
+               "windDeg":332.001,
+               "windDir":"N"
+            },
+            {
+               "condition":"Clear",
+               "date":{
+                  "date":19,
+                  "hours":13,
+                  "minutes":0,
+                  "month":6,
+                  "year":2015
+               },
+               "humidity":74,
+               "icon":"sun",
+               "imperial":{
+                  "rain":0,
+                  "snow":0,
+                  "temp":90.536,
+                  "windSpeed":3.7408
+               },
+               "metric":{
+                  "rain":0,
+                  "snow":0,
+                  "temp":32.52,
+                  "windSpeed":6.012
+               },
+               "pressure":1018.93,
+               "timestamp":1437328800,
+               "windDeg":307.502,
+               "windDir":"NW"
+            },
+            {
+               "condition":"Clear",
+               "date":{
+                  "date":19,
+                  "hours":16,
+                  "minutes":0,
+                  "month":6,
+                  "year":2015
+               },
+               "humidity":67,
+               "icon":"sun",
+               "imperial":{
+                  "rain":0,
+                  "snow":0,
+                  "temp":91.904,
+                  "windSpeed":3.7632000000000003
+               },
+               "metric":{
+                  "rain":0,
+                  "snow":0,
+                  "temp":33.28,
+                  "windSpeed":6.048
+               },
+               "pressure":1016.96,
+               "timestamp":1437339600,
+               "windDeg":268.003,
+               "windDir":"W"
+            },
+            {
+               "condition":"Clear",
+               "date":{
+                  "date":19,
+                  "hours":19,
+                  "minutes":0,
+                  "month":6,
+                  "year":2015
+               },
+               "humidity":68,
+               "icon":"cloud_moon",
+               "imperial":{
+                  "rain":0,
+                  "snow":0,
+                  "temp":88.78999999999999,
+                  "windSpeed":4.144000000000001
+               },
+               "metric":{
+                  "rain":0,
+                  "snow":0,
+                  "temp":31.55,
+                  "windSpeed":6.66
+               },
+               "pressure":1016.48,
+               "timestamp":1437350400,
+               "windDeg":242.008,
+               "windDir":"W"
+            },
+            {
+               "condition":"Clouds",
+               "date":{
+                  "date":19,
+                  "hours":22,
+                  "minutes":0,
+                  "month":6,
+                  "year":2015
+               },
+               "humidity":72,
+               "icon":"cloud_moon",
+               "imperial":{
+                  "rain":0,
+                  "snow":0,
+                  "temp":83.48,
+                  "windSpeed":6.2944
+               },
+               "metric":{
+                  "rain":0,
+                  "snow":0,
+                  "temp":28.6,
+                  "windSpeed":10.116
+               },
+               "pressure":1016.51,
+               "timestamp":1437361200,
+               "windDeg":218.504,
+               "windDir":"SW"
+            }
+         ],
+         "humidity":74,
+         "icon":"sun",
+         "imperial":{
+            "rain":0,
+            "snow":0,
+            "tempMax":91.904,
+            "tempMin":80.564,
+            "windSpeed":3.7408
+         },
+         "metric":{
+            "rain":0,
+            "snow":0,
+            "tempMax":33.28,
+            "tempMin":26.98,
+            "windSpeed":6.012
+         },
+         "pressure":1018.93,
+         "timestamp":1437325200,
+         "windDeg":308,
+         "windDir":"NW"
+      },
+      {
+         "condition":"Rain",
+         "date":{
+            "date":20,
+            "hours":11,
+            "minutes":59,
+            "month":6,
+            "year":2015
+         },
+         "hourly":[
+            {
+               "condition":"Clouds",
+               "date":{
+                  "date":20,
+                  "hours":1,
+                  "minutes":0,
+                  "month":6,
+                  "year":2015
+               },
+               "humidity":77,
+               "icon":"cloud_moon",
+               "imperial":{
+                  "rain":0,
+                  "snow":0,
+                  "temp":81.5,
+                  "windSpeed":5.7568
+               },
+               "metric":{
+                  "rain":0,
+                  "snow":0,
+                  "temp":27.5,
+                  "windSpeed":9.251999999999999
+               },
+               "pressure":1015.89,
+               "timestamp":1437372000,
+               "windDeg":245.501,
+               "windDir":"W"
+            },
+            {
+               "condition":"Clouds",
+               "date":{
+                  "date":20,
+                  "hours":4,
+                  "minutes":0,
+                  "month":6,
+                  "year":2015
+               },
+               "humidity":76,
+               "icon":"cloud_moon",
+               "imperial":{
+                  "rain":0,
+                  "snow":0,
+                  "temp":80.06,
+                  "windSpeed":4.748800000000001
+               },
+               "metric":{
+                  "rain":0,
+                  "snow":0,
+                  "temp":26.7,
+                  "windSpeed":7.632000000000001
+               },
+               "pressure":1014.8,
+               "timestamp":1437382800,
+               "windDeg":257,
+               "windDir":"W"
+            },
+            {
+               "condition":"Rain",
+               "date":{
+                  "date":20,
+                  "hours":7,
+                  "minutes":0,
+                  "month":6,
+                  "year":2015
+               },
+               "humidity":100,
+               "icon":"rain",
+               "imperial":{
+                  "rain":0.17775590551181103,
+                  "snow":0,
+                  "temp":72.356,
+                  "windSpeed":5.958400000000001
+               },
+               "metric":{
+                  "rain":4.515,
+                  "snow":0,
+                  "temp":22.42,
+                  "windSpeed":9.576
+               },
+               "pressure":1016.79,
+               "timestamp":1437393600,
+               "windDeg":296.501,
+               "windDir":"W"
+            },
+            {
+               "condition":"Clouds",
+               "date":{
+                  "date":20,
+                  "hours":10,
+                  "minutes":0,
+                  "month":6,
+                  "year":2015
+               },
+               "humidity":97,
+               "icon":"cloud_sun",
+               "imperial":{
+                  "rain":0,
+                  "snow":0,
+                  "temp":79.268,
+                  "windSpeed":5.958400000000001
+               },
+               "metric":{
+                  "rain":0,
+                  "snow":0,
+                  "temp":26.26,
+                  "windSpeed":9.576
+               },
+               "pressure":1016.6,
+               "timestamp":1437404400,
+               "windDeg":277.502,
+               "windDir":"W"
+            },
+            {
+               "condition":"Clear",
+               "date":{
+                  "date":20,
+                  "hours":13,
+                  "minutes":0,
+                  "month":6,
+                  "year":2015
+               },
+               "humidity":79,
+               "icon":"sun",
+               "imperial":{
+                  "rain":0,
+                  "snow":0,
+                  "temp":87.656,
+                  "windSpeed":6.7424
+               },
+               "metric":{
+                  "rain":0,
+                  "snow":0,
+                  "temp":30.92,
+                  "windSpeed":10.836
+               },
+               "pressure":1014.93,
+               "timestamp":1437415200,
+               "windDeg":294.502,
+               "windDir":"W"
+            },
+            {
+               "condition":"Clear",
+               "date":{
+                  "date":20,
+                  "hours":16,
+                  "minutes":0,
+                  "month":6,
+                  "year":2015
+               },
+               "humidity":67,
+               "icon":"cloud_sun",
+               "imperial":{
+                  "rain":0,
+                  "snow":0,
+                  "temp":88.97,
+                  "windSpeed":8.668800000000001
+               },
+               "metric":{
+                  "rain":0,
+                  "snow":0,
+                  "temp":31.65,
+                  "windSpeed":13.932
+               },
+               "pressure":1013.88,
+               "timestamp":1437426000,
+               "windDeg":298.006,
+               "windDir":"W"
+            },
+            {
+               "condition":"Clear",
+               "date":{
+                  "date":20,
+                  "hours":19,
+                  "minutes":0,
+                  "month":6,
+                  "year":2015
+               },
+               "humidity":65,
+               "icon":"moon",
+               "imperial":{
+                  "rain":0,
+                  "snow":0,
+                  "temp":83.98400000000001,
+                  "windSpeed":5.510400000000001
+               },
+               "metric":{
+                  "rain":0,
+                  "snow":0,
+                  "temp":28.88,
+                  "windSpeed":8.856
+               },
+               "pressure":1014.36,
+               "timestamp":1437436800,
+               "windDeg":322.503,
+               "windDir":"NW"
+            },
+            {
+               "condition":"Clouds",
+               "date":{
+                  "date":20,
+                  "hours":22,
+                  "minutes":0,
+                  "month":6,
+                  "year":2015
+               },
+               "humidity":66,
+               "icon":"cloud_moon",
+               "imperial":{
+                  "rain":0,
+                  "snow":0,
+                  "temp":76.244,
+                  "windSpeed":6.384000000000001
+               },
+               "metric":{
+                  "rain":0,
+                  "snow":0,
+                  "temp":24.58,
+                  "windSpeed":10.26
+               },
+               "pressure":1015.65,
+               "timestamp":1437447600,
+               "windDeg":341.502,
+               "windDir":"N"
+            }
+         ],
+         "humidity":79,
+         "icon":"rain",
+         "imperial":{
+            "rain":0.1779527559055118,
+            "snow":0,
+            "tempMax":88.97,
+            "tempMin":72.24799999999999,
+            "windSpeed":6.7424
+         },
+         "metric":{
+            "rain":4.52,
+            "snow":0,
+            "tempMax":31.65,
+            "tempMin":22.36,
+            "windSpeed":10.836
+         },
+         "pressure":1014.93,
+         "timestamp":1437411600,
+         "windDeg":295,
+         "windDir":"W"
+      },
+      {
+         "condition":"Rain",
+         "date":{
+            "date":21,
+            "hours":11,
+            "minutes":59,
+            "month":6,
+            "year":2015
+         },
+         "hourly":[
+            {
+               "condition":"Clouds",
+               "date":{
+                  "date":21,
+                  "hours":1,
+                  "minutes":0,
+                  "month":6,
+                  "year":2015
+               },
+               "humidity":70,
+               "icon":"cloud_moon",
+               "imperial":{
+                  "rain":0,
+                  "snow":0,
+                  "temp":72.24799999999999,
+                  "windSpeed":6.339200000000001
+               },
+               "metric":{
+                  "rain":0,
+                  "snow":0,
+                  "temp":22.36,
+                  "windSpeed":10.188
+               },
+               "pressure":1015.63,
+               "timestamp":1437458400,
+               "windDeg":320.002,
+               "windDir":"NW"
+            },
+            {
+               "condition":"Clouds",
+               "date":{
+                  "date":21,
+                  "hours":4,
+                  "minutes":0,
+                  "month":6,
+                  "year":2015
+               },
+               "humidity":80,
+               "icon":"cloud",
+               "imperial":{
+                  "rain":0,
+                  "snow":0,
+                  "temp":69.94399999999999,
+                  "windSpeed":3.0240000000000005
+               },
+               "metric":{
+                  "rain":0,
+                  "snow":0,
+                  "temp":21.08,
+                  "windSpeed":4.86
+               },
+               "pressure":1015.59,
+               "timestamp":1437469200,
+               "windDeg":300.501,
+               "windDir":"NW"
+            },
+            {
+               "condition":"Clouds",
+               "date":{
+                  "date":21,
+                  "hours":7,
+                  "minutes":0,
+                  "month":6,
+                  "year":2015
+               },
+               "humidity":80,
+               "icon":"cloud_sun",
+               "imperial":{
+                  "rain":0,
+                  "snow":0,
+                  "temp":76.04599999999999,
+                  "windSpeed":3.7408
+               },
+               "metric":{
+                  "rain":0,
+                  "snow":0,
+                  "temp":24.47,
+                  "windSpeed":6.012
+               },
+               "pressure":1015.89,
+               "timestamp":1437480000,
+               "windDeg":299.008,
+               "windDir":"W"
+            },
+            {
+               "condition":"Clouds",
+               "date":{
+                  "date":21,
+                  "hours":10,
+                  "minutes":0,
+                  "month":6,
+                  "year":2015
+               },
+               "humidity":76,
+               "icon":"cloud_sun",
+               "imperial":{
+                  "rain":0,
+                  "snow":0,
+                  "temp":83.26400000000001,
+                  "windSpeed":3.9424000000000006
+               },
+               "metric":{
+                  "rain":0,
+                  "snow":0,
+                  "temp":28.48,
+                  "windSpeed":6.336
+               },
+               "pressure":1015.73,
+               "timestamp":1437490800,
+               "windDeg":295.5,
+               "windDir":"W"
+            },
+            {
+               "condition":"Clouds",
+               "date":{
+                  "date":21,
+                  "hours":13,
+                  "minutes":0,
+                  "month":6,
+                  "year":2015
+               },
+               "humidity":70,
+               "icon":"cloud_sun",
+               "imperial":{
+                  "rain":0,
+                  "snow":0,
+                  "temp":86.036,
+                  "windSpeed":3.6288000000000005
+               },
+               "metric":{
+                  "rain":0,
+                  "snow":0,
+                  "temp":30.02,
+                  "windSpeed":5.832000000000001
+               },
+               "pressure":1014.18,
+               "timestamp":1437501600,
+               "windDeg":264.503,
+               "windDir":"W"
+            },
+            {
+               "condition":"Clouds",
+               "date":{
+                  "date":21,
+                  "hours":16,
+                  "minutes":0,
+                  "month":6,
+                  "year":2015
+               },
+               "humidity":62,
+               "icon":"cloud",
+               "imperial":{
+                  "rain":0,
+                  "snow":0,
+                  "temp":86.30600000000001,
+                  "windSpeed":5.3984000000000005
+               },
+               "metric":{
+                  "rain":0,
+                  "snow":0,
+                  "temp":30.17,
+                  "windSpeed":8.676
+               },
+               "pressure":1013.37,
+               "timestamp":1437512400,
+               "windDeg":243.501,
+               "windDir":"W"
+            },
+            {
+               "condition":"Rain",
+               "date":{
+                  "date":21,
+                  "hours":19,
+                  "minutes":0,
+                  "month":6,
+                  "year":2015
+               },
+               "humidity":93,
+               "icon":"rain",
+               "imperial":{
+                  "rain":0.06850393700787402,
+                  "snow":0,
+                  "temp":72.73400000000001,
+                  "windSpeed":6.1824
+               },
+               "metric":{
+                  "rain":1.74,
+                  "snow":0,
+                  "temp":22.63,
+                  "windSpeed":9.936
+               },
+               "pressure":1014.16,
+               "timestamp":1437523200,
+               "windDeg":236.003,
+               "windDir":"SW"
+            },
+            {
+               "condition":"Clear",
+               "date":{
+                  "date":21,
+                  "hours":22,
+                  "minutes":0,
+                  "month":6,
+                  "year":2015
+               },
+               "humidity":93,
+               "icon":"cloud_moon",
+               "imperial":{
+                  "rain":0,
+                  "snow":0,
+                  "temp":70.646,
+                  "windSpeed":3.9424000000000006
+               },
+               "metric":{
+                  "rain":0,
+                  "snow":0,
+                  "temp":21.47,
+                  "windSpeed":6.336
+               },
+               "pressure":1014.32,
+               "timestamp":1437534000,
+               "windDeg":249.502,
+               "windDir":"W"
+            }
+         ],
+         "humidity":0,
+         "icon":"rain",
+         "imperial":{
+            "rain":0,
+            "snow":0,
+            "tempMax":83.53399999999999,
+            "tempMin":73.45400000000001,
+            "windSpeed":6.496
+         },
+         "metric":{
+            "rain":0,
+            "snow":0,
+            "tempMax":28.63,
+            "tempMin":23.03,
+            "windSpeed":10.44
+         },
+         "pressure":1012.07,
+         "timestamp":1437498000,
+         "windDeg":317,
+         "windDir":"NW"
+      },
+      {
+         "condition":"Rain",
+         "date":{
+            "date":22,
+            "hours":11,
+            "minutes":59,
+            "month":6,
+            "year":2015
+         },
+         "hourly":[
+            {
+               "condition":"Clear",
+               "date":{
+                  "date":22,
+                  "hours":1,
+                  "minutes":0,
+                  "month":6,
+                  "year":2015
+               },
+               "humidity":94,
+               "icon":"moon",
+               "imperial":{
+                  "rain":0,
+                  "snow":0,
+                  "temp":69.044,
+                  "windSpeed":3.7184000000000004
+               },
+               "metric":{
+                  "rain":0,
+                  "snow":0,
+                  "temp":20.58,
+                  "windSpeed":5.976
+               },
+               "pressure":1013.97,
+               "timestamp":1437544800,
+               "windDeg":253.008,
+               "windDir":"W"
+            },
+            {
+               "condition":"Clear",
+               "date":{
+                  "date":22,
+                  "hours":4,
+                  "minutes":0,
+                  "month":6,
+                  "year":2015
+               },
+               "humidity":94,
+               "icon":"cloud_moon",
+               "imperial":{
+                  "rain":0,
+                  "snow":0,
+                  "temp":68.054,
+                  "windSpeed":3.2032000000000003
+               },
+               "metric":{
+                  "rain":0,
+                  "snow":0,
+                  "temp":20.03,
+                  "windSpeed":5.148
+               },
+               "pressure":1013.68,
+               "timestamp":1437555600,
+               "windDeg":237,
+               "windDir":"SW"
+            },
+            {
+               "condition":"Clouds",
+               "date":{
+                  "date":22,
+                  "hours":7,
+                  "minutes":0,
+                  "month":6,
+                  "year":2015
+               },
+               "humidity":88,
+               "icon":"cloud_sun",
+               "imperial":{
+                  "rain":0,
+                  "snow":0,
+                  "temp":72.518,
+                  "windSpeed":4.1664
+               },
+               "metric":{
+                  "rain":0,
+                  "snow":0,
+                  "temp":22.51,
+                  "windSpeed":6.696000000000001
+               },
+               "pressure":1014.42,
+               "timestamp":1437566400,
+               "windDeg":269.501,
+               "windDir":"W"
+            },
+            {
+               "condition":"Clouds",
+               "date":{
+                  "date":22,
+                  "hours":10,
+                  "minutes":0,
+                  "month":6,
+                  "year":2015
+               },
+               "humidity":83,
+               "icon":"cloud_sun",
+               "imperial":{
+                  "rain":0,
+                  "snow":0,
+                  "temp":81.05000000000001,
+                  "windSpeed":3.9424000000000006
+               },
+               "metric":{
+                  "rain":0,
+                  "snow":0,
+                  "temp":27.25,
+                  "windSpeed":6.336
+               },
+               "pressure":1015.19,
+               "timestamp":1437577200,
+               "windDeg":7.50089,
+               "windDir":"N"
+            },
+            {
+               "condition":"Clouds",
+               "date":{
+                  "date":22,
+                  "hours":13,
+                  "minutes":0,
+                  "month":6,
+                  "year":2015
+               },
+               "humidity":76,
+               "icon":"cloud_sun",
+               "imperial":{
+                  "rain":0,
+                  "snow":0,
+                  "temp":84.28999999999999,
+                  "windSpeed":4.032000000000001
+               },
+               "metric":{
+                  "rain":0,
+                  "snow":0,
+                  "temp":29.05,
+                  "windSpeed":6.48
+               },
+               "pressure":1014.88,
+               "timestamp":1437588000,
+               "windDeg":24.0016,
+               "windDir":"N"
+            },
+            {
+               "condition":"Clouds",
+               "date":{
+                  "date":22,
+                  "hours":16,
+                  "minutes":0,
+                  "month":6,
+                  "year":2015
+               },
+               "humidity":68,
+               "icon":"cloud",
+               "imperial":{
+                  "rain":0,
+                  "snow":0,
+                  "temp":84.146,
+                  "windSpeed":3.8528000000000002
+               },
+               "metric":{
+                  "rain":0,
+                  "snow":0,
+                  "temp":28.97,
+                  "windSpeed":6.192
+               },
+               "pressure":1014.72,
+               "timestamp":1437598800,
+               "windDeg":331.502,
+               "windDir":"N"
+            },
+            {
+               "condition":"Clouds",
+               "date":{
+                  "date":22,
+                  "hours":19,
+                  "minutes":0,
+                  "month":6,
+                  "year":2015
+               },
+               "humidity":69,
+               "icon":"cloud",
+               "imperial":{
+                  "rain":0,
+                  "snow":0,
+                  "temp":82.05799999999999,
+                  "windSpeed":3.8304000000000005
+               },
+               "metric":{
+                  "rain":0,
+                  "snow":0,
+                  "temp":27.81,
+                  "windSpeed":6.156
+               },
+               "pressure":1015.49,
+               "timestamp":1437609600,
+               "windDeg":310.004,
+               "windDir":"NW"
+            },
+            {
+               "condition":"Rain",
+               "date":{
+                  "date":22,
+                  "hours":22,
+                  "minutes":0,
+                  "month":6,
+                  "year":2015
+               },
+               "humidity":72,
+               "icon":"rain",
+               "imperial":{
+                  "rain":0.0011811023622047244,
+                  "snow":0,
+                  "temp":78.044,
+                  "windSpeed":5.1968000000000005
+               },
+               "metric":{
+                  "rain":0.03,
+                  "snow":0,
+                  "temp":25.58,
+                  "windSpeed":8.352
+               },
+               "pressure":1017.2,
+               "timestamp":1437620400,
+               "windDeg":339.001,
+               "windDir":"N"
+            }
+         ],
+         "humidity":0,
+         "icon":"rain",
+         "imperial":{
+            "rain":0.042913385826771656,
+            "snow":0,
+            "tempMax":83.31800000000001,
+            "tempMin":73.274,
+            "windSpeed":2.0608000000000004
+         },
+         "metric":{
+            "rain":1.09,
+            "snow":0,
+            "tempMax":28.51,
+            "tempMin":22.93,
+            "windSpeed":3.3120000000000003
+         },
+         "pressure":1013.42,
+         "timestamp":1437584400,
+         "windDeg":286,
+         "windDir":"W"
+      },
+      {
+         "condition":"Rain",
+         "date":{
+            "date":23,
+            "hours":11,
+            "minutes":59,
+            "month":6,
+            "year":2015
+         },
+         "hourly":[
+            {
+               "condition":"Clouds",
+               "date":{
+                  "date":23,
+                  "hours":1,
+                  "minutes":0,
+                  "month":6,
+                  "year":2015
+               },
+               "humidity":83,
+               "icon":"cloud_moon",
+               "imperial":{
+                  "rain":0,
+                  "snow":0,
+                  "temp":73.904,
+                  "windSpeed":3.7408
+               },
+               "metric":{
+                  "rain":0,
+                  "snow":0,
+                  "temp":23.28,
+                  "windSpeed":6.012
+               },
+               "pressure":1017.28,
+               "timestamp":1437631200,
+               "windDeg":342.501,
+               "windDir":"N"
+            },
+            {
+               "condition":"Clear",
+               "date":{
+                  "date":23,
+                  "hours":4,
+                  "minutes":0,
+                  "month":6,
+                  "year":2015
+               },
+               "humidity":94,
+               "icon":"moon",
+               "imperial":{
+                  "rain":0,
+                  "snow":0,
+                  "temp":70.142,
+                  "windSpeed":2.7328
+               },
+               "metric":{
+                  "rain":0,
+                  "snow":0,
+                  "temp":21.19,
+                  "windSpeed":4.392
+               },
+               "pressure":1017.75,
+               "timestamp":1437642000,
+               "windDeg":299.502,
+               "windDir":"W"
+            },
+            {
+               "condition":"Clouds",
+               "date":{
+                  "date":23,
+                  "hours":7,
+                  "minutes":0,
+                  "month":6,
+                  "year":2015
+               },
+               "humidity":80,
+               "icon":"cloud",
+               "imperial":{
+                  "rain":0,
+                  "snow":0,
+                  "temp":72.59,
+                  "windSpeed":7.638400000000001
+               },
+               "metric":{
+                  "rain":0,
+                  "snow":0,
+                  "temp":22.55,
+                  "windSpeed":12.276000000000002
+               },
+               "pressure":1019.29,
+               "timestamp":1437652800,
+               "windDeg":348.501,
+               "windDir":"N"
+            },
+            {
+               "condition":"Clouds",
+               "date":{
+                  "date":23,
+                  "hours":10,
+                  "minutes":0,
+                  "month":6,
+                  "year":2015
+               },
+               "humidity":74,
+               "icon":"cloud",
+               "imperial":{
+                  "rain":0,
+                  "snow":0,
+                  "temp":77.36,
+                  "windSpeed":6.1824
+               },
+               "metric":{
+                  "rain":0,
+                  "snow":0,
+                  "temp":25.2,
+                  "windSpeed":9.936
+               },
+               "pressure":1020.11,
+               "timestamp":1437663600,
+               "windDeg":19.0006,
+               "windDir":"N"
+            }
+         ],
+         "humidity":0,
+         "icon":"rain",
+         "imperial":{
+            "rain":0.020866141732283468,
+            "snow":0,
+            "tempMax":84.758,
+            "tempMin":73.328,
+            "windSpeed":7.548800000000001
+         },
+         "metric":{
+            "rain":0.53,
+            "snow":0,
+            "tempMax":29.31,
+            "tempMin":22.96,
+            "windSpeed":12.132000000000001
+         },
+         "pressure":1016.1,
+         "timestamp":1437670800,
+         "windDeg":327,
+         "windDir":"NW"
+      },
+      {
+         "condition":"Rain",
+         "date":{
+            "date":24,
+            "hours":11,
+            "minutes":59,
+            "month":6,
+            "year":2015
+         },
+         "hourly":[
+
+         ],
+         "humidity":0,
+         "icon":"rain",
+         "imperial":{
+            "rain":0.013779527559055118,
+            "snow":0,
+            "tempMax":87.17,
+            "tempMin":74.12,
+            "windSpeed":5.6896
+         },
+         "metric":{
+            "rain":0.35,
+            "snow":0,
+            "tempMax":30.65,
+            "tempMin":23.4,
+            "windSpeed":9.144
+         },
+         "pressure":1017.79,
+         "timestamp":1437757200,
+         "windDeg":234,
+         "windDir":"SW"
+      },
+      {
+         "condition":"Rain",
+         "date":{
+            "date":25,
+            "hours":11,
+            "minutes":59,
+            "month":6,
+            "year":2015
+         },
+         "hourly":[
+
+         ],
+         "humidity":0,
+         "icon":"rain",
+         "imperial":{
+            "rain":0.13385826771653545,
+            "snow":0,
+            "tempMax":94.334,
+            "tempMin":80.114,
+            "windSpeed":8.5792
+         },
+         "metric":{
+            "rain":3.4,
+            "snow":0,
+            "tempMax":34.63,
+            "tempMin":26.73,
+            "windSpeed":13.788
+         },
+         "pressure":1012.93,
+         "timestamp":1437843600,
+         "windDeg":233,
+         "windDir":"SW"
+      },
+      {
+         "condition":"Rain",
+         "date":{
+            "date":26,
+            "hours":11,
+            "minutes":59,
+            "month":6,
+            "year":2015
+         },
+         "hourly":[
+
+         ],
+         "humidity":0,
+         "icon":"rain",
+         "imperial":{
+            "rain":0.01141732283464567,
+            "snow":0,
+            "tempMax":93.02,
+            "tempMin":77.756,
+            "windSpeed":7.750400000000001
+         },
+         "metric":{
+            "rain":0.29,
+            "snow":0,
+            "tempMax":33.9,
+            "tempMin":25.42,
+            "windSpeed":12.456
+         },
+         "pressure":1011.84,
+         "timestamp":1437930000,
+         "windDeg":271,
+         "windDir":"W"
+      },
+      {
+         "condition":"Rain",
+         "date":{
+            "date":27,
+            "hours":11,
+            "minutes":59,
+            "month":6,
+            "year":2015
+         },
+         "hourly":[
+
+         ],
+         "humidity":0,
+         "icon":"rain",
+         "imperial":{
+            "rain":0.25826771653543307,
+            "snow":0,
+            "tempMax":93.506,
+            "tempMin":77,
+            "windSpeed":5.443200000000001
+         },
+         "metric":{
+            "rain":6.56,
+            "snow":0,
+            "tempMax":34.17,
+            "tempMin":25,
+            "windSpeed":8.748000000000001
+         },
+         "pressure":1011.02,
+         "timestamp":1438016400,
+         "windDeg":182,
+         "windDir":"S"
+      }
+   ],
+   "save":true,
+   "updated":1437239163515
+}

=== added file 'tests/autopilot/ubuntu_weather_app/files/CMakeLists.txt'
--- tests/autopilot/ubuntu_weather_app/files/CMakeLists.txt	1970-01-01 00:00:00 +0000
+++ tests/autopilot/ubuntu_weather_app/files/CMakeLists.txt	2015-08-05 19:54:56 +0000
@@ -0,0 +1,6 @@
+# make the data files visible on qtcreator
+file(GLOB PYTHON_TEST_RESOURCE_FILES
+     RELATIVE ${CMAKE_CURRENT_SOURCE_DIR}
+     *.json)
+
+add_custom_target(ubuntu-weather-app_PYTHONTestResourceFiles ALL SOURCES ${PYTHON_TEST_RESOURCE_FILES})

=== added directory 'tests/autopilot/ubuntu_weather_app/tests'
=== added file 'tests/autopilot/ubuntu_weather_app/tests/CMakeLists.txt'
--- tests/autopilot/ubuntu_weather_app/tests/CMakeLists.txt	1970-01-01 00:00:00 +0000
+++ tests/autopilot/ubuntu_weather_app/tests/CMakeLists.txt	2015-08-05 19:54:56 +0000
@@ -0,0 +1,6 @@
+# make the test files visible on qtcreator
+file(GLOB PYTHON_TEST_FILES
+     RELATIVE ${CMAKE_CURRENT_SOURCE_DIR}
+     *.py)
+
+add_custom_target(ubuntu-weather-app_PYTHONTESTFiles ALL SOURCES ${PYTHON_TEST_FILES})

=== added file 'tests/autopilot/ubuntu_weather_app/tests/__init__.py'
--- tests/autopilot/ubuntu_weather_app/tests/__init__.py	1970-01-01 00:00:00 +0000
+++ tests/autopilot/ubuntu_weather_app/tests/__init__.py	2015-08-05 19:54:56 +0000
@@ -0,0 +1,303 @@
+# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*-
+#
+# Copyright (C) 2013, 2014, 2015 Canonical Ltd
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 3 as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+"""Weather app autopilot tests."""
+
+import os
+import os.path
+import shutil
+import sqlite3
+import time
+import logging
+
+import fixtures
+from ubuntu_weather_app import UbuntuWeatherApp
+import ubuntu_weather_app
+
+from autopilot import logging as autopilot_logging
+from autopilot.matchers import Eventually
+from testtools.matchers import Equals
+from autopilot.testcase import AutopilotTestCase
+
+import ubuntuuitoolkit
+from ubuntuuitoolkit import base
+
+logger = logging.getLogger(__name__)
+
+
+class BaseTestCaseWithPatchedHome(AutopilotTestCase):
+
+    """A common test case class that provides several useful methods for
+    ubuntu-weather-app tests.
+
+    """
+
+    working_dir = os.getcwd()
+    local_location_dir = os.path.dirname(os.path.dirname(working_dir))
+    local_location = local_location_dir + "/app/ubuntu-weather-app.qml"
+    installed_location = "/usr/share/ubuntu-weather-app/app/" \
+        "ubuntu-weather-app.qml"
+
+    def get_launcher_method_and_type(self):
+        if os.path.exists(self.local_location):
+            launch = self.launch_test_local
+            test_type = 'local'
+        elif os.path.exists(self.installed_location):
+            launch = self.launch_test_installed
+            test_type = 'deb'
+        else:
+            launch = self.launch_test_click
+            test_type = 'click'
+        return launch, test_type
+
+    def setUp(self):
+        super(BaseTestCaseWithPatchedHome, self).setUp()
+        self.launcher, self.test_type = self.get_launcher_method_and_type()
+        self.home_dir = self._patch_home()
+
+    @autopilot_logging.log_action(logger.info)
+    def launch_test_local(self):
+        return self.launch_test_application(
+            base.get_qmlscene_launch_command(),
+            self.local_location,
+            "debug",
+            app_type='qt',
+            emulator_base=ubuntuuitoolkit.UbuntuUIToolkitCustomProxyObjectBase)
+
+    @autopilot_logging.log_action(logger.info)
+    def launch_test_installed(self):
+        return self.launch_test_application(
+            base.get_qmlscene_launch_command(),
+            self.installed_location,
+            "debug",
+            app_type='qt',
+            emulator_base=ubuntuuitoolkit.UbuntuUIToolkitCustomProxyObjectBase)
+
+    @autopilot_logging.log_action(logger.info)
+    def launch_test_click(self):
+        return self.launch_click_package(
+            "com.ubuntu.weather",
+            emulator_base=ubuntuuitoolkit.UbuntuUIToolkitCustomProxyObjectBase)
+
+    def _copy_xauthority_file(self, directory):
+        """ Copy .Xauthority file to directory, if it exists in /home
+        """
+        # If running under xvfb, as jenkins does,
+        # xsession will fail to start without xauthority file
+        # Thus if the Xauthority file is in the home directory
+        # make sure we copy it to our temp home directory
+
+        xauth = os.path.expanduser(os.path.join(os.environ.get('HOME'),
+                                   '.Xauthority'))
+        if os.path.isfile(xauth):
+            logger.debug("Copying .Xauthority to %s" % directory)
+            shutil.copyfile(
+                os.path.expanduser(os.path.join(os.environ.get('HOME'),
+                                   '.Xauthority')),
+                os.path.join(directory, '.Xauthority'))
+
+    def _patch_home(self):
+        """ mock /home for testing purposes to preserve user data
+        """
+
+        # if running on non-phablet device,
+        # run in temp folder to avoid mucking up home
+        # bug 1316746
+        # bug 1376423
+        if self.test_type is 'click':
+            # just use home for now on devices
+            temp_dir = os.environ.get('HOME')
+
+            # before each test, remove the app's databases
+            local_dir = os.path.join(temp_dir,
+                                     '.local/share/com.ubuntu.weather')
+
+            if (os.path.exists(local_dir)):
+                shutil.rmtree(local_dir)
+
+            local_dir = os.path.join(temp_dir, '.config/com.ubuntu.weather')
+
+            if (os.path.exists(local_dir)):
+                shutil.rmtree(local_dir)
+        else:
+            temp_dir_fixture = fixtures.TempDir()
+            self.useFixture(temp_dir_fixture)
+            temp_dir = temp_dir_fixture.path
+
+            # before we set fixture, copy xauthority if needed
+            self._copy_xauthority_file(temp_dir)
+            self.useFixture(fixtures.EnvironmentVariable('HOME',
+                                                         newvalue=temp_dir))
+
+            logger.debug("Patched home to fake home directory %s" % temp_dir)
+
+        return temp_dir
+
+
+class DatabaseMixin(object):
+
+    """
+    Helper functions for dealing with sqlite databases
+    """
+
+    def _execute_sql(self, statement):
+        conn = sqlite3.connect(self.db_path)
+        cursor = conn.cursor()
+        logger.debug("Executing sql")
+        logger.debug(statement)
+        cursor.execute(statement)
+        conn.commit()
+        conn.close()
+
+    def add_locations_to_database(self, limit=None):
+        locations = self.get_locations_data()
+        conn = sqlite3.connect(self.db_path)
+        cursor = conn.cursor()
+        logger.debug("Adding locations to database")
+
+        for loc_data in locations:
+            db_exec = "INSERT INTO Locations(date, data) VALUES('{}', '{}')"
+            cursor.execute(db_exec.format(
+                int(time.time() * 1000), loc_data))
+            conn.commit()
+
+        conn.close()
+
+    def clean_db(self):
+        logger.debug("Removing existing database at %s" % self.db_dir)
+
+        try:
+            shutil.rmtree(self.db_dir)
+        except OSError:
+            logger.debug("Could not remove existing database")
+            pass
+
+    def create_blank_db(self):
+        self.clean_db()
+
+        # create blank db
+        database_tmpl_dir = os.path.join(
+            os.path.dirname(ubuntu_weather_app.__file__),
+            'databases')
+        logger.debug("Creating blank db on filesystem %s" % self.db_dir)
+
+        if not os.path.exists(self.app_dir):
+            os.makedirs(self.app_dir)
+
+        shutil.copytree(database_tmpl_dir, self.db_dir)
+
+        self.assertThat(
+            lambda: os.path.exists(self.db_path),
+            Eventually(Equals(True)))
+
+        # this needs to stay in sync with Storage.qml enties
+        logger.debug("Creating locations and settings tables")
+        self._execute_sql("CREATE TABLE IF NOT EXISTS Locations(id INTEGER "
+                          "PRIMARY KEY AUTOINCREMENT, data TEXT, date TEXT)")
+
+        self._execute_sql("CREATE TABLE IF NOT EXISTS settings(key TEXT "
+                          "UNIQUE, value TEXT)")
+
+    def get_locations_data(self):
+        result = []
+        json_files = [self.json_path + '/1.json', self.json_path + '/2.json']
+
+        for path in json_files:
+            with open(path) as fh:
+                json_str = fh.read()
+                result.append(json_str.strip())
+                fh.close()
+
+        return result
+
+    def load_database_vars(self):
+        self.app_dir = os.path.join(
+            os.environ.get('HOME'),
+            ".local/share/com.ubuntu.weather")
+        self.db_dir = os.path.join(self.app_dir, 'Databases')
+        self.db_file = "34e1e542f2f083ff18f537b07a380071.sqlite"
+        self.db_path = os.path.join(self.db_dir, self.db_file)
+
+        self.json_path = os.path.abspath(
+            os.path.join(os.path.dirname(__file__), '..', 'files'))
+
+
+class SettingsMixin(object):
+
+    """
+    Helper functions for dealing with the settings file
+    """
+
+    def create_settings_with_location_added(self):
+        logger.debug("Creating settings with location added")
+
+        if not os.path.exists(self.settings_dir):
+            os.makedirs(self.settings_dir)
+
+        shutil.copyfile(self.settings_location_added, self.settings_filepath)
+
+        self.assertThat(
+            lambda: os.path.exists(self.settings_filepath),
+            Eventually(Equals(True)))
+
+    def load_settings_vars(self):
+        self.db_dir = os.path.abspath(
+            os.path.join(os.path.dirname(__file__), '..', 'databases'))
+        self.settings_dir = os.path.join(
+            os.environ.get('HOME'),
+            ".config/com.ubuntu.weather")
+        self.settings_filepath = os.path.join(self.settings_dir,
+                                              'com.ubuntu.weather.conf')
+        self.settings_location_added = os.path.join(self.db_dir,
+                                                    "location_added.conf")
+
+
+class UbuntuWeatherAppTestCase(BaseTestCaseWithPatchedHome, DatabaseMixin,
+                               SettingsMixin):
+
+    """Base test case that launches the ubuntu-weather-app."""
+
+    def setUp(self):
+        super(UbuntuWeatherAppTestCase, self).setUp()
+
+        self.load_database_vars()
+        self.create_blank_db()
+
+        self.load_settings_vars()
+        self.create_settings_with_location_added()
+
+        self.app = UbuntuWeatherApp(self.launcher())
+
+
+class UbuntuWeatherAppTestCaseWithData(BaseTestCaseWithPatchedHome,
+                                       DatabaseMixin,
+                                       SettingsMixin):
+
+    """Base test case that launches the ubuntu-weather-app with data."""
+
+    def setUp(self):
+        super(UbuntuWeatherAppTestCaseWithData, self).setUp()
+
+        self.load_database_vars()
+        self.create_blank_db()
+
+        self.load_settings_vars()
+        self.create_settings_with_location_added()
+
+        logger.debug("Adding fake data to new database")
+        self.add_locations_to_database()
+
+        self.app = UbuntuWeatherApp(self.launcher())

=== added file 'tests/autopilot/ubuntu_weather_app/tests/test_empty_state.py'
--- tests/autopilot/ubuntu_weather_app/tests/test_empty_state.py	1970-01-01 00:00:00 +0000
+++ tests/autopilot/ubuntu_weather_app/tests/test_empty_state.py	2015-08-05 19:54:56 +0000
@@ -0,0 +1,37 @@
+# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*-
+# Copyright 2013, 2014, 2015 Canonical
+#
+# This program is free software: you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 3, as published
+# by the Free Software Foundation.
+
+"""Ubuntu Weather app autopilot tests."""
+
+from __future__ import absolute_import
+
+import logging
+from autopilot.matchers import Eventually
+from testtools.matchers import Equals
+
+
+from ubuntu_weather_app.tests import UbuntuWeatherAppTestCase
+
+logger = logging.getLogger(__name__)
+
+
+class TestEmptyState(UbuntuWeatherAppTestCase):
+
+    def setUp(self):
+        super(TestEmptyState, self).setUp()
+
+    def test_add_location_button(self):
+        """ tests that the add location page is shown after swiping up
+            the bottom edge"""
+
+        home_page = self.app.get_home_page()
+        home_page.visible.wait_for(True)
+        home_page.reveal_bottom_edge_page()
+
+        locations_page = self.app.get_locations_page()
+
+        self.assertThat(locations_page.visible, Eventually(Equals(True)))

=== added file 'tests/autopilot/ubuntu_weather_app/tests/test_home_page.py'
--- tests/autopilot/ubuntu_weather_app/tests/test_home_page.py	1970-01-01 00:00:00 +0000
+++ tests/autopilot/ubuntu_weather_app/tests/test_home_page.py	2015-08-05 19:54:56 +0000
@@ -0,0 +1,32 @@
+# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*-
+# Copyright 2013, 2014, 2015 Canonical
+#
+# This program is free software: you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 3, as published
+# by the Free Software Foundation.
+
+"""Ubuntu Weather app autopilot tests."""
+
+from __future__ import absolute_import
+
+import logging
+from autopilot.matchers import Eventually
+from testtools.matchers import Equals
+
+
+from ubuntu_weather_app.tests import UbuntuWeatherAppTestCaseWithData
+
+logger = logging.getLogger(__name__)
+
+
+class TestHomePage(UbuntuWeatherAppTestCaseWithData):
+
+    def setUp(self):
+        super(TestHomePage, self).setUp()
+
+    def test_locations_count_startup(self):
+        """ tests that the correct number of locations appear at startup """
+
+        home_page = self.app.get_home_page()
+
+        self.assertThat(home_page.get_location_count, Eventually(Equals(2)))

=== added file 'ubuntu-weather-app.apparmor'
--- ubuntu-weather-app.apparmor	1970-01-01 00:00:00 +0000
+++ ubuntu-weather-app.apparmor	2015-08-05 19:54:56 +0000
@@ -0,0 +1,8 @@
+{
+    "policy_groups": [
+    	"location",
+    	"networking",
+    	"sensors"
+    ], 
+    "policy_version": 1.3
+}

=== added file 'ubuntu-weather-app.desktop.in.in'
--- ubuntu-weather-app.desktop.in.in	1970-01-01 00:00:00 +0000
+++ ubuntu-weather-app.desktop.in.in	2015-08-05 19:54:56 +0000
@@ -0,0 +1,12 @@
+[Desktop Entry]
+Version=1.0
+Type=Application
+Terminal=false
+Exec=@EXEC@
+Icon=@ICON@
+_Name=Weather
+_Comment=A weather forecast application for Ubuntu with support for multiple online weather data sources
+_Keywords=weather;forecast;twc;openweathermap;the weather channel;
+X-Ubuntu-Touch=true
+X-Ubuntu-Default-Department-ID=accessories
+X-Ubuntu-Splash-Color=#F5F5F5