changed: don't include event.h in stdafx.h
[xbmc:xbmc-antiquated.git] / xbmc / GUIWindowWeather.cpp
1 /*
2  *      Copyright (C) 2005-2008 Team XBMC
3  *      http://www.xbmc.org
4  *
5  *  This Program is free software; you can redistribute it and/or modify
6  *  it under the terms of the GNU General Public License as published by
7  *  the Free Software Foundation; either version 2, or (at your option)
8  *  any later version.
9  *
10  *  This Program is distributed in the hope that it will be useful,
11  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  *  GNU General Public License for more details.
14  *
15  *  You should have received a copy of the GNU General Public License
16  *  along with XBMC; see the file COPYING.  If not, write to
17  *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
18  *  http://www.gnu.org/copyleft/gpl.html
19  *
20  */
21
22 #include "stdafx.h"
23 #include "GUIWindowWeather.h"
24 #include "GUIImage.h"
25 #include "utils/Weather.h"
26 #include "GUISettings.h"
27 #include "GUIWindowManager.h"
28 #include "Util.h"
29 #include "lib/libPython/XBPython.h"
30 #include "LangInfo.h"
31
32 #define CONTROL_BTNREFRESH             2
33 #define CONTROL_SELECTLOCATION         3
34 #define CONTROL_LABELUPDATED          11
35 #define CONTROL_IMAGELOGO            101
36
37 #define CONTROL_STATICTEMP           223
38 #define CONTROL_STATICFEEL           224
39 #define CONTROL_STATICUVID           225
40 #define CONTROL_STATICWIND           226
41 #define CONTROL_STATICDEWP           227
42 #define CONTROL_STATICHUMI           228
43
44 #define CONTROL_LABELD0DAY            31
45 #define CONTROL_LABELD0HI             32
46 #define CONTROL_LABELD0LOW            33
47 #define CONTROL_LABELD0GEN            34
48 #define CONTROL_IMAGED0IMG            35
49
50 #define PARTNER_ID          "1004124588"   //weather.com partner id
51 #define PARTNER_KEY   "079f24145f208494"  //weather.com partner key
52
53 #define MAX_LOCATION                   3
54 #define LOCALIZED_TOKEN_FIRSTID      370
55 #define LOCALIZED_TOKEN_LASTID       395
56
57 DWORD timeToCallPlugin = 1000;
58 /*
59 FIXME'S
60 >strings are not centered
61 >weather.com dev account is mine not a general xbmc one
62 */
63
64 CGUIWindowWeather::CGUIWindowWeather(void)
65     : CGUIWindow(WINDOW_WEATHER, "MyWeather.xml")
66 {
67   m_iCurWeather = 0;
68 #ifdef _USE_ZIP_
69
70
71 #endif
72 }
73
74 CGUIWindowWeather::~CGUIWindowWeather(void)
75 {}
76
77 bool CGUIWindowWeather::OnAction(const CAction &action)
78 {
79   if (action.wID == ACTION_PREVIOUS_MENU)
80   {
81     m_gWindowManager.PreviousWindow();
82     return true;
83   }
84   return CGUIWindow::OnAction(action);
85 }
86
87 bool CGUIWindowWeather::OnMessage(CGUIMessage& message)
88 {
89   switch ( message.GetMessage() )
90   {
91   case GUI_MSG_CLICKED:
92     {
93       int iControl = message.GetSenderId();
94       if (iControl == CONTROL_BTNREFRESH)
95       {
96         Refresh(); // Refresh clicked so do a complete update
97       }
98       else if (iControl == CONTROL_SELECTLOCATION)
99       {
100         // stop the plugin timer here, so the user has a full second
101         if (m_pluginTimer.IsRunning())
102           m_pluginTimer.Stop();
103
104         CGUIMessage msg(GUI_MSG_ITEM_SELECTED,GetID(),CONTROL_SELECTLOCATION);
105         m_gWindowManager.SendMessage(msg);
106         m_iCurWeather = msg.GetParam1();
107
108         CStdString strLabel=g_weatherManager.GetLocation(m_iCurWeather);
109         int iPos = strLabel.ReverseFind(", ");
110         if (iPos)
111         {
112           CStdString strLabel2(strLabel);
113           strLabel = strLabel2.substr(0,iPos);
114         }
115
116         SET_CONTROL_LABEL(CONTROL_SELECTLOCATION,strLabel);
117         Refresh();
118       }
119     }
120     break;
121   case GUI_MSG_NOTIFY_ALL:
122     if (message.GetParam1() == GUI_MSG_WINDOW_RESET)
123     {
124       g_weatherManager.Reset();
125       return true;
126     }
127     else if (message.GetParam1() == GUI_MSG_WEATHER_FETCHED)
128     {
129       UpdateLocations();
130       SetProperties();
131       if (m_gWindowManager.GetActiveWindow() == WINDOW_WEATHER)
132       {
133         if (!g_guiSettings.GetString("weather.plugin").IsEmpty())
134           m_pluginTimer.StartZero();
135       }
136       else
137         CallPlugin();
138     }
139     break;
140   }
141
142   return CGUIWindow::OnMessage(message);
143 }
144
145 void CGUIWindowWeather::OnInitWindow()
146 {
147   // call UpdateButtons() so that we start with our initial stuff already present
148   UpdateButtons();
149   UpdateLocations();
150   CGUIWindow::OnInitWindow();
151 }
152
153 void CGUIWindowWeather::UpdateLocations()
154 {
155   if (!IsActive()) return;
156
157   CGUIMessage msg(GUI_MSG_LABEL_RESET,GetID(),CONTROL_SELECTLOCATION);
158   g_graphicsContext.SendMessage(msg);
159   CGUIMessage msg2(GUI_MSG_LABEL_ADD,GetID(),CONTROL_SELECTLOCATION);
160
161   for (unsigned int i = 0; i < MAX_LOCATION; i++)
162   {
163     char *szLocation = g_weatherManager.GetLocation(i);
164     if (!szLocation) continue;
165     CStdString strLabel(szLocation);
166     if (strlen(szLocation) > 1) //got the location string yet?
167     {
168       int iPos = strLabel.ReverseFind(", ");
169       if (iPos)
170       {
171         CStdString strLabel2(strLabel);
172         strLabel = strLabel2.substr(0,iPos);
173       }
174       msg2.SetParam1(i);
175       msg2.SetLabel(strLabel);
176       g_graphicsContext.SendMessage(msg2);
177     }
178     else
179     {
180       strLabel.Format("AreaCode %i", i + 1);
181
182       msg2.SetLabel(strLabel);
183       msg2.SetParam1(i);
184       g_graphicsContext.SendMessage(msg2);
185     }
186     if (i==m_iCurWeather)
187       SET_CONTROL_LABEL(CONTROL_SELECTLOCATION,strLabel);
188   }
189
190   CONTROL_SELECT_ITEM(CONTROL_SELECTLOCATION, m_iCurWeather);
191 }
192
193 void CGUIWindowWeather::UpdateButtons()
194 {
195   // disable refresh button if internet lookups are disabled
196   if (g_guiSettings.GetBool("network.enableinternet"))
197   {
198     CONTROL_ENABLE(CONTROL_BTNREFRESH);
199   }
200   else
201   {
202     CONTROL_DISABLE(CONTROL_BTNREFRESH);
203   }
204
205   SET_CONTROL_LABEL(CONTROL_BTNREFRESH, 184);   //Refresh
206
207   SET_CONTROL_LABEL(WEATHER_LABEL_LOCATION, g_weatherManager.GetLocation(m_iCurWeather));
208   SET_CONTROL_LABEL(CONTROL_LABELUPDATED, g_weatherManager.GetLastUpdateTime());
209
210   SET_CONTROL_LABEL(WEATHER_LABEL_CURRENT_COND, g_weatherManager.GetInfo(WEATHER_LABEL_CURRENT_COND));
211   SET_CONTROL_LABEL(WEATHER_LABEL_CURRENT_TEMP, g_weatherManager.GetInfo(WEATHER_LABEL_CURRENT_TEMP) + g_langInfo.GetTempUnitString());
212   SET_CONTROL_LABEL(WEATHER_LABEL_CURRENT_FEEL, g_weatherManager.GetInfo(WEATHER_LABEL_CURRENT_FEEL) + g_langInfo.GetTempUnitString());
213   SET_CONTROL_LABEL(WEATHER_LABEL_CURRENT_UVID, g_weatherManager.GetInfo(WEATHER_LABEL_CURRENT_UVID));
214   SET_CONTROL_LABEL(WEATHER_LABEL_CURRENT_WIND, g_weatherManager.GetInfo(WEATHER_LABEL_CURRENT_WIND));
215   SET_CONTROL_LABEL(WEATHER_LABEL_CURRENT_DEWP, g_weatherManager.GetInfo(WEATHER_LABEL_CURRENT_DEWP) + g_langInfo.GetTempUnitString());
216   SET_CONTROL_LABEL(WEATHER_LABEL_CURRENT_HUMI, g_weatherManager.GetInfo(WEATHER_LABEL_CURRENT_HUMI));
217
218   CGUIImage *pImage = (CGUIImage *)GetControl(WEATHER_IMAGE_CURRENT_ICON);
219   if (pImage) pImage->SetFileName(g_weatherManager.GetInfo(WEATHER_IMAGE_CURRENT_ICON));
220
221   //static labels
222   SET_CONTROL_LABEL(CONTROL_STATICTEMP, 401);  //Temperature
223   SET_CONTROL_LABEL(CONTROL_STATICFEEL, 402);  //Feels Like
224   SET_CONTROL_LABEL(CONTROL_STATICUVID, 403);  //UV Index
225   SET_CONTROL_LABEL(CONTROL_STATICWIND, 404);  //Wind
226   SET_CONTROL_LABEL(CONTROL_STATICDEWP, 405);  //Dew Point
227   SET_CONTROL_LABEL(CONTROL_STATICHUMI, 406);  //Humidity
228
229   for (int i = 0; i < NUM_DAYS; i++)
230   {
231     SET_CONTROL_LABEL(CONTROL_LABELD0DAY + (i*10), g_weatherManager.m_dfForcast[i].m_szDay);
232     SET_CONTROL_LABEL(CONTROL_LABELD0HI + (i*10), g_weatherManager.m_dfForcast[i].m_szHigh + g_langInfo.GetTempUnitString());
233     SET_CONTROL_LABEL(CONTROL_LABELD0LOW + (i*10), g_weatherManager.m_dfForcast[i].m_szLow + g_langInfo.GetTempUnitString());
234     SET_CONTROL_LABEL(CONTROL_LABELD0GEN + (i*10), g_weatherManager.m_dfForcast[i].m_szOverview);
235     pImage = (CGUIImage *)GetControl(CONTROL_IMAGED0IMG + (i * 10));
236     if (pImage) pImage->SetFileName(g_weatherManager.m_dfForcast[i].m_szIcon);
237   }
238 }
239
240 void CGUIWindowWeather::Render()
241 {
242   // update our controls
243   UpdateButtons();
244
245   // call weather plugin
246   if (m_pluginTimer.IsRunning() && m_pluginTimer.GetElapsedMilliseconds() > timeToCallPlugin)
247   {
248     m_pluginTimer.Stop();
249     CallPlugin();
250   }
251
252   CGUIWindow::Render();
253 }
254
255 //Do a complete download, parse and update
256 void CGUIWindowWeather::Refresh()
257 {
258   // quietly return if Internet lookups are disabled
259   if (!g_guiSettings.GetBool("network.enableinternet")) return ;
260
261   g_weatherManager.SetArea(m_iCurWeather);
262   g_weatherManager.Refresh();
263 }
264
265 void CGUIWindowWeather::SetProperties()
266 {
267   // Current weather
268   SetProperty("Location", g_weatherManager.GetLocation(m_iCurWeather));
269   SetProperty("LocationIndex", int(m_iCurWeather + 1));
270   CStdString strSetting;
271   strSetting.Format("weather.areacode%i", m_iCurWeather + 1);
272   SetProperty("AreaCode", g_weatherManager.GetAreaCode(g_guiSettings.GetString(strSetting)));
273   SetProperty("Updated", g_weatherManager.GetLastUpdateTime());
274   SetProperty("Current.ConditionIcon", g_weatherManager.GetInfo(WEATHER_IMAGE_CURRENT_ICON));
275   SetProperty("Current.Condition", g_weatherManager.GetInfo(WEATHER_LABEL_CURRENT_COND));
276   SetProperty("Current.Temperature", g_weatherManager.GetInfo(WEATHER_LABEL_CURRENT_TEMP));
277   SetProperty("Current.FeelsLike", g_weatherManager.GetInfo(WEATHER_LABEL_CURRENT_FEEL));
278   SetProperty("Current.UVIndex", g_weatherManager.GetInfo(WEATHER_LABEL_CURRENT_UVID));
279   SetProperty("Current.Wind", g_weatherManager.GetInfo(WEATHER_LABEL_CURRENT_WIND));
280   SetProperty("Current.DewPoint", g_weatherManager.GetInfo(WEATHER_LABEL_CURRENT_DEWP));
281   SetProperty("Current.Humidity", g_weatherManager.GetInfo(WEATHER_LABEL_CURRENT_HUMI));
282   // we use the icons code number for fanart as it's the safest way
283   CStdString fanartcode = CUtil::GetFileName(g_weatherManager.GetInfo(WEATHER_IMAGE_CURRENT_ICON));
284   CUtil::RemoveExtension(fanartcode);
285   SetProperty("Current.FanartCode", fanartcode);
286
287   // Future weather
288   CStdString day;
289   for (int i = 0; i < NUM_DAYS; i++)
290   {
291     day.Format("Day%i.", i);
292     SetProperty(day + "Title", g_weatherManager.m_dfForcast[i].m_szDay);
293     SetProperty(day + "HighTemp", g_weatherManager.m_dfForcast[i].m_szHigh);
294     SetProperty(day + "LowTemp", g_weatherManager.m_dfForcast[i].m_szLow);
295     SetProperty(day + "Outlook", g_weatherManager.m_dfForcast[i].m_szOverview);
296     SetProperty(day + "OutlookIcon", g_weatherManager.m_dfForcast[i].m_szIcon);
297     fanartcode = CUtil::GetFileName(g_weatherManager.m_dfForcast[i].m_szIcon);
298     CUtil::RemoveExtension(fanartcode);
299     SetProperty(day + "FanartCode", fanartcode);
300   }
301 }
302
303 void CGUIWindowWeather::CallPlugin()
304 {
305 #ifdef HAS_PYTHON
306   if (!g_guiSettings.GetString("weather.plugin").IsEmpty())
307   {
308     // create the full path to the plugin
309     CStdString plugin = "special://home/plugins/weather/" + g_guiSettings.GetString("weather.plugin") + "/default.py";
310
311     // initialize our sys.argv variables
312     unsigned int argc = 2;
313     char ** argv = new char*[argc];
314     argv[0] = (char*)plugin.c_str();
315
316     // if plugin is running we wait for another timeout only when in weather window
317     if (m_gWindowManager.GetActiveWindow() == WINDOW_WEATHER)
318     {
319       int id = g_pythonParser.getScriptId(argv[0]);
320       if (id != -1 && g_pythonParser.isRunning(id))
321       {
322         m_pluginTimer.StartZero();
323         return;
324       }
325     }
326
327     // get the current locations area code
328     CStdString strSetting;
329     strSetting.Format("weather.areacode%i", m_iCurWeather + 1);
330     const CStdString &areacode = g_weatherManager.GetAreaCode(g_guiSettings.GetString(strSetting));
331     argv[1] = (char*)areacode.c_str();
332
333     // call our plugin, passing the areacode
334     g_pythonParser.evalFile(argv[0], argc, (const char**)argv);
335
336     CLog::Log(LOGDEBUG, "%s - Weather plugin called: %s (%s)", __FUNCTION__, argv[0], argv[1]);
337   }
338 #endif
339 }