diff options
Diffstat (limited to 'examples/positioning/weatherinfo')
22 files changed, 1285 insertions, 0 deletions
diff --git a/examples/positioning/weatherinfo/appmodel.cpp b/examples/positioning/weatherinfo/appmodel.cpp new file mode 100644 index 00000000..d0a37265 --- /dev/null +++ b/examples/positioning/weatherinfo/appmodel.cpp @@ -0,0 +1,497 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names +** of its contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "appmodel.h" + +#include <qgeopositioninfosource.h> +#include <qgeosatelliteinfosource.h> +#include <qnmeapositioninfosource.h> +#include <qgeopositioninfo.h> +#include <qnetworkconfigmanager.h> +#include <qnetworksession.h> + +#include <QSignalMapper> +#include <QJsonDocument> +#include <QJsonObject> +#include <QJsonArray> +#include <QStringList> +#include <QUrlQuery> +#include <QElapsedTimer> + +/* + *This application uses http://openweathermap.org/api + **/ + +#define ZERO_KELVIN 273.15 + +WeatherData::WeatherData(QObject *parent) : + QObject(parent) +{ +} + +WeatherData::WeatherData(const WeatherData &other) : + QObject(0), + m_dayOfWeek(other.m_dayOfWeek), + m_weather(other.m_weather), + m_weatherDescription(other.m_weatherDescription), + m_temperature(other.m_temperature) +{ +} + +QString WeatherData::dayOfWeek() const +{ + return m_dayOfWeek; +} + +/*! + * The icon value is based on OpenWeatherMap.org icon set. For details + * see http://bugs.openweathermap.org/projects/api/wiki/Weather_Condition_Codes + * + * e.g. 01d ->sunny day + * + * The icon string will be translated to + * http://openweathermap.org/img/w/01d.png + */ +QString WeatherData::weatherIcon() const +{ + return m_weather; +} + +QString WeatherData::weatherDescription() const +{ + return m_weatherDescription; +} + +QString WeatherData::temperature() const +{ + return m_temperature; +} + +void WeatherData::setDayOfWeek(const QString &value) +{ + m_dayOfWeek = value; + emit dataChanged(); +} + +void WeatherData::setWeatherIcon(const QString &value) +{ + m_weather = value; + emit dataChanged(); +} + +void WeatherData::setWeatherDescription(const QString &value) +{ + m_weatherDescription = value; + emit dataChanged(); +} + +void WeatherData::setTemperature(const QString &value) +{ + m_temperature = value; + emit dataChanged(); +} + +class AppModelPrivate +{ +public: + QGeoPositionInfoSource *src; + QGeoCoordinate coord; + QString city; + QNetworkAccessManager *nam; + QNetworkSession *ns; + WeatherData now; + QList<WeatherData*> forecast; + QQmlListProperty<WeatherData> *fcProp; + QSignalMapper *geoReplyMapper; + QSignalMapper *weatherReplyMapper, *forecastReplyMapper; + bool ready; + bool useGps; + QElapsedTimer throttle; + + AppModelPrivate() : + src(NULL), + nam(NULL), + ns(NULL), + fcProp(NULL), + ready(false), + useGps(true) + {} +}; + +static void forecastAppend(QQmlListProperty<WeatherData> *prop, WeatherData *val) +{ + Q_UNUSED(val); + Q_UNUSED(prop); +} + +static WeatherData *forecastAt(QQmlListProperty<WeatherData> *prop, int index) +{ + AppModelPrivate *d = static_cast<AppModelPrivate*>(prop->data); + return d->forecast.at(index); +} + +static int forecastCount(QQmlListProperty<WeatherData> *prop) +{ + AppModelPrivate *d = static_cast<AppModelPrivate*>(prop->data); + return d->forecast.size(); +} + +static void forecastClear(QQmlListProperty<WeatherData> *prop) +{ + static_cast<AppModelPrivate*>(prop->data)->forecast.clear(); +} + +//! [0] +AppModel::AppModel(QObject *parent) : + QObject(parent), + d(new AppModelPrivate) +{ +//! [0] + d->fcProp = new QQmlListProperty<WeatherData>(this, d, + forecastAppend, + forecastCount, + forecastAt, + forecastClear); + + d->geoReplyMapper = new QSignalMapper(this); + d->weatherReplyMapper = new QSignalMapper(this); + d->forecastReplyMapper = new QSignalMapper(this); + + connect(d->geoReplyMapper, SIGNAL(mapped(QObject*)), + this, SLOT(handleGeoNetworkData(QObject*))); + connect(d->weatherReplyMapper, SIGNAL(mapped(QObject*)), + this, SLOT(handleWeatherNetworkData(QObject*))); + connect(d->forecastReplyMapper, SIGNAL(mapped(QObject*)), + this, SLOT(handleForecastNetworkData(QObject*))); + +//! [1] + // make sure we have an active network session + d->nam = new QNetworkAccessManager(this); + + QNetworkConfigurationManager ncm; + d->ns = new QNetworkSession(ncm.defaultConfiguration(), this); + connect(d->ns, SIGNAL(opened()), this, SLOT(networkSessionOpened())); + // the session may be already open. if it is, run the slot directly + if (d->ns->isOpen()) + this->networkSessionOpened(); + // tell the system we want network + d->ns->open(); +} +//! [1] + +AppModel::~AppModel() +{ + d->ns->close(); + if (d->src) + d->src->stopUpdates(); + delete d; +} + +//! [2] +void AppModel::networkSessionOpened() +{ + d->src = QGeoPositionInfoSource::createDefaultSource(this); + + if (d->src) { + d->useGps = true; + connect(d->src, SIGNAL(positionUpdated(QGeoPositionInfo)), + this, SLOT(positionUpdated(QGeoPositionInfo))); + d->src->startUpdates(); + } else { + d->useGps = false; + d->city = "Brisbane"; + emit cityChanged(); + this->refreshWeather(); + } +} +//! [2] + +//! [3] +void AppModel::positionUpdated(QGeoPositionInfo gpsPos) +{ + d->coord = gpsPos.coordinate(); + + if (!(d->useGps)) + return; + + QString latitude, longitude; + longitude.setNum(d->coord.longitude()); + latitude.setNum(d->coord.latitude()); +//! [3] + + //don't update more often then once a minute + //to keep load on server low + if (d->throttle.isValid() && d->throttle.elapsed() < 1000*10 ) { + return; + } + d->throttle.restart(); + + QUrl url("http://api.openweathermap.org/data/2.5/weather"); + QUrlQuery query; + query.addQueryItem("lat", latitude); + query.addQueryItem("lon", longitude); + query.addQueryItem("mode", "json"); + url.setQuery(query); + + QNetworkReply *rep = d->nam->get(QNetworkRequest(url)); + // connect up the signal right away + d->geoReplyMapper->setMapping(rep, rep); + connect(rep, SIGNAL(finished()), + d->geoReplyMapper, SLOT(map())); +} + +void AppModel::handleGeoNetworkData(QObject *replyObj) +{ + QNetworkReply *networkReply = qobject_cast<QNetworkReply*>(replyObj); + if (!networkReply) + return; + + if (!networkReply->error()) { + //convert coordinates to city name + QJsonDocument document = QJsonDocument::fromJson(networkReply->readAll()); + + QJsonObject jo = document.object(); + QJsonValue jv = jo.value(QStringLiteral("name")); + + const QString city = jv.toString(); + if (city != d->city) { + if (!d->throttle.isValid()) + d->throttle.start(); + d->city = city; + emit cityChanged(); + refreshWeather(); + } + } + networkReply->deleteLater(); +} + +void AppModel::refreshWeather() +{ + QUrl url("http://api.openweathermap.org/data/2.5/weather"); + QUrlQuery query; + + query.addQueryItem("q", d->city); + query.addQueryItem("mode", "json"); + url.setQuery(query); + + QNetworkReply *rep = d->nam->get(QNetworkRequest(url)); + // connect up the signal right away + d->weatherReplyMapper->setMapping(rep, rep); + connect(rep, SIGNAL(finished()), + d->weatherReplyMapper, SLOT(map())); +} + +static QString niceTemperatureString(double t) +{ + return QString::number(qRound(t-ZERO_KELVIN)) + QChar(0xB0); +} + +void AppModel::handleWeatherNetworkData(QObject *replyObj) +{ + QNetworkReply *networkReply = qobject_cast<QNetworkReply*>(replyObj); + if (!networkReply) + return; + + if (!networkReply->error()) { + foreach (WeatherData *inf, d->forecast) + delete inf; + d->forecast.clear(); + + QJsonDocument document = QJsonDocument::fromJson(networkReply->readAll()); + + if (document.isObject()) { + QJsonObject obj = document.object(); + QJsonObject tempObject; + QJsonValue val; + + if (obj.contains(QStringLiteral("weather"))) { + val = obj.value(QStringLiteral("weather")); + QJsonArray weatherArray = val.toArray(); + val = weatherArray.at(0); + tempObject = val.toObject(); + d->now.setWeatherDescription(tempObject.value(QStringLiteral("description")).toString()); + d->now.setWeatherIcon(tempObject.value("icon").toString()); + } + if (obj.contains(QStringLiteral("main"))) { + val = obj.value(QStringLiteral("main")); + tempObject = val.toObject(); + val = tempObject.value(QStringLiteral("temp")); + d->now.setTemperature(niceTemperatureString(val.toDouble())); + } + } + } + networkReply->deleteLater(); + + //retrieve the forecast + QUrl url("http://api.openweathermap.org/data/2.5/forecast/daily"); + QUrlQuery query; + + query.addQueryItem("q", d->city); + query.addQueryItem("mode", "json"); + query.addQueryItem("cnt", "5"); + url.setQuery(query); + + QNetworkReply *rep = d->nam->get(QNetworkRequest(url)); + // connect up the signal right away + d->forecastReplyMapper->setMapping(rep, rep); + connect(rep, SIGNAL(finished()), d->forecastReplyMapper, SLOT(map())); +} + +void AppModel::handleForecastNetworkData(QObject *replyObj) +{ + QNetworkReply *networkReply = qobject_cast<QNetworkReply*>(replyObj); + if (!networkReply) + return; + + if (!networkReply->error()) { + QJsonDocument document = QJsonDocument::fromJson(networkReply->readAll()); + + QJsonObject jo; + QJsonValue jv; + QJsonObject root = document.object(); + jv = root.value(QStringLiteral("list")); + if (!jv.isArray()) + qWarning() << "Invalid forecast object"; + QJsonArray ja = jv.toArray(); + //we need 4 days of forecast -> first entry is today + if (ja.count() != 5) + qWarning() << "Invalid forecast object"; + + QString data; + for (int i = 1; i<ja.count(); i++) { + WeatherData *forecastEntry = new WeatherData(); + + //min/max temperature + QJsonObject subtree = ja.at(i).toObject(); + jo = subtree.value(QStringLiteral("temp")).toObject(); + jv = jo.value(QStringLiteral("min")); + data.clear(); + data += niceTemperatureString(jv.toDouble()); + data += QChar('/'); + jv = jo.value(QStringLiteral("max")); + data += niceTemperatureString(jv.toDouble()); + forecastEntry->setTemperature(data); + + //get date + jv = subtree.value(QStringLiteral("dt")); + QDateTime dt = QDateTime::fromMSecsSinceEpoch((qint64)jv.toDouble()*1000); + forecastEntry->setDayOfWeek(dt.date().toString(QStringLiteral("ddd"))); + + //get icon + QJsonArray weatherArray = subtree.value(QStringLiteral("weather")).toArray(); + jo = weatherArray.at(0).toObject(); + forecastEntry->setWeatherIcon(jo.value(QStringLiteral("icon")).toString()); + + //get description + forecastEntry->setWeatherDescription(jo.value(QStringLiteral("description")).toString()); + + d->forecast.append(forecastEntry); + } + + if (!(d->ready)) { + d->ready = true; + emit readyChanged(); + } + + emit weatherChanged(); + } + networkReply->deleteLater(); +} + +bool AppModel::hasValidCity() const +{ + return (!(d->city.isEmpty()) && d->city.size() > 1 && d->city != ""); +} + +bool AppModel::hasValidWeather() const +{ + return hasValidCity() && (!(d->now.weatherIcon().isEmpty()) && + (d->now.weatherIcon().size() > 1) && + d->now.weatherIcon() != ""); +} + +WeatherData *AppModel::weather() const +{ + return &(d->now); +} + +QQmlListProperty<WeatherData> AppModel::forecast() const +{ + return *(d->fcProp); +} + +bool AppModel::ready() const +{ + return d->ready; +} + +bool AppModel::hasSource() const +{ + return (d->src != NULL); +} + +bool AppModel::useGps() const +{ + return d->useGps; +} + +void AppModel::setUseGps(bool value) +{ + d->useGps = value; + if (value) { + d->city = ""; + d->throttle.invalidate(); + emit cityChanged(); + emit weatherChanged(); + } + emit useGpsChanged(); +} + +QString AppModel::city() const +{ + return d->city; +} + +void AppModel::setCity(const QString &value) +{ + d->city = value; + emit cityChanged(); + refreshWeather(); +} diff --git a/examples/positioning/weatherinfo/appmodel.h b/examples/positioning/weatherinfo/appmodel.h new file mode 100644 index 00000000..e0d32148 --- /dev/null +++ b/examples/positioning/weatherinfo/appmodel.h @@ -0,0 +1,170 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names +** of its contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef APPMODEL_H +#define APPMODEL_H + +#include <QtCore/QObject> +#include <QtCore/QString> +#include <QtNetwork/QNetworkReply> +#include <QtQml/QQmlListProperty> + +#include <qgeopositioninfo.h> + +//! [0] +class WeatherData : public QObject { + Q_OBJECT + Q_PROPERTY(QString dayOfWeek + READ dayOfWeek WRITE setDayOfWeek + NOTIFY dataChanged) + Q_PROPERTY(QString weatherIcon + READ weatherIcon WRITE setWeatherIcon + NOTIFY dataChanged) + Q_PROPERTY(QString weatherDescription + READ weatherDescription WRITE setWeatherDescription + NOTIFY dataChanged) + Q_PROPERTY(QString temperature + READ temperature WRITE setTemperature + NOTIFY dataChanged) + +public: + explicit WeatherData(QObject *parent = 0); + WeatherData(const WeatherData &other); + + QString dayOfWeek() const; + QString weatherIcon() const; + QString weatherDescription() const; + QString temperature() const; + + void setDayOfWeek(const QString &value); + void setWeatherIcon(const QString &value); + void setWeatherDescription(const QString &value); + void setTemperature(const QString &value); + +signals: + void dataChanged(); +//! [0] +private: + QString m_dayOfWeek; + QString m_weather; + QString m_weatherDescription; + QString m_temperature; +//! [1] +}; +//! [1] + +Q_DECLARE_METATYPE(WeatherData) + +class AppModelPrivate; +//! [2] +class AppModel : public QObject +{ + Q_OBJECT + Q_PROPERTY(bool ready + READ ready + NOTIFY readyChanged) + Q_PROPERTY(bool hasSource + READ hasSource + NOTIFY readyChanged) + Q_PROPERTY(bool hasValidCity + READ hasValidCity + NOTIFY cityChanged) + Q_PROPERTY(bool hasValidWeather + READ hasValidWeather + NOTIFY weatherChanged) + Q_PROPERTY(bool useGps + READ useGps WRITE setUseGps + NOTIFY useGpsChanged) + Q_PROPERTY(QString city + READ city WRITE setCity + NOTIFY cityChanged) + Q_PROPERTY(WeatherData *weather + READ weather + NOTIFY weatherChanged) + Q_PROPERTY(QQmlListProperty<WeatherData> forecast + READ forecast + NOTIFY weatherChanged) + +public: + explicit AppModel(QObject *parent = 0); + ~AppModel(); + + bool ready() const; + bool hasSource() const; + bool useGps() const; + bool hasValidCity() const; + bool hasValidWeather() const; + void setUseGps(bool value); + + QString city() const; + void setCity(const QString &value); + + WeatherData *weather() const; + QQmlListProperty<WeatherData> forecast() const; + +public slots: + Q_INVOKABLE void refreshWeather(); + +//! [2] +private slots: + void networkSessionOpened(); + void positionUpdated(QGeoPositionInfo gpsPos); + // these would have QNetworkReply* params but for the signalmapper + void handleGeoNetworkData(QObject *networkReply); + void handleWeatherNetworkData(QObject *networkReply); + void handleForecastNetworkData(QObject *networkReply); + +//! [3] +signals: + void readyChanged(); + void useGpsChanged(); + void cityChanged(); + void weatherChanged(); + +//! [3] + +private: + AppModelPrivate *d; + +//! [4] +}; +//! [4] + +#endif // APPMODEL_H diff --git a/examples/positioning/weatherinfo/components/BigForecastIcon.qml b/examples/positioning/weatherinfo/components/BigForecastIcon.qml new file mode 100644 index 00000000..6583d6d3 --- /dev/null +++ b/examples/positioning/weatherinfo/components/BigForecastIcon.qml @@ -0,0 +1,80 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names +** of its contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.0 + +Item { + id: current + + property string topText: "20*" + property string bottomText: "Mostly cloudy" + property string weatherIcon: "01d" + property real smallSide: (current.width < current.height ? current.width : current.height) + + Text { + text: current.topText + font.pointSize: 28 + anchors { + top: current.top + left: current.left + topMargin: 5 + leftMargin: 5 + } + } + + WeatherIcon { + weatherIcon: current.weatherIcon + useServerIcon: false + anchors.centerIn: parent + anchors.verticalCenterOffset: -15 + width: current.smallSide + height: current.smallSide + } + + Text { + text: current.bottomText + font.pointSize: 28 + anchors { + bottom: current.bottom + right: current.right + rightMargin: 5 + } + } +} diff --git a/examples/positioning/weatherinfo/components/ForecastIcon.qml b/examples/positioning/weatherinfo/components/ForecastIcon.qml new file mode 100644 index 00000000..a1393932 --- /dev/null +++ b/examples/positioning/weatherinfo/components/ForecastIcon.qml @@ -0,0 +1,89 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names +** of its contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.0 + +Item { + id: top + + property string topText: "Mon" + property string weatherIcon: "01d" + property string bottomText: "22*/23*" + + Text { + id: dayText + horizontalAlignment: Text.AlignHCenter + width: top.width + text: top.topText + + anchors.top: parent.top + anchors.topMargin: top.height / 5 - dayText.paintedHeight + anchors.horizontalCenter: parent.horizontalCenter + } + + WeatherIcon { + id: icon + weatherIcon: top.weatherIcon + + property real side: { + var h = 3 * top.height / 5 + if (top.width < h) + top.width; + else + h; + } + + width: icon.side + height: icon.side + + anchors.centerIn: parent + } + + Text { + id: tempText + horizontalAlignment: Text.AlignHCenter + width: top.width + text: top.bottomText + + anchors.bottom: parent.bottom + anchors.bottomMargin: top.height / 5 - tempText.paintedHeight + anchors.horizontalCenter: parent.horizontalCenter + } +} diff --git a/examples/positioning/weatherinfo/components/WeatherIcon.qml b/examples/positioning/weatherinfo/components/WeatherIcon.qml new file mode 100644 index 00000000..485a15a5 --- /dev/null +++ b/examples/positioning/weatherinfo/components/WeatherIcon.qml @@ -0,0 +1,102 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names +** of its contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.0 + +Item { + id: container + + property string weatherIcon: "01d" + + //server icons are too small. we keep using the local images + property bool useServerIcon: true + + Image { + id: img + source: { + if (useServerIcon) + "http://openweathermap.org/img/w/" + container.weatherIcon + ".png" + else { + switch (weatherIcon) { + case "01d": + case "01n": + "../icons/weather-sunny.png" + break; + case "02d": + case "02n": + "../icons/weather-sunny-very-few-clouds.png" + break; + case "03d": + case "03n": + "../icons/weather-few-clouds.png" + break; + case "04d": + case "04n": + "../icons/weather-overcast.png" + break; + case "09d": + case "09n": + "../icons/weather-showers.png" + break; + case "10d": + case "10n": + "../icons/weather-showers.png" + break; + case "11d": + case "11n": + "../icons/weather-thundershower.png" + break; + case "13d": + case "13n": + "../icons/weather-snow.png" + break; + case "50d": + case "50n": + "../icons/weather-fog.png" + break; + default: + "../icons/weather-unknown.png" + } + } + } + smooth: true + anchors.fill: parent + } +} diff --git a/examples/positioning/weatherinfo/icons/README.txt b/examples/positioning/weatherinfo/icons/README.txt new file mode 100644 index 00000000..d3841532 --- /dev/null +++ b/examples/positioning/weatherinfo/icons/README.txt @@ -0,0 +1,5 @@ +The scalable icons are from: + +http://tango.freedesktop.org/Tango_Icon_Library +http://darkobra.deviantart.com/art/Tango-Weather-Icon-Pack-98024429 + diff --git a/examples/positioning/weatherinfo/icons/weather-few-clouds.png b/examples/positioning/weatherinfo/icons/weather-few-clouds.png Binary files differnew file mode 100644 index 00000000..a8000ef0 --- /dev/null +++ b/examples/positioning/weatherinfo/icons/weather-few-clouds.png diff --git a/examples/positioning/weatherinfo/icons/weather-fog.png b/examples/positioning/weatherinfo/icons/weather-fog.png Binary files differnew file mode 100644 index 00000000..9ffe9c4a --- /dev/null +++ b/examples/positioning/weatherinfo/icons/weather-fog.png diff --git a/examples/positioning/weatherinfo/icons/weather-haze.png b/examples/positioning/weatherinfo/icons/weather-haze.png Binary files differnew file mode 100644 index 00000000..ae6f13eb --- /dev/null +++ b/examples/positioning/weatherinfo/icons/weather-haze.png diff --git a/examples/positioning/weatherinfo/icons/weather-icy.png b/examples/positioning/weatherinfo/icons/weather-icy.png Binary files differnew file mode 100644 index 00000000..18d20384 --- /dev/null +++ b/examples/positioning/weatherinfo/icons/weather-icy.png diff --git a/examples/positioning/weatherinfo/icons/weather-overcast.png b/examples/positioning/weatherinfo/icons/weather-overcast.png Binary files differnew file mode 100644 index 00000000..9d50f77f --- /dev/null +++ b/examples/positioning/weatherinfo/icons/weather-overcast.png diff --git a/examples/positioning/weatherinfo/icons/weather-showers.png b/examples/positioning/weatherinfo/icons/weather-showers.png Binary files differnew file mode 100644 index 00000000..07489aaa --- /dev/null +++ b/examples/positioning/weatherinfo/icons/weather-showers.png diff --git a/examples/positioning/weatherinfo/icons/weather-sleet.png b/examples/positioning/weatherinfo/icons/weather-sleet.png Binary files differnew file mode 100644 index 00000000..3d225895 --- /dev/null +++ b/examples/positioning/weatherinfo/icons/weather-sleet.png diff --git a/examples/positioning/weatherinfo/icons/weather-snow.png b/examples/positioning/weatherinfo/icons/weather-snow.png Binary files differnew file mode 100644 index 00000000..e7426e3c --- /dev/null +++ b/examples/positioning/weatherinfo/icons/weather-snow.png diff --git a/examples/positioning/weatherinfo/icons/weather-storm.png b/examples/positioning/weatherinfo/icons/weather-storm.png Binary files differnew file mode 100644 index 00000000..6b6b366a --- /dev/null +++ b/examples/positioning/weatherinfo/icons/weather-storm.png diff --git a/examples/positioning/weatherinfo/icons/weather-sunny-very-few-clouds.png b/examples/positioning/weatherinfo/icons/weather-sunny-very-few-clouds.png Binary files differnew file mode 100644 index 00000000..133bcb29 --- /dev/null +++ b/examples/positioning/weatherinfo/icons/weather-sunny-very-few-clouds.png diff --git a/examples/positioning/weatherinfo/icons/weather-sunny.png b/examples/positioning/weatherinfo/icons/weather-sunny.png Binary files differnew file mode 100644 index 00000000..0fac921d --- /dev/null +++ b/examples/positioning/weatherinfo/icons/weather-sunny.png diff --git a/examples/positioning/weatherinfo/icons/weather-thundershower.png b/examples/positioning/weatherinfo/icons/weather-thundershower.png Binary files differnew file mode 100644 index 00000000..1aff1639 --- /dev/null +++ b/examples/positioning/weatherinfo/icons/weather-thundershower.png diff --git a/examples/positioning/weatherinfo/main.cpp b/examples/positioning/weatherinfo/main.cpp new file mode 100644 index 00000000..6afcf1c4 --- /dev/null +++ b/examples/positioning/weatherinfo/main.cpp @@ -0,0 +1,70 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names +** of its contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtGui/QGuiApplication> +#include <QtQuick/QQuickView> +#include <QtQml/QQmlEngine> +#include <QtQml/QQmlContext> +#include <QtQuick/QQuickItem> + +//! [0] +#include "appmodel.h" + +int main(int argc, char *argv[]) +{ + QGuiApplication application(argc, argv); + + qmlRegisterType<WeatherData>("WeatherInfo", 1, 0, "WeatherData"); + qmlRegisterType<AppModel>("WeatherInfo", 1, 0, "AppModel"); + +//! [0] + qRegisterMetaType<WeatherData>("WeatherData"); +//! [1] + const QString mainQmlApp = QLatin1String("qrc:///weatherinfo.qml"); + QQuickView view; + view.setSource(QUrl(mainQmlApp)); + view.setResizeMode(QQuickView::SizeRootObjectToView); + + QObject::connect(view.engine(), SIGNAL(quit()), qApp, SLOT(quit())); + view.setGeometry(QRect(100, 100, 360, 640)); + view.show(); + return application.exec(); +} +//! [1] diff --git a/examples/positioning/weatherinfo/weatherinfo.pro b/examples/positioning/weatherinfo/weatherinfo.pro new file mode 100644 index 00000000..1470b8a0 --- /dev/null +++ b/examples/positioning/weatherinfo/weatherinfo.pro @@ -0,0 +1,22 @@ +TEMPLATE = app +TARGET = weatherinfo + +QT += core network positioning qml quick + +SOURCES += main.cpp \ + appmodel.cpp + +OTHER_FILES += weatherinfo.qml \ + components/WeatherIcon.qml \ + components/ForecastIcon.qml \ + components/BigForecastIcon.qml + +RESOURCES += weatherinfo.qrc + +HEADERS += appmodel.h + +#install +target.path = $$[QT_INSTALL_EXAMPLES]/qtpositioning/weatherinfo +sources.files = $$SOURCES $HEADERS $$RESOURCES $$FORMS *.pro +sources.path = $$[QT_INSTALL_EXAMPLES]/qtpositioning/weatherinfo +INSTALLS += target sources diff --git a/examples/positioning/weatherinfo/weatherinfo.qml b/examples/positioning/weatherinfo/weatherinfo.qml new file mode 100644 index 00000000..0c69090d --- /dev/null +++ b/examples/positioning/weatherinfo/weatherinfo.qml @@ -0,0 +1,230 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names +** of its contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.0 +import "components" +//! [0] +import WeatherInfo 1.0 + +Item { + id: window +//! [0] + width: 360 + height: 640 + + state: "loading" + + states: [ + State { + name: "loading" + PropertyChanges { target: main; opacity: 0 } + PropertyChanges { target: wait; opacity: 1 } + }, + State { + name: "ready" + PropertyChanges { target: main; opacity: 1 } + PropertyChanges { target: wait; opacity: 0 } + } + ] +//! [1] + AppModel { + id: model + onReadyChanged: { + if (model.ready) + window.state = "ready" + else + window.state = "loading" + } + } +//! [1] + Item { + id: wait + anchors.fill: parent + + Text { + text: "Loading weather data..." + anchors.centerIn: parent + font.pointSize: 18 + } + } + + Item { + id: main + anchors.fill: parent + + Column { + spacing: 6 + + anchors { + fill: parent + topMargin: 6; bottomMargin: 6; leftMargin: 6; rightMargin: 6 + } + + Rectangle { + width: parent.width + height: 25 + color: "lightgrey" + + Text { + text: (model.hasValidCity ? model.city : "Unknown location") + (model.useGps ? " (GPS)" : "") + anchors.fill: parent + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + } + + MouseArea { + anchors.fill: parent + onClicked: { + if (model.useGps) { + model.useGps = false + model.city = "Brisbane" + } else { + switch (model.city) { + case "Brisbane": + model.city = "Oslo" + break + case "Oslo": + model.city = "Helsinki" + break + case "Helsinki": + model.city = "New York" + break + case "New York": + model.useGps = true + break + } + } + } + } + } + +//! [3] + BigForecastIcon { + id: current + + width: main.width -12 + height: 2 * (main.height - 25 - 12) / 3 + + weatherIcon: (model.hasValidWeather + ? model.weather.weatherIcon + : "01d") +//! [3] + topText: (model.hasValidWeather + ? model.weather.temperature + : "??") + bottomText: (model.hasValidWeather + ? model.weather.weatherDescription + : "No weather data") + + MouseArea { + anchors.fill: parent + onClicked: { + model.refreshWeather() + } + } +//! [4] + } +//! [4] + + Row { + id: iconRow + spacing: 6 + + width: main.width - 12 + height: (main.height - 25 - 24) / 3 + + property real iconWidth: iconRow.width / 4 - 10 + property real iconHeight: iconRow.height + + ForecastIcon { + id: forecast1 + width: iconRow.iconWidth + height: iconRow.iconHeight + + topText: (model.hasValidWeather ? + model.forecast[0].dayOfWeek : "??") + bottomText: (model.hasValidWeather ? + model.forecast[0].temperature : "??/??") + weatherIcon: (model.hasValidWeather ? + model.forecast[0].weatherIcon : "01d") + } + ForecastIcon { + id: forecast2 + width: iconRow.iconWidth + height: iconRow.iconHeight + + topText: (model.hasValidWeather ? + model.forecast[1].dayOfWeek : "??") + bottomText: (model.hasValidWeather ? + model.forecast[1].temperature : "??/??") + weatherIcon: (model.hasValidWeather ? + model.forecast[1].weatherIcon : "01d") + } + ForecastIcon { + id: forecast3 + width: iconRow.iconWidth + height: iconRow.iconHeight + + topText: (model.hasValidWeather ? + model.forecast[2].dayOfWeek : "??") + bottomText: (model.hasValidWeather ? + model.forecast[2].temperature : "??/??") + weatherIcon: (model.hasValidWeather ? + model.forecast[2].weatherIcon : "01d") + } + ForecastIcon { + id: forecast4 + width: iconRow.iconWidth + height: iconRow.iconHeight + + topText: (model.hasValidWeather ? + model.forecast[3].dayOfWeek : "??") + bottomText: (model.hasValidWeather ? + model.forecast[3].temperature : "??/??") + weatherIcon: (model.hasValidWeather ? + model.forecast[3].weatherIcon : "01d") + } + + } + } + } +//! [2] +} +//! [2] diff --git a/examples/positioning/weatherinfo/weatherinfo.qrc b/examples/positioning/weatherinfo/weatherinfo.qrc new file mode 100644 index 00000000..7b79dbea --- /dev/null +++ b/examples/positioning/weatherinfo/weatherinfo.qrc @@ -0,0 +1,20 @@ +<RCC> + <qresource prefix="/"> + <file>weatherinfo.qml</file> + <file>components/BigForecastIcon.qml</file> + <file>components/ForecastIcon.qml</file> + <file>components/WeatherIcon.qml</file> + <file>icons/weather-few-clouds.png</file> + <file>icons/weather-fog.png</file> + <file>icons/weather-haze.png</file> + <file>icons/weather-icy.png</file> + <file>icons/weather-overcast.png</file> + <file>icons/weather-showers.png</file> + <file>icons/weather-sleet.png</file> + <file>icons/weather-snow.png</file> + <file>icons/weather-storm.png</file> + <file>icons/weather-sunny-very-few-clouds.png</file> + <file>icons/weather-sunny.png</file> + <file>icons/weather-thundershower.png</file> + </qresource> +</RCC> |