aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKai Sommerfeld <kai.sommerfeld@gmx.com>2019-05-20 20:09:04 +0200
committerGitHub <noreply@github.com>2019-05-20 20:09:04 +0200
commit80a8e0edc54d099b252d7212aea86839003e1796 (patch)
tree1ed0d33e2d81572c71af123fa471683e459c2382
parent18f05f9b5cdd6890d17d5f789820328ec9db5875 (diff)
parentf37ca6e9ae71a7ea97bf81d8bfe47c44c22d9445 (diff)
Merge pull request #16173 from ksooo/pvr-directory-listings-leia
[PVR] Separate GUI from PVR core: remove CFileItem usage from core: step 1: directory listings.
-rw-r--r--xbmc/filesystem/PVRDirectory.cpp109
-rw-r--r--xbmc/filesystem/PVRDirectory.h4
-rw-r--r--xbmc/interfaces/json-rpc/PVROperations.cpp26
-rw-r--r--xbmc/pvr/CMakeLists.txt2
-rw-r--r--xbmc/pvr/PVRGUIDirectory.cpp507
-rw-r--r--xbmc/pvr/PVRGUIDirectory.h93
-rw-r--r--xbmc/pvr/channels/PVRChannelGroup.cpp16
-rw-r--r--xbmc/pvr/channels/PVRChannelGroup.h15
-rw-r--r--xbmc/pvr/channels/PVRChannelGroupsContainer.cpp138
-rw-r--r--xbmc/pvr/channels/PVRChannelGroupsContainer.h21
-rw-r--r--xbmc/pvr/dialogs/GUIDialogPVRChannelsOSD.cpp7
-rw-r--r--xbmc/pvr/dialogs/GUIDialogPVRGroupManager.cpp25
-rw-r--r--xbmc/pvr/dialogs/GUIDialogPVRGuideSearch.cpp2
-rw-r--r--xbmc/pvr/dialogs/GUIDialogPVRTimerSettings.cpp11
-rw-r--r--xbmc/pvr/recordings/PVRRecordings.cpp155
-rw-r--r--xbmc/pvr/recordings/PVRRecordings.h25
-rw-r--r--xbmc/pvr/timers/PVRTimers.cpp106
-rw-r--r--xbmc/pvr/timers/PVRTimers.h15
-rw-r--r--xbmc/pvr/windows/GUIWindowPVRGuide.cpp2
19 files changed, 704 insertions, 575 deletions
diff --git a/xbmc/filesystem/PVRDirectory.cpp b/xbmc/filesystem/PVRDirectory.cpp
index 7fe3b66d6d..b4a5e88962 100644
--- a/xbmc/filesystem/PVRDirectory.cpp
+++ b/xbmc/filesystem/PVRDirectory.cpp
@@ -6,19 +6,9 @@
* See LICENSES/README.md for more information.
*/
-#include "FileItem.h"
-#include "guilib/LocalizeStrings.h"
#include "PVRDirectory.h"
-#include "ServiceBroker.h"
-#include "URL.h"
-#include "utils/log.h"
-#include "utils/StringUtils.h"
-#include "utils/URIUtils.h"
-#include "pvr/PVRManager.h"
-#include "pvr/channels/PVRChannelGroupsContainer.h"
-#include "pvr/recordings/PVRRecordings.h"
-#include "pvr/timers/PVRTimers.h"
+#include "pvr/PVRGUIDirectory.h"
using namespace XFILE;
using namespace PVR;
@@ -29,115 +19,38 @@ CPVRDirectory::~CPVRDirectory() = default;
bool CPVRDirectory::Exists(const CURL& url)
{
- if (!CServiceBroker::GetPVRManager().IsStarted())
- return false;
-
- return (url.IsProtocol("pvr") && StringUtils::StartsWith(url.GetFileName(), "recordings"));
+ const CPVRGUIDirectory dir(url);
+ return dir.Exists();
}
bool CPVRDirectory::GetDirectory(const CURL& url, CFileItemList &items)
{
- std::string base(url.Get());
- URIUtils::RemoveSlashAtEnd(base);
-
- std::string fileName = url.GetFileName();
- URIUtils::RemoveSlashAtEnd(fileName);
- CLog::Log(LOGDEBUG, "CPVRDirectory::GetDirectory(%s)", base.c_str());
- items.SetCacheToDisc(CFileItemList::CACHE_NEVER);
-
- if (fileName == "")
- {
- if (CServiceBroker::GetPVRManager().IsStarted())
- {
- CFileItemPtr item;
-
- item.reset(new CFileItem(base + "channels/", true));
- item->SetLabel(g_localizeStrings.Get(19019));
- item->SetLabelPreformatted(true);
- items.Add(item);
-
- item.reset(new CFileItem(base + "recordings/active/", true));
- item->SetLabel(g_localizeStrings.Get(19017)); // TV Recordings
- item->SetLabelPreformatted(true);
- items.Add(item);
-
- item.reset(new CFileItem(base + "recordings/deleted/", true));
- item->SetLabel(g_localizeStrings.Get(19108)); // Deleted TV Recordings
- item->SetLabelPreformatted(true);
- items.Add(item);
-
- // Sort by name only. Labels are preformatted.
- items.AddSortMethod(SortByLabel, 551 /* Name */, LABEL_MASKS("%L", "", "%L", ""));
- }
- return true;
- }
- else if (StringUtils::StartsWith(fileName, "recordings"))
- {
- if (CServiceBroker::GetPVRManager().IsStarted())
- {
- const std::string pathToUrl(url.Get());
- return CServiceBroker::GetPVRManager().Recordings()->GetDirectory(pathToUrl, items);
- }
- return true;
- }
- else if (StringUtils::StartsWith(fileName, "channels"))
- {
- if (CServiceBroker::GetPVRManager().ChannelGroups() && CServiceBroker::GetPVRManager().ChannelGroups()->Loaded())
- {
- const std::string pathToUrl(url.Get());
- return CServiceBroker::GetPVRManager().ChannelGroups()->GetDirectory(pathToUrl, items);
- }
- return true;
- }
- else if (StringUtils::StartsWith(fileName, "timers"))
- {
- if (CServiceBroker::GetPVRManager().IsStarted())
- {
- const std::string pathToUrl(url.Get());
- return CServiceBroker::GetPVRManager().Timers()->GetDirectory(pathToUrl, items);
- }
- return true;
- }
-
- return false;
+ const CPVRGUIDirectory dir(url);
+ return dir.GetDirectory(items);
}
bool CPVRDirectory::SupportsWriteFileOperations(const std::string& strPath)
{
- CURL url(strPath);
- std::string filename = url.GetFileName();
-
- return URIUtils::IsPVRRecording(filename);
-}
-
-bool CPVRDirectory::IsLiveTV(const std::string& strPath)
-{
- CURL url(strPath);
- std::string filename = url.GetFileName();
-
- return URIUtils::IsLiveTV(filename);
+ const CPVRGUIDirectory dir(strPath);
+ return dir.SupportsWriteFileOperations();
}
bool CPVRDirectory::HasTVRecordings()
{
- return CServiceBroker::GetPVRManager().IsStarted() ?
- CServiceBroker::GetPVRManager().Recordings()->GetNumTVRecordings() > 0 : false;
+ return CPVRGUIDirectory::HasTVRecordings();
}
bool CPVRDirectory::HasDeletedTVRecordings()
{
- return CServiceBroker::GetPVRManager().IsStarted() ?
- CServiceBroker::GetPVRManager().Recordings()->HasDeletedTVRecordings() : false;
+ return CPVRGUIDirectory::HasDeletedTVRecordings();
}
bool CPVRDirectory::HasRadioRecordings()
{
- return CServiceBroker::GetPVRManager().IsStarted() ?
- CServiceBroker::GetPVRManager().Recordings()->GetNumRadioRecordings() > 0 : false;
+ return CPVRGUIDirectory::HasRadioRecordings();
}
bool CPVRDirectory::HasDeletedRadioRecordings()
{
- return CServiceBroker::GetPVRManager().IsStarted() ?
- CServiceBroker::GetPVRManager().Recordings()->HasDeletedRadioRecordings() : false;
+ return CPVRGUIDirectory::HasDeletedRadioRecordings();
}
diff --git a/xbmc/filesystem/PVRDirectory.h b/xbmc/filesystem/PVRDirectory.h
index ff034a5ade..77e9291849 100644
--- a/xbmc/filesystem/PVRDirectory.h
+++ b/xbmc/filesystem/PVRDirectory.h
@@ -10,8 +10,6 @@
#include "IDirectory.h"
-class CPVRSession;
-
namespace XFILE {
class CPVRDirectory
@@ -27,7 +25,7 @@ public:
bool Exists(const CURL& url) override;
static bool SupportsWriteFileOperations(const std::string& strPath);
- static bool IsLiveTV(const std::string& strPath);
+
static bool HasTVRecordings();
static bool HasDeletedTVRecordings();
static bool HasRadioRecordings();
diff --git a/xbmc/interfaces/json-rpc/PVROperations.cpp b/xbmc/interfaces/json-rpc/PVROperations.cpp
index 0e33a03ddf..d6e1660c03 100644
--- a/xbmc/interfaces/json-rpc/PVROperations.cpp
+++ b/xbmc/interfaces/json-rpc/PVROperations.cpp
@@ -113,8 +113,11 @@ JSONRPC_STATUS CPVROperations::GetChannels(const std::string &method, ITransport
return InvalidParams;
CFileItemList channels;
- if (channelGroup->GetMembers(channels) < 0)
- return InvalidParams;
+ const std::vector<PVRChannelGroupMember> groupMembers = channelGroup->GetMembers(CPVRChannelGroup::Include::ONLY_VISIBLE);
+ for (const auto& groupMember : groupMembers)
+ {
+ channels.Add(std::make_shared<CFileItem>(groupMember.channel));
+ }
HandleFileItemList("channelid", false, "channels", channels, parameterObject, result, true);
@@ -280,7 +283,12 @@ void CPVROperations::FillChannelGroupDetails(const CPVRChannelGroupPtr &channelG
else
{
CFileItemList channels;
- channelGroup->GetMembers(channels);
+ const std::vector<PVRChannelGroupMember> groupMembers = channelGroup->GetMembers(CPVRChannelGroup::Include::ONLY_VISIBLE);
+ for (const auto& groupMember : groupMembers)
+ {
+ channels.Add(std::make_shared<CFileItem>(groupMember.channel));
+ }
+
object["channels"] = CVariant(CVariant::VariantTypeArray);
HandleFileItemList("channelid", false, "channels", channels, parameterObject["channels"], object, false);
@@ -298,7 +306,11 @@ JSONRPC_STATUS CPVROperations::GetTimers(const std::string &method, ITransportLa
return FailedToExecute;
CFileItemList timerList;
- timers->GetAll(timerList);
+ const std::vector<std::shared_ptr<CPVRTimerInfoTag>> tags = timers->GetAll();
+ for (const auto& timer : tags)
+ {
+ timerList.Add(std::make_shared<CFileItem>(timer));
+ }
HandleFileItemList("timerid", false, "timers", timerList, parameterObject, result, true);
@@ -413,7 +425,11 @@ JSONRPC_STATUS CPVROperations::GetRecordings(const std::string &method, ITranspo
return FailedToExecute;
CFileItemList recordingsList;
- recordings->GetAll(recordingsList);
+ const std::vector<std::shared_ptr<CPVRRecording>> recs = recordings->GetAll();
+ for (const auto& recording : recs)
+ {
+ recordingsList.Add(std::make_shared<CFileItem>(recording));
+ }
HandleFileItemList("recordingid", true, "recordings", recordingsList, parameterObject, result, true);
diff --git a/xbmc/pvr/CMakeLists.txt b/xbmc/pvr/CMakeLists.txt
index 55fe42704f..c3f05358fc 100644
--- a/xbmc/pvr/CMakeLists.txt
+++ b/xbmc/pvr/CMakeLists.txt
@@ -9,6 +9,7 @@ set(SOURCES PVRActionListener.cpp
PVRChannelNumberInputHandler.cpp
PVRJobs.cpp
PVRGUIChannelNavigator.cpp
+ PVRGUIDirectory.cpp
PVRGUIProgressHandler.cpp
PVRGUITimerInfo.cpp
PVRGUITimesInfo.cpp)
@@ -25,6 +26,7 @@ set(HEADERS PVRActionListener.h
PVRChannelNumberInputHandler.h
PVRJobs.h
PVRGUIChannelNavigator.h
+ PVRGUIDirectory.h
PVRGUIProgressHandler.h
PVRGUITimerInfo.h
PVRGUITimesInfo.h)
diff --git a/xbmc/pvr/PVRGUIDirectory.cpp b/xbmc/pvr/PVRGUIDirectory.cpp
new file mode 100644
index 0000000000..b2ce07ef85
--- /dev/null
+++ b/xbmc/pvr/PVRGUIDirectory.cpp
@@ -0,0 +1,507 @@
+/*
+ * Copyright (C) 2012-2019 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 "PVRGUIDirectory.h"
+
+#include "FileItem.h"
+#include "ServiceBroker.h"
+#include "URL.h"
+#include "guilib/LocalizeStrings.h"
+#include "settings/Settings.h"
+#include "settings/SettingsComponent.h"
+#include "utils/StringUtils.h"
+#include "utils/URIUtils.h"
+#include "utils/log.h"
+
+#include "pvr/PVRManager.h"
+#include "pvr/channels/PVRChannelGroups.h"
+#include "pvr/channels/PVRChannelGroupsContainer.h"
+#include "pvr/recordings/PVRRecordings.h"
+#include "pvr/recordings/PVRRecordingsPath.h"
+#include "pvr/timers/PVRTimers.h"
+#include "pvr/timers/PVRTimersPath.h"
+
+using namespace PVR;
+
+bool CPVRGUIDirectory::Exists() const
+{
+ if (!CServiceBroker::GetPVRManager().IsStarted())
+ return false;
+
+ return m_url.IsProtocol("pvr") && StringUtils::StartsWith(m_url.GetFileName(), "recordings");
+}
+
+bool CPVRGUIDirectory::SupportsWriteFileOperations() const
+{
+ if (!CServiceBroker::GetPVRManager().IsStarted())
+ return false;
+
+ const std::string filename = m_url.GetFileName();
+ return URIUtils::IsPVRRecording(filename);
+}
+
+bool CPVRGUIDirectory::GetDirectory(CFileItemList& results) const
+{
+ std::string base = m_url.Get();
+ URIUtils::RemoveSlashAtEnd(base);
+
+ std::string fileName = m_url.GetFileName();
+ URIUtils::RemoveSlashAtEnd(fileName);
+
+ results.SetCacheToDisc(CFileItemList::CACHE_NEVER);
+
+ if (fileName.empty())
+ {
+ if (CServiceBroker::GetPVRManager().IsStarted())
+ {
+ std::shared_ptr<CFileItem> item;
+
+ item.reset(new CFileItem(base + "channels/", true));
+ item->SetLabel(g_localizeStrings.Get(19019));
+ item->SetLabelPreformatted(true);
+ results.Add(item);
+
+ item.reset(new CFileItem(base + "recordings/active/", true));
+ item->SetLabel(g_localizeStrings.Get(19017)); // TV Recordings
+ item->SetLabelPreformatted(true);
+ results.Add(item);
+
+ item.reset(new CFileItem(base + "recordings/deleted/", true));
+ item->SetLabel(g_localizeStrings.Get(19108)); // Deleted TV Recordings
+ item->SetLabelPreformatted(true);
+ results.Add(item);
+
+ // Sort by name only. Labels are preformatted.
+ results.AddSortMethod(SortByLabel, 551 /* Name */, LABEL_MASKS("%L", "", "%L", ""));
+ }
+ return true;
+ }
+ else if (StringUtils::StartsWith(fileName, "recordings"))
+ {
+ if (CServiceBroker::GetPVRManager().IsStarted())
+ {
+ return GetRecordingsDirectory(results);
+ }
+ return true;
+ }
+ else if (StringUtils::StartsWith(fileName, "channels"))
+ {
+ if (CServiceBroker::GetPVRManager().ChannelGroups() &&
+ CServiceBroker::GetPVRManager().ChannelGroups()->Loaded())
+ {
+ return GetChannelsDirectory(results);
+ }
+ return true;
+ }
+ else if (StringUtils::StartsWith(fileName, "timers"))
+ {
+ if (CServiceBroker::GetPVRManager().IsStarted())
+ {
+ return GetTimersDirectory(results);
+ }
+ return true;
+ }
+
+ return false;
+}
+
+bool CPVRGUIDirectory::HasTVRecordings()
+{
+ return CServiceBroker::GetPVRManager().IsStarted() &&
+ CServiceBroker::GetPVRManager().Recordings()->GetNumTVRecordings() > 0;
+}
+
+bool CPVRGUIDirectory::HasDeletedTVRecordings()
+{
+ return CServiceBroker::GetPVRManager().IsStarted() &&
+ CServiceBroker::GetPVRManager().Recordings()->HasDeletedTVRecordings();
+}
+
+bool CPVRGUIDirectory::HasRadioRecordings()
+{
+ return CServiceBroker::GetPVRManager().IsStarted() &&
+ CServiceBroker::GetPVRManager().Recordings()->GetNumRadioRecordings() > 0;
+}
+
+bool CPVRGUIDirectory::HasDeletedRadioRecordings()
+{
+ return CServiceBroker::GetPVRManager().IsStarted() &&
+ CServiceBroker::GetPVRManager().Recordings()->HasDeletedRadioRecordings();
+}
+
+namespace
+{
+
+std::string TrimSlashes(const std::string& strOrig)
+{
+ std::string strReturn = strOrig;
+ while (strReturn[0] == '/')
+ strReturn.erase(0, 1);
+
+ URIUtils::RemoveSlashAtEnd(strReturn);
+ return strReturn;
+}
+
+bool IsDirectoryMember(const std::string& strDirectory,
+ const std::string& strEntryDirectory,
+ bool bGrouped)
+{
+ const std::string strUseDirectory = TrimSlashes(strDirectory);
+ const std::string strUseEntryDirectory = TrimSlashes(strEntryDirectory);
+
+ // Case-insensitive comparison since sub folders are created with case-insensitive matching (GetSubDirectories)
+ if (bGrouped)
+ return StringUtils::EqualsNoCase(strUseDirectory, strUseEntryDirectory);
+ else
+ return StringUtils::StartsWithNoCase(strUseEntryDirectory, strUseDirectory);
+}
+
+void GetSubDirectories(const CPVRRecordingsPath& recParentPath,
+ CVideoDatabase& videoDB,
+ const std::vector<std::shared_ptr<CPVRRecording>>& recordings,
+ CFileItemList& results)
+{
+ // Only active recordings are fetched to provide sub directories.
+ // Not applicable for deleted view which is supposed to be flattened.
+ std::set<std::shared_ptr<CFileItem>> unwatchedFolders;
+ bool bRadio = recParentPath.IsRadio();
+
+ for (const auto& recording : recordings)
+ {
+ if (recording->IsDeleted())
+ continue;
+
+ if (recording->IsRadio() != bRadio)
+ continue;
+
+ const std::string strCurrent = recParentPath.GetUnescapedSubDirectoryPath(recording->m_strDirectory);
+ if (strCurrent.empty())
+ continue;
+
+ CPVRRecordingsPath recChildPath(recParentPath);
+ recChildPath.AppendSegment(strCurrent);
+ const std::string strFilePath = recChildPath;
+
+ recording->UpdateMetadata(videoDB);
+
+ std::shared_ptr<CFileItem> item;
+ if (!results.Contains(strFilePath))
+ {
+ item.reset(new CFileItem(strCurrent, true));
+ item->SetPath(strFilePath);
+ item->SetLabel(strCurrent);
+ item->SetLabelPreformatted(true);
+ item->m_dateTime = recording->RecordingTimeAsLocalTime();
+
+ // Assume all folders are watched, we'll change the overlay later
+ item->SetOverlayImage(CGUIListItem::ICON_OVERLAY_WATCHED, false);
+ results.Add(item);
+ }
+ else
+ {
+ item = results.Get(strFilePath);
+ if (item->m_dateTime < recording->RecordingTimeAsLocalTime())
+ item->m_dateTime = recording->RecordingTimeAsLocalTime();
+ }
+
+ if (recording->GetPlayCount() == 0)
+ unwatchedFolders.insert(item);
+ }
+
+ // Change the watched overlay to unwatched for folders containing unwatched entries
+ for (auto& item : unwatchedFolders)
+ item->SetOverlayImage(CGUIListItem::ICON_OVERLAY_UNWATCHED, false);
+}
+
+} // unnamed namespace
+
+bool CPVRGUIDirectory::GetRecordingsDirectory(CFileItemList& results) const
+{
+ bool bGrouped = false;
+ const std::shared_ptr<CPVRRecordings> recs = CServiceBroker::GetPVRManager().Recordings();
+ const std::vector<std::shared_ptr<CPVRRecording>> recordings = recs->GetAll();
+ CVideoDatabase& videoDB = recs->GetVideoDatabase();
+
+ if (m_url.HasOption("view"))
+ {
+ const std::string view = m_url.GetOption("view");
+ if (view == "grouped")
+ bGrouped = true;
+ else if (view == "flat")
+ bGrouped = false;
+ else
+ {
+ CLog::LogF(LOGERROR, "Unsupported value '%s' for url parameter 'view'", view.c_str());
+ return false;
+ }
+ }
+ else
+ {
+ bGrouped = CServiceBroker::GetSettingsComponent()->GetSettings()->GetBool(CSettings::SETTING_PVRRECORD_GROUPRECORDINGS);
+ }
+
+ const CPVRRecordingsPath recPath(m_url.GetWithoutOptions());
+ if (recPath.IsValid())
+ {
+ // Get the directory structure if in non-flatten mode
+ // Deleted view is always flatten. So only for an active view
+ const std::string strDirectory = recPath.GetUnescapedDirectoryPath();
+ if (!recPath.IsDeleted() && bGrouped)
+ GetSubDirectories(recPath, videoDB, recordings, results);
+
+ // get all files of the current directory or recursively all files starting at the current directory if in flatten mode
+ std::shared_ptr<CFileItem> item;
+ for (const auto& recording : recordings)
+ {
+ // Omit recordings not matching criteria
+ if (recording->IsDeleted() != recPath.IsDeleted() ||
+ recording->IsRadio() != recPath.IsRadio() ||
+ !IsDirectoryMember(strDirectory, recording->m_strDirectory, bGrouped))
+ continue;
+
+ recording->UpdateMetadata(videoDB);
+
+ item = std::make_shared<CFileItem>(recording);
+ item->SetOverlayImage(CGUIListItem::ICON_OVERLAY_UNWATCHED, recording->GetPlayCount() > 0);
+ results.Add(item);
+ }
+ }
+
+ return recPath.IsValid();
+}
+
+bool CPVRGUIDirectory::FilterDirectory(CFileItemList& results) const
+{
+ if (!results.IsEmpty())
+ {
+ if (m_url.HasOption("view"))
+ {
+ const std::string view = m_url.GetOption("view");
+ if (view == "lastplayed")
+ {
+ // remove channels never played so far
+ for (int i = 0; i < results.Size(); ++i)
+ {
+ const std::shared_ptr<CPVRChannel> channel = results.Get(i)->GetPVRChannelInfoTag();
+ time_t lastWatched = channel->LastWatched();
+ if (!lastWatched)
+ {
+ results.Remove(i);
+ --i;
+ }
+ }
+ }
+ else
+ {
+ CLog::LogF(LOGERROR, "Unsupported value '%s' for channel list URL parameter 'view'", view.c_str());
+ return false;
+ }
+ }
+ }
+ return true;
+}
+
+bool CPVRGUIDirectory::GetChannelGroupsDirectory(bool bRadio, CFileItemList& results) const
+{
+ const CPVRChannelGroups* channelGroups = CServiceBroker::GetPVRManager().ChannelGroups()->Get(bRadio);
+ if (channelGroups)
+ {
+ channelGroups->GetGroupList(&results);
+ return true;
+ }
+ return false;
+}
+
+bool CPVRGUIDirectory::GetChannelsDirectory(CFileItemList& results) const
+{
+ std::string base = m_url.Get();
+ URIUtils::RemoveSlashAtEnd(base);
+
+ std::string fileName = m_url.GetFileName();
+ URIUtils::RemoveSlashAtEnd(fileName);
+
+ if (fileName == "channels")
+ {
+ std::shared_ptr<CFileItem> item;
+
+ // all tv channels
+ item.reset(new CFileItem(base + "/tv/", true));
+ item->SetLabel(g_localizeStrings.Get(19020));
+ item->SetLabelPreformatted(true);
+ results.Add(item);
+
+ // all radio channels
+ item.reset(new CFileItem(base + "/radio/", true));
+ item->SetLabel(g_localizeStrings.Get(19021));
+ item->SetLabelPreformatted(true);
+ results.Add(item);
+
+ return true;
+ }
+ else if (fileName == "channels/tv")
+ {
+ return GetChannelGroupsDirectory(false, results);
+ }
+ else if (fileName == "channels/radio")
+ {
+ return GetChannelGroupsDirectory(true, results);
+ }
+ else if (StringUtils::StartsWith(fileName, "channels/tv/"))
+ {
+ std::string strGroupName = fileName.substr(12);
+ URIUtils::RemoveSlashAtEnd(strGroupName);
+
+ std::shared_ptr<CPVRChannelGroup> group;
+ bool bShowHiddenChannels = StringUtils::EndsWithNoCase(fileName, ".hidden");
+ if (bShowHiddenChannels || strGroupName == "*") // all channels
+ group = CServiceBroker::GetPVRManager().ChannelGroups()->GetGroupAllTV();
+ else
+ group = CServiceBroker::GetPVRManager().ChannelGroups()->GetTV()->GetByName(strGroupName);
+
+ if (group)
+ {
+ const std::vector<PVRChannelGroupMember> groupMembers = group->GetMembers();
+ for (const auto& groupMember : groupMembers)
+ {
+ if (bShowHiddenChannels != groupMember.channel->IsHidden())
+ continue;
+
+ results.Add(std::make_shared<CFileItem>(groupMember.channel));
+ }
+ }
+ else
+ {
+ CLog::LogF(LOGERROR, "Unable to obtain members of channel group '%s'", strGroupName.c_str());
+ return false;
+ }
+
+ FilterDirectory(results);
+ return true;
+ }
+ else if (StringUtils::StartsWith(fileName, "channels/radio/"))
+ {
+ std::string strGroupName = fileName.substr(15);
+ URIUtils::RemoveSlashAtEnd(strGroupName);
+
+ std::shared_ptr<CPVRChannelGroup> group;
+ bool bShowHiddenChannels = StringUtils::EndsWithNoCase(fileName, ".hidden");
+ if (bShowHiddenChannels || strGroupName == "*") // all channels
+ group = CServiceBroker::GetPVRManager().ChannelGroups()->GetGroupAllRadio();
+ else
+ group = CServiceBroker::GetPVRManager().ChannelGroups()->GetRadio()->GetByName(strGroupName);
+
+ if (group)
+ {
+ const std::vector<PVRChannelGroupMember> groupMembers = group->GetMembers();
+ for (const auto& groupMember : groupMembers)
+ {
+ if (bShowHiddenChannels != groupMember.channel->IsHidden())
+ continue;
+
+ results.Add(std::make_shared<CFileItem>(groupMember.channel));
+ }
+ }
+ else
+ {
+ CLog::LogF(LOGERROR, "Unable to obtain members of channel group '%s'", strGroupName.c_str());
+ return false;
+ }
+
+ FilterDirectory(results);
+ return true;
+ }
+
+ return false;
+}
+
+namespace
+{
+
+bool GetTimersRootDirectory(const CPVRTimersPath& path,
+ const std::vector<std::shared_ptr<CPVRTimerInfoTag>>& timers,
+ CFileItemList& results)
+{
+ std::shared_ptr<CFileItem> item(new CFileItem(CPVRTimersPath::PATH_ADDTIMER, false));
+ item->SetLabel(g_localizeStrings.Get(19026)); // "Add timer..."
+ item->SetLabelPreformatted(true);
+ item->SetSpecialSort(SortSpecialOnTop);
+ item->SetIconImage("DefaultTVShows.png");
+ results.Add(item);
+
+ bool bRadio = path.IsRadio();
+ bool bRules = path.IsRules();
+
+ bool bHideDisabled = CServiceBroker::GetSettingsComponent()->GetSettings()->GetBool(CSettings::SETTING_PVRTIMERS_HIDEDISABLEDTIMERS);
+
+ for (const auto& timer : timers)
+ {
+ if ((bRadio == timer->m_bIsRadio || (bRules && timer->m_iClientChannelUid == PVR_TIMER_ANY_CHANNEL)) &&
+ (bRules == timer->IsTimerRule()) &&
+ (!bHideDisabled || (timer->m_state != PVR_TIMER_STATE_DISABLED)))
+ {
+ item.reset(new CFileItem(timer));
+ const CPVRTimersPath timersPath(path.GetPath(), timer->m_iClientId, timer->m_iClientIndex);
+ item->SetPath(timersPath.GetPath());
+ results.Add(item);
+ }
+ }
+ return true;
+}
+
+bool GetTimersSubDirectory(const CPVRTimersPath& path,
+ const std::vector<std::shared_ptr<CPVRTimerInfoTag>>& timers,
+ CFileItemList& results)
+{
+ bool bRadio = path.IsRadio();
+ unsigned int iParentId = path.GetParentId();
+ int iClientId = path.GetClientId();
+
+ bool bHideDisabled = CServiceBroker::GetSettingsComponent()->GetSettings()->GetBool(CSettings::SETTING_PVRTIMERS_HIDEDISABLEDTIMERS);
+
+ std::shared_ptr<CFileItem> item;
+
+ for (const auto& timer : timers)
+ {
+ if ((timer->m_bIsRadio == bRadio) &&
+ (timer->m_iParentClientIndex != PVR_TIMER_NO_PARENT) &&
+ (timer->m_iClientId == iClientId) &&
+ (timer->m_iParentClientIndex == iParentId) &&
+ (!bHideDisabled || (timer->m_state != PVR_TIMER_STATE_DISABLED)))
+ {
+ item.reset(new CFileItem(timer));
+ const CPVRTimersPath timersPath(path.GetPath(), timer->m_iClientId, timer->m_iClientIndex);
+ item->SetPath(timersPath.GetPath());
+ results.Add(item);
+ }
+ }
+ return true;
+}
+
+} // unnamed namespace
+
+bool CPVRGUIDirectory::GetTimersDirectory(CFileItemList& results) const
+{
+ const CPVRTimersPath path(m_url.GetWithoutOptions());
+ if (path.IsValid())
+ {
+ const std::vector<std::shared_ptr<CPVRTimerInfoTag>> timers = CServiceBroker::GetPVRManager().Timers()->GetAll();
+
+ if (path.IsTimersRoot())
+ {
+ /* Root folder containing either timer rules or timers. */
+ return GetTimersRootDirectory(path, timers, results);
+ }
+ else if (path.IsTimerRule())
+ {
+ /* Sub folder containing the timers scheduled by the given timer rule. */
+ return GetTimersSubDirectory(path, timers, results);
+ }
+ }
+
+ return false;
+}
diff --git a/xbmc/pvr/PVRGUIDirectory.h b/xbmc/pvr/PVRGUIDirectory.h
new file mode 100644
index 0000000000..86d83fea31
--- /dev/null
+++ b/xbmc/pvr/PVRGUIDirectory.h
@@ -0,0 +1,93 @@
+/*
+ * Copyright (C) 2012-2019 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.
+ */
+
+#pragma once
+
+#include "URL.h"
+
+class CFileItemList;
+
+namespace PVR
+{
+
+class CPVRGUIDirectory
+{
+public:
+ /*!
+ * @brief PVR GUI directory ctor.
+ * @param url The directory's URL.
+ */
+ explicit CPVRGUIDirectory(const CURL& url) : m_url(url) {}
+
+ /*!
+ * @brief PVR GUI directory ctor.
+ * @param path The directory's path.
+ */
+ explicit CPVRGUIDirectory(const std::string& path) : m_url(path) {}
+
+ /*!
+ * @brief PVR GUI directory dtor.
+ */
+ virtual ~CPVRGUIDirectory() = default;
+
+ /*!
+ * @brief Check existense of this directory.
+ * @return True if the directory exists, false otherwise.
+ */
+ bool Exists() const;
+
+ /*!
+ * @brief Obtain the directory listing.
+ * @param results The list to fill with the results.
+ * @return True on success, false otherwise.
+ */
+ bool GetDirectory(CFileItemList& results) const;
+
+ /*!
+ * @brief Check if this directory supports file write operations.
+ * @return True if the directory supports file write operations, false otherwise.
+ */
+ bool SupportsWriteFileOperations() const;
+
+ /*!
+ * @brief Check if any TV recordings are existing.
+ * @return True if TV recordings exists, false otherwise.
+ */
+ static bool HasTVRecordings();
+
+ /*!
+ * @brief Check if any deleted TV recordings are existing.
+ * @return True if deleted TV recordings exists, false otherwise.
+ */
+ static bool HasDeletedTVRecordings();
+
+ /*!
+ * @brief Check if any radio recordings are existing.
+ * @return True if radio recordings exists, false otherwise.
+ */
+ static bool HasRadioRecordings();
+
+ /*!
+ * @brief Check if any deleted radio recordings are existing.
+ * @return True if deleted radio recordings exists, false otherwise.
+ */
+ static bool HasDeletedRadioRecordings();
+
+private:
+
+ bool FilterDirectory(CFileItemList& results) const;
+
+ bool GetChannelGroupsDirectory(bool bRadio, CFileItemList& results) const;
+ bool GetChannelsDirectory(CFileItemList& results) const;
+ bool GetTimersDirectory(CFileItemList& results) const;
+ bool GetRecordingsDirectory(CFileItemList& results) const;
+
+ const CURL m_url;
+};
+
+}
diff --git a/xbmc/pvr/channels/PVRChannelGroup.cpp b/xbmc/pvr/channels/PVRChannelGroup.cpp
index 77b83b783a..12b1ec613a 100644
--- a/xbmc/pvr/channels/PVRChannelGroup.cpp
+++ b/xbmc/pvr/channels/PVRChannelGroup.cpp
@@ -490,17 +490,13 @@ CFileItemPtr CPVRChannelGroup::GetPreviousChannel(const CPVRChannelPtr &channel)
return retval;
}
-PVR_CHANNEL_GROUP_SORTED_MEMBERS CPVRChannelGroup::GetMembers(void) const
+std::vector<PVRChannelGroupMember> CPVRChannelGroup::GetMembers(Include eFilter /* = Include::ALL */) const
{
CSingleLock lock(m_critSection);
- return m_sortedMembers;
-}
-
-int CPVRChannelGroup::GetMembers(CFileItemList &results, Include eFilter /* = Include::ONLY_VISIBLE */) const
-{
- int iOrigSize = results.Size();
- CSingleLock lock(m_critSection);
+ if (eFilter == Include::ALL)
+ return m_sortedMembers;
+ std::vector<PVRChannelGroupMember> members;
for (const auto& member : m_sortedMembers)
{
switch (eFilter)
@@ -517,10 +513,10 @@ int CPVRChannelGroup::GetMembers(CFileItemList &results, Include eFilter /* = In
break;
}
- results.Add(std::make_shared<CFileItem>(member.channel));
+ members.emplace_back(member);
}
- return results.Size() - iOrigSize;
+ return members;
}
void CPVRChannelGroup::GetChannelNumbers(std::vector<std::string>& channelNumbers) const
diff --git a/xbmc/pvr/channels/PVRChannelGroup.h b/xbmc/pvr/channels/PVRChannelGroup.h
index e0253767f0..6d9ddbdd18 100644
--- a/xbmc/pvr/channels/PVRChannelGroup.h
+++ b/xbmc/pvr/channels/PVRChannelGroup.h
@@ -314,12 +314,6 @@ namespace PVR
*/
CPVRChannelPtr GetByChannelID(int iChannelID) const;
- /*!
- * Get the current members of this group
- * @return The group members
- */
- PVR_CHANNEL_GROUP_SORTED_MEMBERS GetMembers(void) const;
-
enum class Include
{
ALL,
@@ -328,12 +322,11 @@ namespace PVR
};
/*!
- * @brief Get a filtered list of channels in this group.
- * @param results The file list to store the results in.
- * @param eFilter A filter to apply to the list.
- * @return The amount of channels that were added to the list.
+ * @brief Get the current members of this group
+ * @param eFilter A filter to apply.
+ * @return The group members
*/
- int GetMembers(CFileItemList &results, Include eFilter = Include::ONLY_VISIBLE) const;
+ std::vector<PVRChannelGroupMember> GetMembers(Include eFilter = Include::ALL) const;
/*!
* @brief Get the list of channel numbers in a group.
diff --git a/xbmc/pvr/channels/PVRChannelGroupsContainer.cpp b/xbmc/pvr/channels/PVRChannelGroupsContainer.cpp
index fb47e02d2c..23bc0cb209 100644
--- a/xbmc/pvr/channels/PVRChannelGroupsContainer.cpp
+++ b/xbmc/pvr/channels/PVRChannelGroupsContainer.cpp
@@ -8,13 +8,9 @@
#include "PVRChannelGroupsContainer.h"
-#include "URL.h"
-#include "guilib/LocalizeStrings.h"
-#include "utils/StringUtils.h"
-#include "utils/URIUtils.h"
+#include "FileItem.h"
#include "utils/log.h"
-#include "pvr/PVRManager.h"
#include "pvr/epg/EpgInfoTag.h"
using namespace PVR;
@@ -115,17 +111,6 @@ std::shared_ptr<CPVRChannel> CPVRChannelGroupsContainer::GetChannelForEpgTag(con
return groups->GetGroupAll()->GetByUniqueID(epgTag->UniqueChannelID(), epgTag->ClientID());
}
-bool CPVRChannelGroupsContainer::GetGroupsDirectory(CFileItemList *results, bool bRadio) const
-{
- const CPVRChannelGroups *channelGroups = Get(bRadio);
- if (channelGroups)
- {
- channelGroups->GetGroupList(results);
- return true;
- }
- return false;
-}
-
CFileItemPtr CPVRChannelGroupsContainer::GetByPath(const std::string &strPath) const
{
for (unsigned int bRadio = 0; bRadio <= 1; ++bRadio)
@@ -140,127 +125,6 @@ CFileItemPtr CPVRChannelGroupsContainer::GetByPath(const std::string &strPath) c
return retVal;
}
-bool CPVRChannelGroupsContainer::GetDirectory(const std::string& strPath, CFileItemList &results) const
-{
- std::string strBase(strPath);
- URIUtils::RemoveSlashAtEnd(strBase);
-
- /* get the filename from curl */
- CURL url(strPath);
- std::string fileName = url.GetFileName();
- URIUtils::RemoveSlashAtEnd(fileName);
-
- if (fileName == "channels")
- {
- CFileItemPtr item;
-
- /* all tv channels */
- item.reset(new CFileItem(strBase + "/tv/", true));
- item->SetLabel(g_localizeStrings.Get(19020));
- item->SetLabelPreformatted(true);
- results.Add(item);
-
- /* all radio channels */
- item.reset(new CFileItem(strBase + "/radio/", true));
- item->SetLabel(g_localizeStrings.Get(19021));
- item->SetLabelPreformatted(true);
- results.Add(item);
-
- return true;
- }
- else if (fileName == "channels/tv")
- {
- return GetGroupsDirectory(&results, false);
- }
- else if (fileName == "channels/radio")
- {
- return GetGroupsDirectory(&results, true);
- }
- else if (StringUtils::StartsWith(fileName, "channels/tv/"))
- {
- std::string strGroupName(fileName.substr(12));
- URIUtils::RemoveSlashAtEnd(strGroupName);
-
- CPVRChannelGroupPtr group;
- bool bShowHiddenChannels = StringUtils::EndsWithNoCase(fileName, ".hidden");
- if (strGroupName == "*" || bShowHiddenChannels) // all channels
- group = GetGroupAllTV();
- else
- group = GetTV()->GetByName(strGroupName);
-
- if (group)
- {
- group->GetMembers(results, bShowHiddenChannels ? CPVRChannelGroup::Include::ONLY_HIDDEN : CPVRChannelGroup::Include::ONLY_VISIBLE);
- }
- else
- {
- CLog::LogF(LOGERROR, "Unable to obtain members of channel group '%s'", strGroupName.c_str());
- return false;
- }
-
- FilterDirectory(url, results);
- return true;
- }
- else if (StringUtils::StartsWith(fileName, "channels/radio/"))
- {
- std::string strGroupName(fileName.substr(15));
- URIUtils::RemoveSlashAtEnd(strGroupName);
-
- CPVRChannelGroupPtr group;
- bool bShowHiddenChannels = StringUtils::EndsWithNoCase(fileName, ".hidden");
- if (strGroupName == "*" || bShowHiddenChannels) // all channels
- group = GetGroupAllRadio();
- else
- group = GetRadio()->GetByName(strGroupName);
-
- if (group)
- {
- group->GetMembers(results, bShowHiddenChannels ? CPVRChannelGroup::Include::ONLY_HIDDEN : CPVRChannelGroup::Include::ONLY_VISIBLE);
- }
- else
- {
- CLog::LogF(LOGERROR, "Unable to obtain members of channel group '%s'", strGroupName.c_str());
- return false;
- }
-
- FilterDirectory(url, results);
- return true;
- }
-
- return false;
-}
-
-bool CPVRChannelGroupsContainer::FilterDirectory(const CURL &url, CFileItemList &results) const
-{
- if (!results.IsEmpty())
- {
- if (url.HasOption("view"))
- {
- const std::string view(url.GetOption("view"));
- if (view == "lastplayed")
- {
- // remove channels never played so far
- for (int i = 0; i < results.Size(); ++i)
- {
- const CPVRChannelPtr channel(results.Get(i)->GetPVRChannelInfoTag());
- time_t lastWatched = channel->LastWatched();
- if (!lastWatched)
- {
- results.Remove(i);
- --i;
- }
- }
- }
- else
- {
- CLog::LogF(LOGERROR, "Unsupported value '%s' for channel list URL parameter 'view'", view.c_str());
- return false;
- }
- }
- }
- return true;
-}
-
CPVRChannelGroupPtr CPVRChannelGroupsContainer::GetSelectedGroup(bool bRadio) const
{
return Get(bRadio)->GetSelectedGroup();
diff --git a/xbmc/pvr/channels/PVRChannelGroupsContainer.h b/xbmc/pvr/channels/PVRChannelGroupsContainer.h
index 5417e45611..f88dd2b5d4 100644
--- a/xbmc/pvr/channels/PVRChannelGroupsContainer.h
+++ b/xbmc/pvr/channels/PVRChannelGroupsContainer.h
@@ -12,8 +12,6 @@
#include "pvr/channels/PVRChannelGroups.h"
-class CURL;
-
namespace PVR
{
class CPVRChannelGroupsContainer
@@ -120,15 +118,6 @@ namespace PVR
std::shared_ptr<CPVRChannel> GetChannelForEpgTag(const std::shared_ptr<CPVREpgInfoTag>& epgTag) const;
/*!
- * @brief Get the groups list for a directory.
- * @param strBase The directory path.
- * @param results The file list to store the results in.
- * @param bRadio Get radio channels or tv channels.
- * @return True if the list was filled successfully.
- */
- bool GetGroupsDirectory(CFileItemList *results, bool bRadio) const;
-
- /*!
* @brief Get a channel given it's path.
* @param strPath The path.
* @return The channel or NULL if it wasn't found.
@@ -136,14 +125,6 @@ namespace PVR
CFileItemPtr GetByPath(const std::string &strPath) const;
/*!
- * @brief Get the directory for a path.
- * @param strPath The path.
- * @param results The file list to store the results in.
- * @return True if the directory was found, false if not.
- */
- bool GetDirectory(const std::string& strPath, CFileItemList &results) const;
-
- /*!
* @brief Get the group that is currently selected in the UI.
* @param bRadio True to get the selected radio group, false to get the selected TV group.
* @return The selected group.
@@ -206,8 +187,6 @@ namespace PVR
CPVRChannelGroupsContainer& operator=(const CPVRChannelGroupsContainer&) = delete;
CPVRChannelGroupsContainer(const CPVRChannelGroupsContainer&) = delete;
- bool FilterDirectory(const CURL &url, CFileItemList &results) const;
-
bool m_bLoaded = false;
};
}
diff --git a/xbmc/pvr/dialogs/GUIDialogPVRChannelsOSD.cpp b/xbmc/pvr/dialogs/GUIDialogPVRChannelsOSD.cpp
index be73f42332..dc6ea592c2 100644
--- a/xbmc/pvr/dialogs/GUIDialogPVRChannelsOSD.cpp
+++ b/xbmc/pvr/dialogs/GUIDialogPVRChannelsOSD.cpp
@@ -166,7 +166,12 @@ void CGUIDialogPVRChannelsOSD::Update()
const CPVRChannelGroupPtr group = pvrMgr.GetPlayingGroup(channel->IsRadio());
if (group)
{
- group->GetMembers(*m_vecItems);
+ const std::vector<PVRChannelGroupMember> groupMembers = group->GetMembers(CPVRChannelGroup::Include::ONLY_VISIBLE);
+ for (const auto& groupMember : groupMembers)
+ {
+ m_vecItems->Add(std::make_shared<CFileItem>(groupMember.channel));
+ }
+
m_viewControl.SetItems(*m_vecItems);
if (!m_group)
diff --git a/xbmc/pvr/dialogs/GUIDialogPVRGroupManager.cpp b/xbmc/pvr/dialogs/GUIDialogPVRGroupManager.cpp
index 8dae3b3aec..30fbed9509 100644
--- a/xbmc/pvr/dialogs/GUIDialogPVRGroupManager.cpp
+++ b/xbmc/pvr/dialogs/GUIDialogPVRGroupManager.cpp
@@ -403,21 +403,30 @@ void CGUIDialogPVRGroupManager::Update()
// Slightly different handling for "all" group...
if (m_selectedGroup->IsInternalGroup())
{
- m_selectedGroup->GetMembers(*m_groupMembers, CPVRChannelGroup::Include::ONLY_VISIBLE);
- m_selectedGroup->GetMembers(*m_ungroupedChannels, CPVRChannelGroup::Include::ONLY_HIDDEN);
+ const std::vector<PVRChannelGroupMember> groupMembers = m_selectedGroup->GetMembers(CPVRChannelGroup::Include::ALL);
+ for (const auto& groupMember : groupMembers)
+ {
+ if (groupMember.channel->IsHidden())
+ m_ungroupedChannels->Add(std::make_shared<CFileItem>(groupMember.channel));
+ else
+ m_groupMembers->Add(std::make_shared<CFileItem>(groupMember.channel));
+ }
}
else
{
- m_selectedGroup->GetMembers(*m_groupMembers, CPVRChannelGroup::Include::ALL);
+ const std::vector<PVRChannelGroupMember> groupMembers = m_selectedGroup->GetMembers(CPVRChannelGroup::Include::ONLY_VISIBLE);
+ for (const auto& groupMember : groupMembers)
+ {
+ m_groupMembers->Add(std::make_shared<CFileItem>(groupMember.channel));
+ }
/* for the center part, get all channels of the "all" channels group that are not in this group */
const CPVRChannelGroupPtr allGroup = CServiceBroker::GetPVRManager().ChannelGroups()->GetGroupAll(m_bIsRadio);
- CFileItemList allChannels;
- allGroup->GetMembers(allChannels, CPVRChannelGroup::Include::ALL);
- for (const auto& channelItem : allChannels)
+ const std::vector<PVRChannelGroupMember> allGroupMembers = allGroup->GetMembers(CPVRChannelGroup::Include::ONLY_VISIBLE);
+ for (const auto& groupMember : allGroupMembers)
{
- if (!m_selectedGroup->IsGroupMember(channelItem->GetPVRChannelInfoTag()))
- m_ungroupedChannels->Add(channelItem);
+ if (!m_selectedGroup->IsGroupMember(groupMember.channel))
+ m_ungroupedChannels->Add(std::make_shared<CFileItem>(groupMember.channel));
}
}
m_viewGroupMembers.SetItems(*m_groupMembers);
diff --git a/xbmc/pvr/dialogs/GUIDialogPVRGuideSearch.cpp b/xbmc/pvr/dialogs/GUIDialogPVRGuideSearch.cpp
index 1e4b119c76..9f0b6fcc5f 100644
--- a/xbmc/pvr/dialogs/GUIDialogPVRGuideSearch.cpp
+++ b/xbmc/pvr/dialogs/GUIDialogPVRGuideSearch.cpp
@@ -67,7 +67,7 @@ void CGUIDialogPVRGuideSearch::UpdateChannelSpin(void)
group = CServiceBroker::GetPVRManager().ChannelGroups()->GetGroupAll(m_searchFilter->IsRadio());
m_channelNumbersMap.clear();
- const std::vector<PVRChannelGroupMember> groupMembers(group->GetMembers());
+ const std::vector<PVRChannelGroupMember> groupMembers(group->GetMembers(CPVRChannelGroup::Include::ONLY_VISIBLE));
int iIndex = 0;
int iSelectedChannel = EPG_SEARCH_UNSET;
for (const auto& groupMember : groupMembers)
diff --git a/xbmc/pvr/dialogs/GUIDialogPVRTimerSettings.cpp b/xbmc/pvr/dialogs/GUIDialogPVRTimerSettings.cpp
index db2e4a7294..65088fed19 100644
--- a/xbmc/pvr/dialogs/GUIDialogPVRTimerSettings.cpp
+++ b/xbmc/pvr/dialogs/GUIDialogPVRTimerSettings.cpp
@@ -771,16 +771,17 @@ void CGUIDialogPVRTimerSettings::InitializeChannelsList()
{
m_channelEntries.clear();
- CFileItemList channelsList;
- CServiceBroker::GetPVRManager().ChannelGroups()->GetGroupAll(m_bIsRadio)->GetMembers(channelsList);
-
- for (int i = 0; i < channelsList.Size(); ++i)
+ const std::shared_ptr<CPVRChannelGroup> allGroup = CServiceBroker::GetPVRManager().ChannelGroups()->GetGroupAll(m_bIsRadio);
+ const std::vector<PVRChannelGroupMember> groupMembers = allGroup->GetMembers(CPVRChannelGroup::Include::ONLY_VISIBLE);
+ int i = 0;
+ for (const auto& groupMember : groupMembers)
{
- const CPVRChannelPtr channel(channelsList[i]->GetPVRChannelInfoTag());
+ const std::shared_ptr<CPVRChannel> channel = groupMember.channel;
std::string channelDescription(
StringUtils::Format("%s %s", channel->ChannelNumber().FormattedChannelNumber().c_str(), channel->ChannelName().c_str()));
m_channelEntries.insert(
std::make_pair(i, ChannelDescriptor(channel->UniqueID(), channel->ClientID(), channelDescription)));
+ i++;
}
// Add special "any channel" entry (used for epg-based timer rules).
diff --git a/xbmc/pvr/recordings/PVRRecordings.cpp b/xbmc/pvr/recordings/PVRRecordings.cpp
index 777e5a1320..ee69673d87 100644
--- a/xbmc/pvr/recordings/PVRRecordings.cpp
+++ b/xbmc/pvr/recordings/PVRRecordings.cpp
@@ -12,12 +12,8 @@
#include "FileItem.h"
#include "ServiceBroker.h"
-#include "URL.h"
#include "filesystem/Directory.h"
-#include "settings/Settings.h"
-#include "settings/SettingsComponent.h"
#include "threads/SingleLock.h"
-#include "utils/StringUtils.h"
#include "utils/URIUtils.h"
#include "utils/log.h"
#include "video/VideoDatabase.h"
@@ -44,84 +40,6 @@ void CPVRRecordings::UpdateFromClients(void)
CServiceBroker::GetPVRManager().Clients()->GetRecordings(this, true);
}
-std::string CPVRRecordings::TrimSlashes(const std::string &strOrig) const
-{
- std::string strReturn(strOrig);
- while (strReturn[0] == '/')
- strReturn.erase(0, 1);
-
- URIUtils::RemoveSlashAtEnd(strReturn);
-
- return strReturn;
-}
-
-bool CPVRRecordings::IsDirectoryMember(const std::string &strDirectory, const std::string &strEntryDirectory, bool bGrouped) const
-{
- std::string strUseDirectory = TrimSlashes(strDirectory);
- std::string strUseEntryDirectory = TrimSlashes(strEntryDirectory);
-
- /* Case-insensitive comparison since sub folders are created with case-insensitive matching (GetSubDirectories) */
- if (bGrouped)
- return StringUtils::EqualsNoCase(strUseDirectory, strUseEntryDirectory);
- else
- return StringUtils::StartsWithNoCase(strUseEntryDirectory, strUseDirectory);
-}
-
-void CPVRRecordings::GetSubDirectories(const CPVRRecordingsPath &recParentPath, CFileItemList *results)
-{
- // Only active recordings are fetched to provide sub directories.
- // Not applicable for deleted view which is supposed to be flattened.
- std::set<CFileItemPtr> unwatchedFolders;
- bool bRadio = recParentPath.IsRadio();
-
- for (const auto recording : m_recordings)
- {
- CPVRRecordingPtr current = recording.second;
- if (current->IsDeleted())
- continue;
-
- if (current->IsRadio() != bRadio)
- continue;
-
- const std::string strCurrent(recParentPath.GetUnescapedSubDirectoryPath(current->m_strDirectory));
- if (strCurrent.empty())
- continue;
-
- CPVRRecordingsPath recChildPath(recParentPath);
- recChildPath.AppendSegment(strCurrent);
- std::string strFilePath(recChildPath);
-
- current->UpdateMetadata(GetVideoDatabase());
-
- CFileItemPtr pFileItem;
- if (!results->Contains(strFilePath))
- {
- pFileItem.reset(new CFileItem(strCurrent, true));
- pFileItem->SetPath(strFilePath);
- pFileItem->SetLabel(strCurrent);
- pFileItem->SetLabelPreformatted(true);
- pFileItem->m_dateTime = current->RecordingTimeAsLocalTime();
-
- // Assume all folders are watched, we'll change the overlay later
- pFileItem->SetOverlayImage(CGUIListItem::ICON_OVERLAY_WATCHED, false);
- results->Add(pFileItem);
- }
- else
- {
- pFileItem = results->Get(strFilePath);
- if (pFileItem->m_dateTime < current->RecordingTimeAsLocalTime())
- pFileItem->m_dateTime = current->RecordingTimeAsLocalTime();
- }
-
- if (current->GetPlayCount() == 0)
- unwatchedFolders.insert(pFileItem);
- }
-
- // Change the watched overlay to unwatched for folders containing unwatched entries
- for (auto item : unwatchedFolders)
- item->SetOverlayImage(CGUIListItem::ICON_OVERLAY_UNWATCHED, false);
-}
-
int CPVRRecordings::Load(void)
{
Unload();
@@ -251,76 +169,17 @@ bool CPVRRecordings::IncrementRecordingsPlayCount(const CFileItemPtr &item)
return ChangeRecordingsPlayCount(item, INCREMENT_PLAY_COUNT);
}
-bool CPVRRecordings::GetDirectory(const std::string& strPath, CFileItemList &items)
+std::vector<std::shared_ptr<CPVRRecording>> CPVRRecordings::GetAll() const
{
- CSingleLock lock(m_critSection);
-
- bool bGrouped = false;
- const CURL url(strPath);
- if (url.HasOption("view"))
- {
- const std::string view(url.GetOption("view"));
- if (view == "grouped")
- bGrouped = true;
- else if (view == "flat")
- bGrouped = false;
- else
- {
- CLog::LogF(LOGERROR, "Unsupported value '%s' for url parameter 'view'", view.c_str());
- return false;
- }
- }
- else
- {
- bGrouped = CServiceBroker::GetSettingsComponent()->GetSettings()->GetBool(CSettings::SETTING_PVRRECORD_GROUPRECORDINGS);
- }
-
- CPVRRecordingsPath recPath(url.GetWithoutOptions());
- if (recPath.IsValid())
- {
- // Get the directory structure if in non-flatten mode
- // Deleted view is always flatten. So only for an active view
- std::string strDirectory(recPath.GetUnescapedDirectoryPath());
- if (!recPath.IsDeleted() && bGrouped)
- GetSubDirectories(recPath, &items);
-
- // get all files of the current directory or recursively all files starting at the current directory if in flatten mode
- for (const auto recording : m_recordings)
- {
- const CPVRRecordingPtr current = recording.second;
+ std::vector<std::shared_ptr<CPVRRecording>> recordings;
- // Omit recordings not matching criteria
- if (!IsDirectoryMember(strDirectory, current->m_strDirectory, bGrouped) ||
- current->IsDeleted() != recPath.IsDeleted() ||
- current->IsRadio() != recPath.IsRadio())
- continue;
-
- current->UpdateMetadata(GetVideoDatabase());
-
- const CFileItemPtr item = std::make_shared<CFileItem>(current);
- item->SetOverlayImage(CGUIListItem::ICON_OVERLAY_UNWATCHED, current->GetPlayCount() > 0);
- items.Add(item);
- }
- }
-
- return recPath.IsValid();
-}
-
-void CPVRRecordings::GetAll(CFileItemList &items, bool bDeleted)
-{
CSingleLock lock(m_critSection);
- for (const auto recording : m_recordings)
+ for (const auto& recordingEntry : m_recordings)
{
- const CPVRRecordingPtr current = recording.second;
- if (current->IsDeleted() != bDeleted)
- continue;
-
- current->UpdateMetadata(GetVideoDatabase());
-
- const CFileItemPtr item = std::make_shared<CFileItem>(current);
- item->SetOverlayImage(CGUIListItem::ICON_OVERLAY_UNWATCHED, current->GetPlayCount() > 0);
- items.Add(item);
+ recordings.emplace_back(recordingEntry.second);
}
+
+ return recordings;
}
CFileItemPtr CPVRRecordings::GetById(unsigned int iId) const
@@ -367,7 +226,7 @@ CPVRRecordingPtr CPVRRecordings::GetById(int iClientId, const std::string &strRe
{
CPVRRecordingPtr retVal;
CSingleLock lock(m_critSection);
- PVR_RECORDINGMAP_CITR it = m_recordings.find(CPVRRecordingUid(iClientId, strRecordingId));
+ const auto it = m_recordings.find(CPVRRecordingUid(iClientId, strRecordingId));
if (it != m_recordings.end())
retVal = it->second;
diff --git a/xbmc/pvr/recordings/PVRRecordings.h b/xbmc/pvr/recordings/PVRRecordings.h
index 4672fb0d40..79352d0d90 100644
--- a/xbmc/pvr/recordings/PVRRecordings.h
+++ b/xbmc/pvr/recordings/PVRRecordings.h
@@ -70,10 +70,10 @@ namespace PVR
*/
bool ResetResumePoint(const CFileItemPtr item);
- bool GetDirectory(const std::string& strPath, CFileItemList &items);
+ std::vector<std::shared_ptr<CPVRRecording>> GetAll() const;
+
CFileItemPtr GetByPath(const std::string &path);
CPVRRecordingPtr GetById(int iClientId, const std::string &strRecordingId) const;
- void GetAll(CFileItemList &items, bool bDeleted = false);
CFileItemPtr GetById(unsigned int iId) const;
/*!
@@ -83,14 +83,16 @@ namespace PVR
*/
CPVRRecordingPtr GetRecordingForEpgTag(const CPVREpgInfoTagPtr &epgTag) const;
- private:
- typedef std::map<CPVRRecordingUid, CPVRRecordingPtr> PVR_RECORDINGMAP;
- typedef PVR_RECORDINGMAP::iterator PVR_RECORDINGMAP_ITR;
- typedef PVR_RECORDINGMAP::const_iterator PVR_RECORDINGMAP_CITR;
+ /**
+ * @brief Get/Open the video database.
+ * @return A reference to the video database.
+ */
+ CVideoDatabase& GetVideoDatabase();
+ private:
mutable CCriticalSection m_critSection;
bool m_bIsUpdating = false;
- PVR_RECORDINGMAP m_recordings;
+ std::map<CPVRRecordingUid, CPVRRecordingPtr> m_recordings;
unsigned int m_iLastId = 0;
std::unique_ptr<CVideoDatabase> m_database;
bool m_bDeletedTVRecordings = false;
@@ -99,15 +101,6 @@ namespace PVR
unsigned int m_iRadioRecordings = 0;
void UpdateFromClients(void);
- std::string TrimSlashes(const std::string &strOrig) const;
- bool IsDirectoryMember(const std::string &strDirectory, const std::string &strEntryDirectory, bool bGrouped) const;
- void GetSubDirectories(const CPVRRecordingsPath &recParentPath, CFileItemList *results);
-
- /**
- * @brief Get/Open the video database.
- * @return A reference to the video database.
- */
- CVideoDatabase& GetVideoDatabase();
/**
* @brief recursively deletes all recordings in the specified directory
diff --git a/xbmc/pvr/timers/PVRTimers.cpp b/xbmc/pvr/timers/PVRTimers.cpp
index 23e18c3f9e..b0a2edc124 100644
--- a/xbmc/pvr/timers/PVRTimers.cpp
+++ b/xbmc/pvr/timers/PVRTimers.cpp
@@ -13,7 +13,6 @@
#include "FileItem.h"
#include "ServiceBroker.h"
#include "addons/PVRClient.h"
-#include "guilib/LocalizeStrings.h"
#include "settings/Settings.h"
#include "threads/SingleLock.h"
#include "utils/log.h"
@@ -23,7 +22,6 @@
#include "pvr/addons/PVRClients.h"
#include "pvr/channels/PVRChannelGroupsContainer.h"
#include "pvr/epg/EpgContainer.h"
-#include "pvr/timers/PVRTimersPath.h"
using namespace PVR;
@@ -78,8 +76,7 @@ CPVRTimers::CPVRTimers(void)
CSettings::SETTING_PVRPOWERMANAGEMENT_PREWAKEUP,
CSettings::SETTING_PVRPOWERMANAGEMENT_BACKENDIDLETIME,
CSettings::SETTING_PVRPOWERMANAGEMENT_DAILYWAKEUPTIME,
- CSettings::SETTING_PVRRECORD_TIMERNOTIFICATIONS,
- CSettings::SETTING_PVRTIMERS_HIDEDISABLEDTIMERS
+ CSettings::SETTING_PVRRECORD_TIMERNOTIFICATIONS
})
{
}
@@ -491,93 +488,6 @@ bool CPVRTimers::HasActiveTimers(void) const
return false;
}
-bool CPVRTimers::GetRootDirectory(const CPVRTimersPath &path, CFileItemList &items) const
-{
- CFileItemPtr item(new CFileItem(CPVRTimersPath::PATH_ADDTIMER, false));
- item->SetLabel(g_localizeStrings.Get(19026)); // "Add timer..."
- item->SetLabelPreformatted(true);
- item->SetSpecialSort(SortSpecialOnTop);
- item->SetIconImage("DefaultTVShows.png");
- items.Add(item);
-
- bool bRadio = path.IsRadio();
- bool bRules = path.IsRules();
-
- bool bHideDisabled = m_settings.GetBoolValue(CSettings::SETTING_PVRTIMERS_HIDEDISABLEDTIMERS);
-
- CSingleLock lock(m_critSection);
- for (const auto &tagsEntry : m_tags)
- {
- for (const auto &timer : tagsEntry.second)
- {
- if ((bRadio == timer->m_bIsRadio || (bRules && timer->m_iClientChannelUid == PVR_TIMER_ANY_CHANNEL)) &&
- (bRules == timer->IsTimerRule()) &&
- (!bHideDisabled || (timer->m_state != PVR_TIMER_STATE_DISABLED)))
- {
- item.reset(new CFileItem(timer));
- std::string strItemPath(
- CPVRTimersPath(path.GetPath(), timer->m_iClientId, timer->m_iClientIndex).GetPath());
- item->SetPath(strItemPath);
- items.Add(item);
- }
- }
- }
- return true;
-}
-
-bool CPVRTimers::GetSubDirectory(const CPVRTimersPath &path, CFileItemList &items) const
-{
- bool bRadio = path.IsRadio();
- unsigned int iParentId = path.GetParentId();
- int iClientId = path.GetClientId();
-
- bool bHideDisabled = m_settings.GetBoolValue(CSettings::SETTING_PVRTIMERS_HIDEDISABLEDTIMERS);
-
- CFileItemPtr item;
-
- CSingleLock lock(m_critSection);
- for (const auto &tagsEntry : m_tags)
- {
- for (const auto &timer : tagsEntry.second)
- {
- if ((timer->m_bIsRadio == bRadio) &&
- (timer->m_iParentClientIndex != PVR_TIMER_NO_PARENT) &&
- (timer->m_iClientId == iClientId) &&
- (timer->m_iParentClientIndex == iParentId) &&
- (!bHideDisabled || (timer->m_state != PVR_TIMER_STATE_DISABLED)))
- {
- item.reset(new CFileItem(timer));
- std::string strItemPath(
- CPVRTimersPath(path.GetPath(), timer->m_iClientId, timer->m_iClientIndex).GetPath());
- item->SetPath(strItemPath);
- items.Add(item);
- }
- }
- }
- return true;
-}
-
-bool CPVRTimers::GetDirectory(const std::string& strPath, CFileItemList &items) const
-{
- CPVRTimersPath path(strPath);
- if (path.IsValid())
- {
- if (path.IsTimersRoot())
- {
- /* Root folder containing either timer rules or timers. */
- return GetRootDirectory(path, items);
- }
- else if (path.IsTimerRule())
- {
- /* Sub folder containing the timers scheduled by the given timer rule. */
- return GetSubDirectory(path, items);
- }
- }
-
- CLog::LogF(LOGERROR,"Invalid URL %s", strPath.c_str());
- return false;
-}
-
/********** channel methods **********/
bool CPVRTimers::DeleteTimersOnChannel(const CPVRChannelPtr &channel, bool bDeleteTimerRules /* = true */, bool bCurrentlyActiveOnly /* = false */)
@@ -823,18 +733,20 @@ void CPVRTimers::UpdateChannels(void)
}
}
-void CPVRTimers::GetAll(CFileItemList& items) const
+std::vector<std::shared_ptr<CPVRTimerInfoTag>> CPVRTimers::GetAll() const
{
- CFileItemPtr item;
+ std::vector<std::shared_ptr<CPVRTimerInfoTag>> timers;
+
CSingleLock lock(m_critSection);
- for (MapTags::const_iterator it = m_tags.begin(); it != m_tags.end(); ++it)
+ for (const auto& tagsEntry : m_tags)
{
- for (VecTimerInfoTag::const_iterator timerIt = it->second.begin(); timerIt != it->second.end(); ++timerIt)
+ for (const auto& timer : tagsEntry.second)
{
- item.reset(new CFileItem(*timerIt));
- items.Add(item);
+ timers.emplace_back(timer);
}
}
+
+ return timers;
}
CPVRTimerInfoTagPtr CPVRTimers::GetById(unsigned int iTimerId) const
diff --git a/xbmc/pvr/timers/PVRTimers.h b/xbmc/pvr/timers/PVRTimers.h
index 4664c37a1b..89d6ddb1b7 100644
--- a/xbmc/pvr/timers/PVRTimers.h
+++ b/xbmc/pvr/timers/PVRTimers.h
@@ -21,7 +21,6 @@
#include "pvr/timers/PVRTimerInfoTag.h"
class CFileItem;
-class CFileItemList;
typedef std::shared_ptr<CFileItem> CFileItemPtr;
namespace PVR
@@ -107,9 +106,9 @@ namespace PVR
/*!
* Get all timers
- * @param items The list to add the timers to
+ * @return The list of all timers
*/
- void GetAll(CFileItemList& items) const;
+ std::vector<std::shared_ptr<CPVRTimerInfoTag>> GetAll() const;
/*!
* @return True when there is at least one timer that is active (states scheduled or recording), false otherwise.
@@ -181,14 +180,6 @@ namespace PVR
int AmountActiveRadioRecordings(void) const;
/*!
- * @brief Get all timers for the given path.
- * @param strPath The vfs path to get the timers for.
- * @param items The results.
- * @return True when the path was valid, false otherwise.
- */
- bool GetDirectory(const std::string& strPath, CFileItemList &items) const;
-
- /*!
* @brief Delete all timers on a channel.
* @param channel The channel to delete the timers for.
* @param bDeleteTimerRules True to delete timer rules too, false otherwise.
@@ -270,8 +261,6 @@ namespace PVR
private:
bool UpdateEntries(const CPVRTimersContainer &timers, const std::vector<int> &failedClients);
- bool GetRootDirectory(const CPVRTimersPath &path, CFileItemList &items) const;
- bool GetSubDirectory(const CPVRTimersPath &path, CFileItemList &items) const;
enum TimerKind
{
diff --git a/xbmc/pvr/windows/GUIWindowPVRGuide.cpp b/xbmc/pvr/windows/GUIWindowPVRGuide.cpp
index 37fad820f9..1cf24d72be 100644
--- a/xbmc/pvr/windows/GUIWindowPVRGuide.cpp
+++ b/xbmc/pvr/windows/GUIWindowPVRGuide.cpp
@@ -623,7 +623,7 @@ bool CGUIWindowPVRGuideBase::RefreshTimelineItems()
m_bFirstOpen = false;
// very first open of the window. come up with some data very fast...
- const std::vector<PVRChannelGroupMember> groupMembers = group->GetMembers();
+ const std::vector<PVRChannelGroupMember> groupMembers = group->GetMembers(CPVRChannelGroup::Include::ONLY_VISIBLE);
for (const auto& groupMember : groupMembers)
{
// fake a channel without epg