summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorCaroline Chao <caroline.chao@digia.com>2013-12-10 14:42:22 +0100
committerCaroline Chao <caroline.chao@digia.com>2013-12-10 14:42:22 +0100
commit9e2a27f41ab4b76851440fe0d5a11e1ae7ca9dde (patch)
tree234b14b90e9627939e2f99087c84e2ce5c1c72bb
Initial commitv1.1
-rw-r--r--.gitignore15
-rw-r--r--android/AndroidManifest.xml40
-rw-r--r--android/res/drawable-hdpi/icon.pngbin0 -> 7414 bytes
-rw-r--r--android/res/drawable-ldpi/icon.pngbin0 -> 3404 bytes
-rw-r--r--android/res/drawable-mdpi/icon.pngbin0 -> 4621 bytes
-rw-r--r--app-icons/AppIcon_100px.pngbin0 -> 11228 bytes
-rw-r--r--app-icons/AppIcon_1024px.pngbin0 -> 293694 bytes
-rw-r--r--app-icons/AppIcon_114px.pngbin0 -> 13680 bytes
-rw-r--r--app-icons/AppIcon_120px.pngbin0 -> 14423 bytes
-rw-r--r--app-icons/AppIcon_144px.pngbin0 -> 18424 bytes
-rw-r--r--app-icons/AppIcon_152px.pngbin0 -> 15072 bytes
-rw-r--r--app-icons/AppIcon_29px.pngbin0 -> 2569 bytes
-rw-r--r--app-icons/AppIcon_36px.pngbin0 -> 3240 bytes
-rw-r--r--app-icons/AppIcon_40px.pngbin0 -> 3515 bytes
-rw-r--r--app-icons/AppIcon_48px.pngbin0 -> 4423 bytes
-rw-r--r--app-icons/AppIcon_50px.pngbin0 -> 4570 bytes
-rw-r--r--app-icons/AppIcon_512px.pngbin0 -> 109605 bytes
-rw-r--r--app-icons/AppIcon_57px.pngbin0 -> 5380 bytes
-rw-r--r--app-icons/AppIcon_58px.pngbin0 -> 5597 bytes
-rw-r--r--app-icons/AppIcon_72px.pngbin0 -> 7127 bytes
-rw-r--r--app-icons/AppIcon_76px.pngbin0 -> 7822 bytes
-rw-r--r--app-icons/AppIcon_80px.pngbin0 -> 8166 bytes
-rw-r--r--fonts/LICENSE.txt202
-rw-r--r--fonts/OpenSans-Bold.ttfbin0 -> 224592 bytes
-rw-r--r--fonts/OpenSans-Regular.ttfbin0 -> 217360 bytes
-rw-r--r--fonts/OpenSans-Semibold.ttfbin0 -> 221328 bytes
-rw-r--r--ios/Images.xcassets/AppIcon.appiconset/AppIcon_100px.pngbin0 -> 11228 bytes
-rw-r--r--ios/Images.xcassets/AppIcon.appiconset/AppIcon_114px.pngbin0 -> 13680 bytes
-rw-r--r--ios/Images.xcassets/AppIcon.appiconset/AppIcon_120px.pngbin0 -> 14423 bytes
-rw-r--r--ios/Images.xcassets/AppIcon.appiconset/AppIcon_144px.pngbin0 -> 18424 bytes
-rw-r--r--ios/Images.xcassets/AppIcon.appiconset/AppIcon_152px.pngbin0 -> 15072 bytes
-rw-r--r--ios/Images.xcassets/AppIcon.appiconset/AppIcon_29px.pngbin0 -> 2569 bytes
-rw-r--r--ios/Images.xcassets/AppIcon.appiconset/AppIcon_40px.pngbin0 -> 3515 bytes
-rw-r--r--ios/Images.xcassets/AppIcon.appiconset/AppIcon_50px.pngbin0 -> 4570 bytes
-rw-r--r--ios/Images.xcassets/AppIcon.appiconset/AppIcon_57px.pngbin0 -> 5380 bytes
-rw-r--r--ios/Images.xcassets/AppIcon.appiconset/AppIcon_58px.pngbin0 -> 5597 bytes
-rw-r--r--ios/Images.xcassets/AppIcon.appiconset/AppIcon_72px.pngbin0 -> 7127 bytes
-rw-r--r--ios/Images.xcassets/AppIcon.appiconset/AppIcon_76px.pngbin0 -> 7822 bytes
-rw-r--r--ios/Images.xcassets/AppIcon.appiconset/AppIcon_80px.pngbin0 -> 8166 bytes
-rw-r--r--ios/Images.xcassets/AppIcon.appiconset/Contents.json104
-rw-r--r--ios/Images.xcassets/LaunchImage.launchimage/Contents.json107
-rw-r--r--ios/Images.xcassets/LaunchImage.launchimage/NoSB_ipad_7_Land.pngbin0 -> 96322 bytes
-rw-r--r--ios/Images.xcassets/LaunchImage.launchimage/NoSB_ipad_7_Port.pngbin0 -> 116434 bytes
-rw-r--r--ios/Images.xcassets/LaunchImage.launchimage/NoSB_ipad_7_R_Land.pngbin0 -> 234465 bytes
-rw-r--r--ios/Images.xcassets/LaunchImage.launchimage/NoSB_ipad_7_R_Port.pngbin0 -> 282805 bytes
-rw-r--r--ios/Images.xcassets/LaunchImage.launchimage/ipad_7_Land.pngbin0 -> 110632 bytes
-rw-r--r--ios/Images.xcassets/LaunchImage.launchimage/ipad_7_Port.pngbin0 -> 130586 bytes
-rw-r--r--ios/Images.xcassets/LaunchImage.launchimage/ipad_7_R_Land.pngbin0 -> 287682 bytes
-rw-r--r--ios/Images.xcassets/LaunchImage.launchimage/ipad_7_R_Port.pngbin0 -> 337781 bytes
-rw-r--r--ios/Images.xcassets/LaunchImage.launchimage/iphone_6.1.pngbin0 -> 48664 bytes
-rw-r--r--ios/Images.xcassets/LaunchImage.launchimage/iphone_7_R3.5.pngbin0 -> 116742 bytes
-rw-r--r--ios/Images.xcassets/LaunchImage.launchimage/iphone_7_R4.pngbin0 -> 144780 bytes
-rw-r--r--ios/iosInfo.plist51
-rw-r--r--ios/readme.txt15
-rw-r--r--qml/js/utils.js277
-rw-r--r--qml/main.qml178
-rw-r--r--qml/models/SearchResultModel.qml32
-rw-r--r--qml/models/WeatherModel.qml134
-rw-r--r--qml/pages/BasicPage.qml205
-rw-r--r--qml/pages/CitiesPage.qml148
-rw-r--r--qml/pages/LongTermDayItem.qml156
-rw-r--r--qml/pages/LongTermPage.qml135
-rw-r--r--qml/pages/OneDayPage.qml100
-rw-r--r--qml/pages/OneDaySliderItem.qml172
-rw-r--r--qml/pages/OneDayZoomItem.qml171
-rw-r--r--qml/pages/Separator.qml52
-rw-r--r--qml/touch/ListViewDelegate.qml158
-rw-r--r--qml/touch/Separator.qml29
-rw-r--r--qml/touch/TouchLabel.qml79
-rw-r--r--qml/touch/TouchScrollView.qml59
-rw-r--r--qml/touch/TouchSlider.qml81
-rw-r--r--qml/touch/TouchTextField.qml115
-rw-r--r--qml/touch/images/BackArrow.pngbin0 -> 376 bytes
-rw-r--r--qml/touch/images/Circle.pngbin0 -> 1219 bytes
-rw-r--r--qml/touch/images/Clear.pngbin0 -> 1783 bytes
-rw-r--r--qml/touch/images/Pointer.pngbin0 -> 5674 bytes
-rw-r--r--qml/touch/images/Pointer_pressed.pngbin0 -> 5690 bytes
-rw-r--r--qml/touch/images/darkclose.pngbin0 -> 3328 bytes
-rw-r--r--qml/touch/images/magnifier.pngbin0 -> 3422 bytes
-rw-r--r--src/applicationinfo.cpp193
-rw-r--r--src/applicationinfo.h139
-rw-r--r--src/applicationpaths.h75
-rw-r--r--src/cities.cpp164
-rw-r--r--src/cities.h92
-rw-r--r--src/citieslistmodel.cpp125
-rw-r--r--src/citieslistmodel.h84
-rw-r--r--src/citymodel.cpp302
-rw-r--r--src/citymodel.h138
-rw-r--r--src/daymodel.cpp149
-rw-r--r--src/daymodel.h116
-rw-r--r--src/main.cpp138
-rw-r--r--src/src.pri16
-rw-r--r--src/weatherimageprovider.h72
-rw-r--r--weatherapp.pro74
94 files changed, 4692 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..d3a8700
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,15 @@
+Makefile
+WeatherApp
+
+*.dll
+*.exe
+*.o
+*.so
+*.pro.user
+*.qrc
+*.wa
+*.settings
+
+moc_*.cpp
+qrc_*.cpp
+
diff --git a/android/AndroidManifest.xml b/android/AndroidManifest.xml
new file mode 100644
index 0000000..7e189fd
--- /dev/null
+++ b/android/AndroidManifest.xml
@@ -0,0 +1,40 @@
+<?xml version='1.0' encoding='utf-8'?>
+<manifest android:versionCode="3" android:installLocation="auto" xmlns:android="http://schemas.android.com/apk/res/android" package="org.qtproject.quickforecast" android:versionName="1.1">
+ <application android:name="org.qtproject.qt5.android.bindings.QtApplication" android:label="@string/app_name" android:icon="@drawable/icon">
+ <activity android:screenOrientation="unspecified" android:name="org.qtproject.qt5.android.bindings.QtActivity" android:label="@string/app_name" android:configChanges="orientation|uiMode|screenLayout|screenSize|smallestScreenSize|locale|fontScale|keyboard|keyboardHidden|navigation">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN"/>
+ <category android:name="android.intent.category.LAUNCHER"/>
+ </intent-filter>
+ <meta-data android:value="QuickForecast" android:name="android.app.lib_name"/>
+ <meta-data android:resource="@array/qt_sources" android:name="android.app.qt_sources_resource_id"/>
+ <meta-data android:value="default" android:name="android.app.repository"/>
+ <meta-data android:resource="@array/qt_libs" android:name="android.app.qt_libs_resource_id"/>
+ <meta-data android:resource="@array/bundled_libs" android:name="android.app.bundled_libs_resource_id"/>
+ <!-- Deploy Qt libs as part of package -->
+ <meta-data android:value="-- %%BUNDLE_LOCAL_QT_LIBS%% --" android:name="android.app.bundle_local_qt_libs"/>
+ <meta-data android:resource="@array/bundled_in_lib" android:name="android.app.bundled_in_lib_resource_id"/>
+ <meta-data android:resource="@array/bundled_in_assets" android:name="android.app.bundled_in_assets_resource_id"/>
+ <!-- Run with local libs -->
+ <meta-data android:value="-- %%USE_LOCAL_QT_LIBS%% --" android:name="android.app.use_local_qt_libs"/>
+ <meta-data android:value="/data/local/tmp/qt/" android:name="android.app.libs_prefix"/>
+ <meta-data android:value="-- %%INSERT_LOCAL_LIBS%% --" android:name="android.app.load_local_libs"/>
+ <meta-data android:value="-- %%INSERT_LOCAL_JARS%% --" android:name="android.app.load_local_jars"/>
+ <meta-data android:value="-- %%INSERT_INIT_CLASSES%% --" android:name="android.app.static_init_classes"/>
+ <!-- Messages maps -->
+ <meta-data android:value="@string/ministro_not_found_msg" android:name="android.app.ministro_not_found_msg"/>
+ <meta-data android:value="@string/ministro_needed_msg" android:name="android.app.ministro_needed_msg"/>
+ <meta-data android:value="@string/fatal_error_msg" android:name="android.app.fatal_error_msg"/>
+ <!-- Messages maps -->
+ <!-- Splash screen -->
+ <meta-data android:resource="@layout/splash" android:name="android.app.splash_screen"/>
+ <!-- Splash screen -->
+ </activity>
+ </application>
+ <uses-sdk android:minSdkVersion="9" android:targetSdkVersion="18"/>
+ <supports-screens android:normalScreens="true" android:smallScreens="true" android:largeScreens="true" android:anyDensity="true"/>
+ <!-- %%INSERT_PERMISSIONS -->
+ <!-- %%INSERT_FEATURES -->
+ <uses-permission android:name="android.permission.INTERNET"/>
+ <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
+</manifest>
diff --git a/android/res/drawable-hdpi/icon.png b/android/res/drawable-hdpi/icon.png
new file mode 100644
index 0000000..4e95fc2
--- /dev/null
+++ b/android/res/drawable-hdpi/icon.png
Binary files differ
diff --git a/android/res/drawable-ldpi/icon.png b/android/res/drawable-ldpi/icon.png
new file mode 100644
index 0000000..17eb470
--- /dev/null
+++ b/android/res/drawable-ldpi/icon.png
Binary files differ
diff --git a/android/res/drawable-mdpi/icon.png b/android/res/drawable-mdpi/icon.png
new file mode 100644
index 0000000..ba69e8f
--- /dev/null
+++ b/android/res/drawable-mdpi/icon.png
Binary files differ
diff --git a/app-icons/AppIcon_100px.png b/app-icons/AppIcon_100px.png
new file mode 100644
index 0000000..7ab56c9
--- /dev/null
+++ b/app-icons/AppIcon_100px.png
Binary files differ
diff --git a/app-icons/AppIcon_1024px.png b/app-icons/AppIcon_1024px.png
new file mode 100644
index 0000000..462c68c
--- /dev/null
+++ b/app-icons/AppIcon_1024px.png
Binary files differ
diff --git a/app-icons/AppIcon_114px.png b/app-icons/AppIcon_114px.png
new file mode 100644
index 0000000..0fe60cb
--- /dev/null
+++ b/app-icons/AppIcon_114px.png
Binary files differ
diff --git a/app-icons/AppIcon_120px.png b/app-icons/AppIcon_120px.png
new file mode 100644
index 0000000..0525a69
--- /dev/null
+++ b/app-icons/AppIcon_120px.png
Binary files differ
diff --git a/app-icons/AppIcon_144px.png b/app-icons/AppIcon_144px.png
new file mode 100644
index 0000000..ad5e348
--- /dev/null
+++ b/app-icons/AppIcon_144px.png
Binary files differ
diff --git a/app-icons/AppIcon_152px.png b/app-icons/AppIcon_152px.png
new file mode 100644
index 0000000..ad63eb3
--- /dev/null
+++ b/app-icons/AppIcon_152px.png
Binary files differ
diff --git a/app-icons/AppIcon_29px.png b/app-icons/AppIcon_29px.png
new file mode 100644
index 0000000..718b00e
--- /dev/null
+++ b/app-icons/AppIcon_29px.png
Binary files differ
diff --git a/app-icons/AppIcon_36px.png b/app-icons/AppIcon_36px.png
new file mode 100644
index 0000000..2592625
--- /dev/null
+++ b/app-icons/AppIcon_36px.png
Binary files differ
diff --git a/app-icons/AppIcon_40px.png b/app-icons/AppIcon_40px.png
new file mode 100644
index 0000000..9a6aeda
--- /dev/null
+++ b/app-icons/AppIcon_40px.png
Binary files differ
diff --git a/app-icons/AppIcon_48px.png b/app-icons/AppIcon_48px.png
new file mode 100644
index 0000000..2e4b199
--- /dev/null
+++ b/app-icons/AppIcon_48px.png
Binary files differ
diff --git a/app-icons/AppIcon_50px.png b/app-icons/AppIcon_50px.png
new file mode 100644
index 0000000..f2c3520
--- /dev/null
+++ b/app-icons/AppIcon_50px.png
Binary files differ
diff --git a/app-icons/AppIcon_512px.png b/app-icons/AppIcon_512px.png
new file mode 100644
index 0000000..74eb30a
--- /dev/null
+++ b/app-icons/AppIcon_512px.png
Binary files differ
diff --git a/app-icons/AppIcon_57px.png b/app-icons/AppIcon_57px.png
new file mode 100644
index 0000000..2874aa9
--- /dev/null
+++ b/app-icons/AppIcon_57px.png
Binary files differ
diff --git a/app-icons/AppIcon_58px.png b/app-icons/AppIcon_58px.png
new file mode 100644
index 0000000..4b56cb7
--- /dev/null
+++ b/app-icons/AppIcon_58px.png
Binary files differ
diff --git a/app-icons/AppIcon_72px.png b/app-icons/AppIcon_72px.png
new file mode 100644
index 0000000..49a8bf4
--- /dev/null
+++ b/app-icons/AppIcon_72px.png
Binary files differ
diff --git a/app-icons/AppIcon_76px.png b/app-icons/AppIcon_76px.png
new file mode 100644
index 0000000..6a3ba5e
--- /dev/null
+++ b/app-icons/AppIcon_76px.png
Binary files differ
diff --git a/app-icons/AppIcon_80px.png b/app-icons/AppIcon_80px.png
new file mode 100644
index 0000000..bf56b81
--- /dev/null
+++ b/app-icons/AppIcon_80px.png
Binary files differ
diff --git a/fonts/LICENSE.txt b/fonts/LICENSE.txt
new file mode 100644
index 0000000..75b5248
--- /dev/null
+++ b/fonts/LICENSE.txt
@@ -0,0 +1,202 @@
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
diff --git a/fonts/OpenSans-Bold.ttf b/fonts/OpenSans-Bold.ttf
new file mode 100644
index 0000000..fd79d43
--- /dev/null
+++ b/fonts/OpenSans-Bold.ttf
Binary files differ
diff --git a/fonts/OpenSans-Regular.ttf b/fonts/OpenSans-Regular.ttf
new file mode 100644
index 0000000..db43334
--- /dev/null
+++ b/fonts/OpenSans-Regular.ttf
Binary files differ
diff --git a/fonts/OpenSans-Semibold.ttf b/fonts/OpenSans-Semibold.ttf
new file mode 100644
index 0000000..1a7679e
--- /dev/null
+++ b/fonts/OpenSans-Semibold.ttf
Binary files differ
diff --git a/ios/Images.xcassets/AppIcon.appiconset/AppIcon_100px.png b/ios/Images.xcassets/AppIcon.appiconset/AppIcon_100px.png
new file mode 100644
index 0000000..7ab56c9
--- /dev/null
+++ b/ios/Images.xcassets/AppIcon.appiconset/AppIcon_100px.png
Binary files differ
diff --git a/ios/Images.xcassets/AppIcon.appiconset/AppIcon_114px.png b/ios/Images.xcassets/AppIcon.appiconset/AppIcon_114px.png
new file mode 100644
index 0000000..0fe60cb
--- /dev/null
+++ b/ios/Images.xcassets/AppIcon.appiconset/AppIcon_114px.png
Binary files differ
diff --git a/ios/Images.xcassets/AppIcon.appiconset/AppIcon_120px.png b/ios/Images.xcassets/AppIcon.appiconset/AppIcon_120px.png
new file mode 100644
index 0000000..0525a69
--- /dev/null
+++ b/ios/Images.xcassets/AppIcon.appiconset/AppIcon_120px.png
Binary files differ
diff --git a/ios/Images.xcassets/AppIcon.appiconset/AppIcon_144px.png b/ios/Images.xcassets/AppIcon.appiconset/AppIcon_144px.png
new file mode 100644
index 0000000..ad5e348
--- /dev/null
+++ b/ios/Images.xcassets/AppIcon.appiconset/AppIcon_144px.png
Binary files differ
diff --git a/ios/Images.xcassets/AppIcon.appiconset/AppIcon_152px.png b/ios/Images.xcassets/AppIcon.appiconset/AppIcon_152px.png
new file mode 100644
index 0000000..ad63eb3
--- /dev/null
+++ b/ios/Images.xcassets/AppIcon.appiconset/AppIcon_152px.png
Binary files differ
diff --git a/ios/Images.xcassets/AppIcon.appiconset/AppIcon_29px.png b/ios/Images.xcassets/AppIcon.appiconset/AppIcon_29px.png
new file mode 100644
index 0000000..718b00e
--- /dev/null
+++ b/ios/Images.xcassets/AppIcon.appiconset/AppIcon_29px.png
Binary files differ
diff --git a/ios/Images.xcassets/AppIcon.appiconset/AppIcon_40px.png b/ios/Images.xcassets/AppIcon.appiconset/AppIcon_40px.png
new file mode 100644
index 0000000..9a6aeda
--- /dev/null
+++ b/ios/Images.xcassets/AppIcon.appiconset/AppIcon_40px.png
Binary files differ
diff --git a/ios/Images.xcassets/AppIcon.appiconset/AppIcon_50px.png b/ios/Images.xcassets/AppIcon.appiconset/AppIcon_50px.png
new file mode 100644
index 0000000..f2c3520
--- /dev/null
+++ b/ios/Images.xcassets/AppIcon.appiconset/AppIcon_50px.png
Binary files differ
diff --git a/ios/Images.xcassets/AppIcon.appiconset/AppIcon_57px.png b/ios/Images.xcassets/AppIcon.appiconset/AppIcon_57px.png
new file mode 100644
index 0000000..2874aa9
--- /dev/null
+++ b/ios/Images.xcassets/AppIcon.appiconset/AppIcon_57px.png
Binary files differ
diff --git a/ios/Images.xcassets/AppIcon.appiconset/AppIcon_58px.png b/ios/Images.xcassets/AppIcon.appiconset/AppIcon_58px.png
new file mode 100644
index 0000000..4b56cb7
--- /dev/null
+++ b/ios/Images.xcassets/AppIcon.appiconset/AppIcon_58px.png
Binary files differ
diff --git a/ios/Images.xcassets/AppIcon.appiconset/AppIcon_72px.png b/ios/Images.xcassets/AppIcon.appiconset/AppIcon_72px.png
new file mode 100644
index 0000000..49a8bf4
--- /dev/null
+++ b/ios/Images.xcassets/AppIcon.appiconset/AppIcon_72px.png
Binary files differ
diff --git a/ios/Images.xcassets/AppIcon.appiconset/AppIcon_76px.png b/ios/Images.xcassets/AppIcon.appiconset/AppIcon_76px.png
new file mode 100644
index 0000000..6a3ba5e
--- /dev/null
+++ b/ios/Images.xcassets/AppIcon.appiconset/AppIcon_76px.png
Binary files differ
diff --git a/ios/Images.xcassets/AppIcon.appiconset/AppIcon_80px.png b/ios/Images.xcassets/AppIcon.appiconset/AppIcon_80px.png
new file mode 100644
index 0000000..bf56b81
--- /dev/null
+++ b/ios/Images.xcassets/AppIcon.appiconset/AppIcon_80px.png
Binary files differ
diff --git a/ios/Images.xcassets/AppIcon.appiconset/Contents.json b/ios/Images.xcassets/AppIcon.appiconset/Contents.json
new file mode 100644
index 0000000..afa67cd
--- /dev/null
+++ b/ios/Images.xcassets/AppIcon.appiconset/Contents.json
@@ -0,0 +1,104 @@
+{
+ "images" : [
+ {
+ "size" : "29x29",
+ "idiom" : "iphone",
+ "filename" : "AppIcon_29px.png",
+ "scale" : "1x"
+ },
+ {
+ "size" : "29x29",
+ "idiom" : "iphone",
+ "filename" : "AppIcon_58px.png",
+ "scale" : "2x"
+ },
+ {
+ "size" : "40x40",
+ "idiom" : "iphone",
+ "filename" : "AppIcon_80px.png",
+ "scale" : "2x"
+ },
+ {
+ "size" : "57x57",
+ "idiom" : "iphone",
+ "filename" : "AppIcon_57px.png",
+ "scale" : "1x"
+ },
+ {
+ "size" : "57x57",
+ "idiom" : "iphone",
+ "filename" : "AppIcon_114px.png",
+ "scale" : "2x"
+ },
+ {
+ "size" : "60x60",
+ "idiom" : "iphone",
+ "filename" : "AppIcon_120px.png",
+ "scale" : "2x"
+ },
+ {
+ "size" : "29x29",
+ "idiom" : "ipad",
+ "filename" : "AppIcon_29px.png",
+ "scale" : "1x"
+ },
+ {
+ "size" : "29x29",
+ "idiom" : "ipad",
+ "filename" : "AppIcon_58px.png",
+ "scale" : "2x"
+ },
+ {
+ "size" : "40x40",
+ "idiom" : "ipad",
+ "filename" : "AppIcon_40px.png",
+ "scale" : "1x"
+ },
+ {
+ "size" : "40x40",
+ "idiom" : "ipad",
+ "filename" : "AppIcon_80px.png",
+ "scale" : "2x"
+ },
+ {
+ "size" : "50x50",
+ "idiom" : "ipad",
+ "filename" : "AppIcon_50px.png",
+ "scale" : "1x"
+ },
+ {
+ "size" : "50x50",
+ "idiom" : "ipad",
+ "filename" : "AppIcon_100px.png",
+ "scale" : "2x"
+ },
+ {
+ "size" : "72x72",
+ "idiom" : "ipad",
+ "filename" : "AppIcon_72px.png",
+ "scale" : "1x"
+ },
+ {
+ "size" : "72x72",
+ "idiom" : "ipad",
+ "filename" : "AppIcon_144px.png",
+ "scale" : "2x"
+ },
+ {
+ "size" : "76x76",
+ "idiom" : "ipad",
+ "filename" : "AppIcon_76px.png",
+ "scale" : "1x"
+ },
+ {
+ "size" : "76x76",
+ "idiom" : "ipad",
+ "filename" : "AppIcon_152px.png",
+ "scale" : "2x"
+ }
+ ],
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ }
+} \ No newline at end of file
diff --git a/ios/Images.xcassets/LaunchImage.launchimage/Contents.json b/ios/Images.xcassets/LaunchImage.launchimage/Contents.json
new file mode 100644
index 0000000..a685873
--- /dev/null
+++ b/ios/Images.xcassets/LaunchImage.launchimage/Contents.json
@@ -0,0 +1,107 @@
+{
+ "images" : [
+ {
+ "orientation" : "portrait",
+ "idiom" : "iphone",
+ "extent" : "full-screen",
+ "minimum-system-version" : "7.0",
+ "filename" : "iphone_7_R3.5.png",
+ "scale" : "2x"
+ },
+ {
+ "extent" : "full-screen",
+ "idiom" : "iphone",
+ "subtype" : "retina4",
+ "filename" : "iphone_7_R4.png",
+ "minimum-system-version" : "7.0",
+ "orientation" : "portrait",
+ "scale" : "2x"
+ },
+ {
+ "orientation" : "portrait",
+ "idiom" : "ipad",
+ "extent" : "full-screen",
+ "minimum-system-version" : "7.0",
+ "filename" : "ipad_7_Port.png",
+ "scale" : "1x"
+ },
+ {
+ "orientation" : "landscape",
+ "idiom" : "ipad",
+ "extent" : "full-screen",
+ "minimum-system-version" : "7.0",
+ "filename" : "ipad_7_Land.png",
+ "scale" : "1x"
+ },
+ {
+ "orientation" : "portrait",
+ "idiom" : "ipad",
+ "extent" : "full-screen",
+ "minimum-system-version" : "7.0",
+ "filename" : "ipad_7_R_Port.png",
+ "scale" : "2x"
+ },
+ {
+ "orientation" : "landscape",
+ "idiom" : "ipad",
+ "extent" : "full-screen",
+ "minimum-system-version" : "7.0",
+ "filename" : "ipad_7_R_Land.png",
+ "scale" : "2x"
+ },
+ {
+ "orientation" : "portrait",
+ "idiom" : "iphone",
+ "extent" : "full-screen",
+ "filename" : "iphone_6.1.png",
+ "scale" : "1x"
+ },
+ {
+ "orientation" : "portrait",
+ "idiom" : "iphone",
+ "extent" : "full-screen",
+ "filename" : "iphone_7_R3.5.png",
+ "scale" : "2x"
+ },
+ {
+ "orientation" : "portrait",
+ "idiom" : "iphone",
+ "extent" : "full-screen",
+ "filename" : "iphone_7_R4.png",
+ "subtype" : "retina4",
+ "scale" : "2x"
+ },
+ {
+ "orientation" : "portrait",
+ "idiom" : "ipad",
+ "extent" : "to-status-bar",
+ "filename" : "NoSB_ipad_7_Port.png",
+ "scale" : "1x"
+ },
+ {
+ "orientation" : "landscape",
+ "idiom" : "ipad",
+ "extent" : "to-status-bar",
+ "filename" : "NoSB_ipad_7_Land.png",
+ "scale" : "1x"
+ },
+ {
+ "orientation" : "portrait",
+ "idiom" : "ipad",
+ "extent" : "to-status-bar",
+ "filename" : "NoSB_ipad_7_R_Port.png",
+ "scale" : "2x"
+ },
+ {
+ "orientation" : "landscape",
+ "idiom" : "ipad",
+ "extent" : "to-status-bar",
+ "filename" : "NoSB_ipad_7_R_Land.png",
+ "scale" : "2x"
+ }
+ ],
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ }
+} \ No newline at end of file
diff --git a/ios/Images.xcassets/LaunchImage.launchimage/NoSB_ipad_7_Land.png b/ios/Images.xcassets/LaunchImage.launchimage/NoSB_ipad_7_Land.png
new file mode 100644
index 0000000..f5c1011
--- /dev/null
+++ b/ios/Images.xcassets/LaunchImage.launchimage/NoSB_ipad_7_Land.png
Binary files differ
diff --git a/ios/Images.xcassets/LaunchImage.launchimage/NoSB_ipad_7_Port.png b/ios/Images.xcassets/LaunchImage.launchimage/NoSB_ipad_7_Port.png
new file mode 100644
index 0000000..0cd0c65
--- /dev/null
+++ b/ios/Images.xcassets/LaunchImage.launchimage/NoSB_ipad_7_Port.png
Binary files differ
diff --git a/ios/Images.xcassets/LaunchImage.launchimage/NoSB_ipad_7_R_Land.png b/ios/Images.xcassets/LaunchImage.launchimage/NoSB_ipad_7_R_Land.png
new file mode 100644
index 0000000..10e007d
--- /dev/null
+++ b/ios/Images.xcassets/LaunchImage.launchimage/NoSB_ipad_7_R_Land.png
Binary files differ
diff --git a/ios/Images.xcassets/LaunchImage.launchimage/NoSB_ipad_7_R_Port.png b/ios/Images.xcassets/LaunchImage.launchimage/NoSB_ipad_7_R_Port.png
new file mode 100644
index 0000000..8e90fd3
--- /dev/null
+++ b/ios/Images.xcassets/LaunchImage.launchimage/NoSB_ipad_7_R_Port.png
Binary files differ
diff --git a/ios/Images.xcassets/LaunchImage.launchimage/ipad_7_Land.png b/ios/Images.xcassets/LaunchImage.launchimage/ipad_7_Land.png
new file mode 100644
index 0000000..055975e
--- /dev/null
+++ b/ios/Images.xcassets/LaunchImage.launchimage/ipad_7_Land.png
Binary files differ
diff --git a/ios/Images.xcassets/LaunchImage.launchimage/ipad_7_Port.png b/ios/Images.xcassets/LaunchImage.launchimage/ipad_7_Port.png
new file mode 100644
index 0000000..b1b02da
--- /dev/null
+++ b/ios/Images.xcassets/LaunchImage.launchimage/ipad_7_Port.png
Binary files differ
diff --git a/ios/Images.xcassets/LaunchImage.launchimage/ipad_7_R_Land.png b/ios/Images.xcassets/LaunchImage.launchimage/ipad_7_R_Land.png
new file mode 100644
index 0000000..b149b62
--- /dev/null
+++ b/ios/Images.xcassets/LaunchImage.launchimage/ipad_7_R_Land.png
Binary files differ
diff --git a/ios/Images.xcassets/LaunchImage.launchimage/ipad_7_R_Port.png b/ios/Images.xcassets/LaunchImage.launchimage/ipad_7_R_Port.png
new file mode 100644
index 0000000..3a660bf
--- /dev/null
+++ b/ios/Images.xcassets/LaunchImage.launchimage/ipad_7_R_Port.png
Binary files differ
diff --git a/ios/Images.xcassets/LaunchImage.launchimage/iphone_6.1.png b/ios/Images.xcassets/LaunchImage.launchimage/iphone_6.1.png
new file mode 100644
index 0000000..51fab95
--- /dev/null
+++ b/ios/Images.xcassets/LaunchImage.launchimage/iphone_6.1.png
Binary files differ
diff --git a/ios/Images.xcassets/LaunchImage.launchimage/iphone_7_R3.5.png b/ios/Images.xcassets/LaunchImage.launchimage/iphone_7_R3.5.png
new file mode 100644
index 0000000..c4130ac
--- /dev/null
+++ b/ios/Images.xcassets/LaunchImage.launchimage/iphone_7_R3.5.png
Binary files differ
diff --git a/ios/Images.xcassets/LaunchImage.launchimage/iphone_7_R4.png b/ios/Images.xcassets/LaunchImage.launchimage/iphone_7_R4.png
new file mode 100644
index 0000000..fe97bdf
--- /dev/null
+++ b/ios/Images.xcassets/LaunchImage.launchimage/iphone_7_R4.png
Binary files differ
diff --git a/ios/iosInfo.plist b/ios/iosInfo.plist
new file mode 100644
index 0000000..6a26fee
--- /dev/null
+++ b/ios/iosInfo.plist
@@ -0,0 +1,51 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>CFBundleDisplayName</key>
+ <string>QuickForecast</string>
+ <key>CFBundleExecutable</key>
+ <string>QuickForecast</string>
+ <key>CFBundleGetInfoString</key>
+ <string>Created by Qt/QMake</string>
+ <key>CFBundleIcons</key>
+ <dict/>
+ <key>CFBundleIcons~ipad</key>
+ <dict/>
+ <key>CFBundleIdentifier</key>
+ <string>com.digia.qt.iosteam.WeatherApp</string>
+ <key>CFBundleName</key>
+ <string>Quick Forecast</string>
+ <key>CFBundlePackageType</key>
+ <string>APPL</string>
+ <key>CFBundleShortVersionString</key>
+ <string>1.1</string>
+ <key>CFBundleSignature</key>
+ <string>????</string>
+ <key>CFBundleVersion</key>
+ <string>1.1</string>
+ <key>NOTE</key>
+ <string>This file was generated by Qt/QMake.</string>
+ <key>UIAppFonts</key>
+ <array>
+ <string>fonts/OpenSans-Bold.ttf</string>
+ <string>fonts/OpenSans-Semibold.ttf</string>
+ <string>fonts/OpenSans-Regular.ttf</string>
+ </array>
+ <key>UIStatusBarHidden</key>
+ <true/>
+ <key>UIStatusBarHidden~ipad</key>
+ <true/>
+ <key>UISupportedInterfaceOrientations</key>
+ <array>
+ <string>UIInterfaceOrientationPortrait</string>
+ </array>
+ <key>UISupportedInterfaceOrientations~ipad</key>
+ <array>
+ <string>UIInterfaceOrientationPortrait</string>
+ <string>UIInterfaceOrientationPortraitUpsideDown</string>
+ <string>UIInterfaceOrientationLandscapeLeft</string>
+ <string>UIInterfaceOrientationLandscapeRight</string>
+ </array>
+</dict>
+</plist>
diff --git a/ios/readme.txt b/ios/readme.txt
new file mode 100644
index 0000000..a59fa72
--- /dev/null
+++ b/ios/readme.txt
@@ -0,0 +1,15 @@
+* In order to use the images assets:
+
+- After running qmake, open the Xcode project
+- In the General tab of the project, go down to App Icons section
+- Click for Source "use Asset Catalog"
+- Validate by selecting Migrate
+- In the pro file directory, replace Images.xcassets under QuickForecast
+by the one under ios.
+
+=> The icons and launch images are ready to be used
+
+* Default image
+
+In Xcode, in the "Bundle Resources" section, remove the default launch
+image. It is not needed.
diff --git a/qml/js/utils.js b/qml/js/utils.js
new file mode 100644
index 0000000..caa21ea
--- /dev/null
+++ b/qml/js/utils.js
@@ -0,0 +1,277 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the FOO module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+.pragma library
+
+// LongTermPage utils
+
+function getAfternoonIndex(dayModel)
+{
+ var index = 0
+ var count = intervalCount
+ if (count > 1)
+ index = count - 1
+ return index
+}
+
+function getTemp(isMax, dayModel) {
+ var temp = getTemperature(0, dayModel)
+ var count = dayModel.periodCount()
+ for (var i = 0; i < count; i++) {
+ var currentTemp = getTemperature(i, dayModel)
+ if (isMax)
+ temp = Math.max(temp, currentTemp)
+ else
+ temp = Math.min(temp, currentTemp)
+ }
+ return temp
+}
+
+function getMinTemp(dayModel)
+{
+ return getTemp(false, dayModel)
+}
+
+function getMaxTemp(dayModel)
+{
+ return getTemp(true, dayModel)
+}
+
+function getTempFormat(temp)
+{
+ return temp + "°C"
+}
+
+function isNegative(val)
+{
+ return val < 0
+}
+
+// OneDayPage utils
+
+function getFromTime(index, dayModel) {
+ var timerange = dayModel.getDayDetails(index, 'timeRange')
+ var pattern_time = /(.*) - .*/
+ var time = timerange.replace(pattern_time, "$1")
+ return time
+}
+
+function getToTime(index, dayModel) {
+ var timerange = dayModel.getDayDetails(index, 'timeRange')
+ var pattern_time = /.* - (.*)/
+ var time = timerange.replace(pattern_time, "$1")
+ return time
+}
+
+function getMaxMinTemp(dayModel) {
+ // at least 1 data per day
+ var minTemp = dayModel.getDayDetails(0, 'temperature')
+ var maxTemp = dayModel.getDayDetails(0, 'temperature')
+ for (var i = 1; i < dayModel.periodCount(); i++)
+ {
+ var tempTemp = dayModel.getDayDetails(i, 'temperature')
+ maxTemp = Math.max(tempTemp, maxTemp)
+ minTemp = Math.min(tempTemp, minTemp)
+ }
+
+ return [minTemp, maxTemp]
+}
+
+function getMaxTempLenght(cityModel) {
+ var maxLength = 1
+ for (var indexDay = 0; indexDay < cityModel.daysCount(); indexDay++) {
+ var day = cityModel.getDayModel(indexDay)
+ var range = getMaxMinTemp(day)
+ maxLength = Math.max(range[0].toString().length, maxLength)
+ maxLength = Math.max(range[1].toString().length, maxLength)
+ }
+ var stringTemp = "555" // temperatures estimated between -55 and +55
+ if (maxLength === 3)
+ stringTemp = "-" + stringTemp
+ return stringTemp.substring(0, maxLength) + "°C."
+}
+
+// WeatherModel utils
+
+function getWindType(windspeed)
+{
+ var speed = parseFloat(windspeed)
+ if (speed <= 0.2)
+ return "Calm" // Calm
+ if (speed <= 1.5)
+ return "0000" // Light air
+ if (speed <= 3.3)
+ return "0025" // Light breeze
+ if (speed <= 5.4)
+ return "0050" // Glentle breeze
+ if (speed <= 7.9)
+ return "0075" // Moderate breeze
+ if (speed <= 10.7)
+ return "0100" // Fresh breeze
+ if (speed <= 13.8)
+ return "0125" // Strong breeze
+ if (speed <= 17.1)
+ return "0150" // Near gale
+ if (speed <= 18.0)
+ return "0175" // Near gale / Gale
+ if (speed <= 20.7)
+ return "0200" // Gale
+ if (speed <= 24.4)
+ return "0225" // Strong storm
+ if (speed <= 28.4)
+ return "0250" // Whole storm
+ if (speed <= 32.6)
+ return "0300" // Storm
+ return "0350" // Hurricane
+}
+
+function updateDayModel(dayModel, item)
+{
+ var windIconUrl = getWindSymbolUrl(item.windSpeed, item.windDirectionDeg)
+ var weatherUrl = extractSymbolUrl(item.symbolcode)
+ var day = Qt.formatDate(new Date(dayModel.date), "dddd")
+ var timeRange = getTimeRange(item)
+
+ dayModel.addRow(day, weatherUrl, timeRange, item.temperature, item.windSpeed, windIconUrl, item.rain, item.period)
+}
+
+function getItemDate(item)
+{
+ var fromDateTime = parseDateTime(item.from)
+ var toDateTime = parseDateTime(item.to)
+ var date = (item.period === "0") ? toDateTime[0] : fromDateTime[0]
+ return date
+}
+
+function getTimeRange(item)
+{
+ var fromDateTime = parseDateTime(item.from)
+ var toDateTime = parseDateTime(item.to)
+ var timeRange = fromDateTime[1] + " - " + toDateTime[1]
+ return timeRange
+}
+
+function parseDateTime(dt)
+{
+ var pattern_date = /(.*)T.*/
+ var pattern_time = /.*T([0-9][0-9]:[0-9][0-9]).*/
+ var time = dt.replace(pattern_time, "$1")
+ var date = dt.replace(pattern_date, "$1")
+ return [date, time]
+}
+
+function getWindSymbolUrl(windspeed, winddir)
+{
+ var windtype = getWindType(windspeed)
+ if (windtype === "Calm")
+ return "http://fil.nrk.no/yr/grafikk/vindpiler/32/vindstille.png"
+
+ var iconurl = "http://fil.nrk.no/yr/grafikk/vindpiler/32/vindpil.TYPE.WINDDIRCODE.png"
+ var windcode = Math.round((parseFloat(winddir).toFixed(0)) / 5) * 5
+ var codeLenght = windcode.toString().length;
+ for (var i = codeLenght; i < 3; i++)
+ windcode = "0" + windcode
+
+ if (windcode === 360)
+ windcode = "000"
+
+ iconurl = iconurl.replace("TYPE", windtype)
+ iconurl = iconurl.replace("WINDDIRCODE", windcode)
+ return iconurl
+}
+
+function extractSymbolUrl(code)
+{
+ // In order to use yr.no weather data service, refer to their terms
+ // and conditions of use. http://om.yr.no/verdata/free-weather-data/
+ var iconUrl = "http://symbol.yr.no/grafikk/sym/b100/__CODE__.png"
+ return iconUrl.replace("__CODE__", code)
+}
+
+// Global
+
+function getDay(index, dayModel)
+{
+ var day = dayModel.getDayDetails(index, "day")
+ return day
+}
+
+function getShortDate(date)
+{
+ return date.substr(8, 2) + "." + date.substr(5, 2) // dd.MM
+}
+
+function getLongDate(date)
+{
+ return date.substr(8, 2) + "." + date.substr(5, 2) + "." + date.substr(0, 4) // dd.MM.yyyy
+}
+
+function getRain(index, dayModel)
+{
+ return dayModel.getDayDetails(index, "rain")
+}
+
+function getTemperature(index, dayModel)
+{
+ return dayModel.getDayDetails(index, "temperature")
+}
+
+function getWindSpeed(index, dayModel)
+{
+ return dayModel.getDayDetails(index, "windSpeed")
+}
+
+function getWindUrl(index, dayModel)
+{
+ var url = dayModel.getDayDetails(index, "windUrl")
+ return dayModel.getCachedImageFile(url)
+}
+
+function getWeatherUrl(index, dayModel, size)
+{
+ var smallUrl = dayModel.getDayDetails(index, "weatherUrl")
+ if (size === "large")
+ smallUrl = smallUrl.replace("b100", "b200")
+ else
+ smallUrl = smallUrl
+ return dayModel.getCachedImageFile(smallUrl)
+}
+
diff --git a/qml/main.qml b/qml/main.qml
new file mode 100644
index 0000000..49720f7
--- /dev/null
+++ b/qml/main.qml
@@ -0,0 +1,178 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the FOO module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.1
+import QtQuick.Controls 1.0
+import QtQuick.Controls.Styles 1.0
+import org.qtproject.demo.weather 1.0
+
+ApplicationWindow {
+ id: root
+ height: 700
+ width: 1200
+ title: qsTr("Quick Forecast")
+
+ property string statusBarMessage
+
+ property Component citiesPage: CitiesPage {
+ onUpdateStatusBar: statusBarMessage = message
+ onNextPage: if (!isLocked) {
+ isLocked = true
+ pageView.push(longTermPage)
+ clearSearchBox()
+ }
+ }
+ property Component longTermPage: LongTermPage {
+ onUpdateStatusBar: statusBarMessage = message
+ onNextPage: if (!isLocked) {
+ isLocked = true
+ pageView.push(oneDayPage)
+ }
+ onPreviousPage: {
+ ApplicationInfo.currentIndexDay = -1
+ pageView.pop()
+ }
+ }
+ property Component oneDayPage: OneDayPage {
+ onUpdateStatusBar: statusBarMessage = message
+ onPreviousPage: if (!isLocked) {
+ isLocked = true
+ pageView.pop()
+ }
+ }
+
+ StackView {
+ id: pageView
+ anchors.fill: parent
+ initialItem: citiesPage
+ delegate: StackViewDelegate {
+ pushTransition: StackViewTransition {
+ function transitionFinished(properties)
+ {
+ properties.exitItem.opacity = 1
+ }
+ PropertyAnimation {
+ target: enterItem
+ property: "x"
+ from: target.width
+ to: 0
+ duration: 500
+ easing.type: Easing.OutSine
+ }
+ PropertyAnimation {
+ target: exitItem
+ property: "x"
+ from: 0
+ to: -target.width
+ duration: 500
+ easing.type: Easing.OutSine
+ }
+ }
+ popTransition: StackViewTransition {
+ function transitionFinished(properties)
+ {
+ properties.exitItem.opacity = 1
+ }
+ PropertyAnimation {
+ target: enterItem
+ property: "x"
+ from: -target.width
+ to: 0
+ duration: 500
+ easing.type: Easing.OutSine
+ }
+ PropertyAnimation {
+ target: exitItem
+ property: "x"
+ from: 0
+ to: target.width
+ duration: 500
+ easing.type: Easing.OutSine
+
+ }
+ }
+ property Component replaceTransition: pushTransition
+ }
+ }
+
+ statusBar: StatusBar {
+ width: parent.width
+ opacity: label.text !== "" ? 1 : 0
+ height: label.text !== "" ? 65 * ApplicationInfo.ratio : 0
+
+ Behavior on height { NumberAnimation {easing.type: Easing.OutSine}}
+ Behavior on opacity { NumberAnimation {}}
+
+ style: StatusBarStyle {
+ padding { left: 0; right: 0 ; top: 0 ; bottom: 0}
+ property Component background: Rectangle {
+ implicitHeight: 65 * ApplicationInfo.ratio
+ implicitWidth: root.width
+ color: ApplicationInfo.colors.smokeGray
+ Rectangle {
+ width: parent.width
+ height: 1
+ color: Qt.darker(parent.color, 1.5)
+ }
+ Rectangle {
+ y: 1
+ width: parent.width
+ height: 1
+ color: "white"
+ }
+ }
+ }
+ TouchLabel {
+ id: label
+ y: 32 * ApplicationInfo.ratio - height/2
+ width: parent.width // The text will only wrap if an explicit width has been set
+ text: statusBarMessage
+ textFormat: Text.RichText
+ onLinkActivated: Qt.openUrlExternally(link)
+ wrapMode: Text.Wrap
+ pixelSize: 18
+ letterSpacing: -0.15
+ color: ApplicationInfo.colors.mediumGray
+ verticalAlignment: Text.AlignVCenter
+ horizontalAlignment: Text.AlignHCenter
+ }
+ }
+}
diff --git a/qml/models/SearchResultModel.qml b/qml/models/SearchResultModel.qml
new file mode 100644
index 0000000..95a871e
--- /dev/null
+++ b/qml/models/SearchResultModel.qml
@@ -0,0 +1,32 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
+**
+** This file is part of the QtQuick Enterprise Controls Demos.
+**
+** $QT_BEGIN_LICENSE$
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.1
+
+ListModel {
+ ListElement { sourceXml: "http://www.yr.no/place/Norway/Oslo/Oslo/Oslo/forecast.xml"; name: "Oslo"; country: "Norway"}
+ ListElement { sourceXml: "http://www.yr.no/place/France/ÃŽle-de-France/Paris/forecast.xml"; name: "Paris"; country: "France"}
+ ListElement { sourceXml: "http://www.yr.no/place/United_Kingdom/England/London/forecast.xml"; name: "London"; country: "United Kingdom"}
+ ListElement { sourceXml: "http://www.yr.no/place/Germany/Berlin/Berlin/forecast.xml"; name: "Berlin"; country: "Germany"}
+ ListElement { sourceXml: "http://www.yr.no/place/United_States/California/San_Francisco/forecast.xml"; name: "San Francisco"; country: "United States"}
+ ListElement { sourceXml: "http://www.yr.no/place/Italy/Lazio/Rome/forecast.xml"; name: "Rome"; country: "Italia"}
+ ListElement { sourceXml: "http://www.yr.no/place/Antarctica/Other/Vostok_Station/forecast.xml"; name: "Vostok Station"; country: "Antarctica"}
+ ListElement { sourceXml: "http://www.yr.no/place/Mali/Tombouctou/Timbuktu/forecast.xml"; name: "Timbuktu"; country: "Mali"}
+}
diff --git a/qml/models/WeatherModel.qml b/qml/models/WeatherModel.qml
new file mode 100644
index 0000000..4ef3530
--- /dev/null
+++ b/qml/models/WeatherModel.qml
@@ -0,0 +1,134 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the FOO module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.1
+import QtQuick.XmlListModel 2.0
+import org.qtproject.demo.weather 1.0
+import "../js/utils.js" as Utils
+
+Item {
+ id: modelitem
+ signal error(string errorMessage)
+ signal showLongTerm()
+
+ property var loadedCityModel
+ property string lastLoadedCity
+
+ function getLongTermModel(model)
+ {
+ if (model.sourceXml !== lastLoadedCity ||
+ standardmodel.xml !== model.contentXml ||
+ model.daysCount() === 0) {
+ if (!!model) model.clear()
+ if (standardmodel.xml !== model.contentXml) {
+ standardmodel.xml = model.contentXml
+ } else {
+ if (!!standardmodel.get(0)) {
+ // no error on last loading
+ model.copyright = standardmodel.get(0).copyright
+ currentCityForecastModel.reload()
+ } else {
+ error("The saved xml file cannot be parsed")
+ }
+ }
+ loadedCityModel = model
+ } else {
+ showLongTerm()
+ }
+ lastLoadedCity = model.sourceXml
+ }
+
+ XmlListModel {
+ id: standardmodel
+ property var city
+ query: "/weatherdata"
+ XmlRole { name: "copyright"; query: "credit/link/@text/string()"}
+ onStatusChanged : {
+ if (status === XmlListModel.Ready && count > 0) {
+ var item = get(0)
+ loadedCityModel.copyright = item.copyright
+ currentCityForecastModel.xml = xml
+ } else if ( status === XmlListModel.Error) {
+ error(errorString())
+ } else if (status === XmlListModel.Ready && count == 0) {
+ error(qsTr("Can't parse the xml file"))
+ }
+ }
+ }
+
+ XmlListModel {
+ id: currentCityForecastModel
+ query: "/weatherdata/forecast/tabular/time"
+ XmlRole { name: "from"; query: "@from/string()" }
+ XmlRole { name: "to"; query: "@to/string()" }
+ XmlRole { name: "period"; query: "@period/string()" }
+ XmlRole { name: "symbolcode"; query: "symbol/@var/string()" }
+ XmlRole { name: "windType"; query: "windSpeed/@name/string()" }
+ XmlRole { name: "windDirectionDeg"; query: "windDirection/@deg/string()" }
+ XmlRole { name: "windSpeed"; query: "windSpeed/@mps/string()" }
+ XmlRole { name: "temperature"; query: "temperature/@value/string()" }
+ XmlRole { name: "rain"; query: "precipitation/@value/string()" }
+
+ onStatusChanged: {
+ if (status === XmlListModel.Ready && count > 0) {
+ for (var i=0; i<count; i++) {
+ var item = get(i)
+ var date = Utils.getItemDate(item)
+ var dayModel = loadedCityModel.getDayModel(date)
+ if (dayModel === null) {
+ // add a dayModel to cityModel
+ dayModel = Qt.createQmlObject('import org.qtproject.demo.weather 1.0; DayModel {}', loadedCityModel, "")
+ dayModel.date = date
+ loadedCityModel.addDayModel(dayModel)
+ }
+ if (item.period === "2")
+ dayModel.afternoonIndex = dayModel.periodCount()
+ Utils.updateDayModel(dayModel, item)
+ }
+ modelitem.showLongTerm()
+ } else if ( status === XmlListModel.Error) {
+ error(errorString())
+ } else if (status === XmlListModel.Ready && count == 0) {
+ error(qsTr("Can't parse the xml file"))
+ }
+ }
+ }
+}
diff --git a/qml/pages/BasicPage.qml b/qml/pages/BasicPage.qml
new file mode 100644
index 0000000..874df94
--- /dev/null
+++ b/qml/pages/BasicPage.qml
@@ -0,0 +1,205 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the FOO module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.1
+import QtQuick.Layouts 1.0
+import QtQuick.Controls 1.0
+import QtQuick.Controls.Styles 1.0
+import org.qtproject.demo.weather 1.0
+
+Item {
+ id: page
+ signal updateStatusBar(string message)
+ signal nextPage
+ signal previousPage
+ signal clearSearchBox
+
+ property Component pageComponent
+ property bool isLocked: true
+ property string title1
+ property string title2
+ property string title3
+
+ property alias searchText: searchField.text
+ property alias hasNoSearchText: searchField.isEmpty
+ signal searchBoxReturn
+ property string statusBarMessageDefault
+
+ property alias blueRect: blueRect
+
+ Binding {
+ target: ApplicationInfo
+ property: "isPortraitMode"
+ value: page.height > page.width
+ when: !ApplicationInfo.isMobile
+ }
+
+ Binding {
+ target: ApplicationInfo
+ property: "applicationWidth"
+ value: page.width
+ }
+
+ Rectangle {
+ id: blueRect
+ z: 2 // so flickable doesn't draw on top
+ anchors.top: parent.top
+ height: 80 * ApplicationInfo.ratio
+ width: parent.width
+ color: page.Stack.index !== 0 && mouseBack.pressed ?
+ Qt.lighter(ApplicationInfo.colors.blue, 1.2) : ApplicationInfo.colors.blue
+ Rectangle {
+ color: Qt.lighter(parent.color, 1.2)
+ height: 1
+ anchors.bottom: parent.bottom
+ anchors.bottomMargin: 1
+ width: parent.width
+ }
+ Rectangle {
+ z: 2 // so flickable doesn't draw on top
+ height: 1
+ width: parent.width
+ color: Qt.darker(ApplicationInfo.colors.blue, 1.6)
+ anchors.bottom: parent.bottom
+ }
+
+ RowLayout {
+ id: titleRow
+ anchors.left: parent.left
+ anchors.right: parent.right
+ spacing: 0
+ anchors.verticalCenter: parent.verticalCenter
+ Separator {}
+ Image {
+ source: ApplicationInfo.getImagePath("BackArrow.png")
+ Layout.preferredWidth: 22 * ApplicationInfo.ratio
+ Layout.preferredHeight: 35 * ApplicationInfo.ratio
+ visible: page.Stack.index > 0
+ }
+ Rectangle {
+ opacity: 0
+ Layout.preferredWidth: 20 * ApplicationInfo.ratio
+ Layout.fillHeight: true
+ visible: page.Stack.index > 0
+ }
+ TouchLabel {
+ id: t1
+ text: title1 + " "
+ color: ApplicationInfo.colors.white
+ pixelSize: 30
+ font.weight: Font.Bold
+ Layout.maximumWidth: ApplicationInfo.applicationWidth - t3.implicitWidth - 2 * ApplicationInfo.hMargin - 5 * ApplicationInfo.ratio - 42 * ApplicationInfo.ratio
+ Layout.alignment: Qt.AlignBaseline
+ }
+ TouchLabel {
+ text: "- " + title2
+ color: ApplicationInfo.colors.white
+ visible: title2 !== ""
+ pixelSize: 22
+ letterSpacing: -0.15
+ Layout.alignment: Qt.AlignBaseline
+ Layout.maximumWidth: freeSpace > implicitWidth ? freeSpace : 0
+ property real freeSpace: ApplicationInfo.applicationWidth - t1.width - t3.implicitWidth - 2 * ApplicationInfo.hMargin - 5 * ApplicationInfo.ratio - 42 * ApplicationInfo.ratio
+ }
+ Item {
+ Layout.fillWidth: true
+ height: 0
+ }
+ TouchLabel {
+ id: t3
+ text: title3
+ color: ApplicationInfo.colors.white
+ visible: title3 !== ""
+ pixelSize: 22
+ letterSpacing: -0.15
+ Layout.alignment: Qt.AlignBaseline
+ }
+ Separator {}
+ }
+ Rectangle {
+ width: parent.width
+ height: 5
+ anchors.top: parent.bottom
+ gradient: Gradient {
+ GradientStop {position: 0 ; color: "#40000000"}
+ GradientStop {position: 1 ; color: "#00000000"}
+ }
+ }
+ MouseArea {
+ id: mouseBack
+ anchors.fill: parent
+ onClicked: if (!isLocked) page.previousPage()
+ }
+ }
+
+ TouchTextField {
+ id: searchField
+ z: 2
+ visible: page.Stack.index === 0 ? 1 : 0
+ anchors.right: blueRect.right
+ anchors.top: blueRect.top
+ anchors.bottom: blueRect.bottom
+ width: ApplicationInfo.isPortraitMode ?
+ parent.width - t1.implicitWidth - ApplicationInfo.ratio * 50 :
+ parent.width/2.5
+ anchors.leftMargin: blueRect.width/2
+ anchors.rightMargin: 20 * ApplicationInfo.ratio
+ anchors.margins: 12 * ApplicationInfo.ratio
+
+ placeholderText: qsTr("Find City")
+ Layout.fillWidth: true
+ Keys.onReturnPressed: page.searchBoxReturn()
+ Keys.onEnterPressed: page.searchBoxReturn()
+ onClearButtonClicked: page.clearSearchBox()
+ }
+
+ Loader {
+ sourceComponent: pageComponent
+ anchors.top: blueRect.bottom
+ anchors.bottom: parent.bottom
+ width: parent.width
+ Rectangle {
+ z: -1
+ anchors.fill: parent
+ color: ApplicationInfo.colors.white
+ }
+ }
+}
diff --git a/qml/pages/CitiesPage.qml b/qml/pages/CitiesPage.qml
new file mode 100644
index 0000000..e5caec8
--- /dev/null
+++ b/qml/pages/CitiesPage.qml
@@ -0,0 +1,148 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the FOO module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.1
+import QtQuick.Controls 1.0
+import QtQuick.Layouts 1.0
+import org.qtproject.demo.weather 1.0
+
+BasicPage {
+ id: page1
+ title1: qsTr("Cities")
+
+ signal cityDeleted(string city)
+ property int selected: -1
+
+ Binding {
+ target: page1
+ property: "pageComponent"
+ value: listViewComponent
+ when: hasNoSearchText
+ }
+ Binding {
+ target: page1
+ property: "pageComponent"
+ value: searchViewComponent
+ when: !hasNoSearchText
+ }
+
+ onSearchTextChanged : ApplicationInfo.queryCities(searchText)
+
+ property Component searchViewComponent: TouchScrollView {
+ flickableItem.interactive: true
+ flickableItem.flickableDirection: Flickable.VerticalFlick
+ ListView {
+ interactive: true
+ flickableDirection: Flickable.VerticalFlick
+ model: ApplicationInfo.foundCities
+ delegate: ListViewDelegate {
+ isSearchView: true
+ onClicked: validateSearchIndex(index)
+ }
+ }
+ }
+ property Component listViewComponent: TouchScrollView {
+ flickableItem.interactive: true
+ flickableItem.flickableDirection: Flickable.VerticalFlick
+ ListView {
+ id: listview
+ model: availableCities
+ interactive: true
+ flickableDirection: Flickable.VerticalFlick
+ delegate: ListViewDelegate {
+ onClicked: page1.processCity(index)
+ onDeleteCity: availableCities.removeCityModel(index)
+ }
+ currentIndex: page1.selected
+ TouchLabel {
+ z: 1
+ anchors.centerIn: parent
+ visible: listview.count === 0
+ text: "No Cities"
+ color: ApplicationInfo.colors.lightGray
+ }
+ }
+ }
+
+ Connections {
+ target: ApplicationInfo
+ onWaitForCitiesQueryReply: if (ApplicationInfo.isMobile) updateStatusBar(message)
+ onErrorOnQueryCities: updateStatusBar(errorMessage)
+ }
+
+ onSearchBoxReturn: validateSearchIndex(0)
+ onClearSearchBox: {
+ searchText = ""
+ blueRect.forceActiveFocus() // attempt to clear focus in TextField
+ Qt.inputMethod.hide()
+ }
+ function validateSearchIndex(index) {
+
+ if (!ApplicationInfo.foundCities.isEmpty) {
+ // get sourcexml at index
+ var foundIndex = availableCities.processSourceXml(ApplicationInfo.foundCities.getCitySourceXml(index))
+ if (foundIndex > -1)
+ processCity(foundIndex)
+ }
+ clearSearchBox()
+ }
+ function processCity(index)
+ {
+ if (!isLocked) {
+ page1.selected = index
+ ApplicationInfo.currentCityModel = availableCities.getCityModel(index)
+ nextPage()
+ }
+ }
+
+ Cities { id: availableCities }
+
+ Connections {
+ target: Qt.application
+ onStateChanged: if (ApplicationInfo.constants.isMobile && Qt.application.state === Qt.ApplicationSuspended) availableCities.saveCities()
+ }
+
+ Stack.onStatusChanged: {
+ isLocked = !(Stack.status === Stack.Active)
+ if (Stack.status === Stack.Activating)
+ updateStatusBar("")
+ }
+}
diff --git a/qml/pages/LongTermDayItem.qml b/qml/pages/LongTermDayItem.qml
new file mode 100644
index 0000000..6053cca
--- /dev/null
+++ b/qml/pages/LongTermDayItem.qml
@@ -0,0 +1,156 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the FOO module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.1
+import QtQuick.Layouts 1.0
+import "../js/utils.js" as Utils
+import org.qtproject.demo.weather 1.0
+
+Rectangle {
+ id: day
+ Layout.preferredHeight: 118 * ApplicationInfo.ratio
+ Layout.preferredWidth: scrollview.viewport.width - 5
+
+ signal next
+ property bool last
+ property var dayModel: ApplicationInfo.currentCityModel.getDayModel(index)
+
+ color: mouse.pressed ? ApplicationInfo.colors.smokeGray : ApplicationInfo.colors.white
+
+ MouseArea {
+ id: mouse
+ anchors.fill: parent
+ onClicked: {
+ ApplicationInfo.currentIndexDay = index
+ next()
+ }
+ }
+ RowLayout {
+ anchors.fill: parent
+ spacing: 0
+ Separator {}
+ TouchLabel {
+ id: shortDay
+ Layout.preferredWidth: expectedTextWidth("Wed.")
+ text: Utils.getDay(0, dayModel).substr(0, 3)
+ font.weight: Font.DemiBold
+ Layout.alignment: Qt.AlignBaseline
+ }
+ TouchLabel {
+ Layout.preferredWidth: expectedTextWidth("00.00")
+ text: Utils.getShortDate(dayModel.date)
+ pixelSize: 20
+ letterSpacing: -0.15
+ Layout.alignment: Qt.AlignBaseline
+ }
+ Separator {
+ Layout.fillHeight: true
+ Layout.fillWidth: true
+ Layout.minimumHeight: 5
+ Layout.minimumWidth: 5
+ }
+ Image {
+ source: Utils.getWeatherUrl(dayModel.afternoonIndex, dayModel)
+ property int weatherIconSize: 80 * ApplicationInfo.ratio
+ Layout.preferredHeight: weatherIconSize
+ Layout.preferredWidth: weatherIconSize
+ onStatusChanged: if (status === Image.Error) updateStatusBar(ApplicationInfo.constants.errorLoadingImage + ": " + source)
+ }
+ Separator {
+ Layout.fillHeight: true
+ Layout.fillWidth: true
+ Layout.minimumHeight: 5
+ Layout.minimumWidth: 5
+ }
+ TouchLabel {
+ Layout.preferredWidth: expectedTextWidth(Utils.getMaxTempLenght(ApplicationInfo.currentCityModel))
+ property string temp: Utils.getMinTemp(dayModel)
+ text: Utils.getTempFormat(temp)
+ color: temp < 0 ? ApplicationInfo.colors.blue : ApplicationInfo.colors.doubleDarkGray
+ Layout.alignment: Qt.AlignBaseline
+ }
+ Rectangle {
+ id: separator2
+ Layout.preferredWidth: 1
+ Layout.preferredHeight: day.height/5
+ color: ApplicationInfo.colors.lightGray
+ }
+ TouchLabel {
+ Layout.preferredWidth: expectedTextWidth(Utils.getMaxTempLenght(ApplicationInfo.currentCityModel))
+ property int temp: Utils.getMaxTemp(dayModel)
+ text: Utils.getTempFormat(temp)
+ horizontalAlignment: Qt.AlignRight
+ color: temp < 0 ? ApplicationInfo.colors.blue : ApplicationInfo.colors.doubleDarkGray
+ Layout.alignment: Qt.AlignBaseline
+ }
+ Separator {
+ Layout.fillHeight: true
+ Layout.fillWidth: true
+ Layout.minimumHeight: 5
+ Layout.minimumWidth: 5
+ }
+ Image {
+ property int windIconSize: 32 * ApplicationInfo.ratio
+ source: Utils.getWindUrl(dayModel.afternoonIndex, dayModel)
+ Layout.preferredHeight: windIconSize
+ Layout.preferredWidth: windIconSize
+ onStatusChanged: if (status === Image.Error) updateStatusBar(ApplicationInfo.constants.errorLoadingImage + ": " + source)
+ }
+ TouchLabel {
+ Layout.preferredWidth: expectedTextWidth("10.0")
+ text: Utils.getWindSpeed(dayModel.afternoonIndex, dayModel)
+ pixelSize: 24
+ Layout.alignment: Qt.AlignBaseline
+ }
+ TouchLabel {
+ text: qsTr("m/s")
+ pixelSize: 18
+ Layout.alignment: Qt.AlignBaseline
+ }
+ Separator {}
+ }
+ Rectangle {
+ width: parent.width
+ height: 1
+ visible: !last
+ color: ApplicationInfo.colors.paleGray
+ }
+}
diff --git a/qml/pages/LongTermPage.qml b/qml/pages/LongTermPage.qml
new file mode 100644
index 0000000..938b78d
--- /dev/null
+++ b/qml/pages/LongTermPage.qml
@@ -0,0 +1,135 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the FOO module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.1
+import QtQuick.Controls 1.1
+import QtQuick.Layouts 1.0
+import org.qtproject.demo.weather 1.0
+
+BasicPage {
+ id: page2
+ title1: ApplicationInfo.currentCityModel.cityNameDisplay
+ title2: ApplicationInfo.currentCityModel.countryName
+ title3: qsTr("10 Days Forecast")
+
+ property bool cityLoaded: false
+
+ onCityLoadedChanged: updateStatusBar(ApplicationInfo.currentCityModel.copyright + " <a href=" + ApplicationInfo.currentCityModel.sourceXml + "\>(source)")
+
+ isLocked: true
+
+ pageComponent: Item {
+ TouchScrollView {
+ id: scrollview
+ anchors.fill: parent
+ flickableItem.interactive: true
+ flickableItem.flickableDirection: Flickable.VerticalFlick
+ ColumnLayout {
+ id: layout
+ spacing: 0
+ Repeater {
+ id: repeat
+ model: cityLoaded ? ApplicationInfo.currentCityModel.daysCount() : null
+ LongTermDayItem {
+ Layout.fillWidth: true
+ last: index === repeat.count
+ onNext: nextPage()
+ }
+ }
+ }
+ }
+
+ Rectangle {
+ anchors.fill: parent
+ opacity: cityLoaded ? 0 : 1
+ Behavior on opacity { NumberAnimation{}}
+ TouchLabel {
+ id: label
+ opacity: cityLoaded ? 0 : 1
+ Behavior on opacity { NumberAnimation{} }
+ anchors.centerIn: parent
+ text: qsTr("Loading data...")
+ horizontalAlignment: Text.AlignCenter
+ verticalAlignment: Text.AlignTop
+ pixelSize: 28
+ color: ApplicationInfo.colors.mediumGray
+ height: label.implicitHeight + 80 * ApplicationInfo.ratio
+ BusyIndicator {
+ opacity: 0.8
+ anchors.horizontalCenter: parent.horizontalCenter
+ anchors.bottom: parent.bottom
+ height: implicitHeight * ApplicationInfo.ratio
+ width: implicitWidth * ApplicationInfo.ratio
+ }
+ }
+ }
+ }
+
+ Connections {
+ id: cityModelConnection
+ target: ApplicationInfo.currentCityModel
+ onError: {
+ cityLoaded = false
+ isLocked = false
+ previousPage()
+ updateStatusBar(errorMessage)
+ }
+ onContentXmlChanged: weathermodel.getLongTermModel(ApplicationInfo.currentCityModel)
+ }
+
+ WeatherModel {
+ id: weathermodel
+ onShowLongTerm: {
+ isLocked = false
+ cityLoaded = true
+ }
+ onError: {
+ cityLoaded = false
+ lastLoadedCity = ""
+ isLocked = false
+ previousPage()
+ updateStatusBar(qsTr("Problem loading the data: ") + errorMessage)
+ }
+ }
+
+ Stack.onStatusChanged: if (Stack.status === Stack.Active)
+ ApplicationInfo.currentCityModel.loadData()
+}
diff --git a/qml/pages/OneDayPage.qml b/qml/pages/OneDayPage.qml
new file mode 100644
index 0000000..8264899
--- /dev/null
+++ b/qml/pages/OneDayPage.qml
@@ -0,0 +1,100 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the FOO module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.1
+import QtQuick.Layouts 1.0
+import QtQuick.Controls 1.0
+import org.qtproject.demo.weather 1.0
+import "../js/utils.js" as Utils
+
+BasicPage {
+ id : page3
+ title1: ApplicationInfo.currentCityModel.cityNameDisplay
+ title2: ApplicationInfo.currentCityModel.countryName
+
+ property QtObject dayModel: ApplicationInfo.currentCityModel.getDayModel(ApplicationInfo.currentIndexDay)
+
+ onDayModelChanged: if (!!dayModel) {
+ if (ApplicationInfo.currentIndexDay === 0)
+ title3 = qsTr("Today")
+ else if (ApplicationInfo.currentIndexDay === 1)
+ title3 = qsTr("Tomorrow")
+ else
+ title3 = Utils.getDay(0, dayModel) + " " + Utils.getLongDate(dayModel.date)
+ }
+
+ pageComponent: GridLayout {
+ id: splitview
+ flow: !ApplicationInfo.isPortraitMode ? GridLayout.LeftToRight : GridLayout.TopToBottom
+ property bool singleItem: sliderItem.slider.minimumValue === sliderItem.slider.maximumValue
+ Separator {
+ Layout.fillHeight: true
+ Layout.fillWidth: true
+ }
+ OneDayZoomItem {
+ id: zoom
+ slider: sliderItem.slider
+ model: page3.dayModel
+ singleItem: splitview.singleItem
+ }
+ Separator {
+ Layout.fillHeight: true
+ Layout.fillWidth: true
+ implicitHeight: 10 * ApplicationInfo.ratio
+ implicitWidth: 10 * ApplicationInfo.ratio
+ Layout.minimumWidth: 0
+ Layout.minimumHeight: 0
+ visible: !singleItem
+ }
+ OneDaySliderItem {
+ id: sliderItem
+ visible: !singleItem
+ model: page3.dayModel
+ }
+ Separator {
+ Layout.fillHeight: true
+ Layout.fillWidth: true
+ }
+ }
+
+ Stack.onStatusChanged: isLocked = !(Stack.status === Stack.Active)
+
+}
diff --git a/qml/pages/OneDaySliderItem.qml b/qml/pages/OneDaySliderItem.qml
new file mode 100644
index 0000000..dfd51db
--- /dev/null
+++ b/qml/pages/OneDaySliderItem.qml
@@ -0,0 +1,172 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the FOO module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.1
+import QtQuick.Layouts 1.0
+import "../js/utils.js" as Utils
+import org.qtproject.demo.weather 1.0
+
+GridLayout {
+ id: root
+ flow: ApplicationInfo.isPortraitMode ? GridLayout.LeftToRight : GridLayout.TopToBottom
+
+ property alias slider: touchSlider
+ property QtObject model
+
+ Separator {
+ Layout.fillHeight: true
+ Layout.fillWidth: ApplicationInfo.isPortraitMode ? true : false
+ Layout.minimumHeight: 10
+ }
+ Canvas {
+ id: canvasSlider
+ Layout.alignment: Qt.AlignHCenter
+
+ property int drawingOffset: ApplicationInfo.sliderGapWidth
+ property var rangeTemp: Utils.getMaxMinTemp(model)
+
+ implicitWidth: touchSlider.width + 2 * drawingOffset
+ implicitHeight: 3.8*drawingOffset
+
+ property int marginsTemperaturesDrawing: calibrate(rangeTemp[1]) + 10 * ApplicationInfo.ratio
+ property real circleIconWidth: 20 * ApplicationInfo.ratio
+ property real weatherIconWidth: 80 * ApplicationInfo.ratio
+
+ function calibrate(temperature) {
+ return 2 * ApplicationInfo.ratio * temperature
+ }
+
+ antialiasing: true
+ smooth: true
+ onPaint: {
+ var ctx = getContext('2d')
+ var count = model.periodCount()
+ ctx.save()
+ ctx.beginPath();
+ ctx.fillStyle = ApplicationInfo.colors.doubleDarkGray
+ ctx.lineWidth = 1
+ ctx.translate(touchSlider.x, marginsTemperaturesDrawing + weatherIconWidth + 15 * ApplicationInfo.ratio + circleIconWidth/2)
+ ctx.moveTo(drawingOffset/2, 0)
+ for (var i = 0; i < count; i++) {
+ ctx.moveTo((i + .5 )* drawingOffset, 0)
+ var temperatureStart = canvasSlider.calibrate(Utils.getTemperature(i, model))
+ var temperatureEnd = canvasSlider.calibrate(Utils.getTemperature(i + 1, model))
+ ctx.moveTo((i + 1 )* drawingOffset, -temperatureStart)
+ if ( (i+1) < count)
+ ctx.lineTo((i + 2) * drawingOffset, -temperatureEnd)
+ }
+ ctx.stroke()
+ ctx.closePath()
+ ctx.restore();
+ }
+ Repeater {
+ id: repeater
+ model: root.model.periodCount()
+ Column {
+ x: (index + 1.5) * ApplicationInfo.sliderGapWidth - canvasSlider.weatherIconWidth/2 - canvasSlider.circleIconWidth/2
+ y: -canvasSlider.calibrate(temperature) + canvasSlider.marginsTemperaturesDrawing
+ property int temperature: Utils.getTemperature(index, root.model)
+ height: parent.height
+ id: col
+ Image {
+ source: Utils.getWeatherUrl(index, root.model)
+ width: canvasSlider.weatherIconWidth
+ height: width
+ anchors.horizontalCenter: col.horizontalCenter
+ }
+ Item {
+ height: 15 * ApplicationInfo.ratio
+ width: height
+ }
+ Image {
+ id: circle
+ source: ApplicationInfo.getImagePath("Circle.png")
+ width: canvasSlider.circleIconWidth
+ height: width
+ anchors.horizontalCenter: col.horizontalCenter
+ }
+ Item {
+ height: 15 * ApplicationInfo.ratio
+ width: height
+ }
+ TouchLabel {
+ text: Utils.getTempFormat(temperature)
+ pixelSize: 24
+ color: temperature > 0 ? ApplicationInfo.colors.doubleDarkGray : ApplicationInfo.colors.blue
+ anchors.horizontalCenter: col.horizontalCenter
+ }
+ }
+ }
+ ColumnLayout {
+ id: column
+ anchors.bottom: parent.bottom
+ anchors.horizontalCenter: parent.horizontalCenter
+ TouchSlider {
+ id: touchSlider
+ Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
+ Layout.preferredWidth: (model.periodCount() - 1) * canvasSlider.drawingOffset + ApplicationInfo.sliderHandleWidth
+ minimumValue: 0
+ maximumValue: model.periodCount() - 1
+ }
+ RowLayout {
+ Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
+ Layout.preferredWidth: model.periodCount() * canvasSlider.drawingOffset + ApplicationInfo.sliderHandleWidth
+ spacing: 0
+ Repeater {
+ model: root.model.periodCount() + 1
+ TouchLabel {
+ pixelSize: 24
+ Layout.fillWidth: true
+ horizontalAlignment: Qt.AlignHCenter
+ Layout.alignment: Qt.AlignBaseline
+ text: (!!root.model && index !== root.model.periodCount()) ? Utils.getFromTime(index, root.model) : Utils.getToTime(index-1, root.model)
+ }
+ }
+ }
+ }
+
+ }
+ Separator {
+ Layout.fillHeight: true
+ Layout.fillWidth: ApplicationInfo.isPortraitMode ? true : false
+ Layout.minimumHeight: 10
+ }
+}
diff --git a/qml/pages/OneDayZoomItem.qml b/qml/pages/OneDayZoomItem.qml
new file mode 100644
index 0000000..5e2af42
--- /dev/null
+++ b/qml/pages/OneDayZoomItem.qml
@@ -0,0 +1,171 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the FOO module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.1
+import QtQuick.Layouts 1.0
+import "../js/utils.js" as Utils
+import org.qtproject.demo.weather 1.0
+
+GridLayout {
+ id: root
+ flow: ApplicationInfo.isPortraitMode ? GridLayout.LeftToRight : GridLayout.TopToBottom
+
+ property QtObject slider
+ property QtObject model
+ property bool singleItem
+ property string singleTimeString: "(" + Utils.getFromTime(0, dayModel) + " - " + Utils.getToTime(0, dayModel) + ")"
+
+ Separator {
+ Layout.fillHeight: true
+ Layout.fillWidth: ApplicationInfo.isPortraitMode ? true : false
+ }
+ GridLayout {
+ id: grid
+ rowSpacing: 0
+ columnSpacing: 15 * ApplicationInfo.ratio
+ columns: 3
+ TouchLabel {
+ id: longDay
+ text : Utils.getDay(root.slider.value, root.model)
+ font.weight: Font.Bold
+ Layout.alignment: Qt.AlignBaseline
+ }
+ TouchLabel {
+ text: Utils.getLongDate(root.model.date)
+ pixelSize: 30
+ Layout.alignment: Qt.AlignBaseline | Qt.AlignLeft
+ color: ApplicationInfo.colors.darkGray
+ }
+ TouchLabel {
+ text: root.singleItem ? root.singleTimeString : ""
+ pixelSize: 20
+ horizontalAlignment: Text.AlignRight
+ Layout.alignment: Qt.AlignBaseline
+ color: ApplicationInfo.colors.darkGray
+ }
+ Item {
+ Image {
+ id: mainIcon
+ source: Utils.getWeatherUrl(Math.round(root.slider.value), root.model, "large")
+ onStatusChanged: if (status === Image.Error) updateStatusBar(ApplicationInfo.constants.errorLoadingImage + ": " + source)
+ anchors.centerIn: parent
+ width: parent.width
+ height: parent.height
+ onSourceChanged: anim.running = true
+ anchors.verticalCenterOffset: offset
+ property real offset: 0
+ ParallelAnimation {
+ id: anim
+ alwaysRunToEnd: true
+ NumberAnimation {
+ target: mainIcon
+ property: "offset"
+ from: -30
+ to: 0
+ duration: 500
+ easing.type: Easing.OutCubic
+ }
+ NumberAnimation {
+ target: mainIcon
+ property: "opacity"
+ from: 0
+ to: 1
+ duration: 300
+ }
+ }
+ }
+
+ Layout.rowSpan: 1
+ Layout.preferredHeight: 200 * ApplicationInfo.ratio
+ Layout.preferredWidth: 200 * ApplicationInfo.ratio
+ Layout.alignment: Qt.AlignCenter
+ }
+ TouchLabel {
+ Layout.preferredWidth: expectedTextWidth(Utils.getMaxTempLenght(ApplicationInfo.currentCityModel))
+ property int temp: Utils.getTemperature(root.slider.value, root.model)
+ text : temp + qsTr("°C")
+ color: temp < 0 ? ApplicationInfo.colors.blue : ApplicationInfo.colors.doubleDarkGray
+ pixelSize: 72
+ letterSpacing: -0.5
+ Layout.alignment: Qt.AlignLeft
+ }
+ RowLayout {
+ Layout.columnSpan: 3
+ TouchLabel {
+ id: rainLabel
+ text : qsTr("Rain: ") + Utils.getRain(root.slider.value, root.model)
+ Layout.alignment: Qt.AlignLeft | Qt.AlignBaseline
+ pixelSize: 30
+ }
+ TouchLabel {
+ text : qsTr("mm")
+ pixelSize: 24
+ Layout.alignment: Qt.AlignBaseline | Qt.AlignLeft
+ }
+ }
+ RowLayout {
+ Layout.columnSpan: 3
+ TouchLabel {
+ id: windLabel
+ text : qsTr("Wind: ") + Utils.getWindSpeed(root.slider.value, root.model) + " "
+ Layout.alignment: Qt.AlignLeft | Qt.AlignBaseline
+ pixelSize: 30
+ }
+ TouchLabel {
+ text : qsTr("m/s")
+ pixelSize: 24
+ Layout.alignment: Qt.AlignLeft | Qt.AlignBaseline
+ }
+ Image {
+ source: Utils.getWindUrl(root.slider.value, root.model)
+ property int windIconSize: 45 * ApplicationInfo.ratio
+ Layout.preferredHeight: windIconSize
+ Layout.preferredWidth: windIconSize
+ onStatusChanged: if (status === Image.Error) updateStatusBar(ApplicationInfo.constants.errorLoadingImage + ": " + source)
+ Layout.alignment: Qt.AlignLeft
+ }
+ }
+ }
+ Separator {
+ Layout.fillHeight: true
+ Layout.fillWidth: ApplicationInfo.isPortraitMode ? true : false
+ }
+}
diff --git a/qml/pages/Separator.qml b/qml/pages/Separator.qml
new file mode 100644
index 0000000..78c1f9f
--- /dev/null
+++ b/qml/pages/Separator.qml
@@ -0,0 +1,52 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the FOO module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.1
+import QtQuick.Layouts 1.0
+import org.qtproject.demo.weather 1.0
+
+Rectangle {
+ implicitHeight: ApplicationInfo.hMargin
+ implicitWidth: ApplicationInfo.hMargin
+ Layout.minimumHeight: implicitHeight
+ Layout.minimumWidth: implicitWidth
+ opacity: 0
+}
diff --git a/qml/touch/ListViewDelegate.qml b/qml/touch/ListViewDelegate.qml
new file mode 100644
index 0000000..eecce49
--- /dev/null
+++ b/qml/touch/ListViewDelegate.qml
@@ -0,0 +1,158 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the FOO module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.1
+import QtQuick.Layouts 1.0
+import org.qtproject.demo.weather 1.0
+
+Rectangle {
+ id: rect
+ height: 118 * ApplicationInfo.ratio
+ width: parent.width
+ signal clicked
+ signal deleteCity
+
+ property bool isSearchView: false
+
+ color: mouseNext.pressed ? ApplicationInfo.colors.smokeGray : ApplicationInfo.colors.white
+
+ GridLayout {
+ id: _grid
+ anchors.fill: parent
+ flow: Qt.LeftToRight
+ rowSpacing: 4 * ApplicationInfo.ratio
+ columnSpacing: 0
+ columns: 2
+ Rectangle {
+ Layout.preferredWidth: ApplicationInfo.hMargin
+ Layout.fillHeight: true
+ opacity: 0
+ }
+ Loader {
+ sourceComponent: isSearchView ? searchViewRow : cityViewRow
+ Layout.fillHeight: true
+ Layout.fillWidth: true
+ }
+ Rectangle {
+ id: separator
+ Layout.fillWidth: true
+ Layout.fillHeight: true
+ Layout.columnSpan: 2
+ }
+ }
+ Rectangle {
+ z: 1
+ height: 1
+ anchors.bottom: parent.bottom
+ width: parent.width
+ color: ApplicationInfo.colors.paleGray
+ }
+ MouseArea {
+ id: mouseNext
+ anchors.left: parent.left
+ width: parent.width - 80 * ApplicationInfo.ratio - ApplicationInfo.hMargin
+ height: parent.height
+ onClicked: rect.clicked()
+ }
+
+ property Component searchViewRow: RowLayout {
+ spacing: 0
+ TouchLabel {
+ color: ApplicationInfo.colors.mediumGray
+ id: countryLabel
+ text: country
+ pixelSize: 28
+ Layout.alignment: Qt.AlignBaseline
+ Layout.fillWidth: true
+ Layout.maximumWidth: rect.width - 2 * ApplicationInfo.hMargin
+ }
+ Rectangle {
+ Layout.preferredWidth: ApplicationInfo.hMargin
+ Layout.fillHeight: true
+ opacity: 0
+ }
+ }
+
+ property Component cityViewRow: RowLayout {
+ spacing: 0
+ TouchLabel {
+ id: city
+ text: name
+ font.weight: Font.DemiBold
+ Layout.maximumWidth: maximumWidth * 2
+ Layout.alignment: Qt.AlignBaseline
+ }
+ Item {
+ implicitWidth: 12 * ApplicationInfo.ratio
+ Layout.minimumWidth: implicitWidth
+ }
+ TouchLabel {
+ color: ApplicationInfo.colors.mediumGray
+ id: countryLabel
+ text: country
+ pixelSize: 28
+ Layout.alignment: Qt.AlignBaseline | Qt.AlignLeft
+ Layout.fillWidth: true
+ Layout.minimumWidth: 0
+ }
+ MouseArea {
+ id: deleteMouse
+ implicitWidth: 110 * ApplicationInfo.ratio
+ implicitHeight: 110 * ApplicationInfo.ratio
+ Layout.minimumWidth: implicitWidth
+ onClicked: if (!isSearchView) rect.deleteCity()
+ Image {
+ id: imageRemove
+ anchors.centerIn: parent
+ source: ApplicationInfo.getImagePath("darkclose.png")
+ width: 31 * ApplicationInfo.ratio
+ height: 31 * ApplicationInfo.ratio
+ }
+ Rectangle {
+ anchors.fill: parent
+ color: ApplicationInfo.colors.smokeGray
+ opacity: deleteMouse.pressed ? 1 : 0
+ z: -1
+ radius: 8
+ }
+ }
+ }
+}
diff --git a/qml/touch/Separator.qml b/qml/touch/Separator.qml
new file mode 100644
index 0000000..dd7516e
--- /dev/null
+++ b/qml/touch/Separator.qml
@@ -0,0 +1,29 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
+**
+** This file is part of the QtQuick Enterprise Controls Demos.
+**
+** $QT_BEGIN_LICENSE$
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.1
+import QtQuick.Layouts 1.0
+import org.qtproject.demo.weather 1.0
+
+Rectangle {
+ Layout.minimumWidth: SystemInfo.hMargin
+ Layout.minimumHeight: SystemInfo.hMargin
+ opacity: 0
+}
diff --git a/qml/touch/TouchLabel.qml b/qml/touch/TouchLabel.qml
new file mode 100644
index 0000000..bea6b3b
--- /dev/null
+++ b/qml/touch/TouchLabel.qml
@@ -0,0 +1,79 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the FOO module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.1
+import QtQuick.Controls 1.0
+import QtQuick.Layouts 1.0
+import org.qtproject.demo.weather 1.0
+
+Label {
+ id: label
+ property int pixelSize: 34
+ property real letterSpacing: -0.25
+
+ font.family: "Open Sans"
+ font.pixelSize: pixelSize * ApplicationInfo.ratio * 1.1 // increasing fonts
+ font.letterSpacing: letterSpacing * ApplicationInfo.ratio
+ color: ApplicationInfo.colors.doubleDarkGray
+ verticalAlignment: Text.AlignBottom
+ horizontalAlignment: Text.AlignLeft
+ elide: Text.ElideRight
+ linkColor: ApplicationInfo.colors.blue
+
+ function expectedTextWidth(value)
+ {
+ dayText.text = value
+ return dayText.width
+ }
+
+ property int maximumWidth: (ApplicationInfo.constants.isMobile ? ApplicationInfo.applicationWidth : 1120) / 4
+ Layout.minimumWidth: Math.min(Layout.maximumWidth, implicitWidth + 1)
+
+ Text {
+ id: dayText
+ visible: false
+ font.family: label.font.family
+ font.pixelSize: label.font.pixelSize
+ font.letterSpacing: label.font.letterSpacing
+ wrapMode: label.wrapMode
+ elide: label.elide
+ }
+}
diff --git a/qml/touch/TouchScrollView.qml b/qml/touch/TouchScrollView.qml
new file mode 100644
index 0000000..5d2c211
--- /dev/null
+++ b/qml/touch/TouchScrollView.qml
@@ -0,0 +1,59 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the FOO module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.1
+import QtQuick.Controls 1.0
+import QtQuick.Controls.Styles 1.0
+import org.qtproject.demo.weather 1.0
+
+ScrollView {
+ frameVisible: false
+ style: ScrollViewStyle {
+ property int handleWidth: 20 * ApplicationInfo.ratio
+ transientScrollBars: true
+ padding{ top: 4 ; bottom: 4 ; right: 4}
+ property bool hovered: false
+ }
+ Rectangle {
+ anchors.fill: parent
+ color: ApplicationInfo.colors.white
+ }
+}
diff --git a/qml/touch/TouchSlider.qml b/qml/touch/TouchSlider.qml
new file mode 100644
index 0000000..6969239
--- /dev/null
+++ b/qml/touch/TouchSlider.qml
@@ -0,0 +1,81 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the FOO module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.1
+import QtQuick.Controls 1.0
+import QtQuick.Controls.Styles 1.0
+import org.qtproject.demo.weather 1.0
+
+Slider {
+ id: slider
+ implicitHeight: ApplicationInfo.sliderHandleHeight + ApplicationInfo.ratio * 25
+ style: SliderStyle {
+ groove: Rectangle {
+ Rectangle {
+ id: beforeHandle
+ width: control.value * ApplicationInfo.sliderGapWidth + ApplicationInfo.sliderHandleWidth/2
+ height: 20 * ApplicationInfo.ratio
+ color: ApplicationInfo.colors.blue
+ radius: 90
+ z: -1
+ }
+ Rectangle {
+ id: afterHandle
+ anchors.left: beforeHandle.right
+ anchors.right: parent.right
+ height: 20 * ApplicationInfo.ratio
+ color: ApplicationInfo.colors.darkGray
+ radius: 90
+ z: -1
+ }
+ }
+ handle: Item {
+ width: ApplicationInfo.sliderHandleWidth
+ height: ApplicationInfo.sliderHandleHeight
+ Image {
+ anchors.centerIn: parent
+ source: ApplicationInfo.getImagePath(control.pressed ? "Pointer_pressed.png" : "Pointer.png")
+ width: ApplicationInfo.sliderHandleWidth + 16 * ApplicationInfo.ratio
+ height: ApplicationInfo.sliderHandleHeight + 16 * ApplicationInfo.ratio
+ }
+ }
+ }
+}
diff --git a/qml/touch/TouchTextField.qml b/qml/touch/TouchTextField.qml
new file mode 100644
index 0000000..9e0ffb0
--- /dev/null
+++ b/qml/touch/TouchTextField.qml
@@ -0,0 +1,115 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the FOO module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.1
+import QtQuick.Controls 1.0
+import QtQuick.Controls.Styles 1.0
+import org.qtproject.demo.weather 1.0
+
+TextField {
+ id: textfield
+ signal clearButtonClicked
+ implicitWidth: parent.width
+ property bool isEmpty: true
+ style: TextFieldStyle {
+ background :
+ Rectangle {
+ radius: 8
+ border.width: 1
+ border.color: Qt.darker(ApplicationInfo.colors.blue, 1.6)
+ color: ApplicationInfo.colors.white
+ gradient: Gradient {
+ GradientStop { position: 0 ; color: "#ddd"}
+ GradientStop { position: 0.05 ; color: "#fff"}
+ }
+
+ implicitHeight: 60 * ApplicationInfo.ratio
+ opacity: 1
+ }
+ padding.left : (12 + 50) * ApplicationInfo.ratio
+ padding.right: (12 + 50) * ApplicationInfo.ratio
+ font.pixelSize: 28 * ApplicationInfo.ratio
+ font.family: "Open Sans"
+ font.letterSpacing: -0.25 * ApplicationInfo.ratio
+ selectedTextColor : ApplicationInfo.colors.lightGray
+ selectionColor : ApplicationInfo.colors.darkBlue
+ textColor : ApplicationInfo.colors.mediumGray
+ }
+
+ Item {
+ id: item
+ anchors.left: parent.left
+ anchors.top: parent.top
+ height: parent.height
+ width: parent.height
+ Image {
+ opacity: 0.9
+ anchors.centerIn: item
+ height: iconSize
+ width: iconSize
+ source: ApplicationInfo.getImagePath("magnifier.png")
+ property int iconSize: 50 * ApplicationInfo.ratio
+ }
+ }
+
+ onTextChanged: isEmpty = (text === "")
+ inputMethodHints: Qt.ImhNoPredictiveText
+ MouseArea {
+ z: 2
+ opacity: !textfield.isEmpty ? 1 : 0
+ Behavior on opacity {NumberAnimation{}}
+ anchors.right: parent.right
+ anchors.rightMargin: 4 * ApplicationInfo.ratio
+ anchors.top: parent.top
+ height: parent.height
+ width: parent.height
+ Image {
+ anchors.centerIn: parent
+ source: ApplicationInfo.getImagePath("Clear.png")
+ property int iconSize: 40 * ApplicationInfo.ratio
+ opacity: parent.pressed ? 1 : 0.9
+ width: iconSize
+ height: iconSize
+ }
+ onClicked: textfield.clearButtonClicked()
+ }
+}
+
diff --git a/qml/touch/images/BackArrow.png b/qml/touch/images/BackArrow.png
new file mode 100644
index 0000000..9070d0f
--- /dev/null
+++ b/qml/touch/images/BackArrow.png
Binary files differ
diff --git a/qml/touch/images/Circle.png b/qml/touch/images/Circle.png
new file mode 100644
index 0000000..7b229ec
--- /dev/null
+++ b/qml/touch/images/Circle.png
Binary files differ
diff --git a/qml/touch/images/Clear.png b/qml/touch/images/Clear.png
new file mode 100644
index 0000000..883dffd
--- /dev/null
+++ b/qml/touch/images/Clear.png
Binary files differ
diff --git a/qml/touch/images/Pointer.png b/qml/touch/images/Pointer.png
new file mode 100644
index 0000000..45b075e
--- /dev/null
+++ b/qml/touch/images/Pointer.png
Binary files differ
diff --git a/qml/touch/images/Pointer_pressed.png b/qml/touch/images/Pointer_pressed.png
new file mode 100644
index 0000000..776e0d1
--- /dev/null
+++ b/qml/touch/images/Pointer_pressed.png
Binary files differ
diff --git a/qml/touch/images/darkclose.png b/qml/touch/images/darkclose.png
new file mode 100644
index 0000000..2f90820
--- /dev/null
+++ b/qml/touch/images/darkclose.png
Binary files differ
diff --git a/qml/touch/images/magnifier.png b/qml/touch/images/magnifier.png
new file mode 100644
index 0000000..42033b5
--- /dev/null
+++ b/qml/touch/images/magnifier.png
Binary files differ
diff --git a/src/applicationinfo.cpp b/src/applicationinfo.cpp
new file mode 100644
index 0000000..dcbc54f
--- /dev/null
+++ b/src/applicationinfo.cpp
@@ -0,0 +1,193 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the FOO module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtCore/QFile>
+#include <QtCore/qmath.h>
+#include <QtCore/QRegExp>
+#include <QtCore/QUrl>
+#include <QtCore/QUrlQuery>
+#include <QtGui/QGuiApplication>
+#include <QtGui/QScreen>
+#include <QtNetwork/QNetworkReply>
+#include <QtNetwork/QNetworkRequest>
+
+#include "applicationinfo.h"
+#include "weatherimageprovider.h"
+#include <QDebug>
+
+ApplicationInfo::ApplicationInfo(WeatherImageProvider *provider)
+ : imageProvider(provider)
+{
+
+ m_isMobile = false;
+#if defined(Q_OS_ANDROID) || defined(Q_OS_IOS) || defined(Q_OS_BLACKBERRY)
+ m_isMobile = true;
+#endif
+
+ m_colors = new QQmlPropertyMap(this);
+ m_colors->insert(QLatin1String("white"), QVariant("#ffffff"));
+ m_colors->insert(QLatin1String("smokeGray"), QVariant("#eeeeee"));
+ m_colors->insert(QLatin1String("paleGray"), QVariant("#d7d6d5"));
+ m_colors->insert(QLatin1String("lightGray"), QVariant("#aeadac"));
+ m_colors->insert(QLatin1String("darkGray"), QVariant("#35322f"));
+ m_colors->insert(QLatin1String("mediumGray"), QVariant("#5d5b59"));
+ m_colors->insert(QLatin1String("doubleDarkGray"), QVariant("#1e1b18"));
+ m_colors->insert(QLatin1String("blue"), QVariant("#14aaff"));
+ m_colors->insert(QLatin1String("darkBlue"), QVariant("#14148c"));
+
+ m_constants = new QQmlPropertyMap(this);
+ m_constants->insert(QLatin1String("isMobile"), QVariant(m_isMobile));
+ m_constants->insert(QLatin1String("errorLoadingImage"), QVariant(tr("Error loading image - Host not found or unreachable")));
+
+ manager = new QNetworkAccessManager(this);
+ connect(manager, SIGNAL(finished(QNetworkReply*)), this, SLOT(replyFinished(QNetworkReply*)));
+ m_citiesFound = new CitiesListModel(this);
+
+ QRect rect = qApp->primaryScreen()->geometry();
+ m_ratio = m_isMobile ? qMin(qMax(rect.width(), rect.height())/1136. , qMin(rect.width(), rect.height())/640.) : 1;
+ m_sliderHandleWidth = getSizeWithRatio(70);
+ m_sliderHandleHeight = getSizeWithRatio(87);
+ m_sliderGapWidth = getSizeWithRatio(100);
+ m_isPortraitMode = m_isMobile ? rect.height() > rect.width() : false;
+ m_hMargin = m_isPortraitMode ? 20 * ratio() : 50 * ratio();
+ m_applicationWidth = m_isMobile ? rect.width() : 1120;
+
+ m_currentIndexDay = -1;
+
+ if (m_isMobile)
+ connect(qApp->primaryScreen(), SIGNAL(physicalSizeChanged(QSizeF)), this, SLOT(notifyPortraitMode()));
+
+ // Search in English
+ // In order to use yr.no weather data service, refer to their terms
+ // and conditions of use. http://om.yr.no/verdata/free-weather-data/
+ QUrl searchUrl2("http://www.yr.no/_/settspr.aspx");
+ QUrlQuery query2;
+ query2.addQueryItem("spr", "eng");
+ query2.addQueryItem("redir", "/");
+ searchUrl2.setQuery(query2);
+ manager->get(QNetworkRequest(searchUrl2));
+}
+
+void ApplicationInfo::setCurrentCityModel(CityModel *model)
+{
+ if (model != m_currentCityModel)
+ {
+ m_currentCityModel = model;
+ emit currentCityModelChanged();
+ }
+}
+
+void ApplicationInfo::setCurrentIndexDay(const int index)
+{
+ if (index != m_currentIndexDay) {
+ m_currentIndexDay = index;
+ emit currentIndexDayChanged();
+ }
+}
+
+void ApplicationInfo::setApplicationWidth(const int newWidth)
+{
+ if (newWidth != m_applicationWidth) {
+ m_applicationWidth = newWidth;
+ emit applicationWidthChanged();
+ }
+}
+
+QString ApplicationInfo::getImagePath(const QString image)
+{
+ return QString("qrc:/weatherapp/qml/touch/images/%1").arg(image);
+}
+
+void ApplicationInfo::notifyPortraitMode()
+{
+ int width = qApp->primaryScreen()->geometry().width();
+ int height = qApp->primaryScreen()->geometry().height();
+ setIsPortraitMode(height > width);
+}
+
+void ApplicationInfo::setIsPortraitMode(const bool newMode)
+{
+ if (m_isPortraitMode != newMode) {
+ m_isPortraitMode = newMode;
+ m_hMargin = m_isPortraitMode ? 20 * ratio() : 50 * ratio();
+ emit portraitModeChanged();
+ emit hMarginChanged();
+ }
+}
+
+void ApplicationInfo::queryCities(const QString input)
+{
+ if (input.isEmpty())
+ return;
+ // In order to use yr.no weather data service, refer to their terms
+ // and conditions of use. http://om.yr.no/verdata/free-weather-data/
+ QUrl searchUrl("http://www.yr.no/_/websvc/jsonforslagsboks.aspx");
+ QUrlQuery query;
+ query.addQueryItem("s", input);
+ searchUrl.setQuery(query);
+ manager->get(QNetworkRequest(searchUrl));
+ m_citiesFound->clear();
+ waitForCitiesQueryReply(tr("Waiting for cities, network may be slow..."));
+}
+
+void ApplicationInfo::replyFinished(QNetworkReply *reply)
+{
+ waitForCitiesQueryReply("");
+ if (reply->request().url().query() != "spr=eng&redir=/" ) {
+ if (reply->error() != QNetworkReply::NoError) {
+ emit(errorOnQueryCities(tr("Network error: %1").arg(reply->errorString())));
+ m_citiesFound->addCities();
+ } else {
+ QString data = reply->readAll();
+ QRegExp regExp;
+ regExp.setPattern("^\\[\\[.*\\],\\[\\[(.*)\\]\\]\\]$");
+ regExp.exactMatch(data);
+ QString foundCities = regExp.capturedTexts().at(1);
+ QStringList citiesFound = foundCities.split(QRegExp("\\],\\["), QString::SkipEmptyParts);
+ m_citiesFound->addCities(citiesFound);
+ }
+ }
+ if (reply) {
+ reply->deleteLater();
+ reply = 0;
+ }
+}
+
diff --git a/src/applicationinfo.h b/src/applicationinfo.h
new file mode 100644
index 0000000..4e001dd
--- /dev/null
+++ b/src/applicationinfo.h
@@ -0,0 +1,139 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the FOO module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef APPLICATIONINFO_H
+#define APPLICATIONINFO_H
+
+#include <QtCore/QObject>
+#include <QtQml/QQmlPropertyMap>
+
+QT_BEGIN_NAMESPACE
+class QNetworkAccessManager;
+class QNetworkReply;
+QT_END_NAMESPACE
+
+class WeatherImageProvider;
+
+#include "citymodel.h"
+#include "citieslistmodel.h"
+
+class ApplicationInfo : public QObject
+{
+ Q_OBJECT
+ Q_PROPERTY(int applicationWidth READ applicationWidth WRITE setApplicationWidth NOTIFY applicationWidthChanged)
+ Q_PROPERTY(QObject *colors READ colors CONSTANT)
+ Q_PROPERTY(QObject *constants READ constants CONSTANT)
+ Q_PROPERTY(bool isPortraitMode READ isPortraitMode WRITE setIsPortraitMode NOTIFY portraitModeChanged)
+ Q_PROPERTY(int currentIndexDay READ currentIndexDay WRITE setCurrentIndexDay NOTIFY currentIndexDayChanged)
+ Q_PROPERTY(CityModel *currentCityModel READ currentCityModel WRITE setCurrentCityModel NOTIFY currentCityModelChanged)
+ Q_PROPERTY(CitiesListModel *foundCities READ foundCities NOTIFY foundCitiesChanged)
+ Q_PROPERTY(qreal ratio READ ratio NOTIFY ratioChanged)
+ Q_PROPERTY(qreal hMargin READ hMargin NOTIFY hMarginChanged)
+ Q_PROPERTY(qreal sliderHandleWidth READ sliderHandleWidth NOTIFY ratioChanged)
+ Q_PROPERTY(qreal sliderHandleHeight READ sliderHandleHeight NOTIFY ratioChanged)
+ Q_PROPERTY(qreal sliderGapWidth READ sliderGapWidth NOTIFY ratioChanged)
+
+public:
+ ApplicationInfo(WeatherImageProvider *provider);
+
+ QQmlPropertyMap *colors() const { return m_colors; }
+ QQmlPropertyMap *constants() const { return m_constants; }
+
+ CityModel *currentCityModel() const { return m_currentCityModel; }
+ void setCurrentCityModel(CityModel *model);
+
+ int applicationWidth() const { return m_applicationWidth; }
+ void setApplicationWidth(const int newWidth);
+
+ int currentIndexDay() const { return m_currentIndexDay; }
+ void setCurrentIndexDay(const int index);
+
+ bool isPortraitMode() const { return m_isPortraitMode; }
+ void setIsPortraitMode(const bool newMode);
+
+ CitiesListModel *foundCities() { return m_citiesFound; }
+
+ qreal hMargin() const { return m_hMargin; }
+ qreal ratio() const { return m_ratio; }
+ qreal sliderHandleHeight() { return m_sliderHandleHeight; }
+ qreal sliderGapWidth() { return m_sliderGapWidth; }
+ qreal sliderHandleWidth() { return m_sliderHandleWidth; }
+
+ Q_INVOKABLE QString getImagePath(const QString image);
+ Q_INVOKABLE void queryCities(const QString input);
+
+protected slots:
+ void notifyPortraitMode();
+
+private slots:
+ void replyFinished(QNetworkReply *reply);
+
+protected:
+ qreal getSizeWithRatio(const qreal height) { return ratio() * height; }
+
+signals:
+ void applicationWidthChanged();
+ void portraitModeChanged();
+ void hMarginChanged();
+ void currentCityModelChanged();
+ void currentIndexDayChanged();
+ void foundCitiesChanged();
+ void ratioChanged();
+ void waitForCitiesQueryReply(const QString message);
+ void errorOnQueryCities(const QString errorMessage);
+
+private:
+ int m_applicationWidth;
+ QQmlPropertyMap *m_colors;
+ QQmlPropertyMap *m_constants;
+ CityModel *m_currentCityModel;
+ bool m_isPortraitMode;
+ int m_currentIndexDay;
+ QNetworkAccessManager *manager;
+ CitiesListModel *m_citiesFound;
+ bool m_isMobile;
+ qreal m_ratio;
+ qreal m_hMargin;
+ qreal m_sliderHandleHeight, m_sliderHandleWidth, m_sliderGapWidth;
+ WeatherImageProvider *imageProvider;
+};
+
+#endif // APPLICATIONINFO_H
diff --git a/src/applicationpaths.h b/src/applicationpaths.h
new file mode 100644
index 0000000..efce270
--- /dev/null
+++ b/src/applicationpaths.h
@@ -0,0 +1,75 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the FOO module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef APPLICATIONPATHS_H
+#define APPLICATIONPATHS_H
+
+#include <QtCore/QDir>
+#include <QtCore/QStandardPaths>
+#include <QtCore/QStringList>
+#include <QDebug>
+
+class ApplicationPaths
+{
+public:
+ inline static QString settingsPath()
+ {
+ return getPath(QStandardPaths::DataLocation);
+ }
+ inline static QString dowloadedFilesPath()
+ {
+ return getPath(QStandardPaths::CacheLocation);
+ }
+protected:
+
+ inline static QString getPath(QStandardPaths::StandardLocation location)
+ {
+ QString path = QStandardPaths::standardLocations(location).value(0);
+ QDir dir(path);
+ if (!dir.exists())
+ dir.mkpath(path);
+ if (!path.isEmpty() && !path.endsWith("/"))
+ path += "/";
+ return path;
+ }
+};
+
+#endif // APPLICATIONPATHS_H
diff --git a/src/cities.cpp b/src/cities.cpp
new file mode 100644
index 0000000..b91c276
--- /dev/null
+++ b/src/cities.cpp
@@ -0,0 +1,164 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the FOO module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtCore/QCoreApplication>
+#include <QtCore/QDir>
+#include <QtCore/QFile>
+#include <QtCore/QIODevice>
+#include <QtCore/QTextStream>
+#include <QtGlobal>
+
+#include "cities.h"
+#include "citymodel.h"
+#include "applicationpaths.h"
+#include <QDebug>
+
+Cities::Cities(QObject *parent) :
+ QAbstractListModel(parent)
+{
+ m_citiesFileName = QString("%1cities.settings").arg(ApplicationPaths::settingsPath());
+ readCities();
+}
+
+Cities::~Cities()
+{
+ saveCities();
+}
+
+CityModel* Cities::getCityModel(int index)
+{
+ Q_ASSERT(index > -1);
+ Q_ASSERT(index < m_cityMap.count());
+ return m_cityMap.at(index).second;
+}
+
+void Cities::removeCityModel(int index)
+{
+ if (index < m_cityMap.count() && index >=0 )
+ {
+ beginRemoveRows(QModelIndex(), index, index);
+ CityModel *modelToDelete = m_cityMap.at(index).second;
+ modelToDelete->cleanAll();
+ modelToDelete->deleteLater();
+ m_cityMap.removeAt(index);
+ endRemoveRows();
+ }
+}
+
+int Cities::addCityModel(CityModel *model)
+{
+ CityModelPair pair = qMakePair(model->sourceXml(), model);
+ int modelIndex = m_cityMap.indexOf(pair);
+ if (modelIndex == -1) {
+ m_cityMap.prepend(pair);
+ connect(model, SIGNAL(contentXmlChanged()), this, SIGNAL(cityModelReady()));
+ if (m_cityMap.count() > 15)
+ removeCityModel(m_cityMap.count() - 1);
+ return 0;
+ }
+ return modelIndex;
+}
+
+void Cities::readCities()
+{
+ QFile file(m_citiesFileName);
+ if (!file.open(QIODevice::ReadOnly | QIODevice::Text))
+ return;
+ QTextStream in(&file);
+ while (!in.atEnd()) {
+ QString sourceXml = in.readLine().trimmed();
+ processSourceXml(sourceXml);
+ }
+ file.close();
+}
+
+int Cities::processSourceXml(const QString sourceXml)
+{
+ // Dont add save town/identical sourceXml twice
+ for (int i = 0; i <m_cityMap.count(); i++) {
+ if (m_cityMap.at(i).first == sourceXml)
+ return i;
+ }
+ CityModel *model = new CityModel(this);
+ if (model->setSourceXml(sourceXml))
+ return addCityModel(model);
+
+ model->deleteLater();
+ return -1;
+}
+
+void Cities::saveCities()
+{
+ QFile file(m_citiesFileName);
+ if (!file.open(QIODevice::WriteOnly | QIODevice::Text))
+ return;
+ QTextStream out(&file);
+ for (int index = m_cityMap.count()-1; index >= 0; index--)
+ out << m_cityMap.at(index).first << endl;
+ file.close();
+}
+
+QVariant Cities::data(const QModelIndex & index, int role) const
+{
+ CityModel *model = m_cityMap.at(index.row()).second;
+ if (model) {
+ switch (role) {
+ case CityNameRole:
+ return model->cityNameDisplay().replace("_", " ");
+ case CountryRole:
+ return model->countryName().replace("_", " ");
+ }
+ }
+ return QVariant();
+}
+
+int Cities::rowCount(const QModelIndex & /*parent*/) const
+{
+ return m_cityMap.count();
+}
+
+QHash<int, QByteArray> Cities::roleNames() const
+{
+ QHash<int, QByteArray> rn;
+ rn[CityNameRole] = "name";
+ rn[CountryRole] = "country";
+ return rn;
+}
diff --git a/src/cities.h b/src/cities.h
new file mode 100644
index 0000000..6839074
--- /dev/null
+++ b/src/cities.h
@@ -0,0 +1,92 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the FOO module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef CITIES_H
+#define CITIES_H
+
+#include <QtCore/QAbstractListModel>
+#include <QtCore/QList>
+#include <QtCore/QPair>
+#include <QtQml/qqml.h>
+
+class CityModel;
+
+typedef QPair<QString, CityModel*> CityModelPair;
+
+class Cities : public QAbstractListModel
+{
+ Q_OBJECT
+public:
+ enum {
+ CityNameRole = Qt::UserRole + 1,
+ CountryRole = Qt::UserRole + 2
+ };
+
+ Cities(QObject *parent = 0);
+ ~Cities();
+
+ Q_INVOKABLE CityModel* getCityModel(const int index);
+ Q_INVOKABLE void removeCityModel(const int index);
+ int addCityModel(CityModel *model);
+ Q_INVOKABLE int processSourceXml(const QString sourceXml);
+
+ QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
+ QHash<int, QByteArray> roleNames() const;
+ int rowCount(const QModelIndex & parent = QModelIndex()) const;
+ Q_INVOKABLE void saveCities();
+
+protected:
+ void readCities();
+
+signals:
+ void cityModelReady();
+ void modelChanged(const int index);
+
+private:
+ QString m_wantedCity;
+ QString m_citiesFileName;
+ QString m_cachePath;
+ QList<CityModelPair> m_cityMap;
+};
+
+QML_DECLARE_TYPE(Cities)
+
+#endif // CITIES_H
diff --git a/src/citieslistmodel.cpp b/src/citieslistmodel.cpp
new file mode 100644
index 0000000..e86bd0d
--- /dev/null
+++ b/src/citieslistmodel.cpp
@@ -0,0 +1,125 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the FOO module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "citieslistmodel.h"
+#include <QDebug>
+
+CitiesListModel::CitiesListModel(QObject *parent) :
+ QAbstractListModel(parent), m_isEmpty(true)
+{
+}
+
+QVariant CitiesListModel::data(const QModelIndex & index, int role) const
+{
+ Q_ASSERT(index.row() < m_foundCities.count());
+ if (role == CountryRole)
+ return QString(m_foundCities.at(index.row()).first).replace("_", " ");
+ else
+ return QVariant("");
+}
+
+int CitiesListModel::rowCount(const QModelIndex & /*parent*/) const
+{
+ return m_foundCities.count();
+}
+
+QString CitiesListModel::getCitySourceXml(const int index)
+{
+ Q_ASSERT(index > -1);
+ Q_ASSERT(index < m_foundCities.count());
+ CityXmlPair pair = m_foundCities.at(index);
+ // In order to use yr.no weather data service, refer to their terms
+ // and conditions of use. http://om.yr.no/verdata/free-weather-data/
+ return QString("http://www.yr.no%1forecast.xml").arg(pair.second);
+}
+
+void CitiesListModel::addCities(QStringList listCities)
+{
+ clear();
+ QList<CityXmlPair> temp;
+ if (!listCities.empty()) {
+ for (int i = 0; i < listCities.count(); i++)
+ {
+ QRegExp regExp2;
+ regExp2.setPattern("^\"(.*)\",\"(.*)\",\"(.*)\",\"(.*)\"$");
+ regExp2.exactMatch(listCities.at(i));
+ QString cityName = regExp2.capturedTexts().at(1);
+ QString countryName = regExp2.capturedTexts().at(3);
+ QString xml = regExp2.capturedTexts().at(2);
+ QRegExp regExp3;
+ regExp3.setPattern("^/place/.*/.*/.*/$");
+ if (countryName.isEmpty() || countryName.contains("Municipality") || !regExp3.exactMatch(xml))
+ continue; // We want cities forecast only
+ QString name = cityName + " - " + countryName;
+ temp.append(qMakePair(name, xml));
+ }
+ }
+
+ if (!temp.isEmpty()) {
+ beginInsertRows(QModelIndex(), 0, temp.count() - 1);
+ m_foundCities.append(temp);
+ m_isEmpty = false;
+ } else {
+ beginInsertRows(QModelIndex(), 0, 0);
+ m_foundCities.append(qMakePair(tr("no city found"), QString("")));
+ }
+
+ endInsertRows();
+}
+
+void CitiesListModel::clear()
+{
+ m_isEmpty = true;
+ if (m_foundCities.count() > 0) {
+ beginRemoveRows(QModelIndex(), 0, m_foundCities.count() - 1);
+ m_foundCities.clear();
+ endRemoveRows();
+ }
+}
+
+QHash<int, QByteArray> CitiesListModel::roleNames() const
+{
+ QHash<int, QByteArray> rn;
+ rn[CountryRole] = "country";
+ rn[NameRole] = "name"; // needed to use in delegate that read both roles (country and name)
+ return rn;
+}
+
diff --git a/src/citieslistmodel.h b/src/citieslistmodel.h
new file mode 100644
index 0000000..7120620
--- /dev/null
+++ b/src/citieslistmodel.h
@@ -0,0 +1,84 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the FOO module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef CITIESLISTMODEL_H
+#define CITIESLISTMODEL_H
+
+#include <QtCore/QAbstractListModel>
+#include <QtCore/QList>
+#include <QtCore/QPair>
+#include <QtCore/QStringList>
+#include <QtQml/qqml.h>
+
+typedef QPair<QString, QString> CityXmlPair;
+
+class CitiesListModel : public QAbstractListModel
+{
+ Q_OBJECT
+ Q_PROPERTY(bool isEmpty READ isEmpty NOTIFY isEmptyChanged)
+public:
+ enum {
+ NameRole = Qt::UserRole + 1,
+ CountryRole = Qt::UserRole + 2
+ };
+ CitiesListModel(QObject *parent = 0);
+
+ Q_INVOKABLE QString getCitySourceXml(const int index);
+ void addCities(QStringList listCities = QStringList());
+
+ bool isEmpty() const { return m_isEmpty; }
+
+ void clear();
+ QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
+ Q_INVOKABLE int rowCount(const QModelIndex & parent = QModelIndex()) const;
+ QHash<int, QByteArray> roleNames() const;
+
+signals:
+ void isEmptyChanged();
+
+private:
+ QList<CityXmlPair> m_foundCities;
+ bool m_isEmpty;
+};
+
+QML_DECLARE_TYPE(CitiesListModel)
+
+#endif // CITIESLISTMODEL_H
diff --git a/src/citymodel.cpp b/src/citymodel.cpp
new file mode 100644
index 0000000..9056398
--- /dev/null
+++ b/src/citymodel.cpp
@@ -0,0 +1,302 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the FOO module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtCore/QDateTime>
+#include <QtCore/QFile>
+#include <QtCore/QIODevice>
+#include <QtCore/QRegExp>
+#include <QtCore/QStringList>
+#include <QtNetwork/QNetworkRequest>
+#include <QtNetwork/QNetworkReply>
+#include <QtNetwork/QNetworkAccessManager>
+
+#include "citymodel.h"
+#include "applicationpaths.h"
+#include <QDebug>
+
+CityModel::CityModel(QObject *parent) :
+ QObject(parent), m_timeStamp(0)
+{
+ manager = new QNetworkAccessManager(this);
+ connect(manager, SIGNAL(finished(QNetworkReply*)),
+ this, SLOT(replyFinished(QNetworkReply*)));
+ connect(this, SIGNAL(ready()), this, SLOT(readXml()));
+}
+
+void CityModel::setCopyright(const QString copyright)
+{
+ if (copyright != m_copyright) {
+ m_copyright = copyright;
+ emit copyrightChanged();
+ }
+}
+
+bool CityModel::setSourceXml(const QString xml)
+{
+ if (xml != m_sourceXml) {
+ QRegExp regExp;
+ // will reject invalid xml string
+ regExp.setPattern("^http://www\\.yr\\.no/place/(([^/]*)/.*/([^/]*))/forecast\\.xml$");
+ if (!regExp.exactMatch(xml))
+ return false;
+ m_sourceXml = xml;
+
+ // get city name, country and filename from sourceXml
+ QStringList list = regExp.capturedTexts();
+ setCityNameDisplay(list.at(3));
+ setCountryName(list.at(2));
+ QString tempFileName = regExp.capturedTexts().at(1);
+ tempFileName = tempFileName.replace(QString("/"), QString("_"));
+ m_filename = QString("%1%2.wa").arg(ApplicationPaths::dowloadedFilesPath()).arg(tempFileName);
+ emit sourceXmlChanged();
+ }
+ return true;
+}
+
+void CityModel::setCityNameDisplay(QString name)
+{
+ int pos = name.indexOf("~");
+ if ( pos > 0)
+ name.truncate(pos);
+
+ if (name != m_cityNameDisplay) {
+ m_cityNameDisplay = name;
+ emit cityNameDisplayChanged();
+ }
+}
+
+QString CityModel::cityNameDisplay() const
+{
+ QString cityName = m_cityNameDisplay;
+ return cityName.replace("_", " ");
+}
+
+void CityModel::setCountryName(const QString name)
+{
+ if (name != m_countryName) {
+ m_countryName = name;
+ emit countryNameChanged();
+ }
+}
+
+QString CityModel::countryName() const
+{
+ QString countryName = m_countryName;
+ return countryName.replace("_", " ");
+}
+
+void CityModel::setError(const QString errorMessage)
+{
+ // Always emit error message
+ emit error(tr("Network error: ") + errorMessage);
+}
+
+QVariant CityModel::data(const QModelIndex & /*index*/, int role) const
+{
+ if (role == CityNameDisplayRole)
+ return m_cityNameDisplay;
+ return QVariant();
+}
+
+QHash<int, QByteArray> CityModel::roleNames() const
+{
+ QHash<int, QByteArray> rn;
+ rn[CityNameDisplayRole] = "name";
+ return rn;
+}
+
+void CityModel::clear()
+{
+ m_copyright = QString();
+ m_timeStamp = 0;
+ for (int i = 0; i < m_citydata.count(); i++) {
+ DayModel *temp = m_citydata.takeAt(i);
+ temp->clear();
+ temp->deleteLater();
+ }
+ m_citydata.clear();
+}
+
+void CityModel::cleanAll()
+{
+ clear();
+ // Clear eventual cached file
+ QFile file(m_filename);
+ if (file.exists())
+ file.remove();
+}
+
+void CityModel::addDayModel(DayModel *newDayModel)
+{
+ m_citydata.append(newDayModel);
+ connect(newDayModel, SIGNAL(addedImages(QStringList)), this, SLOT(addImages(QStringList)));
+}
+
+void CityModel::addImages(const QStringList images)
+{
+ for (int i = 0; i < images.count(); i++)
+ downloadImage(images.at(i));
+}
+
+DayModel* CityModel::getDayModel(QString date)
+{
+ for (int i = 0; i < m_citydata.count(); i++) {
+ if ( m_citydata.at(i)->getDate() == date )
+ return m_citydata.at(i);
+ }
+ return 0;
+}
+
+DayModel* CityModel::getDayModel(int indexDay)
+{
+ Q_ASSERT(indexDay > -1);
+ Q_ASSERT(indexDay < m_citydata.count());
+ return m_citydata.at(indexDay);
+}
+
+void CityModel::refreshData()
+{
+ if (sourceXml() == QString()) {
+ qWarning("Warning: source xml not set");
+ return;
+ }
+ QNetworkRequest request;
+ request.setUrl(QUrl(sourceXml()));
+ request.setRawHeader("Accept", "application/xml,*/*");
+ manager->get(request);
+}
+
+void CityModel::loadData()
+{
+ Q_ASSERT(!m_filename.isEmpty());
+ QFile file(m_filename);
+ m_timeStamp = 0;
+ if (file.exists() && file.open(QIODevice::ReadOnly)) {
+ m_timeStamp = QString(file.readLine().trimmed()).toLongLong();
+ file.close();
+ }
+ if (dataExpired(m_timeStamp))
+ refreshData();
+ else
+ emit ready();
+}
+
+bool CityModel::dataExpired(qint64 timeStamp) {
+ // 10 minutes caching
+ qint64 tenMinutesMSecs = 10 * 60 * 1000;
+ qint64 timeElapsed = QDateTime::currentMSecsSinceEpoch() - timeStamp;
+ return timeStamp == 0 || timeElapsed > tenMinutesMSecs;
+}
+
+void CityModel::replyFinished(QNetworkReply *reply)
+{
+ if (reply->error() != QNetworkReply::NoError) {
+ setError(reply->errorString());
+ } else {
+ QString requestUrl = reply->request().url().toString();
+ if (requestUrl.endsWith(".xml")) {
+ QByteArray data = reply->readAll();
+ if (!data.isEmpty()) {
+ data.prepend("\n");
+ data.prepend(QByteArray::number(QDateTime::currentMSecsSinceEpoch(), 'f', 0));
+ QFile file(m_filename);
+ if (file.open(QIODevice::WriteOnly)) {
+ file.write(data);
+ file.close();
+ emit ready();
+ } else {
+ setError(file.errorString());
+ }
+ } else {
+ setError(tr("No data at given url"));
+ }
+ } else { // download image
+ QString filename = getImageFileName(reply->url().toString());
+ QByteArray data = reply->readAll();
+ if (!data.isEmpty()) {
+ QFile file(filename);
+ if (!file.exists() && file.open(QIODevice::WriteOnly)) {
+ file.write(data);
+ file.close();
+ }
+ }
+ }
+ }
+ if (reply) {
+ reply->deleteLater();
+ reply = 0;
+ }
+}
+
+void CityModel::downloadImage(const QString imageUrl)
+{
+ QString filename = getImageFileName(imageUrl);
+ QFile file(filename);
+ if (!file.exists()) {
+ QNetworkRequest request;
+ request.setUrl(QUrl(imageUrl));
+ manager->get(request);
+ }
+}
+
+QString CityModel::getImageFileName(const QString url)
+{
+ bool isLargeImage = url.contains("b200");
+ QString filename = url.right(url.length() - url.lastIndexOf("/") - 1);
+ if (isLargeImage)
+ filename.prepend("large_");
+ filename = QString("%1%2").arg(ApplicationPaths::dowloadedFilesPath()).arg(filename);
+ return filename;
+}
+
+void CityModel::readXml()
+{
+ QFile file(m_filename);
+ QString content;
+ if (file.open(QIODevice::ReadOnly)) {
+ m_timeStamp = QString(file.readLine().trimmed()).toLongLong();
+ m_contentXml = QString(file.readAll());
+ emit contentXmlChanged(); // always emit this signal
+ file.close();
+ } else {
+ setError(file.errorString());
+ }
+}
diff --git a/src/citymodel.h b/src/citymodel.h
new file mode 100644
index 0000000..34d40ec
--- /dev/null
+++ b/src/citymodel.h
@@ -0,0 +1,138 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the FOO module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef CITYMODEL_H
+#define CITYMODEL_H
+
+#include <QtCore/QModelIndex>
+#include <QtCore/QObject>
+#include <QtQml/qqml.h>
+#include <QDebug>
+
+#include "daymodel.h"
+
+QT_BEGIN_NAMESPACE
+class QNetworkAccessManager;
+class QNetworkReply;
+QT_END_NAMESPACE
+
+class CityModel : public QObject
+{
+ Q_OBJECT
+ Q_ENUMS(Status)
+ Q_PROPERTY(QString copyright READ copyright WRITE setCopyright NOTIFY copyrightChanged)
+ Q_PROPERTY(QString cityNameDisplay READ cityNameDisplay NOTIFY cityNameDisplayChanged)
+ Q_PROPERTY(QString countryName READ countryName NOTIFY countryNameChanged)
+ Q_PROPERTY(QString sourceXml READ sourceXml NOTIFY sourceXmlChanged)
+ Q_PROPERTY(QString contentXml READ contentXml NOTIFY contentXmlChanged)
+
+public:
+ enum {
+ CityNameDisplayRole = Qt::UserRole + 1
+ };
+
+ CityModel(QObject *parent = 0);
+
+ void setError(const QString msg);
+
+ QString copyright() const { return m_copyright;}
+ void setCopyright(const QString copyright);
+
+ QString cityNameDisplay() const;
+ void setCityNameDisplay(QString name);
+
+ QString countryName() const;
+ void setCountryName(const QString name);
+
+ QString sourceXml() const { return m_sourceXml; }
+ bool setSourceXml(const QString xml);
+
+ QString contentXml() const { return m_contentXml; }
+
+ QVariant data(const QModelIndex &index, int role) const;
+ QHash<int, QByteArray> roleNames() const;
+
+ Q_INVOKABLE int daysCount() const { return m_citydata.count(); }
+ Q_INVOKABLE void loadData();
+ Q_INVOKABLE void clear();
+ Q_INVOKABLE void addDayModel(DayModel *newDayModel);
+ Q_INVOKABLE DayModel* getDayModel(QString dayName);
+ Q_INVOKABLE DayModel* getDayModel(int indexDay);
+
+ void cleanAll();
+
+ void downloadImage(const QString imageUrl);
+
+private:
+ void refreshData();
+ bool dataExpired(qint64 timeStamp);
+ QString getImageFileName(const QString url);
+
+private Q_SLOTS:
+ void replyFinished(QNetworkReply*);
+ void readXml();
+ void addImages(const QStringList images);
+
+Q_SIGNALS:
+ void copyrightChanged();
+ void countryNameChanged();
+ void error(const QString errorMessage);
+ void sourceXmlChanged();
+ void contentXmlChanged();
+ void cityNameDisplayChanged();
+ void fileNameChanged();
+ void ready();
+
+private:
+ QString m_copyright;
+ QString m_countryName, m_contentXml;
+ qreal m_timeStamp;
+ QList<DayModel*> m_citydata;
+ QNetworkAccessManager *manager;
+ QString m_filename;
+ QString m_url;
+ QString m_sourceXml;
+ QString m_cityNameDisplay;
+};
+
+QML_DECLARE_TYPE(CityModel)
+
+#endif // CITYMODEL_H
diff --git a/src/daymodel.cpp b/src/daymodel.cpp
new file mode 100644
index 0000000..a0ae9ac
--- /dev/null
+++ b/src/daymodel.cpp
@@ -0,0 +1,149 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the FOO module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtCore/QDir>
+#include <QtCore/QCoreApplication>
+#include <QtNetwork/QNetworkRequest>
+#include <QtNetwork/QNetworkReply>
+#include <QtNetwork/QNetworkAccessManager>
+
+#include "daymodel.h"
+#include "applicationpaths.h"
+#include <QDebug>
+
+DayModel::DayModel()
+ : QObject(), m_afternoonindex(0) {
+}
+
+QVariant DayModel::data(const QModelIndex &index, int role) const
+{
+ if (role == DayRole)
+ return m_data.at(index.row()).day;
+ if (role == WeatherUrlRole)
+ return m_data.at(index.row()).weatherUrl;
+ if (role == TimeRangeRole)
+ return m_data.at(index.row()).timeRange;
+ if (role == TemperatureRole)
+ return m_data.at(index.row()).temperature;
+ if (role == WindSpeedRole)
+ return m_data.at(index.row()).windSpeed;
+ if (role == WindUrlRole)
+ return m_data.at(index.row()).windUrl;
+ if (role == RainRole)
+ return m_data.at(index.row()).rain;
+ return QVariant();
+}
+
+QHash<int, QByteArray> DayModel::roleNames() const
+{
+ QHash<int, QByteArray> rn;
+ rn[DayRole] = "day";
+ rn[WeatherUrlRole] = "weatherUrl";
+ rn[TimeRangeRole] = "timeRange";
+ rn[TemperatureRole] = "temperature";
+ rn[WindSpeedRole] = "windSpeed";
+ rn[WindUrlRole] = "windUrl";
+ rn[RainRole] = "rain";
+ return rn;
+}
+
+void DayModel::clear()
+{
+ m_date = QString();
+ m_afternoonindex = 0;
+ m_data.clear();
+}
+
+void DayModel::addRow(QString day, QString weatherUrl, QString timeRange, QString temperature, QString windSpeed, QString windUrl, QString rain) {
+ QStringList m_images;
+ DayModelStructure temp;
+ temp.day = day;
+ temp.weatherUrl = weatherUrl;
+ m_images.append(weatherUrl);
+ QString largeWeatherIconUrl = weatherUrl;
+ m_images.append(largeWeatherIconUrl.replace("b100", "b200"));
+ temp.timeRange = timeRange;
+ temp.temperature = temperature;
+ temp.windSpeed = windSpeed;
+ temp.windUrl = windUrl;
+ m_images.append(windUrl);
+ temp.rain = rain;
+ m_data.append(temp);
+ emit addedImages(m_images);
+}
+
+QUrl DayModel::getCachedImageFile(const QString url)
+{
+ bool isLargeImage = url.contains("b200");
+ QString filename = url.right(url.length() - url.lastIndexOf("/") - 1);
+ if (isLargeImage)
+ filename.prepend("large_");
+ filename = QString("%1%2").arg(ApplicationPaths::dowloadedFilesPath()).arg(filename);
+ QFile file(filename);
+ if (file.exists())
+ return QUrl(QString("image://weatherImages/%1").arg(filename));
+ else
+ return QUrl(url);
+}
+
+QString DayModel::getDayDetails(int index, QString prop) const
+{
+ if (index == -1)
+ index = 0;
+ if (index < m_data.count()) {
+ DayModelStructure temp = m_data.at(index);
+ if (prop == "day")
+ return temp.day;
+ if (prop == "weatherUrl")
+ return temp.weatherUrl;
+ if (prop == "timeRange")
+ return temp.timeRange;
+ if (prop == "temperature")
+ return temp.temperature;
+ if (prop == "windSpeed")
+ return temp.windSpeed;
+ if (prop == "windUrl")
+ return temp.windUrl;
+ if (prop == "rain")
+ return temp.rain;
+ }
+ return QString();
+}
diff --git a/src/daymodel.h b/src/daymodel.h
new file mode 100644
index 0000000..d93e905
--- /dev/null
+++ b/src/daymodel.h
@@ -0,0 +1,116 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the FOO module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef DAYMODEL_H
+#define DAYMODEL_H
+
+#include <QtCore/QModelIndex>
+
+#include <QtCore/QObject>
+#include <QtCore/QStringList>
+#include <QtQml/qqml.h>
+
+QT_BEGIN_NAMESPACE
+class QNetworkAccessManager;
+class QNetworkReply;
+QT_END_NAMESPACE
+
+class DayModel : public QObject
+{
+ Q_OBJECT
+ Q_PROPERTY(QString date READ getDate WRITE setDate NOTIFY dateChanged)
+ Q_PROPERTY(int afternoonIndex READ getAfternoonIndex WRITE setAfternoonIndex NOTIFY afternoonIndexChanged)
+
+public:
+
+ struct DayModelStructure {
+ QString day;
+ QString weatherUrl;
+ QString timeRange;
+ QString temperature;
+ QString windSpeed;
+ QString windUrl;
+ QString rain;
+ };
+
+ enum {
+ DayRole = Qt::UserRole + 1,
+ WeatherUrlRole = Qt::UserRole + 2,
+ TimeRangeRole = Qt::UserRole + 3,
+ TemperatureRole = Qt::UserRole + 4,
+ WindSpeedRole = Qt::UserRole + 5,
+ WindUrlRole = Qt::UserRole + 6,
+ RainRole = Qt::UserRole + 7
+ };
+
+ DayModel();
+
+ QString getDate() const { return m_date;}
+ void setDate(QString date) { m_date = date; }
+
+ int getAfternoonIndex() const { return m_afternoonindex;}
+ void setAfternoonIndex(int index) { m_afternoonindex = index; }
+
+ void clear();
+
+ QVariant data(const QModelIndex &index, int role) const;
+ QHash<int, QByteArray> roleNames() const;
+
+ Q_INVOKABLE void addRow(QString day, QString weatherUrl, QString timeRange, QString temperature, QString windSpeed, QString windUrl, QString rain);
+ Q_INVOKABLE QString getDayDetails(int index, QString prop) const;
+ Q_INVOKABLE int periodCount() const { return m_data.count(); }
+
+ Q_INVOKABLE QUrl getCachedImageFile(const QString url);
+
+Q_SIGNALS:
+ void dateChanged();
+ void afternoonIndexChanged();
+ void addedImages(const QStringList images);
+
+private:
+ QString m_date;
+ int m_afternoonindex;
+ QList<DayModelStructure> m_data;
+};
+
+QML_DECLARE_TYPE(DayModel)
+
+#endif // DAYMODEL_H
diff --git a/src/main.cpp b/src/main.cpp
new file mode 100644
index 0000000..1704fe2
--- /dev/null
+++ b/src/main.cpp
@@ -0,0 +1,138 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the FOO module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtCore/QString>
+#include <QtGui/QFont>
+#include <QtGui/QFontDatabase>
+#include <QtGui/QGuiApplication>
+#include <QtQuick/QQuickWindow>
+#include <QtQml>
+
+#include "daymodel.h"
+#include "citymodel.h"
+#include "cities.h"
+#include "applicationinfo.h"
+#include "weatherimageprovider.h"
+
+static const struct {
+ const char *type;
+ int major, minor;
+} qmldir_touch [] = {
+ { "TouchSlider", 1, 0 },
+ { "TouchScrollView", 1, 0 },
+ { "TouchLabel", 1, 0 },
+ { "TouchTextField", 1, 0 },
+ { "ListViewDelegate", 1, 0 },
+ { "ListViewDelegateLoading", 1, 0 },
+};
+
+static const struct {
+ const char *type;
+ int major, minor;
+} qmldir_models [] = {
+ { "CitiesModel", 1, 0 },
+ { "WeatherModel", 1, 0 },
+};
+
+static const struct {
+ const char *type;
+ int major, minor;
+} qmldir_pages [] = {
+ { "CitiesPage", 1, 0 },
+ { "LongTermPage", 1, 0 },
+ { "OneDayPage", 1, 0 },
+};
+
+static QObject *systeminfo_provider(QQmlEngine *engine, QJSEngine *scriptEngine)
+{
+ Q_UNUSED(engine)
+ Q_UNUSED(scriptEngine)
+ WeatherImageProvider *provider = new WeatherImageProvider();
+ engine->addImageProvider(QLatin1String("weatherImages"), provider);
+ return new ApplicationInfo(provider);
+}
+
+int main(int argc, char *argv[])
+{
+ QGuiApplication app(argc, argv);
+ app.setOrganizationName("Digia");
+ app.setApplicationName("QuickForecast");
+
+#ifndef Q_OS_IOS //QTBUG-34490
+ QFontDatabase::addApplicationFont(":/weatherapp/fonts/OpenSans-Bold.ttf");
+ QFontDatabase::addApplicationFont(":/weatherapp/fonts/OpenSans-Semibold.ttf");
+ int openSansID = QFontDatabase::addApplicationFont(":/weatherapp/fonts/OpenSans-Regular.ttf");
+ QStringList loadedFontFamilies = QFontDatabase::applicationFontFamilies(openSansID);
+ if (!loadedFontFamilies.empty()) {
+ QString fontName = loadedFontFamilies.at(0);
+ QGuiApplication::setFont(QFont(fontName));
+ } else {
+ qWarning("Error: fail to load Open Sans font");
+ }
+#endif
+
+ const char *uri = "org.qtproject.demo.weather";
+ qmlRegisterType<DayModel>(uri, 1, 0, "DayModel");
+ qmlRegisterType<CityModel>(uri, 1, 0, "CityModel");
+ qmlRegisterType<Cities>(uri, 1, 0, "Cities");
+ qmlRegisterType<CitiesListModel>(uri, 1, 0, "CitiesListModel");
+ qmlRegisterSingletonType<ApplicationInfo>(uri, 1, 0, "ApplicationInfo", systeminfo_provider);
+
+ for (int i = 0; i < int(sizeof(qmldir_touch)/sizeof(qmldir_touch[0])); i++)
+ qmlRegisterType(QUrl(QString("qrc:/weatherapp/qml/touch/%1.qml").arg(qmldir_touch[i].type)), uri, qmldir_touch[i].major, qmldir_touch[i].minor, qmldir_touch[i].type);
+
+ for (int i = 0; i < int(sizeof(qmldir_models)/sizeof(qmldir_models[0])); i++)
+ qmlRegisterType(QUrl(QString("qrc:/weatherapp/qml/models/%1.qml").arg(qmldir_models[i].type)), uri, qmldir_models[i].major, qmldir_models[i].minor, qmldir_models[i].type);
+
+ for (int i = 0; i < int(sizeof(qmldir_pages)/sizeof(qmldir_pages[0])); i++)
+ qmlRegisterType(QUrl(QString("qrc:/weatherapp/qml/pages/%1.qml").arg(qmldir_pages[i].type)), uri, qmldir_pages[i].major, qmldir_pages[i].minor, qmldir_pages[i].type);
+
+ QQmlApplicationEngine engine(QUrl("qrc:/weatherapp/qml/main.qml"));
+ QObject *topLevel = engine.rootObjects().value(0);
+
+ QQuickWindow *window = qobject_cast<QQuickWindow *>(topLevel);
+ if ( !window ) {
+ qWarning("Error: Your root item has to be a Window.");
+ return -1;
+ }
+ window->show();
+ return app.exec();
+}
diff --git a/src/src.pri b/src/src.pri
new file mode 100644
index 0000000..5a3bbdf
--- /dev/null
+++ b/src/src.pri
@@ -0,0 +1,16 @@
+SOURCES += \
+ $$PWD/main.cpp \
+ $$PWD/citymodel.cpp \
+ $$PWD/daymodel.cpp \
+ $$PWD/cities.cpp \
+ $$PWD/applicationinfo.cpp \
+ $$PWD/citieslistmodel.cpp
+
+HEADERS += \
+ $$PWD/citymodel.h \
+ $$PWD/daymodel.h \
+ $$PWD/cities.h \
+ $$PWD/applicationinfo.h \
+ $$PWD/citieslistmodel.h \
+ $$PWD/weatherimageprovider.h \
+ $$PWD/applicationpaths.h
diff --git a/src/weatherimageprovider.h b/src/weatherimageprovider.h
new file mode 100644
index 0000000..59fcbcc
--- /dev/null
+++ b/src/weatherimageprovider.h
@@ -0,0 +1,72 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the FOO module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef WEATHERIMAGEPROVIDER_H
+#define WEATHERIMAGEPROVIDER_H
+
+#include <QtQuick/QQuickImageProvider>
+#include <QtGui/QImage>
+#include <QtCore/QSize>
+
+class WeatherImageProvider : public QQuickImageProvider
+{
+public:
+ WeatherImageProvider()
+ : QQuickImageProvider(QQuickImageProvider::Image)
+ {
+ }
+
+ QImage requestImage(const QString &id, QSize *size, const QSize &requestedSize)
+ {
+ int width = 50;
+ int height = 50;
+
+ if (size)
+ *size = QSize(width, height);
+ QImage image(requestedSize.width() > 0 ? requestedSize.width() : width,
+ requestedSize.height() > 0 ? requestedSize.height() : height,
+ QImage::Format_ARGB32);
+ image.load(id);
+ return image;
+ }
+};
+
+#endif // WEATHERIMAGEPROVIDER_H
diff --git a/weatherapp.pro b/weatherapp.pro
new file mode 100644
index 0000000..a386a5d
--- /dev/null
+++ b/weatherapp.pro
@@ -0,0 +1,74 @@
+cache()
+
+TEMPLATE = app
+QT += qml quick gui network xmlpatterns
+TARGET = QuickForecast
+
+include(src/src.pri)
+
+APP_FILES = \
+ $$PWD/qml/main.qml \
+ $$PWD/qml/pages/BasicPage.qml \
+ $$PWD/qml/pages/CitiesPage.qml \
+ $$PWD/qml/pages/OneDayPage.qml \
+ $$PWD/qml/pages/LongTermPage.qml \
+ $$PWD/qml/pages/LongTermDayItem.qml \
+ $$PWD/qml/pages/OneDayZoomItem.qml \
+ $$PWD/qml/pages/OneDaySliderItem.qml \
+ $$PWD/qml/pages/Separator.qml \
+ $$PWD/qml/models/WeatherModel.qml \
+ $$PWD/qml/js/utils.js
+
+# Touch Styled Controls
+APP_FILES += \
+ $$PWD/qml/touch/TouchLabel.qml \
+ $$PWD/qml/touch/TouchScrollView.qml \
+ $$PWD/qml/touch/TouchSlider.qml \
+ $$PWD/qml/touch/TouchTextField.qml \
+ $$PWD/qml/touch/ListViewDelegate.qml \
+ $$PWD/qml/touch/images/BackArrow.png \
+ $$PWD/qml/touch/images/Pointer.png \
+ $$PWD/qml/touch/images/Pointer_pressed.png \
+ $$PWD/qml/touch/images/Circle.png \
+ $$PWD/qml/touch/images/darkclose.png \
+ $$PWD/qml/touch/images/magnifier.png \
+ $$PWD/qml/touch/images/Clear.png
+
+# Fonts
+APP_FILES += \
+ $$PWD/fonts/OpenSans-Bold.ttf \
+ $$PWD/fonts/OpenSans-Semibold.ttf \
+ $$PWD/fonts/OpenSans-Regular.ttf
+
+OTHER_FILES += $$APP_FILES
+
+# Create the resource file
+GENERATED_RESOURCE_FILE = $$OUT_PWD/weatherapp.qrc
+
+RESOURCE_CONTENT = \
+ "<RCC>" \
+ "<qresource>"
+
+for(resourcefile, APP_FILES) {
+ resourcefileabsolutepath = $$absolute_path($$resourcefile)
+ relativepath_in = $$relative_path($$resourcefileabsolutepath, $$_PRO_FILE_PWD_)
+ relativepath_out = $$relative_path($$resourcefileabsolutepath, $$OUT_PWD)
+ RESOURCE_CONTENT += "<file alias=\"weatherapp/$$relativepath_in\">$$relativepath_out</file>"
+}
+
+RESOURCE_CONTENT += \
+ "</qresource>" \
+ "</RCC>"
+
+write_file($$GENERATED_RESOURCE_FILE, RESOURCE_CONTENT)|error("Aborting.")
+
+RESOURCES += $$GENERATED_RESOURCE_FILE
+
+ios {
+ FONTS.files = $$PWD/fonts/OpenSans-Bold.ttf $$PWD/fonts/OpenSans-Semibold.ttf $$PWD/fonts/OpenSans-Regular.ttf
+ FONTS.path = fonts
+ QMAKE_BUNDLE_DATA += FONTS
+ QMAKE_INFO_PLIST = ios/iosInfo.plist
+}
+
+android: ANDROID_PACKAGE_SOURCE_DIR = $$PWD/android