summaryrefslogtreecommitdiff
path: root/weatherosd.c
blob: af1ba8f699724fd24748f315f8f440425b83e24b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
#include "config.h"
#include "tools/jsonhelpers.h"
#include "weatherosd.h"

extern cWeatherforecastConfig weatherConfig;

cWeatherOsd::cWeatherOsd(cForecastIO *forecastIO) : cSkindesignerOsdMenu("Weather Forecast") {
    isDetailedView = false;
    lastRootMenuElement = 0;
    SetPluginName("weatherforecast");
    this->forecastIO = forecastIO;
    SetRootMenu();
}

cWeatherOsd::~cWeatherOsd(void) {
    
}

eOSState cWeatherOsd::ProcessKey(eKeys key) {
    eOSState state = cOsdMenu::ProcessKey(key);
    switch (key) {
        case kOk: {
            if (isDetailedView) {
                SetRootMenu();
            } else {
                int element = Current();
                lastRootMenuElement = element;
                if (element == 0)
                    SetDetailViewCurrent();
                else if (element == 1)
                    SetDetailViewHourly();
                else if (element == 2)
                    SetDetailViewDaily();
            }
            state = osContinue;
            break;
        } case kLeft: {
            TextKeyLeft();
            state = osContinue;
            break;
        } case kRight: {
            TextKeyRight();
            state = osContinue;            
            break;
        } case kUp: {
            TextKeyUp();
            state = osContinue;            
            break;
        } case kDown: {
            TextKeyDown();
            state = osContinue;
            break;
        } case kBack: {
            if (isDetailedView) {
                SetRootMenu();
                state = osContinue;
            }
            break;
        } default:
            break;
    }
    return state;
}

