• Skip to content
  • Skip to link menu
KDE 4.2 API Reference
  • KDE API Reference
  • API Reference
  • Sitemap
  • Contact Us
 

Plasma

ion_envcan.cpp

Go to the documentation of this file.
00001 /***************************************************************************
00002  *   Copyright (C) 2007-2009 by Shawn Starr <shawn.starr@rogers.com>       *
00003  *                                                                         *
00004  *   This program is free software; you can redistribute it and/or modify  *
00005  *   it under the terms of the GNU General Public License as published by  *
00006  *   the Free Software Foundation; either version 2 of the License, or     *
00007  *   (at your option) any later version.                                   *
00008  *                                                                         *
00009  *   This program is distributed in the hope that it will be useful,       *
00010  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
00011  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
00012  *   GNU General Public License for more details.                          *
00013  *                                                                         *
00014  *   You should have received a copy of the GNU General Public License     *
00015  *   along with this program; if not, write to the                         *
00016  *   Free Software Foundation, Inc.,                                       *
00017  *   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA          *
00018  ***************************************************************************/
00019 
00020 /* Ion for Environment Canada XML data */
00021 
00022 #include "ion_envcan.h"
00023 
00024 class EnvCanadaIon::Private : public QObject
00025 {
00026 public:
00027     Private() {
00028         m_url = 0;
00029     }
00030     ~Private() {
00031         delete m_url;
00032     }
00033 
00034 private:
00035     struct XMLMapInfo {
00036         QString cityName;
00037         QString territoryName;
00038         QString cityCode;
00039         QString sourceOptions;
00040     };
00041 
00042 public:
00043     // Key dicts
00044     QHash<QString, EnvCanadaIon::Private::XMLMapInfo> m_place;
00045     QHash<QString, QString> m_locations;
00046     QString m_code;
00047     QString m_territory;
00048     QString m_cityName;
00049 
00050     // Weather information
00051     QHash<QString, WeatherData> m_weatherData;
00052 
00053     // Store KIO jobs
00054     QMap<KJob *, QXmlStreamReader*> m_jobXml;
00055     QMap<KJob *, QString> m_jobList;
00056     QXmlStreamReader m_xmlSetup;
00057     KUrl *m_url;
00058     KIO::TransferJob *m_job;
00059 
00060     QDateTime m_dateFormat;
00061 };
00062 
00063 
00064 // ctor, dtor
00065 EnvCanadaIon::EnvCanadaIon(QObject *parent, const QVariantList &args)
00066         : IonInterface(parent, args), d(new Private())
00067 {
00068 }
00069 
00070 EnvCanadaIon::~EnvCanadaIon()
00071 {
00072     // Destroy each watch/warning stored in a QVector
00073     foreach(const WeatherData &item, d->m_weatherData) {
00074         foreach(WeatherData::WeatherEvent *warning, item.warnings) {
00075             if (warning) {
00076                 delete warning;
00077             }
00078         }
00079 
00080         foreach(WeatherData::WeatherEvent *watch, item.watches) {
00081             if (watch) {
00082                 delete watch;
00083             }
00084         }
00085 
00086         foreach(WeatherData::ForecastInfo *forecast, item.forecasts) {
00087             if (forecast) {
00088                 delete forecast;
00089             }
00090         }
00091     }
00092 
00093     // Destroy dptr
00094     delete d;
00095 }
00096 
00097 // Get the master list of locations to be parsed
00098 void EnvCanadaIon::init()
00099 {
00100     // Get the real city XML URL so we can parse this
00101     getXMLSetup();
00102 }
00103 
00104 QMap<QString, IonInterface::ConditionIcons> EnvCanadaIon::setupConditionIconMappings(void)
00105 {
00106     QMap<QString, ConditionIcons> conditionList;
00107 
00108     // Explicit periods
00109     conditionList["mainly sunny"] = FewCloudsDay;
00110     conditionList["mainly clear"] = FewCloudsNight;
00111     conditionList["sunny"] = ClearDay;
00112     conditionList["clear"] = ClearNight; 
00113 
00114     // Available conditions
00115     conditionList["blowing snow"] = Snow;
00116     conditionList["cloudy"] = Overcast;
00117     conditionList["distance precipitation"] = LightRain;
00118     conditionList["drifting snow"] = Flurries;
00119     conditionList["drizzle"] = LightRain;
00120     conditionList["dust"] = NotAvailable;
00121     conditionList["dust devils"] = NotAvailable;
00122     conditionList["fog"] = Mist;
00123     conditionList["fog bank near station"] = Mist;
00124     conditionList["fog depositing ice"] = Mist;
00125     conditionList["fog patches"] = Mist;
00126     conditionList["freezing drizzle"] = FreezingDrizzle;
00127     conditionList["freezing rain"] = FreezingRain;
00128     conditionList["funnel cloud"] = NotAvailable;
00129     conditionList["hail"] = Hail;
00130     conditionList["haze"] = Haze;
00131     conditionList["heavy blowing snow"] = Snow;
00132     conditionList["heavy drifting snow"] = Snow;
00133     conditionList["heavy drizzle"] = LightRain;
00134     conditionList["heavy hail"] = Hail;
00135     conditionList["heavy mixed rain and drizzle"] = LightRain;
00136     conditionList["heavy mixed rain and snow shower"] = RainSnow;
00137     conditionList["heavy rain"] = Rain;
00138     conditionList["heavy rain and snow"] = RainSnow;
00139     conditionList["heavy rainshower"] = Rain;
00140     conditionList["heavy snow"] = Snow;
00141     conditionList["heavy snow pellets"] = Snow;
00142     conditionList["heavy snowshower"] = Snow;
00143     conditionList["heavy thunderstorm with hail"] = Thunderstorm;
00144     conditionList["heavy thunderstorm with rain"] = Thunderstorm;
00145     conditionList["ice crystals"] = Flurries;
00146     conditionList["ice pellets"] = Hail;
00147     conditionList["increasing cloud"] = Overcast;
00148     conditionList["light drizzle"] = LightRain;
00149     conditionList["light freezing drizzle"] = FreezingRain;
00150     conditionList["light freezing rain"] = FreezingRain;
00151     conditionList["light rain"] = LightRain;
00152     conditionList["light rainshower"] = LightRain;
00153     conditionList["light snow"] = LightSnow;
00154     conditionList["light snow pellets"] = LightSnow;
00155     conditionList["light snowshower"] = Flurries;
00156     conditionList["lightning visible"] = Thunderstorm;
00157     conditionList["mist"] = Mist;
00158     conditionList["mixed rain and drizzle"] = LightRain;
00159     conditionList["mixed rain and snow shower"] = RainSnow;
00160     conditionList["not reported"] = NotAvailable;
00161     conditionList["rain"] = Rain;
00162     conditionList["rain and snow"] = RainSnow;
00163     conditionList["rainshower"] = LightRain;
00164     conditionList["recent drizzle"] = LightRain;
00165     conditionList["recent dust or sand storm"] = NotAvailable;
00166     conditionList["recent fog"] = Mist;
00167     conditionList["recent freezing precipitation"] = FreezingDrizzle;
00168     conditionList["recent hail"] = Hail;
00169     conditionList["recent rain"] = Rain;
00170     conditionList["recent rain and snow"] = RainSnow;
00171     conditionList["recent rainshower"] = Rain;
00172     conditionList["recent snow"] = Snow;
00173     conditionList["recent snowshower"] = Flurries;
00174     conditionList["recent thunderstorm"] = Thunderstorm;
00175     conditionList["recent thunderstorm with hail"] = Thunderstorm;
00176     conditionList["recent thunderstorm with heavy hail"] = Thunderstorm;
00177     conditionList["recent thunderstorm with heavy rain"] = Thunderstorm;
00178     conditionList["recent thunderstorm with rain"] = Thunderstorm;
00179     conditionList["sand or dust storm"] = NotAvailable;
00180     conditionList["severe sand or dust storm"] = NotAvailable;
00181     conditionList["shallow fog"] = Mist;
00182     conditionList["smoke"] = NotAvailable;
00183     conditionList["snow"] = Snow;
00184     conditionList["snow crystals"] = Flurries;
00185     conditionList["snow grains"] = Flurries;
00186     conditionList["squalls"] = Snow;
00187     conditionList["thunderstorm with hail"] = Thunderstorm;
00188     conditionList["thunderstorm with rain"] = Thunderstorm;
00189     conditionList["thunderstorm with sand or dust storm"] = Thunderstorm;
00190     conditionList["thunderstorm without precipitation"] = Thunderstorm;
00191     conditionList["tornado"] = NotAvailable;
00192     return conditionList;
00193 }
00194 
00195 
00196 QMap<QString, IonInterface::ConditionIcons> EnvCanadaIon::setupForecastIconMappings(void)
00197 {
00198     QMap<QString, ConditionIcons> forecastList;
00199 
00200     // Abbreviated forecast descriptions 
00201     forecastList["a few flurries"] = Flurries;
00202     forecastList["a few flurries mixed with ice pellets"] = RainSnow;
00203     forecastList["a few flurries or rain showers"] = RainSnow;
00204     forecastList["a few flurries or thundershowers"] = RainSnow;
00205     forecastList["a few rain showers or flurries"] = RainSnow;
00206     forecastList["a few rain showers or wet flurries"] = RainSnow;
00207     forecastList["a few showers"] = LightRain;
00208     forecastList["a few showers or drizzle"] = LightRain;
00209     forecastList["a few showers or thundershowers"] = Thunderstorm;
00210     forecastList["a few showers or thunderstorms"] = Thunderstorm;
00211     forecastList["a few thundershowers"] = Thunderstorm;
00212     forecastList["a few thunderstorms"] = Thunderstorm;
00213     forecastList["a few wet flurries"] = RainSnow;
00214     forecastList["a few wet flurries or rain showers"] = RainSnow;
00215     forecastList["a mix of sun and cloud"] = PartlyCloudyDay;
00216     forecastList["cloudy with sunny periods"] = PartlyCloudyDay;
00217     forecastList["sunny"] = ClearDay;
00218     forecastList["blizzard"] = Snow;
00219     forecastList["clear"] = ClearNight;
00220     forecastList["cloudy"] = Overcast;
00221     forecastList["drizzle"] = LightRain;
00222     forecastList["drizzle mixed with freezing drizzle"] = FreezingDrizzle;
00223     forecastList["drizzle mixed with rain"] = LightRain;
00224     forecastList["drizzle or freezing drizzle"] = LightRain;
00225     forecastList["drizzle or rain"] = LightRain;
00226     forecastList["flurries"] = Flurries;
00227     forecastList["flurries at times heavy"] = Flurries;
00228     forecastList["flurries at times heavy or rain snowers"] = RainSnow;
00229     forecastList["flurries mixed with ice pellets"] = FreezingRain;
00230     forecastList["flurries or ice pellets"] = FreezingRain;
00231     forecastList["flurries or rain showers"] = RainSnow;
00232     forecastList["flurries or thundershowers"] = Flurries;
00233     forecastList["fog"] = Mist;
00234     forecastList["fog developing"] = Mist;
00235     forecastList["fog dissipating"] = Mist;
00236     forecastList["fog patches"] = Mist;
00237     forecastList["freezing drizzle"] = FreezingDrizzle;
00238     forecastList["freezing rain"] = FreezingRain;
00239     forecastList["freezing rain mixed with rain"] = FreezingRain;
00240     forecastList["freezing rain mixed with snow"] = FreezingRain;
00241     forecastList["freezing rain or ice pellets"] = FreezingRain;
00242     forecastList["freezing rain or rain"] = FreezingRain;
00243     forecastList["freezing rain or snow"] = FreezingRain;
00244     forecastList["ice fog"] = Mist;
00245     forecastList["ice fog developing"] = Mist;
00246     forecastList["ice fog dissipating"] = Mist;
00247     forecastList["ice pellet"] = Hail;
00248     forecastList["ice pellet mixed with freezing rain"] = Hail;
00249     forecastList["ice pellet mixed with snow"] = Hail;
00250     forecastList["ice pellet or snow"] = RainSnow;
00251     forecastList["light snow"] = LightSnow;
00252     forecastList["light snow and blizzard"] = LightSnow;
00253     forecastList["light snow and blizzard and blowing snow"] = Snow;
00254     forecastList["light snow and blowing snow"] = LightSnow;
00255     forecastList["light snow mixed with freezing drizzle"] = FreezingDrizzle;
00256     forecastList["light snow mixed with freezing rain"] = FreezingRain;
00257     forecastList["light snow or ice pellets"] = LightSnow;
00258     forecastList["light snow or rain"] = RainSnow;
00259     forecastList["light wet snow"] = RainSnow;
00260     forecastList["light wet snow or rain"] = RainSnow;
00261     forecastList["local snow squalls"] = Snow;
00262     forecastList["near blizzard"] = Snow;
00263     forecastList["overcast"] = Overcast;
00264     forecastList["increasing cloudiness"] = Overcast;
00265     forecastList["increasing clouds"] = Overcast;
00266     forecastList["periods of drizzle"] = LightRain;
00267     forecastList["periods of drizzle mixed with freezing drizzle"] = FreezingDrizzle;
00268     forecastList["periods of drizzle mixed with rain"] = LightRain;
00269     forecastList["periods of drizzle or freezing drizzle"] = FreezingDrizzle;
00270     forecastList["periods of drizzle or rain"] = LightRain;
00271     forecastList["periods of freezing drizzle"] = FreezingDrizzle;
00272     forecastList["periods of freezing drizzle or drizzle"] = FreezingDrizzle;
00273     forecastList["periods of freezing drizzle or rain"] = FreezingDrizzle;
00274     forecastList["periods of freezing rain"] = FreezingRain;
00275     forecastList["periods of freezing rain mixed with ice pellets"] = FreezingRain;
00276     forecastList["periods of freezing rain mixed with rain"] = FreezingRain;
00277     forecastList["periods of freezing rain mixed with snow"] = FreezingRain;
00278     forecastList["periods of freezing rain mixed with freezing drizzle"] = FreezingRain;
00279     forecastList["periods of freezing rain or ice pellets"] = FreezingRain;
00280     forecastList["periods of freezing rain or rain"] = FreezingRain;
00281     forecastList["periods of freezing rain or snow"] = FreezingRain;
00282     forecastList["periods of ice pellet"] = Hail;
00283     forecastList["periods of ice pellet mixed with freezing rain"] = Hail;
00284     forecastList["periods of ice pellet mixed with snow"] = Hail;
00285     forecastList["periods of ice pellet or freezing rain"] = Hail;
00286     forecastList["periods of ice pellet or snow"] = Hail;
00287     forecastList["periods of light snow"] = LightSnow;
00288     forecastList["periods of light snow and blizzard"] = Snow;
00289     forecastList["periods of light snow and blizzard and blowing snow"] = Snow;
00290     forecastList["periods of light snow and blowing snow"] = LightSnow;
00291     forecastList["periods of light snow mixed with freezing drizzle"] = RainSnow;
00292     forecastList["periods of light snow mixed with freezing rain"] = RainSnow;
00293     forecastList["periods of light snow mixed with ice pelletS"] = LightSnow;
00294     forecastList["periods of light snow mixed with rain"] = RainSnow;
00295     forecastList["periods of light snow or freezing drizzle"] = RainSnow;
00296     forecastList["periods of light snow or freezing rain"] = RainSnow;
00297     forecastList["periods of light snow or ice pellets"] = LightSnow;
00298     forecastList["periods of light snow or rain"] = RainSnow;
00299     forecastList["periods of light wet snow"] = LightSnow;
00300     forecastList["periods of light wet snow mixed with rain"] = RainSnow;
00301     forecastList["periods of light wet snow or rain"] = RainSnow;
00302     forecastList["periods of rain"] = Rain;
00303     forecastList["periods of rain mixed with freezing rain"] = Rain;
00304     forecastList["periods of rain mixed with snow"] = RainSnow;
00305     forecastList["periods of rain or drizzle"] = Rain;
00306     forecastList["periods of rain or freezing rain"] = Rain;
00307     forecastList["periods of rain or thundershowers"] = Thunderstorm;
00308     forecastList["periods of rain or thunderstorms"] = Thunderstorm;
00309     forecastList["periods of rain or snow"] = RainSnow;
00310     forecastList["periods of snow"] = Snow;
00311     forecastList["periods of snow and blizzard"] = Snow;
00312     forecastList["periods of snow and blizzard and blowing snow"] = Snow;
00313     forecastList["periods of snow and blowing snow"] = Snow;
00314     forecastList["periods of snow mixed with freezing drizzle"] = RainSnow;
00315     forecastList["periods of snow mixed with freezing rain"] = RainSnow;
00316     forecastList["periods of snow mixed with ice pellets"] = Snow;
00317     forecastList["periods of snow mixed with rain"] = RainSnow;
00318     forecastList["periods of snow or freezing drizzle"] = RainSnow;
00319     forecastList["periods of snow or freezing rain"] = RainSnow;
00320     forecastList["periods of snow or ice pellets"] = Snow;
00321     forecastList["periods of snow or rain"] = RainSnow;
00322     forecastList["periods of rain or snow"] = RainSnow;
00323     forecastList["periods of wet snow"] = Snow;
00324     forecastList["periods of wet snow mixed with rain"] = RainSnow;
00325     forecastList["periods of wet snow or rain"] = RainSnow;
00326     forecastList["rain"] = Rain;
00327     forecastList["rain at times heavy"] = Rain;
00328     forecastList["rain at times heavy mixed with freezing rain"] = FreezingRain;
00329     forecastList["rain at times heavy mixed with snow"] = RainSnow;
00330     forecastList["rain at times heavy or drizzle"] = Rain;
00331     forecastList["rain at times heavy or freezing rain"] = Rain;
00332     forecastList["rain at times heavy or snow"] = RainSnow;
00333     forecastList["rain at times heavy or thundershowers"] = Thunderstorm;
00334     forecastList["rain at times heavy or thunderstorms"] = Thunderstorm;
00335     forecastList["rain mixed with freezing rain"] = FreezingRain;
00336     forecastList["rain mixed with snow"] = RainSnow;
00337     forecastList["rain or drizzle"] = Rain;
00338     forecastList["rain or freezing rain"] = Rain;
00339     forecastList["rain or snow"] = RainSnow;
00340     forecastList["rain or thundershowers"] = Thunderstorm;
00341     forecastList["rain or thunderstorms"] = Thunderstorm;
00342     forecastList["rain showers or flurries"] = RainSnow;
00343     forecastList["rain showers or wet flurries"] = RainSnow;
00344     forecastList["showers"] = Showers;
00345     forecastList["showers at times heavy"] = Showers;
00346     forecastList["showers at times heavy or thundershowers"] = Thunderstorm;
00347     forecastList["showers at times heavy or thunderstorms"] = Thunderstorm;
00348     forecastList["showers or drizzle"] = Showers;
00349     forecastList["showers or thundershowers"] = Showers;
00350     forecastList["showers or thunderstorms"] = Showers;
00351     forecastList["smoke"] = NotAvailable;
00352     forecastList["snow"] = Snow;
00353     forecastList["snow and blizzard"] = Snow;
00354     forecastList["snow and blizzard and blowing snow"] = Snow;
00355     forecastList["snow and blowing snow"] = Snow;
00356     forecastList["snow at times heavy"] = Snow;
00357     forecastList["snow at times heavy and blizzard"] = Snow;
00358     forecastList["snow at times heavy and blowing snow"] = Snow;
00359     forecastList["snow at times heavy mixed with freezing drizzle"] = RainSnow;
00360     forecastList["snow at times heavy mixed with freezing rain"] = RainSnow;
00361     forecastList["snow at times heavy mixed with ice pellets"] = Snow;
00362     forecastList["snow at times heavy mixed with rain"] = RainSnow;
00363     forecastList["snow at times heavy or freezing rain"] = RainSnow;
00364     forecastList["snow at times heavy or ice pellets"] = Snow;
00365     forecastList["snow at times heavy or rain"] = RainSnow;
00366     forecastList["snow mixed with freezing drizzle"] = RainSnow;
00367     forecastList["snow mixed with freezing rain"] = RainSnow;
00368     forecastList["snow mixed with ice pellets"] = Snow;
00369     forecastList["snow mixed with rain"] = RainSnow;
00370     forecastList["snow or freezing drizzle"] = RainSnow;
00371     forecastList["snow or freezing rain"] = RainSnow;
00372     forecastList["snow or ice pellets"] = Snow;
00373     forecastList["snow or rain"] = RainSnow;
00374     forecastList["snow squalls"] = Snow;
00375     forecastList["sunny"] = ClearDay;
00376     forecastList["sunny with cloudy periods"] = PartlyCloudyDay;
00377     forecastList["thunderstorms"] = Thunderstorm;
00378     forecastList["thunderstorms and possible hail"] = Thunderstorm;
00379     forecastList["wet flurries"] = Flurries;
00380     forecastList["wet flurries at times heavy"] = Flurries;
00381     forecastList["wet flurries at times heavy or rain snowers"] = RainSnow;
00382     forecastList["wet flurries or rain showers"] = RainSnow;
00383     forecastList["wet snow"] = Snow;
00384     forecastList["wet snow at times heavy"] = Snow;
00385     forecastList["wet snow at times heavy mixed with rain"] = RainSnow;
00386     forecastList["wet snow mixed with rain"] = RainSnow;
00387     forecastList["wet snow or rain"] = RainSnow;
00388     forecastList["windy"] = NotAvailable;
00389     
00390     forecastList["chance of drizzle mixed with freezing drizzle"] = LightRain;
00391     forecastList["chance of flurries mixed with ice pellets"] = Flurries;
00392     forecastList["chance of flurries or ice pellets"] = Flurries;
00393     forecastList["chance of flurries or rain showers"] = RainSnow;
00394     forecastList["chance of flurries or thundershowers"] = RainSnow;
00395     forecastList["chance of freezing drizzle"] = FreezingDrizzle;
00396     forecastList["chance of freezing rain"] = FreezingRain;
00397     forecastList["chance of freezing rain mixed with snow"] = RainSnow;
00398     forecastList["chance of freezing rain or rain"] = FreezingRain;
00399     forecastList["chance of freezing rain or snow"] = RainSnow;
00400     forecastList["chance of light snow and blowing snow"] = LightSnow;
00401     forecastList["chance of light snow mixed with freezing drizzle"] = LightSnow;
00402     forecastList["chance of light snow mixed with ice pellets"] = LightSnow;
00403     forecastList["chance of light snow mixed with rain"] = RainSnow;
00404     forecastList["chance of light snow or freezing rain"] = RainSnow;
00405     forecastList["chance of light snow or ice pellets"] = LightSnow;
00406     forecastList["chance of light snow or rain"] = RainSnow;
00407     forecastList["chance of light wet snow"] = Snow;
00408     forecastList["chance of rain"] = Rain;
00409     forecastList["chance of rain at times heavy"] = Rain;
00410     forecastList["chance of rain mixed with snow"] = RainSnow;
00411     forecastList["chance of rain or drizzle"] = Rain;
00412     forecastList["chance of rain or freezing rain"] = Rain;
00413     forecastList["chance of rain or snow"] = RainSnow;
00414     forecastList["chance of rain showers or flurries"] = RainSnow;
00415     forecastList["chance of rain showers or wet flurries"] = RainSnow;
00416     forecastList["chance of severe thunderstorms"] = Thunderstorm;
00417     forecastList["chance of showers at times heavy"] = Rain;
00418     forecastList["chance of showers at times heavy or thundershowers"] = Thunderstorm;
00419     forecastList["chance of showers at times heavy or thunderstorms"] = Thunderstorm;
00420     forecastList["chance of showers or thundershowers"] = Showers;
00421     forecastList["chance of showers or thunderstorms"] = Thunderstorm;
00422     forecastList["chance of snow"] = Snow;
00423     forecastList["chance of snow and blizzard"] = Snow;
00424     forecastList["chance of snow mixed with freezing drizzle"] = Snow;
00425     forecastList["chance of snow mixed with freezing rain"] = RainSnow;
00426     forecastList["chance of snow mixed with rain"] = RainSnow;
00427     forecastList["chance of snow or rain"] = RainSnow;
00428     forecastList["chance of snow squalls"] = Snow;
00429     forecastList["chance of thundershowers"] = Thunderstorm;
00430     forecastList["chance of thunderstorms"] = Thunderstorm;
00431     forecastList["chance of thunderstorms and possible hail"] = Thunderstorm;
00432     forecastList["chance of wet flurries"] = Flurries;
00433     forecastList["chance of wet flurries at times heavy"] = Flurries;
00434     forecastList["chance of wet flurries or rain showers"] = RainSnow;
00435     forecastList["chance of wet snow"] = Snow;
00436     forecastList["chance of wet snow mixed with rain"] = RainSnow;
00437     forecastList["chance of wet snow or rain"] = RainSnow;
00438 
00439     return forecastList;
00440 }
00441 
00442 QMap<QString, IonInterface::ConditionIcons> const& EnvCanadaIon::conditionIcons(void)
00443 {
00444     static QMap<QString, ConditionIcons> const condval = setupConditionIconMappings();
00445     return condval;
00446 }
00447 
00448 QMap<QString, IonInterface::ConditionIcons> const& EnvCanadaIon::forecastIcons(void)
00449 {
00450     static QMap<QString, ConditionIcons> const foreval = setupForecastIconMappings();
00451     return foreval;
00452 }
00453 
00454 QStringList EnvCanadaIon::validate(const QString& source) const
00455 {
00456     QStringList placeList;
00457     QHash<QString, QString>::const_iterator it = d->m_locations.constBegin();
00458     while (it != d->m_locations.constEnd()) {
00459         if (it.value().toLower().contains(source.toLower())) {
00460             placeList.append(QString("place|%1").arg(it.value().split('|')[1]));
00461         }
00462         ++it;
00463     }
00464 
00465     // Check if placeList is empty if so, return nothing.
00466     if (placeList.isEmpty()) {
00467         return QStringList();
00468     }
00469     placeList.sort();
00470     return placeList;
00471 }
00472 
00473 // Get a specific Ion's data
00474 bool EnvCanadaIon::updateIonSource(const QString& source)
00475 {
00476     // We expect the applet to send the source in the following tokenization:
00477     // ionname|validate|place_name - Triggers validation of place
00478     // ionname|weather|place_name - Triggers receiving weather of place
00479 
00480     QStringList sourceAction = source.split('|');
00481 
00482     // Guard: if the size of array is not 2 then we have bad data, return an error
00483     if (sourceAction.size() < 2) {
00484         setData(source, "validate", QString("envcan|timeout"));
00485         return true;
00486     }
00487 
00488     if (sourceAction[1] == QString("validate")) {
00489         QStringList result = validate(QString("%1|%2").arg(sourceAction[0]).arg(sourceAction[2]));
00490 
00491         if (result.size() == 1) {
00492             setData(source, "validate", QString("envcan|valid|single|%1").arg(result.join("|")));
00493             return true;
00494         } else if (result.size() > 1) {
00495             setData(source, "validate", QString("envcan|valid|multiple|%1").arg(result.join("|")));
00496             return true;
00497         } else if (result.size() == 0) {
00498             setData(source, "validate", QString("envcan|invalid|single|%1").arg(sourceAction[2]));
00499             return true;
00500         }
00501 
00502     } else if (sourceAction[1] == QString("weather")) {
00503         getXMLData(source);
00504         return true;
00505     }
00506     return false;
00507 }
00508 
00509 // Parses city list and gets the correct city based on ID number
00510 void EnvCanadaIon::getXMLSetup()
00511 {
00512     d->m_url = new KUrl("http://dd.weatheroffice.ec.gc.ca/EC_sites/xml/siteList.xml");
00513 
00514     KIO::TransferJob *job = KIO::get(d->m_url->url(), KIO::NoReload, KIO::HideProgressInfo);
00515 
00516     if (job) {
00517         connect(job, SIGNAL(data(KIO::Job *, const QByteArray &)), this,
00518                 SLOT(setup_slotDataArrived(KIO::Job *, const QByteArray &)));
00519         connect(job, SIGNAL(result(KJob *)), this, SLOT(setup_slotJobFinished(KJob *)));
00520     }
00521 }
00522 
00523 // Gets specific city XML data
00524 void EnvCanadaIon::getXMLData(const QString& source)
00525 {
00526     KUrl url;
00527 
00528     // Demunge source name for key only.
00529     QString dataKey = source;
00530     dataKey.remove("|weather");
00531     url = "http://dd.weatheroffice.ec.gc.ca/EC_sites/xml/" + d->m_place[dataKey].territoryName + "/" + d->m_place[dataKey].cityCode + "_e.xml";
00532     //url="file:///home/spstarr/Desktop/s0000649_e.xml";
00533 
00534     if (d->m_place[dataKey].territoryName.isEmpty() && d->m_place[dataKey].cityCode.isEmpty()) {
00535         setData(source, "validate", QString("envcan|timeout"));
00536         return;
00537     }
00538 
00539     d->m_job = KIO::get(url.url(), KIO::Reload, KIO::HideProgressInfo);
00540     d->m_jobXml.insert(d->m_job, new QXmlStreamReader);
00541     d->m_jobList.insert(d->m_job, source);
00542 
00543     if (d->m_job) {
00544         connect(d->m_job, SIGNAL(data(KIO::Job *, const QByteArray &)), this,
00545                 SLOT(slotDataArrived(KIO::Job *, const QByteArray &)));
00546         connect(d->m_job, SIGNAL(result(KJob *)), this, SLOT(slotJobFinished(KJob *)));
00547     }
00548 }
00549 
00550 void EnvCanadaIon::setup_slotDataArrived(KIO::Job *job, const QByteArray &data)
00551 {
00552     Q_UNUSED(job)
00553 
00554     if (data.isEmpty()) {
00555         return;
00556     }
00557 
00558     // Send to xml.
00559     d->m_xmlSetup.addData(data);
00560 }
00561 
00562 void EnvCanadaIon::slotDataArrived(KIO::Job *job, const QByteArray &data)
00563 {
00564 
00565     if (data.isEmpty() || !d->m_jobXml.contains(job)) {
00566         return;
00567     }
00568 
00569     // Send to xml.
00570     d->m_jobXml[job]->addData(data);
00571 }
00572 
00573 void EnvCanadaIon::slotJobFinished(KJob *job)
00574 {
00575     // Dual use method, if we're fetching location data to parse we need to do this first
00576     setData(d->m_jobList[job], Data());
00577     readXMLData(d->m_jobList[job], *d->m_jobXml[job]);
00578     d->m_jobList.remove(job);
00579     delete d->m_jobXml[job];
00580     d->m_jobXml.remove(job);
00581 }
00582 
00583 void EnvCanadaIon::setup_slotJobFinished(KJob *job)
00584 {
00585     Q_UNUSED(job)
00586     readXMLSetup();
00587     setInitialized(true);
00588 }
00589 
00590 // Parse the city list and store into a QMap
00591 bool EnvCanadaIon::readXMLSetup()
00592 {
00593     QString tmp;
00594     while (!d->m_xmlSetup.atEnd()) {
00595         d->m_xmlSetup.readNext();
00596 
00597         if (d->m_xmlSetup.isStartElement()) {
00598 
00599             // XML ID code to match filename
00600             if (d->m_xmlSetup.name() == "site") {
00601                 d->m_code = d->m_xmlSetup.attributes().value("code").toString();
00602             }
00603 
00604             if (d->m_xmlSetup.name() == "nameEn") {
00605                 d->m_cityName = d->m_xmlSetup.readElementText(); // Name of cities
00606             }
00607 
00608             if (d->m_xmlSetup.name() == "provinceCode") {
00609                 d->m_territory = d->m_xmlSetup.readElementText(); // Provinces/Territory list
00610                 tmp = "envcan|" + d->m_cityName + ", " + d->m_territory; // Build the key name.
00611 
00612                 // Set the mappings
00613                 d->m_place[tmp].cityCode = d->m_code;
00614                 d->m_place[tmp].territoryName = d->m_territory;
00615                 d->m_place[tmp].cityName = d->m_cityName;
00616 
00617                 // Set the string list, we will use for the applet to display the available cities.
00618                 d->m_locations[tmp] = tmp;
00619             }
00620         }
00621 
00622     }
00623     return !d->m_xmlSetup.error();
00624 }
00625 
00626 WeatherData EnvCanadaIon::parseWeatherSite(WeatherData& data, QXmlStreamReader& xml)
00627 {
00628     while (!xml.atEnd()) {
00629         xml.readNext();
00630 
00631         if (xml.isStartElement()) {
00632             if (xml.name() == "license") {
00633                 xml.readElementText();
00634             } else if (xml.name() == "location") {
00635                 parseLocations(data, xml);
00636             } else if (xml.name() == "warnings") {
00637                 // Cleanup warning list on update
00638                 data.warnings.clear();
00639                 data.watches.clear();
00640                 parseWarnings(data, xml);
00641             } else if (xml.name() == "currentConditions") {
00642                 parseConditions(data, xml);
00643             } else if (xml.name() == "forecastGroup") {
00644                 // Clean up forecast list on update
00645                 data.forecasts.clear();
00646                 parseWeatherForecast(data, xml);
00647             } else if (xml.name() == "yesterdayConditions") {
00648                 parseYesterdayWeather(data, xml);
00649             } else if (xml.name() == "riseSet") {
00650                 parseAstronomicals(data, xml);
00651             } else if (xml.name() == "almanac") {
00652                 parseWeatherRecords(data, xml);
00653             } else {
00654                 parseUnknownElement(xml);
00655             }
00656         }
00657     }
00658     return data;
00659 }
00660 
00661 // Parse Weather data main loop, from here we have to decend into each tag pair
00662 bool EnvCanadaIon::readXMLData(const QString& source, QXmlStreamReader& xml)
00663 {
00664     WeatherData data;
00665     data.comforttemp = "N/A";
00666     data.recordHigh = 0.0;
00667     data.recordLow = 0.0;
00668 
00669     QString dataKey = source;
00670     dataKey.remove("|weather");
00671     data.shortTerritoryName = d->m_place[dataKey].territoryName;
00672     while (!xml.atEnd()) {
00673         xml.readNext();
00674 
00675         if (xml.isEndElement()) {
00676             break;
00677         }
00678 
00679         if (xml.isStartElement()) {
00680             if (xml.name() == "siteData") {
00681                 data = parseWeatherSite(data, xml);
00682             } else {
00683                 parseUnknownElement(xml);
00684             }
00685         }
00686     }
00687 
00688     d->m_weatherData[source] = data;
00689     updateWeather(source);
00690     return !xml.error();
00691 }
00692 
00693 void EnvCanadaIon::parseDateTime(WeatherData& data, QXmlStreamReader& xml, WeatherData::WeatherEvent *event)
00694 {
00695 
00696     Q_ASSERT(xml.isStartElement() && xml.name() == "dateTime");
00697 
00698     // What kind of date info is this?
00699     QString dateType = xml.attributes().value("name").toString();
00700     QString dateZone = xml.attributes().value("zone").toString();
00701 
00702     QString selectTimeStamp;
00703 
00704     while (!xml.atEnd()) {
00705         xml.readNext();
00706 
00707         if (xml.isEndElement()) {
00708             break;
00709         }
00710 
00711         if (xml.isStartElement()) {
00712             if (dateType == "xmlCreation") {
00713                 return;
00714             }
00715             if (dateZone == "UTC") {
00716                 return;
00717             }
00718             if (xml.name() == "year") {
00719                 xml.readElementText();
00720             } else if (xml.name() == "month") {
00721                 xml.readElementText();
00722             } else if (xml.name() == "day") {
00723                 xml.readElementText();
00724             } else if (xml.name() == "hour")
00725                 xml.readElementText();
00726             else if (xml.name() == "minute")
00727                 xml.readElementText();
00728             else if (xml.name() == "timeStamp")
00729                 selectTimeStamp = xml.readElementText();
00730             else if (xml.name() == "textSummary") {
00731                 if (dateType == "eventIssue") {
00732                     if (event) {
00733                         event->timestamp = xml.readElementText();
00734                     }
00735                 } else if (dateType == "observation") {
00736                     xml.readElementText();
00737                     d->m_dateFormat = QDateTime::fromString(selectTimeStamp, "yyyyMMddHHmmss");
00738                     data.obsTimestamp = d->m_dateFormat.toString("dd.MM.yyyy @ hh:mm ap");
00739                     data.iconPeriodHour = d->m_dateFormat.toString("HH").toInt();
00740                     data.iconPeriodAP = d->m_dateFormat.toString("ap");
00741                 } else if (dateType == "forecastIssue") {
00742                     data.forecastTimestamp = xml.readElementText();
00743                 } else if (dateType == "sunrise") {
00744                     data.sunriseTimestamp = xml.readElementText();
00745                 } else if (dateType == "sunset") {
00746                     data.sunsetTimestamp = xml.readElementText();
00747                 } else if (dateType == "moonrise") {
00748                     data.moonriseTimestamp = xml.readElementText();
00749                 } else if (dateType == "moonset") {
00750                     data.moonsetTimestamp = xml.readElementText();
00751                 }
00752             }
00753         }
00754     }
00755 }
00756 
00757 void EnvCanadaIon::parseLocations(WeatherData& data, QXmlStreamReader& xml)
00758 {
00759     Q_ASSERT(xml.isStartElement() && xml.name() == "location");
00760 
00761     while (!xml.atEnd()) {
00762         xml.readNext();
00763 
00764         if (xml.isEndElement()) {
00765             break;
00766         }
00767 
00768         if (xml.isStartElement()) {
00769             if (xml.name() == "country") {
00770                 data.countryName = xml.readElementText();
00771             } else if (xml.name() == "province" || xml.name() == "territory") {
00772                 data.longTerritoryName = xml.readElementText();
00773             } else if (xml.name() == "name") {
00774                 data.cityName = xml.readElementText();
00775             } else if (xml.name() == "region") {
00776                 data.regionName = xml.readElementText();
00777             } else {
00778                 parseUnknownElement(xml);
00779             }
00780         }
00781     }
00782 }
00783 
00784 void EnvCanadaIon::parseWindInfo(WeatherData& data, QXmlStreamReader& xml)
00785 {
00786     Q_ASSERT(xml.isStartElement() && xml.name() == "wind");
00787 
00788     while (!xml.atEnd()) {
00789         xml.readNext();
00790 
00791         if (xml.isEndElement()) {
00792             break;
00793         }
00794 
00795         if (xml.isStartElement()) {
00796             if (xml.name() == "speed") {
00797                 data.windSpeed = xml.readElementText();
00798             } else if (xml.name() == "gust") {
00799                 data.windGust = xml.readElementText();
00800             } else if (xml.name() == "direction") {
00801                 data.windDirection = xml.readElementText();
00802             } else if (xml.name() == "bearing") {
00803                 data.windDegrees = xml.attributes().value("degrees").toString();
00804             } else {
00805                 parseUnknownElement(xml);
00806             }
00807         }
00808     }
00809 }
00810 
00811 void EnvCanadaIon::parseConditions(WeatherData& data, QXmlStreamReader& xml)
00812 {
00813 
00814     Q_ASSERT(xml.isStartElement() && xml.name() == "currentConditions");
00815     data.temperature = "N/A";
00816     data.dewpoint = "N/A";
00817     data.condition = "N/A";
00818     data.comforttemp = "N/A";
00819     data.stationID = "N/A";
00820     data.pressure = 0.0;
00821     data.pressureTendency = "N/A";
00822     data.visibility = 0;
00823     data.humidity = "N/A";
00824     data.windSpeed = "N/A";
00825     data.windGust = "N/A";
00826 
00827     while (!xml.atEnd()) {
00828         xml.readNext();
00829 
00830         if (xml.isEndElement() && xml.name() == "currentConditions")
00831             break;
00832 
00833         if (xml.isStartElement()) {
00834             if (xml.name() == "station") {
00835                 data.stationID = xml.attributes().value("code").toString();
00836             } else if (xml.name() == "dateTime") {
00837                 parseDateTime(data, xml);
00838             } else if (xml.name() == "condition") {
00839                 data.condition = xml.readElementText();
00840             } else if (xml.name() == "temperature") {
00841                 data.temperature = xml.readElementText();
00842             } else if (xml.name() == "dewpoint") {
00843                 data.dewpoint = xml.readElementText();
00844             } else if (xml.name() == "humidex" || xml.name() == "windChill") {
00845                 data.comforttemp = xml.readElementText();
00846             } else if (xml.name() == "pressure") {
00847                 data.pressureTendency = xml.attributes().value("tendency").toString();
00848                 if (data.pressureTendency.isEmpty()) {
00849                     data.pressureTendency = "steady";
00850                 }
00851                 data.pressure = xml.readElementText().toFloat();
00852             } else if (xml.name() == "visibility") {
00853                 data.visibility = xml.readElementText().toFloat();
00854             } else if (xml.name() == "relativeHumidity") {
00855                 data.humidity = xml.readElementText();
00856             } else if (xml.name() == "wind") {
00857                 parseWindInfo(data, xml);
00858             }
00859             //} else {
00860             //    parseUnknownElement(xml);
00861             //}
00862         }
00863     }
00864     if (data.temperature.isEmpty())  {
00865         data.temperature = "N/A";
00866     }
00867 }
00868 
00869 void EnvCanadaIon::parseWarnings(WeatherData &data, QXmlStreamReader& xml)
00870 {
00871     WeatherData::WeatherEvent *watch = new WeatherData::WeatherEvent;
00872     WeatherData::WeatherEvent *warning = new WeatherData::WeatherEvent;
00873 
00874     Q_ASSERT(xml.isStartElement() && xml.name() == "warnings");
00875     QString eventURL = xml.attributes().value("url").toString();
00876     int flag = 0;
00877 
00878     while (!xml.atEnd()) {
00879         xml.readNext();
00880 
00881         if (xml.isEndElement() && xml.name() == "warnings") {
00882             break;
00883         }
00884 
00885         if (xml.isStartElement()) {
00886             if (xml.name() == "dateTime") {
00887                 if (flag == 1) {
00888                     parseDateTime(data, xml, watch);
00889                 }
00890                 if (flag == 2) {
00891                     parseDateTime(data, xml, warning);
00892                 }
00893 
00894                 if (!warning->timestamp.isEmpty() && !warning->url.isEmpty())  {
00895                     data.warnings.append(warning);
00896                     warning = new WeatherData::WeatherEvent;
00897                 }
00898                 if (!watch->timestamp.isEmpty() && !watch->url.isEmpty()) {
00899                     data.watches.append(watch);
00900                     watch = new WeatherData::WeatherEvent;
00901                 }
00902 
00903             } else if (xml.name() == "event") {
00904                 // Append new event to list.
00905                 QString eventType = xml.attributes().value("type").toString();
00906                 if (eventType == "watch") {
00907                     watch->url = eventURL;
00908                     watch->type = eventType;
00909                     watch->priority = xml.attributes().value("priority").toString();
00910                     watch->description = xml.attributes().value("description").toString();
00911                     flag = 1;
00912                 }
00913 
00914                 if (eventType == "warning") {
00915                     warning->url = eventURL;
00916                     warning->type = eventType;
00917                     warning->priority = xml.attributes().value("priority").toString();
00918                     warning->description = xml.attributes().value("description").toString();
00919                     flag = 2;
00920                 }
00921             } else {
00922                 if (xml.name() != "dateTime") {
00923                     parseUnknownElement(xml);
00924                 }
00925             }
00926         }
00927     }
00928     delete watch;
00929     delete warning;
00930 }
00931 
00932 
00933 void EnvCanadaIon::parseWeatherForecast(WeatherData& data, QXmlStreamReader& xml)
00934 {
00935     WeatherData::ForecastInfo* forecast = new WeatherData::ForecastInfo;
00936     Q_ASSERT(xml.isStartElement() && xml.name() == "forecastGroup");
00937 
00938     while (!xml.atEnd()) {
00939         xml.readNext();
00940 
00941         if (xml.isEndElement() && xml.name() == "forecastGroup") {
00942             break;
00943         }
00944 
00945         if (xml.isStartElement()) {
00946             if (xml.name() == "dateTime") {
00947                 parseDateTime(data, xml);
00948             } else if (xml.name() == "regionalNormals") {
00949                 parseRegionalNormals(data, xml);
00950             } else if (xml.name() == "forecast") {
00951                 parseForecast(data, xml, forecast);
00952                 forecast = new WeatherData::ForecastInfo;
00953             } else {
00954                 parseUnknownElement(xml);
00955             }
00956         }
00957     }
00958     delete forecast;
00959 }
00960 
00961 void EnvCanadaIon::parseRegionalNormals(WeatherData& data, QXmlStreamReader& xml)
00962 {
00963     Q_ASSERT(xml.isStartElement() && xml.name() == "regionalNormals");
00964 
00965     while (!xml.atEnd()) {
00966         xml.readNext();
00967 
00968         if (xml.isEndElement()) {
00969             break;
00970         }
00971 
00972         if (xml.isStartElement()) {
00973             if (xml.name() == "textSummary") {
00974                 xml.readElementText();
00975             } else if (xml.name() == "temperature" && xml.attributes().value("class") == "high") {
00976                 data.normalHigh = xml.readElementText();
00977             } else if (xml.name() == "temperature" && xml.attributes().value("class") == "low") {
00978                 data.normalLow = xml.readElementText();
00979             }
00980         }
00981     }
00982 }
00983 
00984 void EnvCanadaIon::parseForecast(WeatherData& data, QXmlStreamReader& xml, WeatherData::ForecastInfo *forecast)
00985 {
00986 
00987     Q_ASSERT(xml.isStartElement() && xml.name() == "forecast");
00988 
00989     while (!xml.atEnd()) {
00990         xml.readNext();
00991 
00992         if (xml.isEndElement() && xml.name() == "forecast") {
00993             data.forecasts.append(forecast);
00994             break;
00995         }
00996 
00997         if (xml.isStartElement()) {
00998             if (xml.name() == "period") {
00999                 forecast->forecastPeriod = xml.attributes().value("textForecastName").toString();
01000             } else if (xml.name() == "textSummary") {
01001                 forecast->forecastSummary = xml.readElementText();
01002             } else if (xml.name() == "abbreviatedForecast") {
01003                 parseShortForecast(forecast, xml);
01004             } else if (xml.name() == "temperatures") {
01005                 parseForecastTemperatures(forecast, xml);
01006             } else if (xml.name() == "winds") {
01007                 parseWindForecast(forecast, xml);
01008             } else if (xml.name() == "precipitation") {
01009                 parsePrecipitationForecast(forecast, xml);
01010             } else if (xml.name() == "uv") {
01011                 data.UVRating = xml.attributes().value("category").toString();
01012                 parseUVIndex(data, xml);
01013                 // else if (xml.name() == "frost") { FIXME: Wait until winter to see what this looks like.
01014                 //  parseFrost(xml, forecast);
01015             } else {
01016                 if (xml.name() != "forecast") {
01017                     parseUnknownElement(xml);
01018                 }
01019             }
01020         }
01021     }
01022 }
01023 
01024 void EnvCanadaIon::parseShortForecast(WeatherData::ForecastInfo *forecast, QXmlStreamReader& xml)
01025 {
01026     Q_ASSERT(xml.isStartElement() && xml.name() == "abbreviatedForecast");
01027 
01028     QString shortText;
01029 
01030     while (!xml.atEnd()) {
01031         xml.readNext();
01032 
01033         if (xml.isEndElement() && xml.name() == "abbreviatedForecast") {
01034             break;
01035         }
01036 
01037         if (xml.isStartElement()) {
01038             if (xml.name() == "pop") {
01039                 forecast->popPrecent = xml.readElementText();
01040             }
01041             if (xml.name() == "textSummary") {
01042                 shortText = xml.readElementText();
01043                 QMap<QString, ConditionIcons> forecastList;
01044                 forecastList = forecastIcons();
01045                 if ((forecast->forecastPeriod == "tonight") || (forecast->forecastPeriod.contains("night"))) {
01046                  forecastList["a few clouds"] = FewCloudsNight;
01047                      forecastList["cloudy periods"] = PartlyCloudyNight;
01048              forecastList["chance of drizzle mixed with rain"] = ChanceShowersNight;
01049                      forecastList["chance of drizzle"] = ChanceShowersNight;         
01050                      forecastList["chance of drizzle or rain"] = ChanceShowersNight; 
01051                      forecastList["chance of flurries"] = ChanceSnowNight;
01052                      forecastList["chance of light snow"] = ChanceSnowNight;
01053                      forecastList["chance of flurries at times heavy"] = ChanceSnowNight;
01054              forecastList["chance of showers or drizzle"] = ChanceShowersNight;
01055                      forecastList["chance of showers"] = ChanceShowersNight;
01056                      forecastList["clearing"] = ClearNight;
01057                 } else {
01058                  forecastList["a few clouds"] = FewCloudsDay;
01059                      forecastList["cloudy periods"] = PartlyCloudyDay;
01060              forecastList["chance of drizzle mixed with rain"] = ChanceShowersDay;
01061                      forecastList["chance of drizzle"] = ChanceShowersDay;       
01062                      forecastList["chance of drizzle or rain"] = ChanceShowersDay; 
01063                      forecastList["chance of flurries"] = ChanceSnowDay;
01064                      forecastList["chance of light snow"] = ChanceSnowDay;
01065                      forecastList["chance of flurries at times heavy"] = ChanceSnowDay;
01066              forecastList["chance of showers or drizzle"] = ChanceShowersDay;
01067                      forecastList["chance of showers"] = ChanceShowersDay;
01068                      forecastList["clearing"] = ClearDay;
01069                 }
01070                     forecast->shortForecast = shortText;
01071                     forecast->iconName = getWeatherIcon(forecastList, shortText.toLower());
01072             }
01073         }
01074     }
01075 }
01076 
01077 void EnvCanadaIon::parseUVIndex(WeatherData& data, QXmlStreamReader& xml)
01078 {
01079     Q_ASSERT(xml.isStartElement() && xml.name() == "uv");
01080 
01081     while (!xml.atEnd()) {
01082         xml.readNext();
01083 
01084         if (xml.isEndElement() && xml.name() == "uv") {
01085             break;
01086         }
01087 
01088         if (xml.isStartElement()) {
01089             if (xml.name() == "index") {
01090                 data.UVIndex = xml.readElementText();
01091             }
01092             if (xml.name() == "textSummary") {
01093                 xml.readElementText();
01094             }
01095         }
01096     }
01097 }
01098 
01099 void EnvCanadaIon::parseForecastTemperatures(WeatherData::ForecastInfo *forecast, QXmlStreamReader& xml)
01100 {
01101     Q_ASSERT(xml.isStartElement() && xml.name() == "temperatures");
01102 
01103     while (!xml.atEnd()) {
01104         xml.readNext();
01105 
01106         if (xml.isEndElement() && xml.name() == "temperatures") {
01107             break;
01108         }
01109 
01110         if (xml.isStartElement()) {
01111             if (xml.name() == "temperature" && xml.attributes().value("class") == "low") {
01112                 forecast->forecastTempLow = xml.readElementText();
01113             } else if (xml.name() == "temperature" && xml.attributes().value("class") == "high") {
01114                 forecast->forecastTempHigh = xml.readElementText();
01115             } else if (xml.name() == "textSummary") {
01116                 xml.readElementText();
01117             }
01118         }
01119     }
01120 }
01121 
01122 void EnvCanadaIon::parsePrecipitationForecast(WeatherData::ForecastInfo *forecast, QXmlStreamReader& xml)
01123 {
01124     Q_ASSERT(xml.isStartElement() && xml.name() == "precipitation");
01125 
01126     while (!xml.atEnd()) {
01127         xml.readNext();
01128 
01129         if (xml.isEndElement() && xml.name() == "precipitation") {
01130             break;
01131         }
01132 
01133         if (xml.isStartElement()) {
01134             //kDebug() << "parsePrecipitationForecast() ====> TAG: " << xml.name().toString();
01135             if (xml.name() == "textSummary") {
01136                 forecast->precipForecast = xml.readElementText();
01137             } else if (xml.name() == "precipType") {
01138                 forecast->precipType = xml.readElementText();
01139             } else if (xml.name() == "accumulation") {
01140                 parsePrecipTotals(forecast, xml);
01141             }
01142         }
01143     }
01144 }
01145 
01146 void EnvCanadaIon::parsePrecipTotals(WeatherData::ForecastInfo *forecast, QXmlStreamReader& xml)
01147 {
01148     Q_ASSERT(xml.isStartElement() && xml.name() == "accumulation");
01149 
01150     while (!xml.atEnd()) {
01151         xml.readNext();
01152 
01153         if (xml.isEndElement() && xml.name() == "accumulation") {
01154             break;
01155         }
01156 
01157         if (xml.name() == "name") {
01158             xml.readElementText();
01159         } else if (xml.name() == "amount") {
01160             forecast->precipTotalExpected = xml.readElementText();
01161         }
01162     }
01163 }
01164 
01165 void EnvCanadaIon::parseWindForecast(WeatherData::ForecastInfo *forecast, QXmlStreamReader& xml)
01166 {
01167     Q_ASSERT(xml.isStartElement() && xml.name() == "winds");
01168 
01169     while (!xml.atEnd()) {
01170         xml.readNext();
01171 
01172         if (xml.isEndElement() && xml.name() == "winds") {
01173             break;
01174         }
01175 
01176         if (xml.isStartElement()) {
01177             if (xml.name() == "textSummary") {
01178                 forecast->windForecast = xml.readElementText();
01179             } else {
01180                 if (xml.name() != "winds") {
01181                     parseUnknownElement(xml);
01182                 }
01183             }
01184         }
01185     }
01186 }
01187 
01188 void EnvCanadaIon::parseYesterdayWeather(WeatherData& data, QXmlStreamReader& xml)
01189 {
01190     Q_ASSERT(xml.isStartElement() && xml.name() == "yesterdayConditions");
01191 
01192     while (!xml.atEnd()) {
01193         xml.readNext();
01194 
01195         if (xml.isEndElement()) {
01196             break;
01197         }
01198 
01199         if (xml.isStartElement()) {
01200             if (xml.name() == "temperature" && xml.attributes().value("class") == "high") {
01201                 data.prevHigh = xml.readElementText();
01202             } else if (xml.name() == "temperature" && xml.attributes().value("class") == "low") {
01203                 data.prevLow = xml.readElementText();
01204             } else if (xml.name() == "precip") {
01205                 data.prevPrecipType = xml.attributes().value("units").toString();
01206                 if (data.prevPrecipType.isEmpty()) {
01207                     data.prevPrecipType = QString::number(WeatherUtils::NoUnit);
01208                 }
01209                 data.prevPrecipTotal = xml.readElementText();
01210             }
01211         }
01212     }
01213 }
01214 
01215 void EnvCanadaIon::parseWeatherRecords(WeatherData& data, QXmlStreamReader& xml)
01216 {
01217     Q_ASSERT(xml.isStartElement() && xml.name() == "almanac");
01218 
01219     while (!xml.atEnd()) {
01220         xml.readNext();
01221 
01222         if (xml.isEndElement() && xml.name() == "almanac") {
01223             break;
01224         }
01225 
01226         if (xml.isStartElement()) {
01227             if (xml.name() == "temperature" && xml.attributes().value("class") == "extremeMax") {
01228                 data.recordHigh = xml.readElementText().toFloat();
01229             } else if (xml.name() == "temperature" && xml.attributes().value("class") == "extremeMin") {
01230                 data.recordLow = xml.readElementText().toFloat();
01231             } else if (xml.name() == "precipitation" && xml.attributes().value("class") == "extremeRainfall") {
01232                 data.recordRain = xml.readElementText().toFloat();
01233             } else if (xml.name() == "precipitation" && xml.attributes().value("class") == "extremeSnowfall") {
01234                 data.recordSnow = xml.readElementText().toFloat();
01235             }
01236         }
01237     }
01238 }
01239 
01240 void EnvCanadaIon::parseAstronomicals(WeatherData& data, QXmlStreamReader& xml)
01241 {
01242     Q_ASSERT(xml.isStartElement() && xml.name() == "riseSet");
01243 
01244     while (!xml.atEnd()) {
01245         xml.readNext();
01246 
01247         if (xml.isEndElement() && xml.name() == "riseSet") {
01248             break;
01249         }
01250 
01251         if (xml.isStartElement()) {
01252             if (xml.name() == "disclaimer") {
01253                 xml.readElementText();
01254             } else if (xml.name() == "dateTime") {
01255                 parseDateTime(data, xml);
01256             }
01257         }
01258     }
01259 }
01260 
01261 // handle when no XML tag is found
01262 void EnvCanadaIon::parseUnknownElement(QXmlStreamReader& xml)
01263 {
01264 
01265     while (!xml.atEnd()) {
01266         xml.readNext();
01267 
01268         if (xml.isEndElement()) {
01269             break;
01270         }
01271 
01272         if (xml.isStartElement()) {
01273             parseUnknownElement(xml);
01274         }
01275     }
01276 }
01277 
01278 void EnvCanadaIon::updateWeather(const QString& source)
01279 {
01280     QMap<QString, QString> dataFields;
01281     QStringList fieldList;
01282     QVector<QString> forecastList;
01283     int i = 0;
01284 
01285     setData(source, "Country", country(source));
01286     setData(source, "Place", QString("%1, %2").arg(city(source)).arg(territory(source)));
01287     setData(source, "Region", region(source));
01288     setData(source, "Station", station(source));
01289 
01290     // Real weather - Current conditions
01291     setData(source, "Observation Period", observationTime(source));
01292     setData(source, "Current Conditions", condition(source));
01293 
01294     // Tell applet which icon to use for conditions and provide mapping for condition type to the icons to display
01295     QMap<QString, ConditionIcons> conditionList;
01296     conditionList = conditionIcons();
01297 
01298     if ((periodHour(source) >= 0 && periodHour(source) < 6) || (periodHour(source) >= 18)) {
01299         conditionList["decreasing cloud"] = FewCloudsNight;
01300         conditionList["mostly cloudy"] = PartlyCloudyNight;
01301         conditionList["partly cloudy"] = PartlyCloudyNight;
01302         conditionList["fair"] = FewCloudsNight;
01303     } else {
01304         conditionList["decreasing cloud"] = FewCloudsDay;
01305         conditionList["mostly cloudy"] = PartlyCloudyDay;
01306         conditionList["partly cloudy"] = PartlyCloudyDay;
01307         conditionList["fair"] = FewCloudsDay;
01308     }
01309 
01310     setData(source, "Condition Icon", getWeatherIcon(conditionList, condition(source)));
01311 
01312     dataFields = temperature(source);
01313     setData(source, "Temperature", dataFields["temperature"]);
01314 
01315     // Do we have a comfort temperature? if so display it
01316     if (dataFields["comfortTemperature"] != "N/A" && !dataFields["comfortTemperature"].isEmpty()) {
01317         if (dataFields["comfortTemperature"].toFloat() <= 0) {
01318             setData(source, "Windchill", QString("%1").arg(dataFields["comfortTemperature"]));
01319             setData(source, "Humidex", "N/A");
01320         } else {
01321             setData(source, "Humidex", QString("%1").arg(dataFields["comfortTemperature"]));
01322             setData(source, "Windchill", "N/A");
01323         }
01324     } else {
01325         setData(source, "Windchill", "N/A");
01326         setData(source, "Humidex", "N/A");
01327     }
01328 
01329     setData(source, "Temperature Unit", dataFields["temperatureUnit"]);
01330 
01331     setData(source, "Dewpoint", dewpoint(source));
01332     if (dewpoint(source) != "N/A") {
01333         setData(source, "Dewpoint Unit", dataFields["temperatureUnit"]);
01334     }
01335 
01336     dataFields = pressure(source);
01337     setData(source, "Pressure", dataFields["pressure"]);
01338 
01339     if (dataFields["pressure"] != "N/A") {
01340         setData(source, "Pressure Tendency", dataFields["pressureTendency"]);
01341         setData(source, "Pressure Unit", dataFields["pressureUnit"]);
01342     }
01343 
01344     dataFields = visibility(source);
01345     setData(source, "Visibility", dataFields["visibility"]);
01346     if (dataFields["visibility"] != "N/A") {
01347         setData(source, "Visibility Unit", dataFields["visibilityUnit"]);
01348     }
01349 
01350     setData(source, "Humidity", humidity(source));
01351 
01352     dataFields = wind(source);
01353     setData(source, "Wind Speed", dataFields["windSpeed"]);
01354     if (dataFields["windSpeed"] != "N/A") {
01355         setData(source, "Wind Speed Unit", dataFields["windUnit"]);
01356     }
01357     setData(source, "Wind Gust", dataFields["windGust"]);
01358     setData(source, "Wind Direction", dataFields["windDirection"]);
01359     setData(source, "Wind Degrees", dataFields["windDegrees"]);
01360     setData(source, "Wind Gust Unit", dataFields["windGustUnit"]);
01361 
01362     dataFields = regionalTemperatures(source);
01363     setData(source, "Normal High", dataFields["normalHigh"]);
01364     setData(source, "Normal Low", dataFields["normalLow"]);
01365     if (dataFields["normalHigh"] != "N/A" && dataFields["normalLow"] != "N/A") {
01366         setData(source, "Regional Temperature Unit", dataFields["regionalTempUnit"]);
01367     }
01368 
01369     // Check if UV index is available for the location
01370     dataFields = uvIndex(source);
01371     setData(source, "UV Index", dataFields["uvIndex"]);
01372     if (dataFields["uvIndex"] != "N/A") {
01373         setData(source, "UV Rating", dataFields["uvRating"]);
01374     }
01375 
01376     dataFields = watches(source);
01377 
01378     // Set number of forecasts per day/night supported
01379     setData(source, QString("Total Watches Issued"), d->m_weatherData[source].watches.size());
01380 
01381     // Check if we have warnings or watches
01382     for (int i = 0; i < d->m_weatherData[source].watches.size(); i++) {
01383         fieldList = dataFields[QString("watch %1").arg(i)].split('|');
01384         setData(source, QString("Watch Priority %1").arg(i), fieldList[0]);
01385         setData(source, QString("Watch Description %1").arg(i), fieldList[1]);
01386         setData(source, QString("Watch Info %1").arg(i), fieldList[2]);
01387         setData(source, QString("Watch Timestamp %1").arg(i), fieldList[3]);
01388     }
01389 
01390     dataFields = warnings(source);
01391 
01392     setData(source, QString("Total Warnings Issued"), d->m_weatherData[source].warnings.size());
01393 
01394     for (int k = 0; k < d->m_weatherData[source].warnings.size(); k++) {
01395         fieldList = dataFields[QString("warning %1").arg(k)].split('|');
01396         setData(source, QString("Warning Priority %1").arg(k), fieldList[0]);
01397         setData(source, QString("Warning Description %1").arg(k), fieldList[1]);
01398         setData(source, QString("Warning Info %1").arg(k), fieldList[2]);
01399         setData(source, QString("Warning Timestamp %1").arg(k), fieldList[3]);
01400     }
01401 
01402     forecastList = forecasts(source);
01403 
01404     // Set number of forecasts per day/night supported
01405     setData(source, QString("Total Weather Days"), d->m_weatherData[source].forecasts.size());
01406 
01407     foreach(const QString &forecastItem, forecastList) {
01408         fieldList = forecastItem.split('|');
01409 
01410         setData(source, QString("Short Forecast Day %1").arg(i), QString("%1|%2|%3|%4|%5|%6") \
01411                 .arg(fieldList[0]).arg(fieldList[1]).arg(fieldList[2]).arg(fieldList[3]).arg(fieldList[4]).arg(fieldList[5]));
01412 
01413         /*
01414                 setData(source, QString("Long Forecast Day %1").arg(i), QString("%1|%2|%3|%4|%5|%6|%7|%8") \
01415                         .arg(fieldList[0]).arg(fieldList[2]).arg(fieldList[3]).arg(fieldList[4]).arg(fieldList[6]) \
01416                         .arg(fieldList[7]).arg(fieldList[8]).arg(fieldList[9]));
01417         */
01418         i++;
01419     }
01420 
01421     dataFields = yesterdayWeather(source);
01422     setData(source, "Yesterday High", dataFields["prevHigh"]);
01423     setData(source, "Yesterday Low", dataFields["prevLow"]);
01424 
01425     if (dataFields["prevHigh"] != "N/A" && dataFields["prevLow"] != "N/A") {
01426         setData(source , "Yesterday Temperature Unit", dataFields["yesterdayTempUnit"]);
01427     }
01428 
01429     setData(source, "Yesterday Precip Total", dataFields["prevPrecip"]);
01430     setData(source, "Yesterday Precip Unit", dataFields["prevPrecipUnit"]);
01431 
01432     dataFields = sunriseSet(source);
01433     setData(source, "Sunrise At", dataFields["sunrise"]);
01434     setData(source, "Sunset At", dataFields["sunset"]);
01435 
01436     dataFields = moonriseSet(source);
01437     setData(source, "Moonrise At", dataFields["moonrise"]);
01438     setData(source, "Moonset At", dataFields["moonset"]);
01439 
01440     dataFields = weatherRecords(source);
01441     setData(source, "Record High Temperature", dataFields["recordHigh"]);
01442     setData(source, "Record Low Temperature", dataFields["recordLow"]);
01443     if (dataFields["recordHigh"] != "N/A" && dataFields["recordLow"] != "N/A") {
01444         setData(source, "Record Temperature Unit", dataFields["recordTempUnit"]);
01445     }
01446 
01447     setData(source, "Record Rainfall", dataFields["recordRain"]);
01448     setData(source, "Record Rainfall Unit", dataFields["recordRainUnit"]);
01449     setData(source, "Record Snowfall", dataFields["recordSnow"]);
01450     setData(source, "Record Snowfall Unit", dataFields["recordSnowUnit"]);
01451 
01452     setData(source, "Credit", "Meteorological data is provided by Environment Canada");
01453 }
01454 
01455 QString EnvCanadaIon::country(const QString& source)
01456 {
01457     return d->m_weatherData[source].countryName;
01458 }
01459 QString EnvCanadaIon::territory(const QString& source)
01460 {
01461     return d->m_weatherData[source].shortTerritoryName;
01462 }
01463 QString EnvCanadaIon::city(const QString& source)
01464 {
01465     return d->m_weatherData[source].cityName;
01466 }
01467 QString EnvCanadaIon::region(const QString& source)
01468 {
01469     return d->m_weatherData[source].regionName;
01470 }
01471 QString EnvCanadaIon::station(const QString& source)
01472 {
01473     if (!d->m_weatherData[source].stationID.isEmpty()) {
01474         return d->m_weatherData[source].stationID.toUpper();
01475     }
01476 
01477     return QString("N/A");
01478 }
01479 
01480 QString EnvCanadaIon::observationTime(const QString& source)
01481 {
01482     return d->m_weatherData[source].obsTimestamp;
01483 }
01484 
01485 /*
01486 bool EnvCanadaIon::night(const QString& source)
01487 {
01488     if (d->m_weatherData[source].iconPeriodAP == "pm") {
01489         return true;
01490     }
01491     return false;
01492 }
01493 */
01494 
01495 int EnvCanadaIon::periodHour(const QString& source)
01496 {
01497     return d->m_weatherData[source].iconPeriodHour;
01498 }
01499 
01500 QString EnvCanadaIon::condition(const QString& source)
01501 {
01502     if (d->m_weatherData[source].condition.isEmpty()) {
01503         d->m_weatherData[source].condition = "N/A";
01504     }
01505     return d->m_weatherData[source].condition;
01506 }
01507 
01508 QString EnvCanadaIon::dewpoint(const QString& source)
01509 {
01510     if (!d->m_weatherData[source].dewpoint.isEmpty()) {
01511         return QString::number(d->m_weatherData[source].dewpoint.toFloat(), 'f', 1);
01512     }
01513     return QString("N/A");
01514 }
01515 
01516 QString EnvCanadaIon::humidity(const QString& source)
01517 {
01518     if (!d->m_weatherData[source].humidity.isEmpty()) {
01519         return QString("%1%").arg(d->m_weatherData[source].humidity);
01520     }
01521     return QString("N/A");
01522 }
01523 
01524 QMap<QString, QString> EnvCanadaIon::visibility(const QString& source)
01525 {
01526     QMap<QString, QString> visibilityInfo;
01527 
01528     if (!d->m_weatherData[source].visibility == 0) {
01529         visibilityInfo.insert("visibility", QString::number(d->m_weatherData[source].visibility, 'f', 1));
01530         visibilityInfo.insert("visibilityUnit", QString::number(WeatherUtils::Kilometers));
01531     } else {
01532         visibilityInfo.insert("visibility", "N/A");
01533     }
01534     return visibilityInfo;
01535 }
01536 
01537 QMap<QString, QString> EnvCanadaIon::temperature(const QString& source)
01538 {
01539     QMap<QString, QString> temperatureInfo;
01540     if (!d->m_weatherData[source].temperature.isEmpty()) {
01541         temperatureInfo.insert("temperature", QString::number(d->m_weatherData[source].temperature.toFloat(), 'f', 1));
01542     } 
01543 
01544     if (d->m_weatherData[source].temperature == "N/A") {
01545         temperatureInfo.insert("temperature", "N/A");
01546     }
01547 
01548     temperatureInfo.insert("temperatureUnit", QString::number(WeatherUtils::Celsius));
01549     temperatureInfo.insert("comfortTemperature", "N/A");
01550 
01551     if (d->m_weatherData[source].comforttemp != "N/A") {
01552         temperatureInfo.insert("comfortTemperature", d->m_weatherData[source].comforttemp);
01553     }
01554     return temperatureInfo;
01555 }
01556 
01557 QMap<QString, QString> EnvCanadaIon::watches(const QString& source)
01558 {
01559     QMap<QString, QString> watchData;
01560     QString watchType;
01561     for (int i = 0; i < d->m_weatherData[source].watches.size(); ++i) {
01562         watchType = QString("watch %1").arg(i);
01563         watchData[watchType] = QString("%1|%2|%3|%4").arg(d->m_weatherData[source].watches[i]->priority) \
01564                                .arg(d->m_weatherData[source].watches[i]->description) \
01565                                .arg(d->m_weatherData[source].watches[i]->url) \
01566                                .arg(d->m_weatherData[source].watches[i]->timestamp);
01567     }
01568     return watchData;
01569 }
01570 
01571 QMap<QString, QString> EnvCanadaIon::warnings(const QString& source)
01572 {
01573     QMap<QString, QString> warningData;
01574     QString warnType;
01575     for (int i = 0; i < d->m_weatherData[source].warnings.size(); ++i) {
01576         warnType = QString("warning %1").arg(i);
01577         warningData[warnType] = QString("%1|%2|%3|%4").arg(d->m_weatherData[source].warnings[i]->priority) \
01578                                 .arg(d->m_weatherData[source].warnings[i]->description) \
01579                                 .arg(d->m_weatherData[source].warnings[i]->url) \
01580                                 .arg(d->m_weatherData[source].warnings[i]->timestamp);
01581     }
01582     return warningData;
01583 }
01584 
01585 QVector<QString> EnvCanadaIon::forecasts(const QString& source)
01586 {
01587     QVector<QString> forecastData;
01588 
01589     // Do some checks for empty data
01590     for (int i = 0; i < d->m_weatherData[source].forecasts.size(); ++i) {
01591         if (d->m_weatherData[source].forecasts[i]->forecastPeriod.isEmpty()) {
01592             d->m_weatherData[source].forecasts[i]->forecastPeriod = "N/A";
01593         }
01594         if (d->m_weatherData[source].forecasts[i]->shortForecast.isEmpty()) {
01595             d->m_weatherData[source].forecasts[i]->shortForecast = "N/A";
01596         }
01597         if (d->m_weatherData[source].forecasts[i]->iconName.isEmpty()) {
01598             d->m_weatherData[source].forecasts[i]->iconName = "N/A";
01599         }
01600         if (d->m_weatherData[source].forecasts[i]->forecastSummary.isEmpty()) {
01601             d->m_weatherData[source].forecasts[i]->forecastSummary = "N/A";
01602         }
01603         if (d->m_weatherData[source].forecasts[i]->forecastTempHigh.isEmpty()) {
01604             d->m_weatherData[source].forecasts[i]->forecastTempHigh = "N/A";
01605         }
01606         if (d->m_weatherData[source].forecasts[i]->forecastTempLow.isEmpty()) {
01607             d->m_weatherData[source].forecasts[i]->forecastTempLow = "N/A";
01608         }
01609         if (d->m_weatherData[source].forecasts[i]->popPrecent.isEmpty()) {
01610             d->m_weatherData[source].forecasts[i]->popPrecent = "N/A";
01611         }
01612         if (d->m_weatherData[source].forecasts[i]->windForecast.isEmpty()) {
01613             d->m_weatherData[source].forecasts[i]->windForecast = "N/A";
01614         }
01615         if (d->m_weatherData[source].forecasts[i]->precipForecast.isEmpty()) {
01616             d->m_weatherData[source].forecasts[i]->precipForecast = "N/A";
01617         }
01618         if (d->m_weatherData[source].forecasts[i]->precipType.isEmpty()) {
01619             d->m_weatherData[source].forecasts[i]->precipType = "N/A";
01620         }
01621         if (d->m_weatherData[source].forecasts[i]->precipTotalExpected.isEmpty()) {
01622             d->m_weatherData[source].forecasts[i]->precipTotalExpected = "N/A";
01623         }
01624     }
01625 
01626     for (int i = 0; i < d->m_weatherData[source].forecasts.size(); ++i) {
01627         // We need to shortform the day/night strings.
01628         if (d->m_weatherData[source].forecasts[i]->forecastPeriod.contains("Tonight")) {
01629             d->m_weatherData[source].forecasts[i]->forecastPeriod.replace("Tonight", "nite");
01630         }
01631 
01632         if (d->m_weatherData[source].forecasts[i]->forecastPeriod.contains("night")) {
01633             d->m_weatherData[source].forecasts[i]->forecastPeriod.replace("night", "nt");
01634         }
01635 
01636         if (d->m_weatherData[source].forecasts[i]->forecastPeriod.contains("Saturday")) {
01637             d->m_weatherData[source].forecasts[i]->forecastPeriod.replace("Saturday", "Sat");
01638         }
01639 
01640         if (d->m_weatherData[source].forecasts[i]->forecastPeriod.contains("Sunday")) {
01641             d->m_weatherData[source].forecasts[i]->forecastPeriod.replace("Sunday", "Sun");
01642         }
01643 
01644         if (d->m_weatherData[source].forecasts[i]->forecastPeriod.contains("Monday")) {
01645             d->m_weatherData[source].forecasts[i]->forecastPeriod.replace("Monday", "Mon");
01646         }
01647 
01648         if (d->m_weatherData[source].forecasts[i]->forecastPeriod.contains("Tuesday")) {
01649             d->m_weatherData[source].forecasts[i]->forecastPeriod.replace("Tuesday", "Tue");
01650         }
01651 
01652         if (d->m_weatherData[source].forecasts[i]->forecastPeriod.contains("Wednesday")) {
01653             d->m_weatherData[source].forecasts[i]->forecastPeriod.replace("Wednesday", "Wed");
01654         }
01655 
01656         if (d->m_weatherData[source].forecasts[i]->forecastPeriod.contains("Thursday")) {
01657             d->m_weatherData[source].forecasts[i]->forecastPeriod.replace("Thursday", "Thu");
01658         }
01659         if (d->m_weatherData[source].forecasts[i]->forecastPeriod.contains("Friday")) {
01660             d->m_weatherData[source].forecasts[i]->forecastPeriod.replace("Friday", "Fri");
01661         }
01662 
01663         forecastData.append(QString("%1|%2|%3|%4|%5|%6") \
01664                             .arg(d->m_weatherData[source].forecasts[i]->forecastPeriod) \
01665                             .arg(d->m_weatherData[source].forecasts[i]->iconName) \
01666                             .arg(d->m_weatherData[source].forecasts[i]->shortForecast) \
01667                             .arg(d->m_weatherData[source].forecasts[i]->forecastTempHigh) \
01668                             .arg(d->m_weatherData[source].forecasts[i]->forecastTempLow) \
01669                             .arg(d->m_weatherData[source].forecasts[i]->popPrecent));
01670     }
01671     return forecastData;
01672 }
01673 
01674 QMap<QString, QString> EnvCanadaIon::pressure(const QString& source)
01675 {
01676     QMap<QString, QString> pressureInfo;
01677 
01678     if (d->m_weatherData[source].pressure == 0) {
01679         pressureInfo.insert("pressure", "N/A");
01680         return pressureInfo;
01681     } else {
01682         pressureInfo.insert("pressure", QString::number(d->m_weatherData[source].pressure, 'f', 1));
01683         pressureInfo.insert("pressureUnit", QString::number(WeatherUtils::Kilopascals));
01684         pressureInfo.insert("pressureTendency", d->m_weatherData[source].pressureTendency);
01685     }
01686     return pressureInfo;
01687 }
01688 
01689 QMap<QString, QString> EnvCanadaIon::wind(const QString& source)
01690 {
01691     QMap<QString, QString> windInfo;
01692 
01693     // May not have any winds
01694     if (d->m_weatherData[source].windSpeed.isEmpty()) {
01695         windInfo.insert("windSpeed", "N/A");
01696         windInfo.insert("windUnit", QString::number(WeatherUtils::NoUnit));
01697     } else if (d->m_weatherData[source].windSpeed.toInt() == 0) {
01698         windInfo.insert("windSpeed", "Calm");
01699         windInfo.insert("windUnit", QString::number(WeatherUtils::NoUnit));
01700     } else {
01701         windInfo.insert("windSpeed", QString::number(d->m_weatherData[source].windSpeed.toInt()));
01702         windInfo.insert("windUnit", QString::number(WeatherUtils::KilometersAnHour));
01703     }
01704 
01705     // May not always have gusty winds
01706     if (d->m_weatherData[source].windGust.isEmpty()) {
01707         windInfo.insert("windGust", "N/A");
01708         windInfo.insert("windGustUnit", QString::number(WeatherUtils::NoUnit));
01709     } else {
01710         windInfo.insert("windGust", QString::number(d->m_weatherData[source].windGust.toInt()));
01711         windInfo.insert("windGustUnit", QString::number(WeatherUtils::KilometersAnHour));
01712     }
01713 
01714     if (d->m_weatherData[source].windDirection.isEmpty() && d->m_weatherData[source].windSpeed.isEmpty()) {
01715         windInfo.insert("windDirection", "N/A");
01716         windInfo.insert("windDegrees", "N/A");
01717     } else if (d->m_weatherData[source].windSpeed.toInt() == 0) {
01718         windInfo.insert("windDirection", "VR");
01719     } else {
01720         windInfo.insert("windDirection", d->m_weatherData[source].windDirection);
01721         windInfo.insert("windDegrees", d->m_weatherData[source].windDegrees);
01722     }
01723     return windInfo;
01724 }
01725 
01726 QMap<QString, QString> EnvCanadaIon::uvIndex(const QString& source)
01727 {
01728     QMap<QString, QString> uvInfo;
01729 
01730     if (d->m_weatherData[source].UVRating.isEmpty()) {
01731         uvInfo.insert("uvRating", "N/A");
01732     } else {
01733         uvInfo.insert("uvRating", d->m_weatherData[source].UVRating);
01734     }
01735 
01736     if (d->m_weatherData[source].UVIndex.isEmpty()) {
01737         uvInfo.insert("uvIndex", "N/A");
01738     } else {
01739         uvInfo.insert("uvIndex", d->m_weatherData[source].UVIndex);
01740     }
01741 
01742     return uvInfo;
01743 }
01744 
01745 QMap<QString, QString> EnvCanadaIon::regionalTemperatures(const QString& source)
01746 {
01747     QMap<QString, QString> regionalTempInfo;
01748 
01749     if (d->m_weatherData[source].normalHigh.isEmpty()) {
01750         regionalTempInfo.insert("normalHigh", "N/A");
01751     } else {
01752         regionalTempInfo.insert("normalHigh", d->m_weatherData[source].normalHigh);
01753     }
01754 
01755     if (d->m_weatherData[source].normalLow.isEmpty()) {
01756         regionalTempInfo.insert("normalLow", "N/A");
01757     } else {
01758         regionalTempInfo.insert("normalLow", d->m_weatherData[source].normalLow);
01759     }
01760 
01761     regionalTempInfo.insert("regionalTempUnit", QString::number(WeatherUtils::Celsius));
01762     return regionalTempInfo;
01763 }
01764 
01765 QMap<QString, QString> EnvCanadaIon::yesterdayWeather(const QString& source)
01766 {
01767     QMap<QString, QString> yesterdayInfo;
01768 
01769     if (d->m_weatherData[source].prevHigh.isEmpty()) {
01770         yesterdayInfo.insert("prevHigh", "N/A");
01771     } else {
01772         yesterdayInfo.insert("prevHigh", d->m_weatherData[source].prevHigh);
01773     }
01774 
01775     if (d->m_weatherData[source].prevLow.isEmpty()) {
01776         yesterdayInfo.insert("prevLow", "N/A");
01777     } else {
01778         yesterdayInfo.insert("prevLow", d->m_weatherData[source].prevLow);
01779     }
01780 
01781     yesterdayInfo.insert("yesterdayTempUnit", QString::number(WeatherUtils::Celsius));
01782 
01783     if (d->m_weatherData[source].prevPrecipTotal == "Trace") {
01784         yesterdayInfo.insert("prevPrecip", "Trace");
01785         return yesterdayInfo;
01786     }
01787 
01788     if (d->m_weatherData[source].prevPrecipTotal.isEmpty()) {
01789         yesterdayInfo.insert("prevPrecip", "N/A");
01790     } else {
01791         yesterdayInfo.insert("prevPrecipTotal", d->m_weatherData[source].prevPrecipTotal);
01792         if (d->m_weatherData[source].prevPrecipType == "mm") {
01793             yesterdayInfo.insert("prevPrecipUnit", QString::number(WeatherUtils::Millimeters));
01794         } else if (d->m_weatherData[source].prevPrecipType == "cm") {
01795             yesterdayInfo.insert("prevPrecipUnit", QString::number(WeatherUtils::Centimeters));
01796         } else {
01797             yesterdayInfo.insert("prevPrecipUnit", QString::number(WeatherUtils::NoUnit));
01798         }
01799     }
01800 
01801     return yesterdayInfo;
01802 }
01803 
01804 QMap<QString, QString> EnvCanadaIon::sunriseSet(const QString& source)
01805 {
01806     QMap<QString, QString> sunInfo;
01807 
01808     if (d->m_weatherData[source].sunriseTimestamp.isEmpty()) {
01809         sunInfo.insert("sunrise", "N/A");
01810     } else {
01811         sunInfo.insert("sunrise", d->m_weatherData[source].sunriseTimestamp);
01812     }
01813 
01814     if (d->m_weatherData[source].sunsetTimestamp.isEmpty()) {
01815         sunInfo.insert("sunset", "N/A");
01816     } else {
01817         sunInfo.insert("sunset", d->m_weatherData[source].sunsetTimestamp);
01818     }
01819 
01820     return sunInfo;
01821 }
01822 
01823 QMap<QString, QString> EnvCanadaIon::moonriseSet(const QString& source)
01824 {
01825     QMap<QString, QString> moonInfo;
01826 
01827     if (d->m_weatherData[source].moonriseTimestamp.isEmpty()) {
01828         moonInfo.insert("moonrise", "N/A");
01829     } else {
01830         moonInfo.insert("moonrise", d->m_weatherData[source].moonriseTimestamp);
01831     }
01832 
01833     if (d->m_weatherData[source].moonsetTimestamp.isEmpty()) {
01834         moonInfo.insert("moonset", "N/A");
01835     } else {
01836         moonInfo.insert("moonset", d->m_weatherData[source].moonsetTimestamp);
01837     }
01838 
01839     return moonInfo;
01840 }
01841 
01842 QMap<QString, QString> EnvCanadaIon::weatherRecords(const QString& source)
01843 {
01844     QMap<QString, QString> recordInfo;
01845 
01846     if (d->m_weatherData[source].recordHigh == 0) {
01847         recordInfo.insert("recordHigh", "N/A");
01848     } else {
01849         recordInfo.insert("recordHigh", QString("%1").arg(d->m_weatherData[source].recordHigh));
01850     }
01851 
01852     if (d->m_weatherData[source].recordLow == 0) {
01853         recordInfo.insert("recordLow", "N/A");
01854     } else {
01855         recordInfo.insert("recordLow", QString("%1").arg(d->m_weatherData[source].recordLow));
01856     }
01857 
01858     recordInfo.insert("recordTempUnit", QString::number(WeatherUtils::Celsius));
01859 
01860     if (d->m_weatherData[source].recordRain == 0) {
01861         recordInfo.insert("recordRain", "N/A");
01862     } else {
01863         recordInfo.insert("recordRain", QString("%1").arg(d->m_weatherData[source].recordRain));
01864         recordInfo.insert("recordRainUnit", QString::number(WeatherUtils::Millimeters));
01865     }
01866 
01867     if (d->m_weatherData[source].recordSnow == 0) {
01868         recordInfo.insert("recordSnow", "N/A");
01869     } else {
01870         recordInfo.insert("recordSnow", QString("%1").arg(d->m_weatherData[source].recordSnow));
01871         recordInfo.insert("recordSnowUnit", QString::number(WeatherUtils::Centimeters));
01872     }
01873 
01874     return recordInfo;
01875 }
01876 
01877 #include "ion_envcan.moc"

Plasma

Skip menu "Plasma"
  • Main Page
  • Namespace List
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Namespace Members
  • Class Members

API Reference

Skip menu "API Reference"
  • KWin
  •   KWin Libraries
  • Libraries
  •   libkworkspace
  •   libsolidcontrol
  •   libtaskmanager
  • Plasma
  •   Animators
  •   Applets
  •   Engines
  • Solid Modules
Generated for API Reference by doxygen 1.5.7
This website is maintained by Adriaan de Groot and Allen Winter.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal