30 #include <QCoreApplication> 
   38 #include <QFontMetrics> 
   39 #include <QPushButton> 
   40 #include <QSvgRenderer> 
   51 class WeatherItemPrivate
 
   53     Q_DECLARE_TR_FUNCTIONS(WeatherItemPrivate)
 
   57         : m_marbleWidget( 0 ),
 
   59           m_browserAction( tr( 
"Weather" ), parent ),
 
   60           m_favoriteAction( parent ),
 
   62           m_frameItem( m_parent ),
 
   63           m_conditionLabel( &m_frameItem ),
 
   64           m_temperatureLabel( &m_frameItem ),
 
   65           m_windDirectionLabel( &m_frameItem ),
 
   66           m_windSpeedLabel( &m_frameItem ),
 
   67           m_favoriteButton( &m_frameItem )
 
   70         m_temperatureLabel.setMinimumSize( QSizeF( 0, 
imageSize.height() ) );
 
   71         m_windSpeedLabel.setMinimumSize( QSizeF( 0, 
imageSize.height() ) );
 
   73         QPushButton *button = 
new QPushButton();
 
   74         button->setStyleSheet( 
"border-style: outset;" );
 
   75         button->setIcon( QIcon( 
":/icons/bookmarks.png" ) );
 
   76         button->setFixedSize( 22, 22 );
 
   77         button->setFlat( 
true );
 
   78         button->setCheckable( 
true );
 
   80         m_favoriteButton.setWidget( button );
 
   85         topLayout->
addItem( &m_frameItem, 0, 0 );
 
   90         m_frameItem.setLayout( gridLayout );
 
   93         gridLayout->
addItem( &m_conditionLabel, 0, 0 );
 
   94         gridLayout->
addItem( &m_temperatureLabel, 0, 1 );
 
   95         gridLayout->
setAlignment( &m_temperatureLabel, Qt::AlignRight | Qt::AlignVCenter );
 
   96         gridLayout->
addItem( &m_windDirectionLabel, 1, 0 );
 
   97         gridLayout->
addItem( &m_windSpeedLabel, 1, 1 );
 
   98         gridLayout->
setAlignment( &m_windSpeedLabel, Qt::AlignRight | Qt::AlignVCenter );
 
   99         gridLayout->