void cWeatherOsd::SetRootMenu(void) {
    isDetailedView = false;
    SetPluginMenu(meRoot, mtList);
    Clear();
    SetTitle(tr("Weather Forecast"));
    
    cSkindesignerOsdItem *currentWeather = new cSkindesignerOsdItem();
    string itemLabelCurrent = tr("Current Weather");
    currentWeather->SetText(itemLabelCurrent.c_str());
    currentWeather->AddStringToken("menuitemtext", itemLabelCurrent.c_str());
    currentWeather->AddIntToken("iscurrent", 1);
    currentWeather->AddIntToken("ishourly", 0);
    currentWeather->AddIntToken("isdaily", 0);
    currentWeather->AddStringToken("city", weatherConfig.city);
    currentWeather->AddStringToken("latitude", FloatToString(weatherConfig.lat));
    currentWeather->AddStringToken("longitude", FloatToString(weatherConfig.lon));

    cForecast *currentForecast = forecastIO->GetCurrentForecast();
    if (currentForecast) {
        currentWeather->AddStringToken("timestamp", currentForecast->GetDateTimeString());
        currentWeather->AddStringToken("temperature", currentForecast->GetTemperatureString());
        currentWeather->AddStringToken("apparenttemperature", currentForecast->GetApparentTemperatureString());
        currentWeather->AddStringToken("summary", currentForecast->GetSummary());
        currentWeather->AddStringToken("icon", currentForecast->GetIcon());
        currentWeather->AddStringToken("precipitationintensity", currentForecast->GetPrecipIntensityString());
        currentWeather->AddIntToken("precipitationprobability", currentForecast->GetPrecipProbabilityPercent());
        currentWeather->AddStringToken("precipitationtype", currentForecast->GetPercipType());
        currentWeather->AddIntToken("humidity", currentForecast->GetHumidityPercent());
        currentWeather->AddStringToken("windspeed", currentForecast->GetWindSpeedString());
        currentWeather->AddIntToken("windbearing", currentForecast->GetWindBearing());
        currentWeather->AddStringToken("windbearingstring", currentForecast->GetWindBearingString());
        currentWeather->AddStringToken("visibility", currentForecast->GetVisibilityString());
        currentWeather->AddIntToken("cloudcover", currentForecast->GetCloudCoverPercent());
        currentWeather->AddStringToken("pressure", currentForecast->GetPressureString());
        currentWeather->AddStringToken("ozone", currentForecast->GetOzoneString());
    }
    Add(currentWeather, (lastRootMenuElement == 0)?true:false);

    cSkindesignerOsdItem *nextHours = new cSkindesignerOsdItem();
    string itemLabelNextHours = tr("Next 48 Hours");
    nextHours->SetText(itemLabelNextHours.c_str());
    nextHours->AddStringToken("menuitemtext", itemLabelNextHours.c_str());
    nextHours->AddIntToken("iscurrent", 0);
    nextHours->AddIntToken("ishourly", 1);
    nextHours->AddIntToken("isdaily", 0);
    nextHours->AddStringToken("city", weatherConfig.city);
    nextHours->AddStringToken("latitude", FloatToString(weatherConfig.lat));
    nextHours->AddStringToken("longitude", FloatToString(weatherConfig.lon));

    cForecasts *hourlyForecast = forecastIO->GetHourlyForecast();
    if (hourlyForecast) {
        nextHours->AddStringToken("summary", hourlyForecast->GetSummary());
        nextHours->AddStringToken("icon", hourlyForecast->GetIcon());

        cForecast *fc = hourlyForecast->GetFirstHourly();
        int num = 1;
        while (fc) {
            map<string, string> tokens;
            tokens.insert(pair<string,string>("hourly[num]", IntToString(num++)));
            tokens.insert(pair<string,string>("hourly[timestamp]", fc->GetTimeString()));
            tokens.insert(pair<string,string>("hourly[temperature]", fc->GetTemperatureString()));
            tokens.insert(pair<string,string>("hourly[apparenttemperature]", fc->GetApparentTemperatureString()));
            tokens.insert(pair<string,string>("hourly[summary]", fc->GetSummary()));
            tokens.insert(pair<string,string>("hourly[icon]", fc->GetIcon()));
            tokens.insert(pair<string,string>("hourly[precipitationintensity]", fc->GetPrecipIntensityString()));
            tokens.insert(pair<string,string>("hourly[precipitationprobability]", IntToString(fc->GetPrecipProbabilityPercent())));
            tokens.insert(pair<string,string>("hourly[precipitationtype]", fc->GetPercipType()));
            tokens.insert(pair<string,string>("hourly[humidity]", IntToString(fc->GetHumidityPercent())));
            tokens.insert(pair<string,string>("hourly[windspeed]", fc->GetWindSpeedString()));
            tokens.insert(pair<string,string>("hourly[windbearing]", IntToString(fc->GetWindBearing())));
            tokens.insert(pair<string,string>("hourly[windbearingstring]", fc->GetWindBearingString()));
            tokens.insert(pair<string,string>("hourly[visibility]", fc->GetVisibilityString()));
            tokens.insert(pair<string,string>("hourly[cloudcover]", IntToString(fc->GetCloudCoverPercent())));
            tokens.insert(pair<string,string>("hourly[pressure]", fc->GetPressureString()));
            tokens.insert(pair<string,string>("hourly[ozone]", fc->GetOzoneString()));
            nextHours->AddLoopToken("hourly", tokens);
            fc = hourlyForecast->GetNext();
        }
    }

    Add(nextHours, (lastRootMenuElement == 1)?true:false);

    cSkindesignerOsdItem *nextDays = new cSkindesignerOsdItem();
    string itemLabelNextDays = tr("Next 7 Days");
    nextDays->SetText(itemLabelNextDays.c_str());
    nextDays->AddStringToken("menuitemtext", itemLabelNextDays.c_str());
    nextDays->AddIntToken("iscurrent", 0);
    nextDays->AddIntToken("ishourly", 0);
    nextDays->AddIntToken("isdaily", 1);
    nextDays->AddStringToken("city", weatherConfig.city);
    nextDays->AddStringToken("latitude", FloatToString(weatherConfig.lat));
    nextDays->AddStringToken("longitude", FloatToString(weatherConfig.lon));

    cForecasts *dailyForecast = forecastIO->GetDailyForecast();
    if (dailyForecast) {
        nextDays->AddStringToken("summary", dailyForecast->GetSummary());
        nextDays->AddStringToken("icon", dailyForecast->GetIcon());

        cForecast *fc = dailyForecast->GetFirstDaily();
        while (fc) {
            map<string, string> tokens;
            tokens.insert(pair<string,string>("daily[day]", fc->GetDateString()));
            tokens.insert(pair<string,string>("daily[dayname]", fc->GetDayName()));
            tokens.insert(pair<string,string>("daily[temperaturemin]", fc->GetTemperatureMinString()));
            tokens.insert(pair<string,string>("daily[temperaturemintime]", fc->GetTemperatureMinTimeString()));
            tokens.insert(pair<string,string>("daily[temperaturemax]", fc->GetTemperatureMaxString()));
            tokens.insert(pair<string,string>("daily[temperaturemaxtime]", fc->GetTemperatureMaxTimeString()));
            tokens.insert(pair<string,string>("daily[summary]", fc->GetSummary()));
            tokens.insert(pair<string,string>("daily[icon]", fc->GetIcon()));
            tokens.insert(pair<string,string>("daily[precipitationintensity]", fc->GetPrecipIntensityString()));
            tokens.insert(pair<string,string>("daily[precipitationprobability]", IntToString(fc->GetPrecipProbabilityPercent())));
            tokens.insert(pair<string,string>("daily[precipitationtype]", fc->GetPercipType()));
            tokens.insert(pair<string,string>("daily[humidity]", IntToString(fc->GetHumidityPercent())));
            tokens.insert(pair<string,string>("daily[windspeed]", fc->GetWindSpeedString()));
            tokens.insert(pair<string,string>("daily[windbearing]", IntToString(fc->GetWindBearing())));
            tokens.insert(pair<string,string>("daily[windbearingstring]", fc->GetWindBearingString()));
            tokens.insert(pair<string,string>("daily[visibility]", fc->GetVisibilityString()));
            tokens.insert(pair<string,string>("daily[cloudcover]", IntToString(fc->GetCloudCoverPercent())));
            tokens.insert(pair<string,string>("daily[pressure]", fc->GetPressureString()));
            tokens.insert(pair<string,string>("daily[ozone]", fc->GetOzoneString()));
            nextDays->AddLoopToken("daily", tokens);
            fc = dailyForecast->GetNext();
        }
    }

    Add(nextDays, (lastRootMenuElement == 2)?true:false);

    Display();
}

