[Windows] Fix driver version detection of AMD RDNA+ GPU on Windows 10
[xbmc.git] / xbmc / pvr / epg / EpgSearchFilter.cpp
blob4d96993a177f5c1c8eefc0fc2065c2ece13e8721
1 /*
2 * Copyright (C) 2012-2018 Team Kodi
3 * This file is part of Kodi - https://kodi.tv
5 * SPDX-License-Identifier: GPL-2.0-or-later
6 * See LICENSES/README.md for more information.
7 */
9 #include "EpgSearchFilter.h"
11 #include "ServiceBroker.h"
12 #include "pvr/PVRManager.h"
13 #include "pvr/addons/PVRClients.h"
14 #include "pvr/channels/PVRChannel.h"
15 #include "pvr/channels/PVRChannelGroup.h"
16 #include "pvr/channels/PVRChannelGroups.h"
17 #include "pvr/channels/PVRChannelGroupsContainer.h"
18 #include "pvr/epg/EpgContainer.h"
19 #include "pvr/epg/EpgInfoTag.h"
20 #include "pvr/epg/EpgSearchPath.h"
21 #include "pvr/recordings/PVRRecordings.h"
22 #include "pvr/timers/PVRTimers.h"
23 #include "utils/TextSearch.h"
24 #include "utils/log.h"
26 #include <algorithm>
27 #include <memory>
29 using namespace PVR;
31 CPVREpgSearchFilter::CPVREpgSearchFilter(bool bRadio)
32 : m_bIsRadio(bRadio)
34 Reset();
37 void CPVREpgSearchFilter::Reset()
39 m_searchData.Reset();
40 m_bEpgSearchDataFiltered = false;
42 m_bIsCaseSensitive = false;
43 m_iMinimumDuration = EPG_SEARCH_UNSET;
44 m_iMaximumDuration = EPG_SEARCH_UNSET;
45 m_bRemoveDuplicates = false;
47 /* pvr specific filters */
48 m_iClientID = -1;
49 m_iChannelGroupID = -1;
50 m_iChannelUID = -1;
51 m_bFreeToAirOnly = false;
52 m_bIgnorePresentTimers = true;
53 m_bIgnorePresentRecordings = true;
55 m_groupIdMatches.reset();
57 m_iDatabaseId = -1;
58 m_title.clear();
59 m_lastExecutedDateTime.SetValid(false);
62 std::string CPVREpgSearchFilter::GetPath() const
64 return CPVREpgSearchPath(*this).GetPath();
67 void CPVREpgSearchFilter::SetSearchTerm(const std::string& strSearchTerm)
69 if (m_searchData.m_strSearchTerm != strSearchTerm)
71 m_searchData.m_strSearchTerm = strSearchTerm;
72 m_bChanged = true;
76 void CPVREpgSearchFilter::SetSearchPhrase(const std::string& strSearchPhrase)
78 // match the exact phrase
79 SetSearchTerm("\"" + strSearchPhrase + "\"");
82 void CPVREpgSearchFilter::SetCaseSensitive(bool bIsCaseSensitive)
84 if (m_bIsCaseSensitive != bIsCaseSensitive)
86 m_bIsCaseSensitive = bIsCaseSensitive;
87 m_bChanged = true;
91 void CPVREpgSearchFilter::SetSearchInDescription(bool bSearchInDescription)
93 if (m_searchData.m_bSearchInDescription != bSearchInDescription)
95 m_searchData.m_bSearchInDescription = bSearchInDescription;
96 m_bChanged = true;
100 void CPVREpgSearchFilter::SetGenreType(int iGenreType)
102 if (m_searchData.m_iGenreType != iGenreType)
104 m_searchData.m_iGenreType = iGenreType;
105 m_bChanged = true;
109 void CPVREpgSearchFilter::SetMinimumDuration(int iMinimumDuration)
111 if (m_iMinimumDuration != iMinimumDuration)
113 m_iMinimumDuration = iMinimumDuration;
114 m_bChanged = true;
118 void CPVREpgSearchFilter::SetMaximumDuration(int iMaximumDuration)
120 if (m_iMaximumDuration != iMaximumDuration)
122 m_iMaximumDuration = iMaximumDuration;
123 m_bChanged = true;
127 void CPVREpgSearchFilter::SetIgnoreFinishedBroadcasts(bool bIgnoreFinishedBroadcasts)
129 if (m_searchData.m_bIgnoreFinishedBroadcasts != bIgnoreFinishedBroadcasts)
131 m_searchData.m_bIgnoreFinishedBroadcasts = bIgnoreFinishedBroadcasts;
132 m_bChanged = true;
136 void CPVREpgSearchFilter::SetIgnoreFutureBroadcasts(bool bIgnoreFutureBroadcasts)
138 if (m_searchData.m_bIgnoreFutureBroadcasts != bIgnoreFutureBroadcasts)
140 m_searchData.m_bIgnoreFutureBroadcasts = bIgnoreFutureBroadcasts;
141 m_bChanged = true;
145 void CPVREpgSearchFilter::SetStartDateTime(const CDateTime& startDateTime)
147 if (m_searchData.m_startDateTime != startDateTime)
149 m_searchData.m_startDateTime = startDateTime;
150 m_bChanged = true;
154 void CPVREpgSearchFilter::SetEndDateTime(const CDateTime& endDateTime)
156 if (m_searchData.m_endDateTime != endDateTime)
158 m_searchData.m_endDateTime = endDateTime;
159 m_bChanged = true;
163 void CPVREpgSearchFilter::SetIncludeUnknownGenres(bool bIncludeUnknownGenres)
165 if (m_searchData.m_bIncludeUnknownGenres != bIncludeUnknownGenres)
167 m_searchData.m_bIncludeUnknownGenres = bIncludeUnknownGenres;
168 m_bChanged = true;
172 void CPVREpgSearchFilter::SetRemoveDuplicates(bool bRemoveDuplicates)
174 if (m_bRemoveDuplicates != bRemoveDuplicates)
176 m_bRemoveDuplicates = bRemoveDuplicates;
177 m_bChanged = true;
181 void CPVREpgSearchFilter::SetClientID(int iClientID)
183 if (m_iClientID != iClientID)
185 m_iClientID = iClientID;
186 m_bChanged = true;
190 void CPVREpgSearchFilter::SetChannelGroupID(int iChannelGroupID)
192 if (m_iChannelGroupID != iChannelGroupID)
194 m_iChannelGroupID = iChannelGroupID;
195 m_groupIdMatches.reset();
196 m_bChanged = true;
200 void CPVREpgSearchFilter::SetChannelUID(int iChannelUID)
202 if (m_iChannelUID != iChannelUID)
204 m_iChannelUID = iChannelUID;
205 m_bChanged = true;
209 void CPVREpgSearchFilter::SetFreeToAirOnly(bool bFreeToAirOnly)
211 if (m_bFreeToAirOnly != bFreeToAirOnly)
213 m_bFreeToAirOnly = bFreeToAirOnly;
214 m_bChanged = true;
218 void CPVREpgSearchFilter::SetIgnorePresentTimers(bool bIgnorePresentTimers)
220 if (m_bIgnorePresentTimers != bIgnorePresentTimers)
222 m_bIgnorePresentTimers = bIgnorePresentTimers;
223 m_bChanged = true;
227 void CPVREpgSearchFilter::SetIgnorePresentRecordings(bool bIgnorePresentRecordings)
229 if (m_bIgnorePresentRecordings != bIgnorePresentRecordings)
231 m_bIgnorePresentRecordings = bIgnorePresentRecordings;
232 m_bChanged = true;
236 void CPVREpgSearchFilter::SetDatabaseId(int iDatabaseId)
238 if (m_iDatabaseId != iDatabaseId)
240 m_iDatabaseId = iDatabaseId;
241 m_bChanged = true;
245 void CPVREpgSearchFilter::SetTitle(const std::string& title)
247 if (m_title != title)
249 m_title = title;
250 m_bChanged = true;
254 void CPVREpgSearchFilter::SetLastExecutedDateTime(const CDateTime& lastExecutedDateTime)
256 // Note: No need to set m_bChanged here
257 m_lastExecutedDateTime = lastExecutedDateTime;
260 bool CPVREpgSearchFilter::MatchGenre(const std::shared_ptr<const CPVREpgInfoTag>& tag) const
262 if (m_bEpgSearchDataFiltered)
263 return true;
265 if (m_searchData.m_iGenreType != EPG_SEARCH_UNSET)
267 if (m_searchData.m_bIncludeUnknownGenres)
269 // match the exact genre and everything with unknown genre
270 return (tag->GenreType() == m_searchData.m_iGenreType ||
271 tag->GenreType() < EPG_EVENT_CONTENTMASK_MOVIEDRAMA ||
272 tag->GenreType() > EPG_EVENT_CONTENTMASK_USERDEFINED);
274 else
276 // match only the exact genre
277 return (tag->GenreType() == m_searchData.m_iGenreType);
281 // match any genre
282 return true;
285 bool CPVREpgSearchFilter::MatchDuration(const std::shared_ptr<const CPVREpgInfoTag>& tag) const
287 bool bReturn(true);
289 if (m_iMinimumDuration != EPG_SEARCH_UNSET)
290 bReturn = (tag->GetDuration() > m_iMinimumDuration * 60);
292 if (bReturn && m_iMaximumDuration != EPG_SEARCH_UNSET)
293 bReturn = (tag->GetDuration() < m_iMaximumDuration * 60);
295 return bReturn;
298 bool CPVREpgSearchFilter::MatchStartAndEndTimes(
299 const std::shared_ptr<const CPVREpgInfoTag>& tag) const
301 if (m_bEpgSearchDataFiltered)
302 return true;
304 return ((!m_searchData.m_bIgnoreFinishedBroadcasts ||
305 tag->EndAsUTC() > CDateTime::GetUTCDateTime()) &&
306 (!m_searchData.m_bIgnoreFutureBroadcasts ||
307 tag->StartAsUTC() < CDateTime::GetUTCDateTime()) &&
308 (!m_searchData.m_startDateTime.IsValid() || // invalid => match any datetime
309 tag->StartAsUTC() >= m_searchData.m_startDateTime) &&
310 (!m_searchData.m_endDateTime.IsValid() || // invalid => match any datetime
311 tag->EndAsUTC() <= m_searchData.m_endDateTime));
314 bool CPVREpgSearchFilter::MatchSearchTerm(const std::shared_ptr<const CPVREpgInfoTag>& tag) const
316 bool bReturn(true);
318 if (!m_searchData.m_strSearchTerm.empty())
320 bReturn = !CServiceBroker::GetPVRManager().IsParentalLocked(tag);
321 if (bReturn && (m_bIsCaseSensitive || !m_bEpgSearchDataFiltered))
323 CTextSearch search(m_searchData.m_strSearchTerm, m_bIsCaseSensitive, SEARCH_DEFAULT_OR);
325 bReturn = search.Search(tag->Title()) || search.Search(tag->PlotOutline()) ||
326 (m_searchData.m_bSearchInDescription && search.Search(tag->Plot()));
330 return bReturn;
333 bool CPVREpgSearchFilter::FilterEntry(const std::shared_ptr<const CPVREpgInfoTag>& tag) const
335 return MatchGenre(tag) && MatchDuration(tag) && MatchStartAndEndTimes(tag) &&
336 MatchSearchTerm(tag) && MatchChannel(tag) && MatchChannelGroup(tag) && MatchTimers(tag) &&
337 MatchRecordings(tag) && MatchFreeToAir(tag);
340 void CPVREpgSearchFilter::RemoveDuplicates(std::vector<std::shared_ptr<CPVREpgInfoTag>>& results)
342 for (auto it = results.begin(); it != results.end();)
344 it = results.erase(std::remove_if(results.begin(), results.end(),
345 [&it](const std::shared_ptr<const CPVREpgInfoTag>& entry) {
346 return *it != entry && (*it)->Title() == entry->Title() &&
347 (*it)->Plot() == entry->Plot() &&
348 (*it)->PlotOutline() == entry->PlotOutline();
350 results.end());
354 bool CPVREpgSearchFilter::MatchChannel(const std::shared_ptr<const CPVREpgInfoTag>& tag) const
356 return tag && (tag->IsRadio() == m_bIsRadio) &&
357 (m_iClientID == -1 || tag->ClientID() == m_iClientID) &&
358 (m_iChannelUID == -1 || tag->UniqueChannelID() == m_iChannelUID) &&
359 CServiceBroker::GetPVRManager().Clients()->IsCreatedClient(tag->ClientID());
362 bool CPVREpgSearchFilter::MatchChannelGroup(const std::shared_ptr<const CPVREpgInfoTag>& tag) const
364 if (m_iChannelGroupID != -1)
366 if (!m_groupIdMatches.has_value())
368 const std::shared_ptr<const CPVRChannelGroup> group = CServiceBroker::GetPVRManager()
369 .ChannelGroups()
370 ->Get(m_bIsRadio)
371 ->GetById(m_iChannelGroupID);
372 m_groupIdMatches =
373 group && (group->GetByUniqueID({tag->ClientID(), tag->UniqueChannelID()}) != nullptr);
376 return *m_groupIdMatches;
379 return true;
382 bool CPVREpgSearchFilter::MatchFreeToAir(const std::shared_ptr<const CPVREpgInfoTag>& tag) const
384 if (m_bFreeToAirOnly)
386 const std::shared_ptr<const CPVRChannel> channel =
387 CServiceBroker::GetPVRManager().ChannelGroups()->GetChannelForEpgTag(tag);
388 return channel && !channel->IsEncrypted();
391 return true;
394 bool CPVREpgSearchFilter::MatchTimers(const std::shared_ptr<const CPVREpgInfoTag>& tag) const
396 return (!m_bIgnorePresentTimers || !CServiceBroker::GetPVRManager().Timers()->GetTimerForEpgTag(tag));
399 bool CPVREpgSearchFilter::MatchRecordings(const std::shared_ptr<const CPVREpgInfoTag>& tag) const
401 return (!m_bIgnorePresentRecordings || !CServiceBroker::GetPVRManager().Recordings()->GetRecordingForEpgTag(tag));