summaryrefslogtreecommitdiffstats
path: root/xbmc/pvr/dialogs/GUIDialogPVRGuideSearch.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'xbmc/pvr/dialogs/GUIDialogPVRGuideSearch.cpp')
-rw-r--r--xbmc/pvr/dialogs/GUIDialogPVRGuideSearch.cpp391
1 files changed, 391 insertions, 0 deletions
diff --git a/xbmc/pvr/dialogs/GUIDialogPVRGuideSearch.cpp b/xbmc/pvr/dialogs/GUIDialogPVRGuideSearch.cpp
new file mode 100644
index 0000000..4cf7f2f
--- /dev/null
+++ b/xbmc/pvr/dialogs/GUIDialogPVRGuideSearch.cpp
@@ -0,0 +1,391 @@
+/*
+ * Copyright (C) 2012-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 "GUIDialogPVRGuideSearch.h"
+
+#include "ServiceBroker.h"
+#include "guilib/GUIEditControl.h"
+#include "guilib/GUIKeyboardFactory.h"
+#include "guilib/GUIMessage.h"
+#include "guilib/LocalizeStrings.h"
+#include "pvr/PVRManager.h"
+#include "pvr/channels/PVRChannel.h"
+#include "pvr/channels/PVRChannelGroupMember.h"
+#include "pvr/channels/PVRChannelGroups.h"
+#include "pvr/channels/PVRChannelGroupsContainer.h"
+#include "pvr/epg/EpgContainer.h"
+#include "pvr/epg/EpgSearchFilter.h"
+#include "utils/StringUtils.h"
+
+#include <string>
+#include <utility>
+#include <vector>
+
+using namespace PVR;
+
+#define CONTROL_EDIT_SEARCH 9
+#define CONTROL_BTN_INC_DESC 10
+#define CONTROL_BTN_CASE_SENS 11
+#define CONTROL_SPIN_MIN_DURATION 12
+#define CONTROL_SPIN_MAX_DURATION 13
+#define CONTROL_EDIT_START_DATE 14
+#define CONTROL_EDIT_STOP_DATE 15
+#define CONTROL_EDIT_START_TIME 16
+#define CONTROL_EDIT_STOP_TIME 17
+#define CONTROL_SPIN_GENRE 18
+#define CONTROL_SPIN_NO_REPEATS 19
+#define CONTROL_BTN_UNK_GENRE 20
+#define CONTROL_SPIN_GROUPS 21
+#define CONTROL_BTN_FTA_ONLY 22
+#define CONTROL_SPIN_CHANNELS 23
+#define CONTROL_BTN_IGNORE_TMR 24
+#define CONTROL_BTN_CANCEL 25
+#define CONTROL_BTN_SEARCH 26
+#define CONTROL_BTN_IGNORE_REC 27
+#define CONTROL_BTN_DEFAULTS 28
+static constexpr int CONTROL_BTN_SAVE = 29;
+static constexpr int CONTROL_BTN_IGNORE_FINISHED = 30;
+static constexpr int CONTROL_BTN_IGNORE_FUTURE = 31;
+
+CGUIDialogPVRGuideSearch::CGUIDialogPVRGuideSearch()
+ : CGUIDialog(WINDOW_DIALOG_PVR_GUIDE_SEARCH, "DialogPVRGuideSearch.xml")
+{
+}
+
+void CGUIDialogPVRGuideSearch::SetFilterData(
+ const std::shared_ptr<CPVREpgSearchFilter>& searchFilter)
+{
+ m_searchFilter = searchFilter;
+}
+
+void CGUIDialogPVRGuideSearch::UpdateChannelSpin()
+{
+ int iChannelGroup = GetSpinValue(CONTROL_SPIN_GROUPS);
+
+ std::vector< std::pair<std::string, int> > labels;
+ if (m_searchFilter->IsRadio())
+ labels.emplace_back(g_localizeStrings.Get(19216), EPG_SEARCH_UNSET); // All radio channels
+ else
+ labels.emplace_back(g_localizeStrings.Get(19217), EPG_SEARCH_UNSET); // All TV channels
+
+ std::shared_ptr<CPVRChannelGroup> group;
+ if (iChannelGroup != EPG_SEARCH_UNSET)
+ group = CServiceBroker::GetPVRManager().ChannelGroups()->GetByIdFromAll(iChannelGroup);
+
+ if (!group)
+ group = CServiceBroker::GetPVRManager().ChannelGroups()->GetGroupAll(m_searchFilter->IsRadio());
+
+ m_channelsMap.clear();
+ const std::vector<std::shared_ptr<CPVRChannelGroupMember>> groupMembers =
+ group->GetMembers(CPVRChannelGroup::Include::ONLY_VISIBLE);
+ int iIndex = 0;
+ int iSelectedChannel = EPG_SEARCH_UNSET;
+ for (const auto& groupMember : groupMembers)
+ {
+ labels.emplace_back(std::make_pair(groupMember->Channel()->ChannelName(), iIndex));
+ m_channelsMap.insert(std::make_pair(iIndex, groupMember));
+
+ if (iSelectedChannel == EPG_SEARCH_UNSET &&
+ groupMember->ChannelUID() == m_searchFilter->GetChannelUID() &&
+ groupMember->ClientID() == m_searchFilter->GetClientID())
+ iSelectedChannel = iIndex;
+
+ ++iIndex;
+ }
+
+ SET_CONTROL_LABELS(CONTROL_SPIN_CHANNELS, iSelectedChannel, &labels);
+}
+
+void CGUIDialogPVRGuideSearch::UpdateGroupsSpin()
+{
+ std::vector<std::pair<std::string, int>> labels;
+ const std::vector<std::shared_ptr<CPVRChannelGroup>> groups =
+ CServiceBroker::GetPVRManager().ChannelGroups()->Get(m_searchFilter->IsRadio())->GetMembers();
+ int selectedGroup = EPG_SEARCH_UNSET;
+ for (const auto& group : groups)
+ {
+ labels.emplace_back(group->GroupName(), group->GroupID());
+
+ if (selectedGroup == EPG_SEARCH_UNSET &&
+ group->GroupID() == m_searchFilter->GetChannelGroupID())
+ selectedGroup = group->GroupID();
+ }
+
+ SET_CONTROL_LABELS(CONTROL_SPIN_GROUPS, selectedGroup, &labels);
+}
+
+void CGUIDialogPVRGuideSearch::UpdateGenreSpin()
+{
+ std::vector< std::pair<std::string, int> > labels;
+ labels.emplace_back(g_localizeStrings.Get(593), EPG_SEARCH_UNSET);
+ labels.emplace_back(g_localizeStrings.Get(19500), EPG_EVENT_CONTENTMASK_MOVIEDRAMA);
+ labels.emplace_back(g_localizeStrings.Get(19516), EPG_EVENT_CONTENTMASK_NEWSCURRENTAFFAIRS);
+ labels.emplace_back(g_localizeStrings.Get(19532), EPG_EVENT_CONTENTMASK_SHOW);
+ labels.emplace_back(g_localizeStrings.Get(19548), EPG_EVENT_CONTENTMASK_SPORTS);
+ labels.emplace_back(g_localizeStrings.Get(19564), EPG_EVENT_CONTENTMASK_CHILDRENYOUTH);
+ labels.emplace_back(g_localizeStrings.Get(19580), EPG_EVENT_CONTENTMASK_MUSICBALLETDANCE);
+ labels.emplace_back(g_localizeStrings.Get(19596), EPG_EVENT_CONTENTMASK_ARTSCULTURE);
+ labels.emplace_back(g_localizeStrings.Get(19612), EPG_EVENT_CONTENTMASK_SOCIALPOLITICALECONOMICS);
+ labels.emplace_back(g_localizeStrings.Get(19628), EPG_EVENT_CONTENTMASK_EDUCATIONALSCIENCE);
+ labels.emplace_back(g_localizeStrings.Get(19644), EPG_EVENT_CONTENTMASK_LEISUREHOBBIES);
+ labels.emplace_back(g_localizeStrings.Get(19660), EPG_EVENT_CONTENTMASK_SPECIAL);
+ labels.emplace_back(g_localizeStrings.Get(19499), EPG_EVENT_CONTENTMASK_USERDEFINED);
+
+ SET_CONTROL_LABELS(CONTROL_SPIN_GENRE, m_searchFilter->GetGenreType(), &labels);
+}
+
+void CGUIDialogPVRGuideSearch::UpdateDurationSpin()
+{
+ /* minimum duration */
+ std::vector< std::pair<std::string, int> > labels;
+
+ labels.emplace_back("-", EPG_SEARCH_UNSET);
+ for (int i = 1; i < 12*60/5; ++i)
+ labels.emplace_back(StringUtils::Format(g_localizeStrings.Get(14044), i * 5), i * 5);
+
+ SET_CONTROL_LABELS(CONTROL_SPIN_MIN_DURATION, m_searchFilter->GetMinimumDuration(), &labels);
+
+ /* maximum duration */
+ labels.clear();
+
+ labels.emplace_back("-", EPG_SEARCH_UNSET);
+ for (int i = 1; i < 12*60/5; ++i)
+ labels.emplace_back(StringUtils::Format(g_localizeStrings.Get(14044), i * 5), i * 5);
+
+ SET_CONTROL_LABELS(CONTROL_SPIN_MAX_DURATION, m_searchFilter->GetMaximumDuration(), &labels);
+}
+
+bool CGUIDialogPVRGuideSearch::OnMessage(CGUIMessage& message)
+{
+ CGUIDialog::OnMessage(message);
+
+ switch (message.GetMessage())
+ {
+ case GUI_MSG_CLICKED:
+ {
+ int iControl = message.GetSenderId();
+ if (iControl == CONTROL_BTN_SEARCH)
+ {
+ // Read data from controls, update m_searchfilter accordingly
+ UpdateSearchFilter();
+
+ m_result = Result::SEARCH;
+ Close();
+ return true;
+ }
+ else if (iControl == CONTROL_BTN_CANCEL)
+ {
+ m_result = Result::CANCEL;
+ Close();
+ return true;
+ }
+ else if (iControl == CONTROL_BTN_DEFAULTS)
+ {
+ if (m_searchFilter)
+ {
+ m_searchFilter->Reset();
+ Update();
+ }
+ return true;
+ }
+ else if (iControl == CONTROL_BTN_SAVE)
+ {
+ // Read data from controls, update m_searchfilter accordingly
+ UpdateSearchFilter();
+
+ std::string title = m_searchFilter->GetTitle();
+ if (title.empty())
+ {
+ title = m_searchFilter->GetSearchTerm();
+ if (title.empty())
+ title = g_localizeStrings.Get(137); // "Search"
+ else
+ StringUtils::Trim(title, "\"");
+
+ if (!CGUIKeyboardFactory::ShowAndGetInput(
+ title, CVariant{g_localizeStrings.Get(528)}, // "Enter title"
+ false))
+ {
+ return false;
+ }
+ m_searchFilter->SetTitle(title);
+ }
+
+ m_result = Result::SAVE;
+ Close();
+ return true;
+ }
+ else if (iControl == CONTROL_SPIN_GROUPS)
+ {
+ UpdateChannelSpin();
+ return true;
+ }
+ }
+ break;
+ }
+
+ return false;
+}
+
+void CGUIDialogPVRGuideSearch::OnInitWindow()
+{
+ CGUIDialog::OnInitWindow();
+
+ m_result = Result::CANCEL;
+}
+
+void CGUIDialogPVRGuideSearch::OnWindowLoaded()
+{
+ Update();
+ return CGUIDialog::OnWindowLoaded();
+}
+
+CDateTime CGUIDialogPVRGuideSearch::ReadDateTime(const std::string& strDate, const std::string& strTime) const
+{
+ CDateTime dateTime;
+ int iHours, iMinutes;
+ sscanf(strTime.c_str(), "%d:%d", &iHours, &iMinutes);
+ dateTime.SetFromDBDate(strDate);
+ dateTime.SetDateTime(dateTime.GetYear(), dateTime.GetMonth(), dateTime.GetDay(), iHours, iMinutes, 0);
+ return dateTime.GetAsUTCDateTime();
+}
+
+bool CGUIDialogPVRGuideSearch::IsRadioSelected(int controlID)
+{
+ CGUIMessage msg(GUI_MSG_IS_SELECTED, GetID(), controlID);
+ OnMessage(msg);
+ return (msg.GetParam1() == 1);
+}
+
+int CGUIDialogPVRGuideSearch::GetSpinValue(int controlID)
+{
+ CGUIMessage msg(GUI_MSG_ITEM_SELECTED, GetID(), controlID);
+ OnMessage(msg);
+ return msg.GetParam1();
+}
+
+std::string CGUIDialogPVRGuideSearch::GetEditValue(int controlID)
+{
+ CGUIMessage msg(GUI_MSG_ITEM_SELECTED, GetID(), controlID);
+ OnMessage(msg);
+ return msg.GetLabel();
+}
+
+void CGUIDialogPVRGuideSearch::UpdateSearchFilter()
+{
+ if (!m_searchFilter)
+ return;
+
+ m_searchFilter->SetSearchTerm(GetEditValue(CONTROL_EDIT_SEARCH));
+
+ m_searchFilter->SetSearchInDescription(IsRadioSelected(CONTROL_BTN_INC_DESC));
+ m_searchFilter->SetCaseSensitive(IsRadioSelected(CONTROL_BTN_CASE_SENS));
+ m_searchFilter->SetFreeToAirOnly(IsRadioSelected(CONTROL_BTN_FTA_ONLY));
+ m_searchFilter->SetIncludeUnknownGenres(IsRadioSelected(CONTROL_BTN_UNK_GENRE));
+ m_searchFilter->SetIgnorePresentRecordings(IsRadioSelected(CONTROL_BTN_IGNORE_REC));
+ m_searchFilter->SetIgnorePresentTimers(IsRadioSelected(CONTROL_BTN_IGNORE_TMR));
+ m_searchFilter->SetRemoveDuplicates(IsRadioSelected(CONTROL_SPIN_NO_REPEATS));
+ m_searchFilter->SetIgnoreFinishedBroadcasts(IsRadioSelected(CONTROL_BTN_IGNORE_FINISHED));
+ m_searchFilter->SetIgnoreFutureBroadcasts(IsRadioSelected(CONTROL_BTN_IGNORE_FUTURE));
+ m_searchFilter->SetGenreType(GetSpinValue(CONTROL_SPIN_GENRE));
+ m_searchFilter->SetMinimumDuration(GetSpinValue(CONTROL_SPIN_MIN_DURATION));
+ m_searchFilter->SetMaximumDuration(GetSpinValue(CONTROL_SPIN_MAX_DURATION));
+
+ auto it = m_channelsMap.find(GetSpinValue(CONTROL_SPIN_CHANNELS));
+ m_searchFilter->SetClientID(it == m_channelsMap.end() ? -1 : (*it).second->ClientID());
+ m_searchFilter->SetChannelUID(it == m_channelsMap.end() ? -1 : (*it).second->ChannelUID());
+ m_searchFilter->SetChannelGroupID(GetSpinValue(CONTROL_SPIN_GROUPS));
+
+ const CDateTime start =
+ ReadDateTime(GetEditValue(CONTROL_EDIT_START_DATE), GetEditValue(CONTROL_EDIT_START_TIME));
+ if (start != m_startDateTime)
+ {
+ m_searchFilter->SetStartDateTime(start);
+ m_startDateTime = start;
+ }
+ const CDateTime end =
+ ReadDateTime(GetEditValue(CONTROL_EDIT_STOP_DATE), GetEditValue(CONTROL_EDIT_STOP_TIME));
+ if (end != m_endDateTime)
+ {
+ m_searchFilter->SetEndDateTime(end);
+ m_endDateTime = end;
+ }
+}
+
+void CGUIDialogPVRGuideSearch::Update()
+{
+ if (!m_searchFilter)
+ return;
+
+ SET_CONTROL_LABEL2(CONTROL_EDIT_SEARCH, m_searchFilter->GetSearchTerm());
+ {
+ CGUIMessage msg(GUI_MSG_SET_TYPE, GetID(), CONTROL_EDIT_SEARCH, CGUIEditControl::INPUT_TYPE_TEXT, 16017);
+ OnMessage(msg);
+ }
+
+ SET_CONTROL_SELECTED(GetID(), CONTROL_BTN_CASE_SENS, m_searchFilter->IsCaseSensitive());
+ SET_CONTROL_SELECTED(GetID(), CONTROL_BTN_INC_DESC, m_searchFilter->ShouldSearchInDescription());
+ SET_CONTROL_SELECTED(GetID(), CONTROL_BTN_FTA_ONLY, m_searchFilter->IsFreeToAirOnly());
+ SET_CONTROL_SELECTED(GetID(), CONTROL_BTN_UNK_GENRE, m_searchFilter->ShouldIncludeUnknownGenres());
+ SET_CONTROL_SELECTED(GetID(), CONTROL_BTN_IGNORE_REC, m_searchFilter->ShouldIgnorePresentRecordings());
+ SET_CONTROL_SELECTED(GetID(), CONTROL_BTN_IGNORE_TMR, m_searchFilter->ShouldIgnorePresentTimers());
+ SET_CONTROL_SELECTED(GetID(), CONTROL_SPIN_NO_REPEATS, m_searchFilter->ShouldRemoveDuplicates());
+ SET_CONTROL_SELECTED(GetID(), CONTROL_BTN_IGNORE_FINISHED,
+ m_searchFilter->ShouldIgnoreFinishedBroadcasts());
+ SET_CONTROL_SELECTED(GetID(), CONTROL_BTN_IGNORE_FUTURE,
+ m_searchFilter->ShouldIgnoreFutureBroadcasts());
+
+ // Set start/end datetime fields
+ m_startDateTime = m_searchFilter->GetStartDateTime();
+ m_endDateTime = m_searchFilter->GetEndDateTime();
+ if (!m_startDateTime.IsValid() || !m_endDateTime.IsValid())
+ {
+ const auto dates = CServiceBroker::GetPVRManager().EpgContainer().GetFirstAndLastEPGDate();
+ if (!m_startDateTime.IsValid())
+ m_startDateTime = dates.first;
+ if (!m_endDateTime.IsValid())
+ m_endDateTime = dates.second;
+ }
+
+ if (!m_startDateTime.IsValid())
+ m_startDateTime = CDateTime::GetUTCDateTime();
+
+ if (!m_endDateTime.IsValid())
+ m_endDateTime = m_startDateTime + CDateTimeSpan(10, 0, 0, 0); // default to start + 10 days
+
+ CDateTime startLocal;
+ startLocal.SetFromUTCDateTime(m_startDateTime);
+ CDateTime endLocal;
+ endLocal.SetFromUTCDateTime(m_endDateTime);
+
+ SET_CONTROL_LABEL2(CONTROL_EDIT_START_TIME, startLocal.GetAsLocalizedTime("", false));
+ {
+ CGUIMessage msg(GUI_MSG_SET_TYPE, GetID(), CONTROL_EDIT_START_TIME, CGUIEditControl::INPUT_TYPE_TIME, 14066);
+ OnMessage(msg);
+ }
+ SET_CONTROL_LABEL2(CONTROL_EDIT_STOP_TIME, endLocal.GetAsLocalizedTime("", false));
+ {
+ CGUIMessage msg(GUI_MSG_SET_TYPE, GetID(), CONTROL_EDIT_STOP_TIME, CGUIEditControl::INPUT_TYPE_TIME, 14066);
+ OnMessage(msg);
+ }
+ SET_CONTROL_LABEL2(CONTROL_EDIT_START_DATE, startLocal.GetAsDBDate());
+ {
+ CGUIMessage msg(GUI_MSG_SET_TYPE, GetID(), CONTROL_EDIT_START_DATE, CGUIEditControl::INPUT_TYPE_DATE, 14067);
+ OnMessage(msg);
+ }
+ SET_CONTROL_LABEL2(CONTROL_EDIT_STOP_DATE, endLocal.GetAsDBDate());
+ {
+ CGUIMessage msg(GUI_MSG_SET_TYPE, GetID(), CONTROL_EDIT_STOP_DATE, CGUIEditControl::INPUT_TYPE_DATE, 14067);
+ OnMessage(msg);
+ }
+
+ UpdateDurationSpin();
+ UpdateGroupsSpin();
+ UpdateChannelSpin();
+ UpdateGenreSpin();
+}