void cWeatherOsd::SetDetailViewCurrent(void) {
    isDetailedView = true;
    SetPluginMenu(meDetailCurrent, mtText);
    ClearTokens();
    Clear();
    SetTitle(tr("Current Weather"));
    cForecast *current = forecastIO->GetCurrentForecast();
    if (!current)
        return;
    cForecasts *daily = forecastIO->GetDailyForecast();
    if (!daily)
        return;
    cForecast *today = daily->GetFirstDaily();
    if (!today)
        return;

    stringstream plainText;
    plainText << tr("Weather for") << " " << weatherConfig.city << " " << current->GetDateTimeString() << ": " <<  current->GetSummary() << "\n";
    plainText << tr("Current Temperature") << ": " << current->GetTemperatureString() << "°C" << "\n";
    plainText << tr("Apparent Temperature") << ": " << current->GetApparentTemperatureString() << "°C" << "\n";
    plainText << tr("Minimum Temperature today") << ": " << today->GetTemperatureMinString() << "°C" << "\n";
    plainText << tr("Maximum Temperature today") << ": " << today->GetTemperatureMaxString() << "°C" << "\n";
    plainText << tr("Precipitation Probability") << ": " << current->GetPrecipProbabilityPercent() << " %" << "\n";
    plainText << tr("Precipitation Intensity") << ": " << current->GetPrecipIntensityString() << " l/qm" << "\n";
    plainText << tr("Humidity") << ": " << current->GetHumidityPercent() << " %" << "\n";
    plainText << tr("Wind Speed") << ": " << current->GetWindSpeedString() << " km/h" << "\n";
    plainText << tr("Wind Bearing") << ": " << current->GetWindBearing() << "° " << current->GetWindBearingString() << "\n";
    plainText << tr("Visibility") << ": " << current->GetVisibilityString() << " km" << "\n";
    plainText << tr("Cloud Cover") << ": " << current->GetCloudCoverPercent() << " %" << "\n";
    plainText << tr("Pressure") << ": " << current->GetPressureString() << " HPa" << "\n";
    plainText << tr("Ozone") << ": " << current->GetOzoneString() << " DU" << "\n";
    SetText(plainText.str().c_str());


    AddStringToken("menuheader", tr("Current Weather"));
    AddStringToken("city", weatherConfig.city);
    AddStringToken("latitude", FloatToString(weatherConfig.lat));
    AddStringToken("longitude", FloatToString(weatherConfig.lon));
    AddStringToken("timestamp", current->GetDateTimeString());
    AddStringToken("temperature", current->GetTemperatureString());
    AddStringToken("apparenttemperature", current->GetApparentTemperatureString());
    AddStringToken("mintemperature", today->GetTemperatureMinString());
    AddStringToken("maxtemperature", today->GetTemperatureMaxString());
    AddStringToken("summary", current->GetSummary());
    AddStringToken("icon", current->GetIcon());
    AddStringToken("precipitationintensity", current->GetPrecipIntensityString());
    AddIntToken("precipitationprobability", current->GetPrecipProbabilityPercent());
    AddStringToken("precipitationtype", current->GetPercipType());
    AddIntToken("humidity", current->GetHumidityPercent());
    AddStringToken("windspeed", current->GetWindSpeedString());
    AddIntToken("windbearing", current->GetWindBearing());
    AddStringToken("windbearingstring", current->GetWindBearingString());
    AddStringToken("visibility", current->GetVisibilityString());
    AddIntToken("cloudcover", current->GetCloudCoverPercent());
    AddStringToken("pressure", current->GetPressureString());
    AddStringToken("ozone", current->GetOzoneString());

    Display();
}

