diff options
Diffstat (limited to 'src/pvr/dialogs/GUIDialogPVRTimerSettings.cpp')
-rw-r--r-- | src/pvr/dialogs/GUIDialogPVRTimerSettings.cpp | 528 |
1 files changed, 528 insertions, 0 deletions
diff --git a/src/pvr/dialogs/GUIDialogPVRTimerSettings.cpp b/src/pvr/dialogs/GUIDialogPVRTimerSettings.cpp new file mode 100644 index 0000000000..7fda3d932c --- /dev/null +++ b/src/pvr/dialogs/GUIDialogPVRTimerSettings.cpp @@ -0,0 +1,528 @@ +/* + * Copyright (C) 2012-2014 Team XBMC + * http://xbmc.org + * + * This Program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This Program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with XBMC; see the file COPYING. If not, see + * <http://www.gnu.org/licenses/>. + * + */ + +#include "GUIDialogPVRTimerSettings.h" +#include "FileItem.h" +#include "dialogs/GUIDialogNumeric.h" +#include "guilib/LocalizeStrings.h" +#include "pvr/PVRManager.h" +#include "pvr/addons/PVRClient.h" +#include "pvr/channels/PVRChannelGroupsContainer.h" +#include "pvr/timers/PVRTimerInfoTag.h" +#include "settings/lib/Setting.h" +#include "settings/lib/SettingsManager.h" +#include "settings/windows/GUIControlSettings.h" +#include "utils/log.h" +#include "utils/StringUtils.h" + +using namespace PVR; + +#define SETTING_TMR_ACTIVE "timer.active" +#define SETTING_TMR_CHNAME_TV "timer.tvchannelname" +#define SETTING_TMR_DAY "timer.day" +#define SETTING_TMR_BEGIN "timer.begin" +#define SETTING_TMR_END "timer.end" +#define SETTING_TMR_PRIORITY "timer.priority" +#define SETTING_TMR_LIFETIME "timer.lifetime" +#define SETTING_TMR_FIRST_DAY "timer.firstday" +#define SETTING_TMR_NAME "timer.name" +#define SETTING_TMR_DIR "timer.directory" +#define SETTING_TMR_RADIO "timer.radio" +#define SETTING_TMR_CHNAME_RADIO "timer.radiochannelname" + +CGUIDialogPVRTimerSettings::CGUIDialogPVRTimerSettings(void) + : CGUIDialogSettingsManualBase(WINDOW_DIALOG_PVR_TIMER_SETTING, "DialogPVRTimerSettings.xml"), + m_tmp_iFirstDay(0), + m_tmp_day(11), + m_bTimerActive(false), + m_timerItem(NULL) +{ + m_loadType = LOAD_EVERY_TIME; +} + +void CGUIDialogPVRTimerSettings::SetTimer(CFileItem *item) +{ + m_timerItem = item; + + m_timerItem->GetPVRTimerInfoTag()->StartAsLocalTime().GetAsSystemTime(m_timerStartTime); + m_timerItem->GetPVRTimerInfoTag()->EndAsLocalTime().GetAsSystemTime(m_timerEndTime); + m_timerStartTimeStr = m_timerItem->GetPVRTimerInfoTag()->StartAsLocalTime().GetAsLocalizedTime("", false); + m_timerEndTimeStr = m_timerItem->GetPVRTimerInfoTag()->EndAsLocalTime().GetAsLocalizedTime("", false); + + m_tmp_iFirstDay = 0; + m_tmp_day = 11; +} + +void CGUIDialogPVRTimerSettings::OnSettingChanged(const CSetting *setting) +{ + if (setting == NULL) + return; + + CGUIDialogSettingsManualBase::OnSettingChanged(setting); + + CPVRTimerInfoTag* tag = m_timerItem->GetPVRTimerInfoTag(); + if (tag == NULL) + return; + + const std::string &settingId = setting->GetId(); + if (settingId == SETTING_TMR_ACTIVE) + m_bTimerActive = static_cast<const CSettingBool*>(setting)->GetValue(); + if (settingId == SETTING_TMR_RADIO || settingId == SETTING_TMR_CHNAME_TV || settingId == SETTING_TMR_CHNAME_RADIO) + { + if (settingId == SETTING_TMR_RADIO) + { + tag->m_bIsRadio = static_cast<const CSettingBool*>(setting)->GetValue(); + m_selectedChannelEntry = 0; + } + else + m_selectedChannelEntry = static_cast<const CSettingInt*>(setting)->GetValue(); + + std::map<std::pair<bool, int>, int>::iterator itc = m_channelEntries.find(std::make_pair(tag->m_bIsRadio, m_selectedChannelEntry)); + if (itc != m_channelEntries.end()) + { + CPVRChannelPtr channel = g_PVRChannelGroups->GetChannelById(itc->second); + if (channel) + { + tag->m_iClientChannelUid = channel->UniqueID(); + tag->m_iClientId = channel->ClientID(); + tag->m_bIsRadio = channel->IsRadio(); + tag->m_iChannelNumber = channel->ChannelNumber(); + } + else + { + tag->m_iClientChannelUid = PVR_VIRTUAL_CHANNEL_UID; + tag->m_iClientId = PVR_VIRTUAL_CLIENT_ID; + tag->m_iChannelNumber = 0; + } + // Update channel pointer from above values + tag->UpdateChannel(); + } + } + else if (settingId == SETTING_TMR_DAY) + { + m_tmp_day = static_cast<const CSettingInt*>(setting)->GetValue(); + + if (m_tmp_day <= 10) + SetTimerFromWeekdaySetting(*tag); + else + { + CDateTime time = CDateTime::GetCurrentDateTime(); + CDateTime timestart = m_timerStartTime; + CDateTime timestop = m_timerEndTime; + int m_tmp_diff; + + // get diffence of timer in days between today and timer start date + tm time_cur; time.GetAsTm(time_cur); + tm time_tmr; timestart.GetAsTm(time_tmr); + + m_tmp_diff = time_tmr.tm_yday - time_cur.tm_yday; + if (time_tmr.tm_yday - time_cur.tm_yday < 0) + m_tmp_diff = 365; + + CDateTime newStart = timestart + CDateTimeSpan(m_tmp_day - 11 - m_tmp_diff, 0, 0, 0); + CDateTime newEnd = timestop + CDateTimeSpan(m_tmp_day - 11 - m_tmp_diff, 0, 0, 0); + + // add a day to end time if end time is before start time + // TODO: this should be removed after separate end date control was added + if (newEnd < newStart) + newEnd += CDateTimeSpan(1, 0, 0, 0); + + tag->SetStartFromLocalTime(newStart); + tag->SetEndFromLocalTime(newEnd); + + tag->m_bIsRepeating = false; + tag->m_iWeekdays = 0; + } + } + else if (settingId == SETTING_TMR_PRIORITY) + tag->m_iPriority = static_cast<const CSettingInt*>(setting)->GetValue(); + else if (settingId == SETTING_TMR_LIFETIME) + tag->m_iLifetime = static_cast<const CSettingInt*>(setting)->GetValue(); + else if (settingId == SETTING_TMR_FIRST_DAY) + { + m_tmp_iFirstDay = static_cast<const CSettingInt*>(setting)->GetValue(); + + CDateTime newFirstDay; + if (m_tmp_iFirstDay > 0) + newFirstDay = CDateTime::GetCurrentDateTime() + CDateTimeSpan(m_tmp_iFirstDay - 1, 0, 0, 0); + + tag->SetFirstDayFromLocalTime(newFirstDay); + } + else if (settingId == SETTING_TMR_NAME) + tag->m_strTitle = static_cast<const CSettingString*>(setting)->GetValue(); + else if (settingId == SETTING_TMR_DIR) + tag->m_strDirectory = static_cast<const CSettingString*>(setting)->GetValue(); + + tag->UpdateSummary(); +} + +void CGUIDialogPVRTimerSettings::OnSettingAction(const CSetting *setting) +{ + if (setting == NULL) + return; + + CGUIDialogSettingsManualBase::OnSettingAction(setting); + + CPVRTimerInfoTag* tag = m_timerItem->GetPVRTimerInfoTag(); + if (tag == NULL) + return; + + const std::string &settingId = setting->GetId(); + if (settingId == SETTING_TMR_BEGIN) + { + if (CGUIDialogNumeric::ShowAndGetTime(m_timerStartTime, g_localizeStrings.Get(14066))) + { + CDateTime timestart = m_timerStartTime; + int start_day = tag->StartAsLocalTime().GetDay(); + int start_month = tag->StartAsLocalTime().GetMonth(); + int start_year = tag->StartAsLocalTime().GetYear(); + int start_hour = timestart.GetHour(); + int start_minute = timestart.GetMinute(); + CDateTime newStart(start_year, start_month, start_day, start_hour, start_minute, 0); + tag->SetStartFromLocalTime(newStart); + + m_timerStartTimeStr = tag->StartAsLocalTime().GetAsLocalizedTime("", false); + setButtonLabels(); + } + } + else if (settingId == SETTING_TMR_END) + { + if (CGUIDialogNumeric::ShowAndGetTime(m_timerEndTime, g_localizeStrings.Get(14066))) + { + CDateTime timestop = m_timerEndTime; + // TODO: add separate end date control to schedule a show with more then 24 hours + int start_day = tag->StartAsLocalTime().GetDay(); + int start_month = tag->StartAsLocalTime().GetMonth(); + int start_year = tag->StartAsLocalTime().GetYear(); + int start_hour = timestop.GetHour(); + int start_minute = timestop.GetMinute(); + CDateTime newEnd(start_year, start_month, start_day, start_hour, start_minute, 0); + + // add a day to end time if end time is before start time + // TODO: this should be removed after separate end date control was added + if (newEnd < tag->StartAsLocalTime()) + newEnd += CDateTimeSpan(1, 0, 0, 0); + + tag->SetEndFromLocalTime(newEnd); + + m_timerEndTimeStr = tag->EndAsLocalTime().GetAsLocalizedTime("", false); + setButtonLabels(); + } + } + + tag->UpdateSummary(); +} + +void CGUIDialogPVRTimerSettings::Save() +{ + CPVRTimerInfoTag* tag = m_timerItem->GetPVRTimerInfoTag(); + + // Set the timer's title to the channel name if it's 'New Timer' or empty + if (tag->m_strTitle == g_localizeStrings.Get(19056) || tag->m_strTitle.empty()) + { + CPVRChannelPtr channel = g_PVRChannelGroups->GetByUniqueID(tag->m_iClientChannelUid, tag->m_iClientId); + if (channel) + tag->m_strTitle = channel->ChannelName(); + } + + if (m_bTimerActive) + tag->m_state = PVR_TIMER_STATE_SCHEDULED; + else + tag->m_state = PVR_TIMER_STATE_CANCELLED; +} + +void CGUIDialogPVRTimerSettings::SetupView() +{ + CGUIDialogSettingsManualBase::SetupView(); + + setButtonLabels(); +} + +void CGUIDialogPVRTimerSettings::InitializeSettings() +{ + CGUIDialogSettingsManualBase::InitializeSettings(); + + CSettingCategory *category = AddCategory("pvrtimersettings", -1); + if (category == NULL) + { + CLog::Log(LOGERROR, "CGUIDialogPVRTimerSettings: unable to setup settings"); + return; + } + + CSettingGroup *group = AddGroup(category); + if (group == NULL) + { + CLog::Log(LOGERROR, "CGUIDialogPVRTimerSettings: unable to setup settings"); + return; + } + + // add a condition + m_settingsManager->AddCondition("IsTimerDayRepeating", IsTimerDayRepeating); + + CPVRTimerInfoTag* tag = m_timerItem->GetPVRTimerInfoTag(); + + m_selectedChannelEntry = 0; + m_channelEntries.clear(); + m_bTimerActive = tag->IsActive(); + + AddToggle(group, SETTING_TMR_ACTIVE, 19074, 0, m_bTimerActive); + AddEdit(group, SETTING_TMR_NAME, 19075, 0, tag->m_strTitle, false, false, 19097); + + if (tag->SupportsFolders()) + AddEdit(group, SETTING_TMR_DIR, 19076, 0, tag->m_strDirectory, true, false, 19104); + + AddToggle(group, SETTING_TMR_RADIO, 19077, 0, tag->m_bIsRadio); + + /// Channel names + { + // For TV + AddChannelNames(group, false); + + // For Radio + AddChannelNames(group, true); + } + + /// Day + { + // get diffence of timer in days between today and timer start date + tm time_cur; CDateTime::GetCurrentDateTime().GetAsTm(time_cur); + tm time_tmr; tag->StartAsLocalTime().GetAsTm(time_tmr); + + m_tmp_day += time_tmr.tm_yday - time_cur.tm_yday; + if (time_tmr.tm_yday - time_cur.tm_yday < 0) + m_tmp_day += 365; + + SetWeekdaySettingFromTimer(*tag); + + AddSpinner(group, SETTING_TMR_DAY, 19079, 0, m_tmp_day, DaysOptionsFiller); + } + + AddButton(group, SETTING_TMR_BEGIN, 19080, 0); + AddButton(group, SETTING_TMR_END, 19081, 0); + AddSpinner(group, SETTING_TMR_PRIORITY, 19082, 0, tag->m_iPriority, 0, 1, 99); + AddSpinner(group, SETTING_TMR_LIFETIME, 19083, 0, tag->m_iLifetime, 0, 1, 365); + + /// First day + { + CDateTime time = CDateTime::GetCurrentDateTime(); + CDateTime timestart = tag->FirstDayAsLocalTime(); + + // get diffence of timer in days between today and timer start date + if (time < timestart) + { + tm time_cur; time.GetAsTm(time_cur); + tm time_tmr; timestart.GetAsTm(time_tmr); + + m_tmp_iFirstDay += time_tmr.tm_yday - time_cur.tm_yday + 1; + if (time_tmr.tm_yday - time_cur.tm_yday < 0) + m_tmp_iFirstDay += 365; + } + + CSettingInt *settingFirstDay = AddSpinner(group, SETTING_TMR_FIRST_DAY, 19084, 0, m_tmp_iFirstDay, DaysOptionsFiller); + + // define an enable dependency with m_tmp_day <= 10 + CSettingDependency depdendencyFirstDay(SettingDependencyTypeEnable, m_settingsManager); + depdendencyFirstDay.And() + ->Add(CSettingDependencyConditionPtr(new CSettingDependencyCondition("IsTimerDayRepeating", "true", SETTING_TMR_DAY, false, m_settingsManager))); + SettingDependencies deps; + deps.push_back(depdendencyFirstDay); + settingFirstDay->SetDependencies(deps); + } +} + +CSetting* CGUIDialogPVRTimerSettings::AddChannelNames(CSettingGroup *group, bool bRadio) +{ + std::vector< std::pair<std::string, int> > options; + getChannelNames(bRadio, options, m_selectedChannelEntry, true); + + int timerChannelID; + if (m_timerItem->GetPVRTimerInfoTag()->ChannelTag()) + timerChannelID = m_timerItem->GetPVRTimerInfoTag()->ChannelTag()->ChannelID(); + else + timerChannelID = PVR_VIRTUAL_CHANNEL_UID; + + for (std::vector< std::pair<std::string, int> >::const_iterator option = options.begin(); option != options.end(); ++option) + { + std::map<std::pair<bool, int>, int>::const_iterator channelEntry = m_channelEntries.find(std::make_pair(bRadio, option->second)); + if (channelEntry != m_channelEntries.end() && channelEntry->second == timerChannelID) + { + m_selectedChannelEntry = option->second; + break; + } + } + + CSettingInt *setting = AddSpinner(group, bRadio ? SETTING_TMR_CHNAME_RADIO : SETTING_TMR_CHNAME_TV, 19078, 0, m_selectedChannelEntry, ChannelNamesOptionsFiller); + if (setting == NULL) + return NULL; + + // define an enable dependency with tag->m_bIsRadio + CSettingDependency depdendencyIsRadio(SettingDependencyTypeEnable, m_settingsManager); + depdendencyIsRadio.And() + ->Add(CSettingDependencyConditionPtr(new CSettingDependencyCondition(SETTING_TMR_RADIO, "true", SettingDependencyOperatorEquals, !bRadio, m_settingsManager))); + SettingDependencies deps; + deps.push_back(depdendencyIsRadio); + setting->SetDependencies(deps); + + return setting; +} + +void CGUIDialogPVRTimerSettings::SetWeekdaySettingFromTimer(const CPVRTimerInfoTag &timer) +{ + if (timer.m_bIsRepeating) + { + if (timer.m_iWeekdays == 0x01) + m_tmp_day = 0; + else if (timer.m_iWeekdays == 0x02) + m_tmp_day = 1; + else if (timer.m_iWeekdays == 0x04) + m_tmp_day = 2; + else if (timer.m_iWeekdays == 0x08) + m_tmp_day = 3; + else if (timer.m_iWeekdays == 0x10) + m_tmp_day = 4; + else if (timer.m_iWeekdays == 0x20) + m_tmp_day = 5; + else if (timer.m_iWeekdays == 0x40) + m_tmp_day = 6; + else if (timer.m_iWeekdays == 0x1F) + m_tmp_day = 7; + else if (timer.m_iWeekdays == 0x3F) + m_tmp_day = 8; + else if (timer.m_iWeekdays == 0x7F) + m_tmp_day = 9; + else if (timer.m_iWeekdays == 0x60) + m_tmp_day = 10; + } +} + +void CGUIDialogPVRTimerSettings::SetTimerFromWeekdaySetting(CPVRTimerInfoTag &timer) +{ + timer.m_bIsRepeating = true; + + if (m_tmp_day == 0) + timer.m_iWeekdays = 0x01; + else if (m_tmp_day == 1) + timer.m_iWeekdays = 0x02; + else if (m_tmp_day == 2) + timer.m_iWeekdays = 0x04; + else if (m_tmp_day == 3) + timer.m_iWeekdays = 0x08; + else if (m_tmp_day == 4) + timer.m_iWeekdays = 0x10; + else if (m_tmp_day == 5) + timer.m_iWeekdays = 0x20; + else if (m_tmp_day == 6) + timer.m_iWeekdays = 0x40; + else if (m_tmp_day == 7) + timer.m_iWeekdays = 0x1F; + else if (m_tmp_day == 8) + timer.m_iWeekdays = 0x3F; + else if (m_tmp_day == 9) + timer.m_iWeekdays = 0x7F; + else if (m_tmp_day == 10) + timer.m_iWeekdays = 0x60; + else + timer.m_iWeekdays = 0; +} + +void CGUIDialogPVRTimerSettings::getChannelNames(bool bRadio, std::vector< std::pair<std::string, int> > &list, int ¤t, bool updateChannelEntries /* = false */) +{ + CFileItemList channelsList; + g_PVRChannelGroups->GetGroupAll(bRadio)->GetMembers(channelsList); + + int entry = 0; + list.push_back(std::make_pair("0 dummy", entry)); + if (updateChannelEntries) + m_channelEntries.insert(std::make_pair(std::make_pair(bRadio, entry), PVR_VIRTUAL_CHANNEL_UID)); + ++entry; + + for (int i = 0; i < channelsList.Size(); i++) + { + const CPVRChannel *channel = channelsList[i]->GetPVRChannelInfoTag(); + + list.push_back(std::make_pair(StringUtils::Format("%i %s", channel->ChannelNumber(), channel->ChannelName().c_str()), entry)); + if (updateChannelEntries) + m_channelEntries.insert(std::make_pair(std::make_pair(bRadio, entry), channel->ChannelID())); + ++entry; + } +} + +void CGUIDialogPVRTimerSettings::setButtonLabels() +{ + // timer start time + BaseSettingControlPtr settingControl = GetSettingControl(SETTING_TMR_BEGIN); + if (settingControl != NULL && settingControl->GetControl() != NULL) + SET_CONTROL_LABEL2(settingControl->GetID(), m_timerStartTimeStr); + + // timer end time + settingControl = GetSettingControl(SETTING_TMR_END); + if (settingControl != NULL && settingControl->GetControl() != NULL) + SET_CONTROL_LABEL2(settingControl->GetID(), m_timerEndTimeStr); +} + + bool CGUIDialogPVRTimerSettings::IsTimerDayRepeating(const std::string &condition, const std::string &value, const CSetting *setting) + { + if (setting == NULL || setting->GetType() != SettingTypeInteger) + return false; + + bool result = static_cast<const CSettingInt*>(setting)->GetValue() <= 10; + return result == StringUtils::EqualsNoCase(value, "true"); + } + +void CGUIDialogPVRTimerSettings::ChannelNamesOptionsFiller(const CSetting *setting, std::vector< std::pair<std::string, int> > &list, int ¤t, void *data) +{ + if (data == NULL) + return; + + CGUIDialogPVRTimerSettings *dialog = static_cast<CGUIDialogPVRTimerSettings*>(data); + if (dialog == NULL) + return; + + dialog->getChannelNames(setting->GetId() == SETTING_TMR_CHNAME_RADIO, list, current, false); +} + +void CGUIDialogPVRTimerSettings::DaysOptionsFiller(const CSetting *setting, std::vector< std::pair<std::string, int> > &list, int ¤t, void *data) +{ + if (setting == NULL || data == NULL) + return; + + CGUIDialogPVRTimerSettings *dialog = static_cast<CGUIDialogPVRTimerSettings*>(data); + if (dialog == NULL) + return; + + const CPVRTimerInfoTag *tag = dialog->m_timerItem->GetPVRTimerInfoTag(); + if (tag == NULL) + return; + + if (setting->GetId() == SETTING_TMR_DAY) + { + for (unsigned int iDayPtr = 19086; iDayPtr <= 19096; iDayPtr++) + list.push_back(std::make_pair(g_localizeStrings.Get(iDayPtr), list.size())); + } + else if (setting->GetId() == SETTING_TMR_FIRST_DAY) + list.push_back(std::make_pair(g_localizeStrings.Get(19030), 0)); + + CDateTime time = CDateTime::GetCurrentDateTime(); + for (int i = 1; i < 365; ++i) + { + list.push_back(std::make_pair(time.GetAsLocalizedDate(), list.size())); + time += CDateTimeSpan(1, 0, 0, 0); + } +} |