diff options
author | ksooo <3226626+ksooo@users.noreply.github.com> | 2023-10-22 22:58:42 +0200 |
---|---|---|
committer | ksooo <3226626+ksooo@users.noreply.github.com> | 2023-10-23 23:19:18 +0200 |
commit | ad6d9716dc366cb0a32dd0d5b7164d1bb44327e8 (patch) | |
tree | 4bcd6888b185fb429ebd710478e3c0b7065236fa | |
parent | 58bad6f4829ea5de5d7d96080c6e71b693149701 (diff) |
[PVR] Improve recently played channels widget (e.g. respect hidden groups and channels).
-rw-r--r-- | xbmc/pvr/channels/PVRChannelGroup.h | 2 | ||||
-rw-r--r-- | xbmc/pvr/filesystem/PVRGUIDirectory.cpp | 149 |
2 files changed, 115 insertions, 36 deletions
diff --git a/xbmc/pvr/channels/PVRChannelGroup.h b/xbmc/pvr/channels/PVRChannelGroup.h index 605908663a..3792816e53 100644 --- a/xbmc/pvr/channels/PVRChannelGroup.h +++ b/xbmc/pvr/channels/PVRChannelGroup.h @@ -31,6 +31,8 @@ static constexpr int PVR_GROUP_TYPE_LOCAL = 2; static constexpr int PVR_GROUP_CLIENT_ID_UNKNOWN = -2; static constexpr int PVR_GROUP_CLIENT_ID_LOCAL = -1; +static constexpr int PVR_GROUP_ID_UNNKOWN{-1}; + enum class PVREvent; class CPVRChannel; diff --git a/xbmc/pvr/filesystem/PVRGUIDirectory.cpp b/xbmc/pvr/filesystem/PVRGUIDirectory.cpp index 8928cc0539..513a1964b2 100644 --- a/xbmc/pvr/filesystem/PVRGUIDirectory.cpp +++ b/xbmc/pvr/filesystem/PVRGUIDirectory.cpp @@ -458,6 +458,109 @@ bool CPVRGUIDirectory::GetChannelGroupsDirectory(bool bRadio, return false; } +namespace +{ +std::shared_ptr<CPVRChannelGroupMember> GetLastWatchedChannelGroupMember( + const std::shared_ptr<CPVRChannel>& channel) +{ + const int lastGroupId{channel->LastWatchedGroupId()}; + if (lastGroupId != PVR_GROUP_ID_UNNKOWN) + { + const std::shared_ptr<CPVRChannelGroup> lastGroup{ + CServiceBroker::GetPVRManager().ChannelGroups()->GetByIdFromAll(lastGroupId)}; + if (lastGroup && !lastGroup->IsHidden() && !lastGroup->IsDeleted()) + return lastGroup->GetByUniqueID(channel->StorageId()); + } + return {}; +} + +std::shared_ptr<CPVRChannelGroupMember> GetFirstMatchingGroupMember( + const std::shared_ptr<CPVRChannel>& channel) +{ + CPVRChannelGroups* groups{ + CServiceBroker::GetPVRManager().ChannelGroups()->Get(channel->IsRadio())}; + if (groups) + { + const std::vector<std::shared_ptr<CPVRChannelGroup>> channelGroups{ + groups->GetMembers(true /* exclude hidden */)}; + + for (const auto& channelGroup : channelGroups) + { + if (channelGroup->IsDeleted()) + continue; + + const std::shared_ptr<CPVRChannelGroupMember> groupMember{ + channelGroup->GetByUniqueID(channel->StorageId())}; + if (groupMember) + return groupMember; + } + } + return {}; +} + +std::vector<std::shared_ptr<CPVRChannelGroupMember>> GetChannelGroupMembers( + const CPVRChannelsPath& path) +{ + const std::string& groupName{path.GetGroupName()}; + + std::shared_ptr<CPVRChannelGroup> group; + if (path.IsHiddenChannelGroup()) // hidden channels from the 'all channels' group + { + group = CServiceBroker::GetPVRManager().ChannelGroups()->GetGroupAll(path.IsRadio()); + } + else if (groupName == "*") // all channels across all groups + { + group = CServiceBroker::GetPVRManager().ChannelGroups()->GetGroupAll(path.IsRadio()); + if (group) + { + std::vector<std::shared_ptr<CPVRChannelGroupMember>> result; + + const std::vector<std::shared_ptr<CPVRChannelGroupMember>> allGroupMembers{ + group->GetMembers(CPVRChannelGroup::Include::ONLY_VISIBLE)}; + for (const auto& allGroupMember : allGroupMembers) + { + std::shared_ptr<CPVRChannelGroupMember> member{ + GetLastWatchedChannelGroupMember(allGroupMember->Channel())}; + if (member) + { + result.emplace_back(member); + continue; // Process next 'All channels' group member. + } + + if (group->IsHidden()) + { + // Very special case. 'All channels' group is hidden. Let's see what we get iterating all + // non-hidden / non-deleted groups. We must not return any 'All channels' group members, + // because their path is invalid (it contains the group). + member = GetFirstMatchingGroupMember(allGroupMember->Channel()); + if (member) + result.emplace_back(member); + } + else + { + // Use the 'All channels' group member. + result.emplace_back(allGroupMember); + } + } + return result; + } + } + else + { + group = CServiceBroker::GetPVRManager() + .ChannelGroups() + ->Get(path.IsRadio()) + ->GetByName(groupName, path.GetGroupClientID()); + } + + if (group) + return group->GetMembers(CPVRChannelGroup::Include::ALL); + + CLog::LogF(LOGERROR, "Unable to obtain members for channel group '{}'", groupName); + return {}; +} +} // unnamed namespace + bool CPVRGUIDirectory::GetChannelsDirectory(CFileItemList& results) const { const CPVRChannelsPath path(m_url.GetWithoutOptions()); @@ -487,46 +590,20 @@ bool CPVRGUIDirectory::GetChannelsDirectory(CFileItemList& results) const } else if (path.IsChannelGroup()) { - const std::string& strGroupName = path.GetGroupName(); - bool bShowHiddenChannels = path.IsHiddenChannelGroup(); - - std::shared_ptr<CPVRChannelGroup> group; - if (bShowHiddenChannels || strGroupName == "*") // all channels + const bool playedOnly{(m_url.HasOption("view") && (m_url.GetOption("view") == "lastplayed"))}; + const bool showHiddenChannels{path.IsHiddenChannelGroup()}; + const std::vector<std::shared_ptr<CPVRChannelGroupMember>> groupMembers{ + GetChannelGroupMembers(path)}; + for (const auto& groupMember : groupMembers) { - group = CServiceBroker::GetPVRManager().ChannelGroups()->GetGroupAll(path.IsRadio()); - } - else - { - group = CServiceBroker::GetPVRManager() - .ChannelGroups() - ->Get(path.IsRadio()) - ->GetByName(strGroupName, path.GetGroupClientID()); - } - - if (group) - { - const bool playedOnly = - (m_url.HasOption("view") && (m_url.GetOption("view") == "lastplayed")); - - const std::vector<std::shared_ptr<CPVRChannelGroupMember>> groupMembers = - group->GetMembers(); - for (const auto& groupMember : groupMembers) - { - if (bShowHiddenChannels != groupMember->Channel()->IsHidden()) - continue; + if (showHiddenChannels != groupMember->Channel()->IsHidden()) + continue; - if (playedOnly && !groupMember->Channel()->LastWatched()) - continue; + if (playedOnly && !groupMember->Channel()->LastWatched()) + continue; - results.Add(std::make_shared<CFileItem>(groupMember)); - } + results.Add(std::make_shared<CFileItem>(groupMember)); } - else - { - CLog::LogF(LOGERROR, "Unable to obtain members of channel group '{}'", strGroupName); - return false; - } - return true; } } |