void cWeatherOsd::SetDetailViewHourly(void) {
    isDetailedView = true;
    SetPluginMenu(meDetailHourly, mtText);
    Clear();
    ClearTokens();
    SetTitle(tr("Weather in the next 48 Hours"));

    cForecasts *hourly = forecastIO->GetHourlyForecast();
    if (!hourly)
        return;

    stringstream plainText;
    cForecast *fc = hourly->GetFirstHourly();

    AddStringToken("menuheader", tr("Weather in the next 48 Hours"));
    AddStringToken("summary", hourly->GetSummary());
    AddStringToken("icon", hourly->GetIcon());
    AddStringToken("city", weatherConfig.city);
    AddStringToken("latitude", FloatToString(weatherConfig.lat));
    AddStringToken("longitude", FloatToString(weatherConfig.lon));

    int num = 1;
    while (fc) {
        map<string, string> tokens;
        tokens.insert(pair<string,string>("hourly[num]", IntToString(num++)));
        tokens.insert(pair<string,string>("hourly[timestamp]", fc->GetTimeString()));
        tokens.insert(pair<string,string>("hourly[temperature]", fc->GetTemperatureString()));
        tokens.insert(pair<string,string>("hourly[apparenttemperature]", fc->GetApparentTemperatureString()));
        tokens.insert(pair<string,string>("hourly[summary]", fc->GetSummary()));
        tokens.insert(pair<string,string>("hourly[icon]", fc->GetIcon()));
        tokens.insert(pair<string,string>("hourly[precipitationintensity]", fc->GetPrecipIntensityString()));
        tokens.insert(pair<string,string>("hourly[precipitationprobability]", IntToString(fc->GetPrecipProbabilityPercent())));
        tokens.insert(pair<string,string>("hourly[precipitationtype]", fc->GetPercipType()));
        tokens.insert(pair<string,string>("hourly[humidity]", IntToString(fc->GetHumidityPercent())));
        tokens.insert(pair<string,string>("hourly[windspeed]", fc->GetWindSpeedString()));
        tokens.insert(pair<string,string>("hourly[windbearing]", IntToString(fc->GetWindBearing())));
        tokens.insert(pair<string,string>("hourly[windbearingstring]", fc->GetWindBearingString()));
        tokens.insert(pair<string,string>("hourly[visibility]", fc->GetVisibilityString()));
        tokens.insert(pair<string,string>("hourly[cloudcover]", IntToString(fc->GetCloudCoverPercent())));
        tokens.insert(pair<string,string>("hourly[pressure]", fc->GetPressureString()));
        tokens.insert(pair<string,string>("hourly[ozone]", fc->GetOzoneString()));
        AddLoopToken("hourly", tokens);
    
        plainText << fc->GetDateTimeString() << ": " <<  fc->GetSummary() << "\n";
        plainText << tr("Temperature") << ": " << fc->GetTemperatureString() << "°C, " << tr("felt") << " " << fc->GetApparentTemperatureString() << "°C""\n";
        plainText << tr("Precipitation Probability") << ": " << fc->GetPrecipProbabilityPercent() << " %, " << tr("Intensity") << ": " << fc->GetPrecipIntensityString() << " l/qm""\n";
        plainText << tr("Wind") << ": " << fc->GetWindSpeedString() << " km/h, " << fc->GetWindBearing() << "° " << fc->GetWindBearingString() << "\n";
        plainText << tr("Cloud Cover") << ": " << fc->GetCloudCoverPercent() << " %" << "\n";
        plainText << "\n";

        fc = hourly->GetNext();
    }
    
    SetText(plainText.str().c_str());
    Display();
}