addItem( &m_favoriteButton, 0, 2 );
 
  104     ~WeatherItemPrivate()
 
  110         QLocale locale = QLocale::system();
 
  112         toolTip += tr( 
"Station: %1\n" ).arg( m_parent->stationName() );
 
  113         if ( m_currentWeather.hasValidCondition() && m_currentWeather.hasValidTemperature() )
 
  114             toolTip += QString( 
"%2, %3\n" ).arg( m_currentWeather.conditionString() )
 
  115                                            .arg( temperatureString() );
 
  116         else if ( m_currentWeather.hasValidCondition() )
 
  117             toolTip += QString( 
"%2\n" ).arg( m_currentWeather.conditionString() );
 
  118         else if ( m_currentWeather.hasValidTemperature() )
 
  119             toolTip += QString( 
"%2\n" ).arg( temperatureString() );
 
  121         if ( m_currentWeather.hasValidWindSpeed() && m_currentWeather.hasValidWindDirection() )
 
  122             toolTip += tr( 
"Wind: %4, %5\n", 
"Wind: WindSpeed, WindDirection" )
 
  123                     .arg( windSpeedString( ) )
 
  124                     .arg( m_currentWeather.windDirectionString() );
 
  125         else if ( m_currentWeather.hasValidWindSpeed() )
 
  126             toolTip += tr( 
"Wind: %4\n", 
"Wind: WindSpeed" )
 
  127                     .arg( m_currentWeather.windSpeedString() );
 
  128         else if ( m_currentWeather.hasValidWindDirection() )
 
  129             toolTip += tr( 
"Wind: %4\n", 
"Wind: WindDirection" )
 
  130                     .arg( m_currentWeather.windDirectionString() );
 
  132         if ( m_currentWeather.hasValidPressure() && m_currentWeather.hasValidPressureDevelopment() )
 
  133             toolTip += tr( 
"Pressure: %6, %7", 
"Pressure: Pressure, Development" )
 
  134                     .arg( pressureString() )
 
  135                     .arg( m_currentWeather.pressureDevelopmentString() );
 
  136         else if ( m_currentWeather.hasValidPressure() )
 
  137             toolTip += tr( 
"Pressure: %6", 
"Pressure: Pressure" )
 
  138                     .arg( pressureString() );
 
  139         else if ( m_currentWeather.hasValidPressureDevelopment() )
 
  140             toolTip += tr( 
"Pressure %7", 
"Pressure Development" )
 
  141                     .arg( m_currentWeather.pressureDevelopmentString() );
 
  143         if ( !m_forecastWeather.isEmpty() ) {
 
  146             QDate minDate = QDate::currentDate();
 
  147             minDate.addDays( -1 );
 
  148             foreach( 
const WeatherData& data, m_forecastWeather ) {
 
  156                     toolTip += tr( 
"%1: %2, %3 to %4", 
"DayOfWeek: Condition, MinTemp to MaxTemp" )
 
  157                                .arg( locale.standaloneDayName( date.dayOfWeek() ) )
 
  165         m_parent->setToolTip( toolTip );
 
  170         if ( isConditionShown() ) {
 
  171             m_conditionLabel.setImage( m_currentWeather.icon(), 
imageSize );
 
  174             m_conditionLabel.clear();
 
  177         if ( isTemperatureShown() ) {
 
  178             m_temperatureLabel.setText( temperatureString() );
 
  181             m_temperatureLabel.clear();
 
  184         if ( isWindDirectionShown() ) {
 
  185             QString windDirectionString = m_currentWeather.windDirectionString();
 
  186             QSizeF windDirectionImageSize;
 
  188             QSizeF windDirectionSizeF = s_windIcons.boundsOnElement( windDirectionString ).size();
 
  189             double windDirectionRatio = windDirectionSizeF.width() / windDirectionSizeF.height();
 
  191                 windDirectionImageSize.setWidth( 
imageSize.width() );
 
  192                 windDirectionImageSize.setHeight( 
imageSize.width() / windDirectionRatio );
 
  195                 windDirectionImageSize.setHeight( 
imageSize.height() );
 
  196                 windDirectionImageSize.setWidth( 
imageSize.height() * windDirectionRatio );
 
  199             QImage windArrow( windDirectionImageSize.toSize(), QImage::Format_ARGB32 );
 
  200             windArrow.fill( Qt::transparent );
 
  202             s_windIcons.render( &painter, windDirectionString );
 
  203             m_windDirectionLabel.setImage( windArrow );
 
  206             m_windDirectionLabel.clear();
 
  209         if ( isWindSpeedShown() ) {
 
  210             m_windSpeedLabel.setText( windSpeedString() );
 
  213             m_windSpeedLabel.clear();
 
  219     void updateFavorite()
 
  221         QStringList items = m_settings.value( 
"favoriteItems" ).toString()
 
  222                                         .split(QLatin1Char(
','), QString::SkipEmptyParts);
 
  223         bool favorite = items.contains( m_parent->id() );
 
  225         m_favoriteButton.setVisible( favorite );
 
  226         m_favoriteAction.setText( favorite ? tr( 
"Remove from Favorites" )
 
  227                                            : tr( 
"Add to Favorites" ) );
 
  229         if ( m_parent->isFavorite() != favorite ) {
 
  230             m_parent->setFavorite( favorite );
 
  236     bool isConditionShown()
 
  238         return m_currentWeather.hasValidCondition()
 
  242     bool isTemperatureShown()
 
  244         return m_currentWeather.hasValidTemperature()
 
  248     bool isWindDirectionShown()
 
  250         return m_currentWeather.hasValidWindDirection()
 
  254     bool isWindSpeedShown()
 
  256         return m_currentWeather.hasValidWindSpeed()
 
  260     QString temperatureString()
 
  263         return m_currentWeather.temperatureString( tUnit );
 
  274     QString windSpeedString()
 
  276         return m_currentWeather.windSpeedString( speedUnit() );
 
  285     QString pressureString()
 
  287         return m_currentWeather.pressureString( pressureUnit() );
 
  299     QMap<QDate, WeatherData> m_forecastWeather;
 
  302     QAction m_browserAction;
 
  303     QAction m_favoriteAction;
 
  305     QString m_stationName;
 
  306     QHash<QString,QVariant> m_settings;
 
  322     QFont WeatherItemPrivate::s_font = QFont( 
"Sans Serif", 10 );
 
  324     QFont WeatherItemPrivate::s_font = QFont( 
"Sans Serif", 8 );
 
  329     d( new WeatherItemPrivate( this ) )
 
  336     d( new WeatherItemPrivate( this ) )
 
  339     d->m_marbleWidget = widget;
 
  349     disconnect( &d->m_browserAction, SIGNAL(triggered()),
 
  351     connect(    &d->m_browserAction, SIGNAL(triggered()),
 
  353     return &d->m_browserAction;
 
  358     return QString( 
"weatherItem" );
 
  369     return d->isConditionShown()
 
  370            || d->isTemperatureShown()
 
  371            || d->isWindDirectionShown()
 
  372            || d->isWindSpeedShown();
 
  388     return d->m_stationName;
 
  393     if ( name != d->m_stationName ) {
 
  394         d->m_browserAction.setText( name );
 
  395         d->m_stationName = name;
 
  404     return d->m_currentWeather;
 
  409     d->m_currentWeather = weather;
 
  420     return d->m_forecastWeather;
 
  425     d->m_forecastWeather = forecasts;
 
  435         WeatherData other = d->m_forecastWeather.value( date );
 
  437             d->m_forecastWeather.insert( date, data );
 
  440             d->m_forecastWeather.remove( date );
 
  441             d->m_forecastWeather.insert( date, data );
 
  446     QDate minDate = QDate::currentDate();
 
  447     minDate.addDays( -1 );
 
  449     QMap<QDate, WeatherData>::iterator it = d->m_forecastWeather.begin();
 
  451     while( it != d->m_forecastWeather.end() ) {
 
  452         if ( it.key() < minDate ) {
 
  453             d->m_forecastWeather.remove( it.key() );
 
  464     return d->m_priority;
 
  474     if ( d->m_settings == settings ) {
 
  478     d->m_settings = settings;
 
  487     d->m_marbleWidget = widget;
 
  492     if (d->m_marbleWidget) {
 
  493         PopupLayer *popup = d->m_marbleWidget->popupLayer();
 
  495         popup->
setSize( QSizeF( 610, 550 ) ); 
 
  498         QFile weatherHtmlFile(
":/marble/weather/weather.html");
 
  499         if ( !weatherHtmlFile.open(QIODevice::ReadOnly) ) {
 
  503         QString templateHtml = weatherHtmlFile.readAll();
 
  504         popup->
setContent( createFromTemplate(templateHtml) );
 
  508 QString WeatherItem::createFromTemplate(
const QString &templateHtml)
 
  510     QString html = templateHtml;
 
  511     QLocale locale = QLocale::system();
 
  513     html.replace(
"%weather_situation%", 
"file://"+d->m_currentWeather.iconSource());
 
  514     html.replace(
"%current_temp%", d->temperatureString());
 
  515     html.replace(
"%current_condition%", d->m_currentWeather.conditionString());
 
  516     html.replace(
"%wind_direction%", d->m_currentWeather.windDirectionString());
 
  517     html.replace(
"%wind_speed%", d->m_currentWeather.windSpeedString());
 
  518     html.replace(
"%humidity_level%", d->m_currentWeather.humidityString());
 
  519     html.replace(
"%publish_time%", d->m_currentWeather.publishingTime().toString());
 
  521     if(d->m_forecastWeather.size() < 1) {
 
  522         html.replace(
"%forecast_available%", 
"none");
 
  524         html.replace(
"%forecast_available%", 
"block");
 
  527     int forecastNumber = 0;
 
  529     foreach ( 
const WeatherData &forecast, d->m_forecastWeather ) {
 
  531         const QString suffix = QString::number(forecastNumber);
 
  532         QDate date = forecast.dataDate();
 
  533         html.replace(QLatin1String(
"%day_f")+suffix+
'%', locale.standaloneDayName(date.dayOfWeek()));
 
  534         html.replace(QLatin1String(
"%weather_situation_f")+suffix+
'%', 
"file://"+forecast.iconSource());
 
  535         html.replace(QLatin1String(
"%max_temp_f")+suffix+
'%',
 
  537         html.replace(QLatin1String(
"%min_temp_f")+suffix+
'%',
 
  539         html.replace(QLatin1String(
"%condition_f")+suffix+
'%', forecast.conditionString());
 
  540         html.replace(QLatin1String(
"%wind_direction_f")+suffix+
'%', forecast.windDirectionString());
 
  541         html.replace(QLatin1String(
"%wind_speed_f")+suffix+
'%', forecast.windSpeedString());
 
  542         html.replace(QLatin1String(
"%publish_time_f")+suffix+
'%', forecast.publishingTime().toString());
 
  550     QList<QAction*> result;
 
  551     result << &d->m_browserAction;
 
  553     disconnect( &d->m_favoriteAction, SIGNAL(triggered()),
 
  555     connect(    &d->m_favoriteAction, SIGNAL(triggered()),
 
  558     result << &d->m_favoriteAction;
 
  570     return d->m_currentWeather.iconSource();
 
  575     return d->m_currentWeather.hasValidTemperature()
 
  582 #include "WeatherItem.moc" 
bool hasValidCondition() const 
 
void stationNameChanged()
 
QString itemType() const 
Returns the type of this specific item. 
 
static QString path(const QString &relativePath)
 
const bool showWindDirectionDefault
 
const bool showTemperatureDefault
 
bool operator<(const AbstractDataPluginItem *other) const 
 
WeatherData currentWeather() const 
 
QString minTemperatureString(WeatherData::TemperatureUnit format=WeatherData::Kelvin) const 
 
const double imageSizeRatio
 
QDateTime publishingTime() const 
Get the time when the data was published. 
 
void descriptionChanged()
 
QDate dataDate() const 
Get the date the data is meant for. 
 
void setAlignment(Qt::Alignment align)
 
void setLayout(AbstractMarbleGraphicsLayout *layout)
Set the layout of the graphics item. 
 
void addItem(ScreenGraphicsItem *item, int row, int column)
 
QMap< QDate, WeatherData > forecastWeather() const 
 
const bool showWindSpeedDefault
 
void setSpacing(int spacing)
Set the spacing between the items inside the layout. 
 
const QSize imageSize(28, 28)
 
virtual QList< QAction * > actions()
 
void setStationName(const QString &name)
 
const bool showConditionDefault
 
virtual bool request(const QString &type)
Test if the item wants to request type again. 
 
const qint32 verticalSpacing
 
void setForecastWeather(const QMap< QDate, WeatherData > &forecasts)
 
void addForecastWeather(const QList< WeatherData > &forecasts)
Adds additional forecasts to the list. 
 
void setPriority(quint8 priority)
 
WeatherItem(QObject *parent=0)
 
QAction * action()
Returns the action of this specific item. 
 
const QSize borderSpacing(4, 4)
 
QString stationName() const 
 
QString maxTemperatureString(WeatherData::TemperatureUnit format=WeatherData::Kelvin) const 
 
bool hasValidMaxTemperature() const 
 
void setCacheMode(CacheMode mode)
Set the cache mode of the item. 
 
void setSettings(const QHash< QString, QVariant > &settings)
Set the settings of the item. 
 
GeoDataCoordinates coordinate() const 
 
A label item provides an Item that displays text or images/pixmaps. 
 
void setMarbleWidget(MarbleWidget *widget)
 
QString description() const 
 
double temperature() const 
 
This is the class painting a weather item on the screen. 
 
QString conditionString() const 
 
const qint32 horizontalSpacing
 
bool hasValidMinTemperature() const 
 
void temperatureChanged()
 
void setCurrentWeather(const WeatherData &weather)