/* * Copyright (C) 2005-2018 Team Kodi * This file is part of Kodi - https://kodi.tv * * SPDX-License-Identifier: GPL-2.0-or-later * See LICENSES/README.md for more information. */ #include "GUIWindowWeather.h" #include "GUIUserMessages.h" #include "LangInfo.h" #include "ServiceBroker.h" #include "guilib/WindowIDs.h" #include "utils/StringUtils.h" #include "utils/URIUtils.h" #include "utils/Variant.h" #include "weather/WeatherManager.h" #include using namespace ADDON; #define CONTROL_BTNREFRESH 2 #define CONTROL_SELECTLOCATION 3 #define CONTROL_LABELUPDATED 11 #define CONTROL_STATICTEMP 223 #define CONTROL_STATICFEEL 224 #define CONTROL_STATICUVID 225 #define CONTROL_STATICWIND 226 #define CONTROL_STATICDEWP 227 #define CONTROL_STATICHUMI 228 #define CONTROL_LABELD0DAY 31 #define CONTROL_LABELD0HI 32 #define CONTROL_LABELD0LOW 33 #define CONTROL_LABELD0GEN 34 #define CONTROL_IMAGED0IMG 35 #define LOCALIZED_TOKEN_FIRSTID 370 #define LOCALIZED_TOKEN_LASTID 395 /* FIXME'S >strings are not centered */ CGUIWindowWeather::CGUIWindowWeather(void) : CGUIWindow(WINDOW_WEATHER, "MyWeather.xml") { m_loadType = KEEP_IN_MEMORY; } CGUIWindowWeather::~CGUIWindowWeather(void) = default; bool CGUIWindowWeather::OnMessage(CGUIMessage& message) { switch ( message.GetMessage() ) { case GUI_MSG_CLICKED: { int iControl = message.GetSenderId(); if (iControl == CONTROL_BTNREFRESH) { CServiceBroker::GetWeatherManager().Refresh(); // Refresh clicked so do a complete update } else if (iControl == CONTROL_SELECTLOCATION) { CGUIMessage msg(GUI_MSG_ITEM_SELECTED,GetID(),CONTROL_SELECTLOCATION); OnMessage(msg); SetLocation(msg.GetParam1()); } } break; case GUI_MSG_NOTIFY_ALL: if (message.GetParam1() == GUI_MSG_WINDOW_RESET) { CServiceBroker::GetWeatherManager().Reset(); return true; } else if (message.GetParam1() == GUI_MSG_WEATHER_FETCHED) { UpdateLocations(); SetProperties(); } break; case GUI_MSG_ITEM_SELECT: { if (message.GetSenderId() == 0) //handle only message from builtin { SetLocation(message.GetParam1()); return true; } } break; case GUI_MSG_MOVE_OFFSET: { if (message.GetSenderId() == 0 && m_maxLocation > 0) //handle only message from builtin { // Clamp location between 1 and m_maxLocation int v = (CServiceBroker::GetWeatherManager().GetArea() + message.GetParam1() - 1) % m_maxLocation + 1; if (v < 1) v += m_maxLocation; SetLocation(v); return true; } } break; default: break; } return CGUIWindow::OnMessage(message); } void CGUIWindowWeather::OnInitWindow() { // call UpdateButtons() so that we start with our initial stuff already present UpdateButtons(); UpdateLocations(); CGUIWindow::OnInitWindow(); } void CGUIWindowWeather::UpdateLocations() { if (!IsActive()) return; m_maxLocation = strtol(GetProperty("Locations").asString().c_str(),0,10); if (m_maxLocation < 1) return; std::vector< std::pair > labels; unsigned int iCurWeather = CServiceBroker::GetWeatherManager().GetArea(); if (iCurWeather > m_maxLocation) { CServiceBroker::GetWeatherManager().SetArea(m_maxLocation); iCurWeather = m_maxLocation; ClearProperties(); CServiceBroker::GetWeatherManager().Refresh(); } for (unsigned int i = 1; i <= m_maxLocation; i++) { std::string strLabel = CServiceBroker::GetWeatherManager().GetLocation(i); if (strLabel.size() > 1) //got the location string yet? { size_t iPos = strLabel.rfind(", "); if (iPos != std::string::npos) { std::string strLabel2(strLabel); strLabel = strLabel2.substr(0,iPos); } labels.emplace_back(strLabel, i); } else { strLabel = StringUtils::Format("AreaCode {}", i); labels.emplace_back(strLabel, i); } // in case it's a button, set the label if (i == iCurWeather) SET_CONTROL_LABEL(CONTROL_SELECTLOCATION,strLabel); } SET_CONTROL_LABELS(CONTROL_SELECTLOCATION, iCurWeather, &labels); } void CGUIWindowWeather::UpdateButtons() { CONTROL_ENABLE(CONTROL_BTNREFRESH); SET_CONTROL_LABEL(CONTROL_BTNREFRESH, 184); //Refresh SET_CONTROL_LABEL(WEATHER_LABEL_LOCATION, CServiceBroker::GetWeatherManager().GetLocation(CServiceBroker::GetWeatherManager().GetArea())); SET_CONTROL_LABEL(CONTROL_LABELUPDATED, CServiceBroker::GetWeatherManager().GetLastUpdateTime()); SET_CONTROL_LABEL(WEATHER_LABEL_CURRENT_COND, CServiceBroker::GetWeatherManager().GetInfo(WEATHER_LABEL_CURRENT_COND)); SET_CONTROL_LABEL(WEATHER_LABEL_CURRENT_TEMP, CServiceBroker::GetWeatherManager().GetInfo(WEATHER_LABEL_CURRENT_TEMP) + g_langInfo.GetTemperatureUnitString()); SET_CONTROL_LABEL(WEATHER_LABEL_CURRENT_FEEL, CServiceBroker::GetWeatherManager().GetInfo(WEATHER_LABEL_CURRENT_FEEL) + g_langInfo.GetTemperatureUnitString()); SET_CONTROL_LABEL(WEATHER_LABEL_CURRENT_UVID, CServiceBroker::GetWeatherManager().GetInfo(WEATHER_LABEL_CURRENT_UVID)); SET_CONTROL_LABEL(WEATHER_LABEL_CURRENT_WIND, CServiceBroker::GetWeatherManager().GetInfo(WEATHER_LABEL_CURRENT_WIND)); SET_CONTROL_LABEL(WEATHER_LABEL_CURRENT_DEWP, CServiceBroker::GetWeatherManager().GetInfo(WEATHER_LABEL_CURRENT_DEWP) + g_langInfo.GetTemperatureUnitString()); SET_CONTROL_LABEL(WEATHER_LABEL_CURRENT_HUMI, CServiceBroker::GetWeatherManager().GetInfo(WEATHER_LABEL_CURRENT_HUMI)); SET_CONTROL_FILENAME(WEATHER_IMAGE_CURRENT_ICON, CServiceBroker::GetWeatherManager().GetInfo(WEATHER_IMAGE_CURRENT_ICON)); //static labels SET_CONTROL_LABEL(CONTROL_STATICTEMP, 401); //Temperature SET_CONTROL_LABEL(CONTROL_STATICFEEL, 402); //Feels Like SET_CONTROL_LABEL(CONTROL_STATICUVID, 403); //UV Index SET_CONTROL_LABEL(CONTROL_STATICWIND, 404); //Wind SET_CONTROL_LABEL(CONTROL_STATICDEWP, 405); //Dew Point SET_CONTROL_LABEL(CONTROL_STATICHUMI, 406); //Humidity for (int i = 0; i < NUM_DAYS; i++) { SET_CONTROL_LABEL(CONTROL_LABELD0DAY + (i*10), CServiceBroker::GetWeatherManager().GetForecast(i).m_day); SET_CONTROL_LABEL(CONTROL_LABELD0HI + (i*10), CServiceBroker::GetWeatherManager().GetForecast(i).m_high + g_langInfo.GetTemperatureUnitString()); SET_CONTROL_LABEL(CONTROL_LABELD0LOW + (i*10), CServiceBroker::GetWeatherManager().GetForecast(i).m_low + g_langInfo.GetTemperatureUnitString()); SET_CONTROL_LABEL(CONTROL_LABELD0GEN + (i*10), CServiceBroker::GetWeatherManager().GetForecast(i).m_overview); SET_CONTROL_FILENAME(CONTROL_IMAGED0IMG + (i*10), CServiceBroker::GetWeatherManager().GetForecast(i).m_icon); } } void CGUIWindowWeather::FrameMove() { // update our controls UpdateButtons(); CGUIWindow::FrameMove(); } /*! \brief Sets the location to the specified index and refreshes the weather \param loc the location index (in the range [1..MAXLOCATION]) */ void CGUIWindowWeather::SetLocation(int loc) { if (loc < 1 || loc > (int)m_maxLocation) return; // Avoid a settings write if old location == new location if (CServiceBroker::GetWeatherManager().GetArea() != loc) { ClearProperties(); CServiceBroker::GetWeatherManager().SetArea(loc); std::string strLabel = CServiceBroker::GetWeatherManager().GetLocation(loc); size_t iPos = strLabel.rfind(", "); if (iPos != std::string::npos) strLabel = strLabel.substr(0, iPos); SET_CONTROL_LABEL(CONTROL_SELECTLOCATION, strLabel); } CServiceBroker::GetWeatherManager().Refresh(); } void CGUIWindowWeather::SetProperties() { // Current weather int iCurWeather = CServiceBroker::GetWeatherManager().GetArea(); SetProperty("Location", CServiceBroker::GetWeatherManager().GetLocation(iCurWeather)); SetProperty("LocationIndex", iCurWeather); SetProperty("Updated", CServiceBroker::GetWeatherManager().GetLastUpdateTime()); SetProperty("Current.ConditionIcon", CServiceBroker::GetWeatherManager().GetInfo(WEATHER_IMAGE_CURRENT_ICON)); SetProperty("Current.Condition", CServiceBroker::GetWeatherManager().GetInfo(WEATHER_LABEL_CURRENT_COND)); SetProperty("Current.Temperature", CServiceBroker::GetWeatherManager().GetInfo(WEATHER_LABEL_CURRENT_TEMP)); SetProperty("Current.FeelsLike", CServiceBroker::GetWeatherManager().GetInfo(WEATHER_LABEL_CURRENT_FEEL)); SetProperty("Current.UVIndex", CServiceBroker::GetWeatherManager().GetInfo(WEATHER_LABEL_CURRENT_UVID)); SetProperty("Current.Wind", CServiceBroker::GetWeatherManager().GetInfo(WEATHER_LABEL_CURRENT_WIND)); SetProperty("Current.DewPoint", CServiceBroker::GetWeatherManager().GetInfo(WEATHER_LABEL_CURRENT_DEWP)); SetProperty("Current.Humidity", CServiceBroker::GetWeatherManager().GetInfo(WEATHER_LABEL_CURRENT_HUMI)); // we use the icons code number for fanart as it's the safest way std::string fanartcode = URIUtils::GetFileName(CServiceBroker::GetWeatherManager().GetInfo(WEATHER_IMAGE_CURRENT_ICON)); URIUtils::RemoveExtension(fanartcode); SetProperty("Current.FanartCode", fanartcode); // Future weather std::string day; for (int i = 0; i < NUM_DAYS; i++) { day = StringUtils::Format("Day{}.", i); SetProperty(day + "Title", CServiceBroker::GetWeatherManager().GetForecast(i).m_day); SetProperty(day + "HighTemp", CServiceBroker::GetWeatherManager().GetForecast(i).m_high); SetProperty(day + "LowTemp", CServiceBroker::GetWeatherManager().GetForecast(i).m_low); SetProperty(day + "Outlook", CServiceBroker::GetWeatherManager().GetForecast(i).m_overview); SetProperty(day + "OutlookIcon", CServiceBroker::GetWeatherManager().GetForecast(i).m_icon); fanartcode = URIUtils::GetFileName(CServiceBroker::GetWeatherManager().GetForecast(i).m_icon); URIUtils::RemoveExtension(fanartcode); SetProperty(day + "FanartCode", fanartcode); } } void CGUIWindowWeather::ClearProperties() { // Current weather SetProperty("Location", ""); SetProperty("LocationIndex", ""); SetProperty("Updated", ""); SetProperty("Current.ConditionIcon", ""); SetProperty("Current.Condition", ""); SetProperty("Current.Temperature", ""); SetProperty("Current.FeelsLike", ""); SetProperty("Current.UVIndex", ""); SetProperty("Current.Wind", ""); SetProperty("Current.DewPoint", ""); SetProperty("Current.Humidity", ""); SetProperty("Current.FanartCode", ""); // Future weather std::string day; for (int i = 0; i < NUM_DAYS; i++) { day = StringUtils::Format("Day{}.", i); SetProperty(day + "Title", ""); SetProperty(day + "HighTemp", ""); SetProperty(day + "LowTemp", ""); SetProperty(day + "Outlook", ""); SetProperty(day + "OutlookIcon", ""); SetProperty(day + "FanartCode", ""); } }