void cWeatherOsd::SetDetailViewDaily(void) {
    isDetailedView = true;
    SetPluginMenu(meDetailDaily, mtText);
    Clear();
    ClearTokens();
    SetTitle(tr("Weather the next 7 days"));

    cForecasts *daily = forecastIO->GetDailyForecast();
    if (!daily)
        return;

    stringstream plainText;
    cForecast *fc = daily->GetFirstDaily();

    AddStringToken("menuheader", tr("Weather the next 7 days"));
    AddStringToken("summary", daily->GetSummary());
    AddStringToken("icon", daily->GetIcon());
    AddStringToken("city", weatherConfig.city);
    AddStringToken("latitude", FloatToString(weatherConfig.lat));
    AddStringToken("longitude", FloatToString(weatherConfig.lon));

    while (fc) {
        map<string, string> tokens;
        tokens.insert(pair<string,string>("daily[day]", fc->GetDateString()));
        tokens.insert(pair<string,string>("daily[dayname]", fc->GetDayName()));
        tokens.insert(pair<string,string>("daily[temperaturemin]", fc->GetTemperatureMinString()));
        tokens.insert(pair<string,string>("daily[temperaturemintime]", fc->GetTemperatureMinTimeString()));
        tokens.insert(pair<string,string>("daily[temperaturemax]", fc->GetTemperatureMaxString()));
        tokens.insert(pair<string,string>("daily[temperaturemaxtime]", fc->GetTemperatureMaxTimeString()));
        tokens.insert(pair<string,string>("daily[summary]", fc->GetSummary()));
        tokens.insert(pair<string,string>("daily[icon]", fc->GetIcon()));
        tokens.insert(pair<string,string>("daily[precipitationintensity]", fc->GetPrecipIntensityString()));
        tokens.insert(pair<string,string>("daily[precipitationprobability]", IntToString(fc->GetPrecipProbabilityPercent())));
        tokens.insert(pair<string,string>("daily[precipitationtype]", fc->GetPercipType()));
        tokens.insert(pair<string,string>("daily[humidity]", IntToString(fc->GetHumidityPercent())));
        tokens.insert(pair<string,string>("daily[windspeed]", fc->GetWindSpeedString()));
        tokens.insert(pair<string,string>("daily[windbearing]", IntToString(fc->GetWindBearing())));
        tokens.insert(pair<string,string>("daily[windbearingstring]", fc->GetWindBearingString()));
        tokens.insert(pair<string,string>("daily[visibility]", fc->GetVisibilityString()));
        tokens.insert(pair<string,string>("daily[cloudcover]", IntToString(fc->GetCloudCoverPercent())));
        tokens.insert(pair<string,string>("daily[pressure]", fc->GetPressureString()));
        tokens.insert(pair<string,string>("daily[ozone]", fc->GetOzoneString()));
        AddLoopToken("daily", tokens);
    
        plainText << fc->GetDayName() << " " << fc->GetDateString() << ": " <<  fc->GetSummary() << "\n";
        plainText << tr("Minimum Temperature") << ": " << fc->GetTemperatureMinString() << "°C " << tr("at") << " " << fc->GetTemperatureMinTimeString() << " ,";
        plainText << tr("Maximum Temperature") << ": " << fc->GetTemperatureMaxString() << "°C " << tr("at") << " " << fc->GetTemperatureMaxTimeString() << "\n";
        plainText << tr("Precipitation Probability") << ": " << fc->GetPrecipProbabilityPercent() << " %, " << tr("Intensity") << ": " << fc->GetPrecipIntensityString() << " l/qm""\n";
        plainText << tr("Wind") << ": " << fc->GetWindSpeedString() << " km/h, " << fc->GetWindBearing() << "° " << fc->GetWindBearingString() << "\n";
        plainText << tr("Cloud Cover") << ": " << fc->GetCloudCoverPercent() << " %" << "\n";
        plainText << tr("Pressure") << ": " << fc->GetPressureString() << " HPa" << "\n";
        plainText << tr("Ozone") << ": " << fc->GetOzoneString() << " DU" << "\n";
        plainText << "\n";

        fc = daily->GetNext();
    }
    
    SetText(plainText.str().c_str());
    Display();
}