KWeather: updated icon handling.

The newly added class abstracts away icon names from the main code
and has the ability to fall back to "safer" icon choices so as to
ensure (if possible) icon theme consistency.

Signed-off-by: Mavridis Philippe <mavridisf@gmail.com>
pull/18/head
Mavridis Philippe 3 years ago
parent 5fea80f569
commit 0e7033dd09
No known key found for this signature in database
GPG Key ID: F8D2D7E2F989A494

@ -36,7 +36,7 @@ tde_add_tdeinit_executable( kweatherreport AUTOMOC
##### kweatherservice (executable) ############## ##### kweatherservice (executable) ##############
tde_add_executable( kweatherservice AUTOMOC tde_add_executable( kweatherservice AUTOMOC
SOURCES main.cpp metar_parser.cpp SOURCES main.cpp weather_icon.cpp metar_parser.cpp
weatherlib.cpp weatherservice.cpp weatherlib.cpp weatherservice.cpp
weatherservice.skel stationdatabase.cpp weatherservice.skel stationdatabase.cpp
sun.cpp weatherservice.stub sun.cpp weatherservice.stub
@ -92,7 +92,7 @@ add_custom_command(
# #
# tde_add_executable( metar_parser_test AUTOMOC # tde_add_executable( metar_parser_test AUTOMOC
# SOURCES metar_parser_test.cpp metar_parser.cpp # SOURCES metar_parser_test.cpp metar_parser.cpp
# stationdatabase.cpp sun.cpp # weather_icon.cpp stationdatabase.cpp sun.cpp
# ) # )
# #
# add_test( NAME metar_parser_test-test # add_test( NAME metar_parser_test-test

@ -28,6 +28,7 @@ email : jratke@comcast.net
#include "metar_parser.h" #include "metar_parser.h"
#include "stationdatabase.h" #include "stationdatabase.h"
#include "weather_icon.h"
#include "sun.h" #include "sun.h"
// Temperature conversion macros // Temperature conversion macros
@ -257,7 +258,7 @@ bool MetarParser::parseCurrent(const TQString &s)
if (sCode.contains("DZ")) if (sCode.contains("DZ"))
{ {
phenomena = i18n("Drizzle"); phenomena = i18n("Drizzle");
weatherInfo.theWeather = "light_rain"; weatherInfo.theWeather = iconName( WeatherIcon::LightRain, false );
} }
else if (sCode.contains("RA")) else if (sCode.contains("RA"))
{ {
@ -272,32 +273,32 @@ bool MetarParser::parseCurrent(const TQString &s)
else if (sCode.contains("SG")) else if (sCode.contains("SG"))
{ {
phenomena = i18n("Snow Grains"); phenomena = i18n("Snow Grains");
weatherInfo.theWeather = "snow4"; weatherInfo.theWeather = iconName( WeatherIcon::Snow, false, 4 );
} }
else if (sCode.contains("IC")) else if (sCode.contains("IC"))
{ {
phenomena = i18n("Ice Crystals"); phenomena = i18n("Ice Crystals");
weatherInfo.theWeather = "hail"; weatherInfo.theWeather = iconName( WeatherIcon::Hail, false );
} }
else if (sCode.contains("PE")) else if (sCode.contains("PE"))
{ {
phenomena = i18n("Ice Pellets"); phenomena = i18n("Ice Pellets");
weatherInfo.theWeather = "hail"; weatherInfo.theWeather = iconName( WeatherIcon::Hail, false );
} }
else if (s.contains("GR")) else if (s.contains("GR"))
{ {
phenomena = i18n("Hail"); phenomena = i18n("Hail");
weatherInfo.theWeather = "hail"; weatherInfo.theWeather = iconName( WeatherIcon::Hail, false );
} }
else if (sCode.contains("GS")) else if (sCode.contains("GS"))
{ {
phenomena = i18n("Small Hail Pellets"); phenomena = i18n("Small Hail Pellets");
weatherInfo.theWeather = "hail"; weatherInfo.theWeather = iconName( WeatherIcon::Hail, false );
} }
else if (s.contains("UP")) else if (s.contains("UP"))
{ {
phenomena = i18n("Unknown Precipitation"); phenomena = i18n("Unknown Precipitation");
weatherInfo.theWeather = iconName("shower1"); weatherInfo.theWeather = iconName( WeatherIcon::Showers, isNight(weatherInfo.reportLocation), 1);
} }
else if (sCode.contains("BR")) else if (sCode.contains("BR"))
{ {
@ -721,24 +722,25 @@ bool MetarParser::parseStationNeedsMaintenance(const TQString &s)
void MetarParser::calcCurrentIcon() void MetarParser::calcCurrentIcon()
{ {
// Default to overcast clouds bool night = isNight( weatherInfo.reportLocation );
if ( weatherInfo.clouds == -1 )
weatherInfo.clouds = 64;
if (weatherInfo.theWeather.isEmpty()) if (weatherInfo.theWeather.isEmpty())
{ {
if (weatherInfo.clouds == 0) if (weatherInfo.clouds == 0)
weatherInfo.theWeather = iconName("sunny"); weatherInfo.theWeather = iconName( WeatherIcon::Sunny, night );
else if (weatherInfo.clouds > 0 && weatherInfo.clouds <= 2) else if (weatherInfo.clouds > 0 && weatherInfo.clouds <= 2)
weatherInfo.theWeather = iconName("cloudy1"); weatherInfo.theWeather = iconName( WeatherIcon::Cloudy, night, 1 );
else if ( weatherInfo.clouds > 2 && weatherInfo.clouds <= 4) else if ( weatherInfo.clouds > 2 && weatherInfo.clouds <= 4)
weatherInfo.theWeather = iconName("cloudy2"); weatherInfo.theWeather = iconName( WeatherIcon::Cloudy, night, 2 );
else if ( weatherInfo.clouds > 4 && weatherInfo.clouds <= 8) else if ( weatherInfo.clouds > 4 && weatherInfo.clouds <= 8)
weatherInfo.theWeather = iconName("cloudy3"); weatherInfo.theWeather = iconName( WeatherIcon::Cloudy, night, 3 );
else if ( weatherInfo.clouds > 8 && weatherInfo.clouds < 63) else if ( weatherInfo.clouds > 8 && weatherInfo.clouds < 63)
weatherInfo.theWeather = iconName( "cloudy4" ); weatherInfo.theWeather = iconName( WeatherIcon::Cloudy, night, 4 );
else if (weatherInfo.clouds < 0)
weatherInfo.theWeather = iconName( WeatherIcon::Cloudy, night, weatherInfo.clouds);
else else
weatherInfo.theWeather = "cloudy5"; weatherInfo.theWeather = iconName( WeatherIcon::Cloudy, night, 5 );
} }
else if (weatherInfo.theWeather == "tstorm") else if (weatherInfo.theWeather == "tstorm")
{ {
@ -746,11 +748,11 @@ void MetarParser::calcCurrentIcon()
weatherInfo.clouds = 30; weatherInfo.clouds = 30;
if (weatherInfo.clouds >= 0 && weatherInfo.clouds <= 10) if (weatherInfo.clouds >= 0 && weatherInfo.clouds <= 10)
weatherInfo.theWeather = iconName("tstorm1"); weatherInfo.theWeather = iconName( WeatherIcon::Thunderstorm, night, 1 );
else if ( weatherInfo.clouds > 10 && weatherInfo.clouds <= 20) else if ( weatherInfo.clouds > 10 && weatherInfo.clouds <= 20)
weatherInfo.theWeather = iconName("tstorm2"); weatherInfo.theWeather = iconName( WeatherIcon::Thunderstorm, night, 2 );
else else
weatherInfo.theWeather = "tstorm3"; weatherInfo.theWeather = iconName( WeatherIcon::Thunderstorm, night, 3 );
} }
else if (weatherInfo.theWeather == "shower") else if (weatherInfo.theWeather == "shower")
{ {
@ -758,11 +760,11 @@ void MetarParser::calcCurrentIcon()
weatherInfo.clouds = 30; weatherInfo.clouds = 30;
if (weatherInfo.clouds >= 0 && weatherInfo.clouds <= 10) if (weatherInfo.clouds >= 0 && weatherInfo.clouds <= 10)
weatherInfo.theWeather = iconName("shower1"); weatherInfo.theWeather = iconName( WeatherIcon::Showers, night, 1 );
else if ( weatherInfo.clouds > 10 && weatherInfo.clouds <= 20) else if ( weatherInfo.clouds > 10 && weatherInfo.clouds <= 20)
weatherInfo.theWeather = iconName("shower2"); weatherInfo.theWeather = iconName( WeatherIcon::Showers, night, 2 );
else else
weatherInfo.theWeather = "shower3"; weatherInfo.theWeather = iconName( WeatherIcon::Showers, night, 3 );
} }
else if (weatherInfo.theWeather == "snow") else if (weatherInfo.theWeather == "snow")
{ {
@ -770,22 +772,22 @@ void MetarParser::calcCurrentIcon()
weatherInfo.clouds = 30; weatherInfo.clouds = 30;
if (weatherInfo.clouds >= 0 && weatherInfo.clouds <= 8) if (weatherInfo.clouds >= 0 && weatherInfo.clouds <= 8)
weatherInfo.theWeather = iconName("snow1"); weatherInfo.theWeather = iconName( WeatherIcon::Snow, night, 1 );
else if ( weatherInfo.clouds > 8 && weatherInfo.clouds <= 16) else if ( weatherInfo.clouds > 8 && weatherInfo.clouds <= 16)
weatherInfo.theWeather = iconName("snow2"); weatherInfo.theWeather = iconName( WeatherIcon::Snow, night, 2 );
else if (weatherInfo.clouds > 16 && weatherInfo.clouds <= 24) else if (weatherInfo.clouds > 16 && weatherInfo.clouds <= 24)
weatherInfo.theWeather = iconName("snow3"); weatherInfo.theWeather = iconName( WeatherIcon::Snow, night, 3 );
else else
weatherInfo.theWeather = "snow5"; weatherInfo.theWeather = iconName( WeatherIcon::Snow, night, 5 );
} }
else if (isNight(weatherInfo.reportLocation) && weatherInfo.theWeather == "mist")
weatherInfo.theWeather = "mist_night";
else if (isNight(weatherInfo.reportLocation) && weatherInfo.theWeather == "fog")
weatherInfo.theWeather = "fog_night";
else if ( weatherInfo.theWeather == "mist" || weatherInfo.theWeather == "fog" ) else if ( weatherInfo.theWeather == "mist" || weatherInfo.theWeather == "fog" )
{ {
if ( weatherInfo.clouds >= 63 ) if ( weatherInfo.clouds >= 63 )
weatherInfo.theWeather = "cloudy5"; weatherInfo.theWeather = iconName( WeatherIcon::Cloudy, night, 5 );
else if ( weatherInfo.theWeather == "mist" )
weatherInfo.theWeather = iconName( WeatherIcon::Mist, night );
else if ( weatherInfo.theWeather == "fog" )
weatherInfo.theWeather = iconName( WeatherIcon::Fog, night );
} }
kdDebug(12006) << "Clouds: " << weatherInfo.clouds << ", Icon: " kdDebug(12006) << "Clouds: " << weatherInfo.clouds << ", Icon: "
@ -861,13 +863,23 @@ bool MetarParser::isNight(const TQString &stationID) const
} }
} }
TQString MetarParser::iconName( const TQString &icon ) const TQString MetarParser::iconName( int condition, bool night, int strength ) const
{ {
TQString _iconName = icon; TQString _iconName;
if( strength != 0 )
if ( isNight( weatherInfo.reportLocation ) ) {
_iconName += "_night"; // Simple
WeatherIcon* wi = new WeatherIcon( condition, night, strength );
_iconName = wi->name();
delete wi;
}
else
{
// Ranged
WeatherIcon* wi = new WeatherIcon( condition, night );
_iconName = wi->name();
delete wi;
}
return _iconName; return _iconName;
} }

@ -92,7 +92,7 @@ class MetarParser
void calcCurrentIcon(); void calcCurrentIcon();
void calcWindChill(); void calcWindChill();
bool isNight(const TQString &stationID) const; bool isNight(const TQString &stationID) const;
TQString iconName( const TQString &icon ) const; TQString iconName( int condition, bool night, int strength = 0 ) const;
/* /*
* Reset the internal WeatherInfo struct of the class so that * Reset the internal WeatherInfo struct of the class so that

@ -0,0 +1,171 @@
#include <kiconloader.h>
#include "weather_icon.h"
WeatherIcon::WeatherIcon( int condition, bool night )
: iconLoader()
{
TQString name;
switch( condition )
{
case Sunny:
{
name = "weather-clear";
iconName = ( night ? name.append("-night") : name );
return;
}
case Fog:
{
name = "weather-fog";
if( night && iconExists( TQString(name.latin1()).append("-night")) )
{
name.append("-night");
}
iconName = name;
return;
}
case Mist:
{
name = "weather-mist";
if( night && iconExists( TQString(name.latin1()).append("-night")) )
{
name.append("-night");
}
iconName = name;
return;
}
case Overcast: { iconName = "weather-overcast"; return; }
case Hail: { iconName = "weather-freezing-rain"; return; }
case LightRain: { iconName = "weather-showers-scattered"; return; }
case Sleet: { iconName = "weather-snow-rain"; return; }
}
}
WeatherIcon::WeatherIcon( int condition, bool night, unsigned int strength )
: iconLoader()
{
TQString name;
switch ( condition )
{
case Cloudy:
{
switch ( strength )
{
case 1: { name = "weather-few-clouds"; break; }
case 2:
{
name = "weather-moderate-clouds";
if (! iconExists(name) )
{
name = "weather-few-clouds";
}
break;
}
case 3: { name = "weather-clouds"; break; }
case 4:
{
name = "weather-ample-clouds";
if (! iconExists(name) )
{
name = "weather-clouds";
}
break;
}
case 5: { iconName = "weather-many-clouds"; return; }
default: { iconName = "weather-clouds"; return; }
}
iconName = name.append( night ? "-night" : "" );
return;
}
case Showers:
{
switch ( strength )
{
case 1: { name = "weather-showers-scattered"; break; }
case 2: { name = "weather-showers"; break; }
case 3:
default: { iconName = "weather-showers"; return; }
}
iconName = name.append( night ? "-night" : "-day" );
return;
}
case Snow:
{
switch( strength )
{
case 1: { name = "weather-snow-scattered"; break; }
case 2:
{
name = "weather-snow-moderate";
if (! iconExists( TQString(name.latin1()).append("-day")) )
{
name = "weather-snow-scattered";
}
break;
}
case 3:
{
name = "weather-snow-ample";
if ( iconExists( TQString(name.latin1()).append("-day") ) )
break;
}
case 4: { iconName = "weather-snow-scattered"; return; }
case 5:
default: { iconName = "weather-snow"; return; }
}
iconName = name.append( night ? "-night" : "-day" );
return;
}
case Thunderstorm:
switch ( strength )
{
case 1: { name = "weather-storm"; break; }
case 2:
{
name = "weather-storm-moderate";
if (! iconExists( TQString(name.latin1()).append("-day")) )
{
name = "weather-storm";
}
break;
}
case 3:
default: { iconName = "weather-storm"; return; }
}
iconName = name.append( night ? "-night" : "-day" );
return;
}
}
WeatherIcon::~WeatherIcon()
{}
bool WeatherIcon::iconExists( TQString& icon, bool inTheme )
{
if ( inTheme )
{
return iconLoader->theme()->iconPath(icon, TDEIcon::SizeMedium, TDEIcon::MatchExact).isValid();
}
else
{
return !(iconLoader->iconPath(icon, TDEIcon::SizeMedium, true).isNull());
}
}

@ -0,0 +1,20 @@
class TDEIconLoader;
class WeatherIcon {
public:
enum SimpleCondition { Sunny, Fog, Mist, Overcast, Hail, LightRain, Sleet };
enum RangedCondition { Cloudy, Showers, Snow, Thunderstorm };
WeatherIcon( int condition /* SimpleCondition */, bool night );
WeatherIcon( int condition /* RangedCondition */, bool night, unsigned int strength );
~WeatherIcon();
static TQString unknown() { return "weather-none-available"; };
TQString& name() { return iconName; }
private:
bool iconExists( TQString& icon, bool inTheme = true );
TDEIconLoader* iconLoader;
TQString iconName = unknown();
};

@ -39,6 +39,7 @@ email : geiseri@msoe.edu
#include "stationdatabase.h" #include "stationdatabase.h"
#include "sun.h" #include "sun.h"
#include "weatherlib.h" #include "weatherlib.h"
#include "weather_icon.h"
#include "weatherlib.moc" #include "weatherlib.moc"
@ -271,7 +272,7 @@ TQString WeatherLib::windChill(const TQString &stationID){
TQString WeatherLib::iconName(const TQString &stationID){ TQString WeatherLib::iconName(const TQString &stationID){
TQString result("dunno"); TQString result = WeatherIcon::unknown();
// isEmpty is true for null or 0 length strings // isEmpty is true for null or 0 length strings
if ( !stationID.isEmpty() ) if ( !stationID.isEmpty() )

Loading…
Cancel
Save