aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--xbmc/FileItem.cpp4
-rw-r--r--xbmc/pvr/PVRDatabase.cpp4
-rw-r--r--xbmc/pvr/PVRGUIDirectory.cpp137
-rw-r--r--xbmc/pvr/channels/CMakeLists.txt6
-rw-r--r--xbmc/pvr/channels/PVRChannel.cpp8
-rw-r--r--xbmc/pvr/channels/PVRChannel.h4
-rw-r--r--xbmc/pvr/channels/PVRChannelGroup.cpp148
-rw-r--r--xbmc/pvr/channels/PVRChannelGroup.h33
-rw-r--r--xbmc/pvr/channels/PVRChannelGroupInternal.cpp26
-rw-r--r--xbmc/pvr/channels/PVRChannelGroups.cpp52
-rw-r--r--xbmc/pvr/channels/PVRChannelGroups.h2
-rw-r--r--xbmc/pvr/channels/PVRChannelGroupsContainer.cpp11
-rw-r--r--xbmc/pvr/channels/PVRChannelsPath.cpp169
-rw-r--r--xbmc/pvr/channels/PVRChannelsPath.h67
-rw-r--r--xbmc/pvr/dialogs/GUIDialogPVRGroupManager.cpp2
-rw-r--r--xbmc/pvr/windows/GUIWindowPVRChannels.cpp7
-rw-r--r--xbmc/utils/URIUtils.cpp12
-rw-r--r--xbmc/utils/URIUtils.h1
18 files changed, 439 insertions, 254 deletions
diff --git a/xbmc/FileItem.cpp b/xbmc/FileItem.cpp
index d1b4127ebc..34e72b8056 100644
--- a/xbmc/FileItem.cpp
+++ b/xbmc/FileItem.cpp
@@ -851,9 +851,7 @@ bool CFileItem::IsPVRChannel() const
bool CFileItem::IsPVRChannelGroup() const
{
- return !StringUtils::EndsWithNoCase(m_strPath, ".pvr") &&
- (StringUtils::StartsWithNoCase(m_strPath, "pvr://channels/tv/") ||
- StringUtils::StartsWithNoCase(m_strPath, "pvr://channels/radio/"));
+ return URIUtils::IsPVRChannelGroup(m_strPath);
}
bool CFileItem::IsPVRRecording() const
diff --git a/xbmc/pvr/PVRDatabase.cpp b/xbmc/pvr/PVRDatabase.cpp
index 8be567884d..3404ca0205 100644
--- a/xbmc/pvr/PVRDatabase.cpp
+++ b/xbmc/pvr/PVRDatabase.cpp
@@ -573,7 +573,9 @@ bool CPVRDatabase::Get(CPVRChannelGroups &results)
{
while (!m_pDS->eof())
{
- CPVRChannelGroup data(m_pDS->fv("bIsRadio").get_asBool(), m_pDS->fv("idGroup").get_asInt(), m_pDS->fv("sName").get_asString(), results.GetGroupAll());
+ CPVRChannelGroup data(CPVRChannelsPath(m_pDS->fv("bIsRadio").get_asBool(), m_pDS->fv("sName").get_asString()),
+ m_pDS->fv("idGroup").get_asInt(),
+ results.GetGroupAll());
data.SetGroupType(m_pDS->fv("iGroupType").get_asInt());
data.SetLastWatched(static_cast<time_t>(m_pDS->fv("iLastWatched").get_asInt()));
data.SetHidden(m_pDS->fv("bIsHidden").get_asBool());
diff --git a/xbmc/pvr/PVRGUIDirectory.cpp b/xbmc/pvr/PVRGUIDirectory.cpp
index 6a54b54954..16ba93f31e 100644
--- a/xbmc/pvr/PVRGUIDirectory.cpp
+++ b/xbmc/pvr/PVRGUIDirectory.cpp
@@ -16,6 +16,7 @@
#include "pvr/channels/PVRChannelGroup.h"
#include "pvr/channels/PVRChannelGroups.h"
#include "pvr/channels/PVRChannelGroupsContainer.h"
+#include "pvr/channels/PVRChannelsPath.h"
#include "pvr/recordings/PVRRecording.h"
#include "pvr/recordings/PVRRecordings.h"
#include "pvr/recordings/PVRRecordingsPath.h"
@@ -69,17 +70,17 @@ bool CPVRGUIDirectory::GetDirectory(CFileItemList& results) const
std::shared_ptr<CFileItem> item;
item.reset(new CFileItem(base + "channels/", true));
- item->SetLabel(g_localizeStrings.Get(19019));
+ item->SetLabel(g_localizeStrings.Get(19019)); // Channels
item->SetLabelPreformatted(true);
results.Add(item);
item.reset(new CFileItem(base + "recordings/active/", true));
- item->SetLabel(g_localizeStrings.Get(19017)); // TV Recordings
+ item->SetLabel(g_localizeStrings.Get(19017)); // 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->SetLabel(g_localizeStrings.Get(19184)); // Deleted recordings
item->SetLabelPreformatted(true);
results.Add(item);
@@ -327,103 +328,67 @@ bool CPVRGUIDirectory::GetChannelGroupsDirectory(bool bRadio, bool bExcludeHidde
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, false, results);
- }
- else if (fileName == "channels/radio")
- {
- return GetChannelGroupsDirectory(true, false, results);
- }
- else if (StringUtils::StartsWith(fileName, "channels/tv/"))
+ const CPVRChannelsPath path(m_url.GetWithoutOptions());
+ if (path.IsValid())
{
- std::string strGroupName = fileName.substr(12);
- URIUtils::RemoveSlashAtEnd(strGroupName);
+ if (path.IsEmpty())
+ {
+ std::shared_ptr<CFileItem> item;
- 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);
+ // all tv channels
+ item.reset(new CFileItem(CPVRChannelsPath::PATH_TV_CHANNELS, true));
+ item->SetLabel(g_localizeStrings.Get(19020)); // TV
+ item->SetLabelPreformatted(true);
+ results.Add(item);
- if (group)
- {
- const std::vector<PVRChannelGroupMember> groupMembers = group->GetMembers();
- for (const auto& groupMember : groupMembers)
- {
- if (bShowHiddenChannels != groupMember.channel->IsHidden())
- continue;
+ // all radio channels
+ item.reset(new CFileItem(CPVRChannelsPath::PATH_RADIO_CHANNELS, true));
+ item->SetLabel(g_localizeStrings.Get(19021)); // Radio
+ item->SetLabelPreformatted(true);
+ results.Add(item);
- results.Add(std::make_shared<CFileItem>(groupMember.channel));
- }
+ return true;
}
- else
+ else if (path.IsChannelsRoot())
{
- CLog::LogF(LOGERROR, "Unable to obtain members of channel group '%s'", strGroupName.c_str());
- return false;
+ return GetChannelGroupsDirectory(path.IsRadio(), false, results);
}
+ else if (path.IsChannelGroup())
+ {
+ const std::string& strGroupName = path.GetGroupName();
+ bool bShowHiddenChannels = path.IsHiddenChannelGroup();
- 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);
+ std::shared_ptr<CPVRChannelGroup> group;
+ if (bShowHiddenChannels || strGroupName == "*") // all channels
+ {
+ group = CServiceBroker::GetPVRManager().ChannelGroups()->GetGroupAll(path.IsRadio());
+ }
+ else
+ {
+ group = CServiceBroker::GetPVRManager().ChannelGroups()->Get(path.IsRadio())->GetByName(strGroupName);
+ }
- if (group)
- {
- const std::vector<PVRChannelGroupMember> groupMembers = group->GetMembers();
- for (const auto& groupMember : groupMembers)
+ if (group)
{
- if (bShowHiddenChannels != groupMember.channel->IsHidden())
- continue;
+ 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));
+ 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;
}
- }
- else
- {
- CLog::LogF(LOGERROR, "Unable to obtain members of channel group '%s'", strGroupName.c_str());
- return false;
- }
- FilterDirectory(results);
- return true;
+ FilterDirectory(results);
+ return true;
+ }
}
-
return false;
}
diff --git a/xbmc/pvr/channels/CMakeLists.txt b/xbmc/pvr/channels/CMakeLists.txt
index f8f9f06dfa..39aa18f37f 100644
--- a/xbmc/pvr/channels/CMakeLists.txt
+++ b/xbmc/pvr/channels/CMakeLists.txt
@@ -4,7 +4,8 @@ set(SOURCES PVRChannel.cpp
PVRChannelGroups.cpp
PVRChannelGroupsContainer.cpp
PVRChannelNumber.cpp
- PVRRadioRDSInfoTag.cpp)
+ PVRRadioRDSInfoTag.cpp
+ PVRChannelsPath.cpp)
set(HEADERS PVRChannel.h
PVRChannelGroup.h
@@ -12,6 +13,7 @@ set(HEADERS PVRChannel.h
PVRChannelGroups.h
PVRChannelGroupsContainer.h
PVRChannelNumber.h
- PVRRadioRDSInfoTag.h)
+ PVRRadioRDSInfoTag.h
+ PVRChannelsPath.h)
core_add_library(pvr_channels)
diff --git a/xbmc/pvr/channels/PVRChannel.cpp b/xbmc/pvr/channels/PVRChannel.cpp
index 764fbaa869..f906b6a7de 100644
--- a/xbmc/pvr/channels/PVRChannel.cpp
+++ b/xbmc/pvr/channels/PVRChannel.cpp
@@ -14,6 +14,7 @@
#include "guilib/LocalizeStrings.h"
#include "pvr/PVRDatabase.h"
#include "pvr/PVRManager.h"
+#include "pvr/channels/PVRChannelsPath.h"
#include "pvr/epg/Epg.h"
#include "pvr/epg/EpgChannelData.h"
#include "pvr/epg/EpgContainer.h"
@@ -414,16 +415,13 @@ bool CPVRChannel::SetClientID(int iClientId)
return false;
}
-void CPVRChannel::UpdatePath(const std::string& groupPath)
+void CPVRChannel::UpdatePath(const std::string& channelGroup)
{
const CPVRClientPtr client = CServiceBroker::GetPVRManager().GetClient(m_iClientId);
if (client)
{
CSingleLock lock(m_critSection);
- const std::string strFileNameAndPath = StringUtils::Format("%s%s_%d.pvr",
- groupPath,
- client->ID().c_str(),
- m_iUniqueId);
+ const std::string strFileNameAndPath = CPVRChannelsPath(m_bIsRadio, channelGroup, client->ID(), m_iUniqueId);
if (m_strFileNameAndPath != strFileNameAndPath)
{
m_strFileNameAndPath = strFileNameAndPath;
diff --git a/xbmc/pvr/channels/PVRChannel.h b/xbmc/pvr/channels/PVRChannel.h
index 93c9e30f07..22f2adc39d 100644
--- a/xbmc/pvr/channels/PVRChannel.h
+++ b/xbmc/pvr/channels/PVRChannel.h
@@ -275,9 +275,9 @@ namespace PVR
/*!
* @brief Update the channel path
- * @param groupPath The new path of the group this channel belongs to
+ * @param channelGroup The (new) name of the group this channel belongs to
*/
- void UpdatePath(const std::string& groupPath);
+ void UpdatePath(const std::string& channelGroup);
/*!
* @return Storage id for this channel in CPVRChannelGroup
diff --git a/xbmc/pvr/channels/PVRChannelGroup.cpp b/xbmc/pvr/channels/PVRChannelGroup.cpp
index 5025d62c76..5fc561937c 100644
--- a/xbmc/pvr/channels/PVRChannelGroup.cpp
+++ b/xbmc/pvr/channels/PVRChannelGroup.cpp
@@ -17,6 +17,7 @@
#include "pvr/PVRManager.h"
#include "pvr/addons/PVRClients.h"
#include "pvr/channels/PVRChannel.h"
+#include "pvr/channels/PVRChannelsPath.h"
#include "pvr/epg/Epg.h"
#include "pvr/epg/EpgChannelData.h"
#include "pvr/epg/EpgInfoTag.h"
@@ -35,53 +36,43 @@
using namespace PVR;
-CPVRChannelGroup::CPVRChannelGroup()
-{
- OnInit();
-}
-
-CPVRChannelGroup::CPVRChannelGroup(bool bRadio,
- int iGroupId,
- const std::string& strGroupName,
- const std::shared_ptr<CPVRChannelGroup>& allChannelsGroup) :
- m_bRadio(bRadio),
- m_iGroupId(iGroupId),
- m_strGroupName(strGroupName),
- m_allChannelsGroup(allChannelsGroup)
+CPVRChannelGroup::CPVRChannelGroup(const CPVRChannelsPath& path,
+ int iGroupId /* = INVALID_GROUP_ID */,
+ const std::shared_ptr<CPVRChannelGroup>& allChannelsGroup /* = {} */)
+ : m_iGroupId(iGroupId)
+ , m_allChannelsGroup(allChannelsGroup)
+ , m_path(path)
{
OnInit();
}
CPVRChannelGroup::CPVRChannelGroup(const PVR_CHANNEL_GROUP& group,
- const std::shared_ptr<CPVRChannelGroup>& allChannelsGroup) :
- m_bRadio(group.bIsRadio),
- m_strGroupName(group.strGroupName),
- m_iPosition(group.iPosition),
- m_allChannelsGroup(allChannelsGroup)
+ const std::shared_ptr<CPVRChannelGroup>& allChannelsGroup)
+ : m_iPosition(group.iPosition)
+ , m_allChannelsGroup(allChannelsGroup)
+ , m_path(group.bIsRadio, group.strGroupName)
{
OnInit();
}
-CPVRChannelGroup::CPVRChannelGroup(const CPVRChannelGroup &group) :
- m_strGroupName(group.m_strGroupName)
-{
- m_bRadio = group.m_bRadio;
- m_iGroupType = group.m_iGroupType;
- m_iGroupId = group.m_iGroupId;
- m_bLoaded = group.m_bLoaded;
- m_bChanged = group.m_bChanged;
- m_bUsingBackendChannelOrder = group.m_bUsingBackendChannelOrder;
- m_bUsingBackendChannelNumbers = group.m_bUsingBackendChannelNumbers;
- m_iLastWatched = group.m_iLastWatched;
- m_bHidden = group.m_bHidden;
- m_bPreventSortAndRenumber = group.m_bPreventSortAndRenumber;
- m_members = group.m_members;
- m_sortedMembers = group.m_sortedMembers;
- m_iPosition = group.m_iPosition;
- m_failedClientsForChannels = group.m_failedClientsForChannels;
- m_failedClientsForChannelGroupMembers = group.m_failedClientsForChannelGroupMembers;
- m_allChannelsGroup = group.m_allChannelsGroup;
-
+CPVRChannelGroup::CPVRChannelGroup(const CPVRChannelGroup& group)
+ : m_iGroupType(group.m_iGroupType)
+ , m_iGroupId(group.m_iGroupId)
+ , m_bLoaded(group.m_bLoaded)
+ , m_bChanged(group.m_bChanged)
+ , m_bUsingBackendChannelOrder(group.m_bUsingBackendChannelOrder)
+ , m_bUsingBackendChannelNumbers(group.m_bUsingBackendChannelNumbers)
+ , m_bPreventSortAndRenumber(group.m_bPreventSortAndRenumber)
+ , m_iLastWatched(group.m_iLastWatched)
+ , m_bHidden(group.m_bHidden)
+ , m_iPosition(group.m_iPosition)
+ , m_sortedMembers(group.m_sortedMembers)
+ , m_members(group.m_members)
+ , m_failedClientsForChannels(group.m_failedClientsForChannels)
+ , m_failedClientsForChannelGroupMembers(group.m_failedClientsForChannelGroupMembers)
+ , m_allChannelsGroup(group.m_allChannelsGroup)
+ , m_path(group.m_path)
+{
OnInit();
}
@@ -93,11 +84,10 @@ CPVRChannelGroup::~CPVRChannelGroup(void)
bool CPVRChannelGroup::operator==(const CPVRChannelGroup& right) const
{
- return (m_bRadio == right.m_bRadio &&
- m_iGroupType == right.m_iGroupType &&
- m_iGroupId == right.m_iGroupId &&
- m_strGroupName == right.m_strGroupName &&
- m_iPosition == right.m_iPosition);
+ return (m_iGroupType == right.m_iGroupType &&
+ m_iGroupId == right.m_iGroupId &&
+ m_iPosition == right.m_iPosition &&
+ m_path == right.m_path);
}
bool CPVRChannelGroup::operator!=(const CPVRChannelGroup &right) const
@@ -125,18 +115,18 @@ bool CPVRChannelGroup::Load(std::vector<std::shared_ptr<CPVRChannel>>& channelsT
m_bUsingBackendChannelNumbers = settings->GetBool(CSettings::SETTING_PVRMANAGER_USEBACKENDCHANNELNUMBERS);
int iChannelCount = m_iGroupId > 0 ? LoadFromDb() : 0;
- CLog::LogFC(LOGDEBUG, LOGPVR, "%d channels loaded from the database for group '%s'", iChannelCount, m_strGroupName.c_str());
+ CLog::LogFC(LOGDEBUG, LOGPVR, "%d channels loaded from the database for group '%s'", iChannelCount, GroupName().c_str());
if (!Update(channelsToRemove))
{
- CLog::LogF(LOGERROR, "Failed to update channels for group '%s', m_strGroupName.c_str()");
+ CLog::LogF(LOGERROR, "Failed to update channels for group '%s'", GroupName().c_str());
return false;
}
if (Size() - iChannelCount > 0)
{
CLog::LogFC(LOGDEBUG, LOGPVR, "%d channels added from clients to group '%s'",
- static_cast<int>(Size() - iChannelCount), m_strGroupName.c_str());
+ static_cast<int>(Size() - iChannelCount), GroupName().c_str());
}
SortAndRenumber();
@@ -161,16 +151,28 @@ bool CPVRChannelGroup::Update(std::vector<std::shared_ptr<CPVRChannel>>& channel
!CServiceBroker::GetSettingsComponent()->GetSettings()->GetBool(CSettings::SETTING_PVRMANAGER_SYNCCHANNELGROUPS))
return true;
- CPVRChannelGroup PVRChannels_tmp(m_bRadio, m_iGroupId, m_strGroupName, m_allChannelsGroup);
+ CPVRChannelGroup PVRChannels_tmp(m_path, m_iGroupId, m_allChannelsGroup);
PVRChannels_tmp.SetPreventSortAndRenumber();
PVRChannels_tmp.LoadFromClients();
m_failedClientsForChannelGroupMembers = PVRChannels_tmp.m_failedClientsForChannelGroupMembers;
return UpdateGroupEntries(PVRChannels_tmp, channelsToRemove);
}
-std::string CPVRChannelGroup::GetPath() const
+const CPVRChannelsPath& CPVRChannelGroup::GetPath() const
+{
+ CSingleLock lock(m_critSection);
+ return m_path;
+}
+
+void CPVRChannelGroup::SetPath(const CPVRChannelsPath& path)
{
- return StringUtils::Format("pvr://channels/%s/%s/", m_bRadio ? "radio" : "tv", GroupName().c_str());
+ CSingleLock lock(m_critSection);
+ if (m_path != path)
+ {
+ m_path = path;
+ m_bChanged = true;
+ Persist();
+ }
}
bool CPVRChannelGroup::SetChannelNumber(const CPVRChannelPtr &channel, const CPVRChannelNumber &channelNumber)
@@ -499,7 +501,7 @@ bool CPVRChannelGroup::AddAndUpdateChannels(const CPVRChannelGroup &channels, bo
bReturn = true;
CLog::Log(LOGINFO,"Added %s channel '%s' to group '%s'",
- m_bRadio ? "radio" : "TV", existingChannel.channel->ChannelName().c_str(), GroupName().c_str());
+ IsRadio() ? "radio" : "TV", existingChannel.channel->ChannelName().c_str(), GroupName().c_str());
}
}
@@ -535,7 +537,7 @@ std::vector<CPVRChannelPtr> CPVRChannelGroup::RemoveDeletedChannels(const CPVRCh
{
/* channel was not found */
CLog::Log(LOGINFO,"Deleted %s channel '%s' from group '%s'",
- m_bRadio ? "radio" : "TV", channel->ChannelName().c_str(), GroupName().c_str());
+ IsRadio() ? "radio" : "TV", channel->ChannelName().c_str(), GroupName().c_str());
removedChannels.emplace_back(channel);
@@ -671,28 +673,6 @@ bool CPVRChannelGroup::IsGroupMember(int iChannelId) const
return bReturn;
}
-bool CPVRChannelGroup::SetGroupName(const std::string &strGroupName, bool bSaveInDb /* = false */)
-{
- bool bReturn(false);
- CSingleLock lock(m_critSection);
-
- if (m_strGroupName != strGroupName)
- {
- /* update the name */
- m_strGroupName = strGroupName;
- m_bChanged = true;
-// SetChanged();
-
- /* persist the changes */
- if (bSaveInDb)
- Persist();
-
- bReturn = true;
- }
-
- return bReturn;
-}
-
bool CPVRChannelGroup::Persist(void)
{
bool bReturn(true);
@@ -830,7 +810,7 @@ void CPVRChannelGroup::OnSettingChanged(std::shared_ptr<const CSetting> setting)
if (bChannelOrderChanged || bChannelNumbersChanged)
{
CLog::LogFC(LOGDEBUG, LOGPVR, "Renumbering channel group '%s' to use the backend channel order and/or numbers",
- m_strGroupName.c_str());
+ GroupName().c_str());
if (bChannelOrderChanged)
UpdateClientPriorities();
@@ -948,8 +928,24 @@ int CPVRChannelGroup::GroupType(void) const
std::string CPVRChannelGroup::GroupName(void) const
{
CSingleLock lock(m_critSection);
- std::string strReturn(m_strGroupName);
- return strReturn;
+ return m_path.GetGroupName();
+}
+
+void CPVRChannelGroup::SetGroupName(const std::string& strGroupName)
+{
+ CSingleLock lock(m_critSection);
+ if (m_path.GetGroupName() != strGroupName)
+ {
+ m_path = CPVRChannelsPath(m_path.IsRadio(), strGroupName);
+ m_bChanged = true;
+ Persist();
+ }
+}
+
+bool CPVRChannelGroup::IsRadio() const
+{
+ CSingleLock lock(m_critSection);
+ return m_path.IsRadio();
}
time_t CPVRChannelGroup::LastWatched(void) const
diff --git a/xbmc/pvr/channels/PVRChannelGroup.h b/xbmc/pvr/channels/PVRChannelGroup.h
index 878eafe856..4f05b2d70e 100644
--- a/xbmc/pvr/channels/PVRChannelGroup.h
+++ b/xbmc/pvr/channels/PVRChannelGroup.h
@@ -11,6 +11,7 @@
#include "XBDateTime.h"
#include "pvr/PVRTypes.h"
#include "pvr/channels/PVRChannelNumber.h"
+#include "pvr/channels/PVRChannelsPath.h"
#include "settings/lib/ISettingCallback.h"
#include "utils/Observer.h"
@@ -61,12 +62,13 @@ namespace PVR
/*!
* @brief Create a new channel group instance.
- * @param bRadio True if this group holds radio channels.
+ * @param path The channel group path.
* @param iGroupId The database ID of this group or INVALID_GROUP_ID if the group was not yet stored in the database.
- * @param strGroupName The name of this group.
* @param allChannelsGroup The channel group containing all TV or radio channels.
*/
- CPVRChannelGroup(bool bRadio, int iGroupId, const std::string& strGroupName, const std::shared_ptr<CPVRChannelGroup>& allChannelsGroup);
+ CPVRChannelGroup(const CPVRChannelsPath& path,
+ int iGroupId = INVALID_GROUP_ID,
+ const std::shared_ptr<CPVRChannelGroup>& allChannelsGroup = {});
/*!
* @brief Create a new channel group instance from a channel group provided by an add-on.
@@ -113,7 +115,13 @@ namespace PVR
* @brief Get the path of this group.
* @return the path.
*/
- std::string GetPath() const;
+ const CPVRChannelsPath& GetPath() const;
+
+ /*!
+ * @brief Set the path of this group.
+ * @param the path.
+ */
+ void SetPath(const CPVRChannelsPath& path);
/*!
* @brief Change the channelnumber of a group. Used by CGUIDialogPVRChannelManager. Call SortByChannelNumber() and Renumber() after all changes are done.
@@ -141,10 +149,8 @@ namespace PVR
/*!
* @brief Change the name of this group.
* @param strGroupName The new group name.
- * @param bSaveInDb Save in the database or not.
- * @return True if the something changed, false otherwise.
*/
- bool SetGroupName(const std::string &strGroupName, bool bSaveInDb = false);
+ void SetGroupName(const std::string& strGroupName);
/*!
* @brief Persist changed or new data.
@@ -176,13 +182,7 @@ namespace PVR
* @brief True if this group holds radio channels, false if it holds TV channels.
* @return True if this group holds radio channels, false if it holds TV channels.
*/
- bool IsRadio(void) const { return m_bRadio; }
-
- /*!
- * @brief Set 'radio' property of this group.
- * @param bIsRadio The new value for the 'radio' property.
- */
- void SetRadio(bool bIsRadio) { m_bRadio = bIsRadio; }
+ bool IsRadio() const;
/*!
* @brief True if sorting should be prevented when adding/updating channels to the group.
@@ -439,8 +439,6 @@ namespace PVR
bool IsMissingChannelsFromClient(int iClientId) const;
protected:
- CPVRChannelGroup();
-
/*!
* @brief Init class
*/
@@ -506,10 +504,8 @@ namespace PVR
*/
bool UpdateClientPriorities();
- bool m_bRadio = false; /*!< true if this container holds radio channels, false if it holds TV channels */
int m_iGroupType = PVR_GROUP_TYPE_DEFAULT; /*!< The type of this group */
int m_iGroupId = INVALID_GROUP_ID; /*!< The ID of this group in the database */
- std::string m_strGroupName; /*!< The name of this group */
bool m_bLoaded = false; /*!< True if this container is loaded, false otherwise */
bool m_bChanged = false; /*!< true if anything changed in this group that hasn't been persisted, false otherwise */
bool m_bUsingBackendChannelOrder = false; /*!< true to use the channel order from backends, false otherwise */
@@ -528,5 +524,6 @@ namespace PVR
CDateTime GetEPGDate(EpgDateType epgDateType) const;
std::shared_ptr<CPVRChannelGroup> m_allChannelsGroup;
+ CPVRChannelsPath m_path;
};
}
diff --git a/xbmc/pvr/channels/PVRChannelGroupInternal.cpp b/xbmc/pvr/channels/PVRChannelGroupInternal.cpp
index b540bab79e..103c7f5c53 100644
--- a/xbmc/pvr/channels/PVRChannelGroupInternal.cpp
+++ b/xbmc/pvr/channels/PVRChannelGroupInternal.cpp
@@ -26,12 +26,10 @@
using namespace PVR;
using namespace KODI::MESSAGING;
-CPVRChannelGroupInternal::CPVRChannelGroupInternal(bool bRadio) :
- m_iHiddenChannels(0)
+CPVRChannelGroupInternal::CPVRChannelGroupInternal(bool bRadio)
+: CPVRChannelGroup(CPVRChannelsPath(bRadio, g_localizeStrings.Get(19287)), PVR_GROUP_TYPE_INTERNAL)
+, m_iHiddenChannels(0)
{
- m_iGroupType = PVR_GROUP_TYPE_INTERNAL;
- m_bRadio = bRadio;
- m_strGroupName = g_localizeStrings.Get(19287);
}
CPVRChannelGroupInternal::CPVRChannelGroupInternal(const CPVRChannelGroup &group) :
@@ -64,10 +62,10 @@ void CPVRChannelGroupInternal::CheckGroupName(void)
CSingleLock lock(m_critSection);
/* check whether the group name is still correct, or channels will fail to load after the language setting changed */
- std::string strNewGroupName = g_localizeStrings.Get(19287);
- if (m_strGroupName != strNewGroupName)
+ const std::string strNewGroupName = g_localizeStrings.Get(19287);
+ if (GroupName() != strNewGroupName)
{
- SetGroupName(strNewGroupName, true);
+ SetGroupName(strNewGroupName);
UpdateChannelPaths();
}
}
@@ -81,7 +79,7 @@ void CPVRChannelGroupInternal::UpdateChannelPaths(void)
if (it->second.channel->IsHidden())
++m_iHiddenChannels;
else
- it->second.channel->UpdatePath(GetPath());
+ it->second.channel->UpdatePath(GroupName());
}
}
@@ -101,7 +99,7 @@ CPVRChannelPtr CPVRChannelGroupInternal::UpdateFromClient(const CPVRChannelPtr &
iChannelNumber = static_cast<int>(m_sortedMembers.size()) + 1;
PVRChannelGroupMember newMember(channel, CPVRChannelNumber(iChannelNumber, channelNumber.GetSubChannelNumber()), 0);
- channel->UpdatePath(GetPath());
+ channel->UpdatePath(GroupName());
m_sortedMembers.push_back(newMember);
m_members.insert(std::make_pair(channel->StorageId(), newMember));
m_bChanged = true;
@@ -113,7 +111,7 @@ CPVRChannelPtr CPVRChannelGroupInternal::UpdateFromClient(const CPVRChannelPtr &
bool CPVRChannelGroupInternal::Update(std::vector<std::shared_ptr<CPVRChannel>>& channelsToRemove)
{
- CPVRChannelGroupInternal PVRChannels_tmp(m_bRadio);
+ CPVRChannelGroupInternal PVRChannels_tmp(IsRadio());
PVRChannels_tmp.SetPreventSortAndRenumber();
PVRChannels_tmp.LoadFromClients();
m_failedClientsForChannels = PVRChannels_tmp.m_failedClientsForChannels;
@@ -243,7 +241,7 @@ bool CPVRChannelGroupInternal::AddAndUpdateChannels(const CPVRChannelGroup &chan
if (existingChannel.channel->UpdateFromClient(it->second.channel))
{
bReturn = true;
- CLog::LogFC(LOGDEBUG, LOGPVR, "Updated {} channel '{}' from PVR client", m_bRadio ? "radio" : "TV", it->second.channel->ChannelName());
+ CLog::LogFC(LOGDEBUG, LOGPVR, "Updated {} channel '{}' from PVR client", IsRadio() ? "radio" : "TV", it->second.channel->ChannelName());
}
}
else
@@ -252,10 +250,10 @@ bool CPVRChannelGroupInternal::AddAndUpdateChannels(const CPVRChannelGroup &chan
UpdateFromClient(it->second.channel, bUseBackendChannelNumbers ? it->second.channel->ClientChannelNumber() : CPVRChannelNumber());
if (it->second.channel->CreateEPG())
{
- CLog::LogFC(LOGDEBUG, LOGPVR, "Created EPG for {} channel '{}' from PVR client", m_bRadio ? "radio" : "TV", it->second.channel->ChannelName());
+ CLog::LogFC(LOGDEBUG, LOGPVR, "Created EPG for {} channel '{}' from PVR client", IsRadio() ? "radio" : "TV", it->second.channel->ChannelName());
}
bReturn = true;
- CLog::LogFC(LOGDEBUG, LOGPVR, "Added {} channel '{}' from PVR client", m_bRadio ? "radio" : "TV", it->second.channel->ChannelName());
+ CLog::LogFC(LOGDEBUG, LOGPVR, "Added {} channel '{}' from PVR client", IsRadio() ? "radio" : "TV", it->second.channel->ChannelName());
}
}
diff --git a/xbmc/pvr/channels/PVRChannelGroups.cpp b/xbmc/pvr/channels/PVRChannelGroups.cpp
index d5e2ccd400..4a3030521d 100644
--- a/xbmc/pvr/channels/PVRChannelGroups.cpp
+++ b/xbmc/pvr/channels/PVRChannelGroups.cpp
@@ -13,6 +13,7 @@
#include "pvr/PVRManager.h"
#include "pvr/addons/PVRClients.h"
#include "pvr/channels/PVRChannelGroupInternal.h"
+#include "pvr/channels/PVRChannelsPath.h"
#include "settings/AdvancedSettings.h"
#include "settings/Settings.h"
#include "settings/SettingsComponent.h"
@@ -77,13 +78,12 @@ bool CPVRChannelGroups::Update(const CPVRChannelGroup &group, bool bUpdateFromCl
{
// create a new group if none was found. Copy the properties immediately
// so the group doesn't get flagged as "changed" further down.
- updateGroup.reset(new CPVRChannelGroup(group.IsRadio(), group.GroupID(), group.GroupName(), GetGroupAll()));
+ updateGroup.reset(new CPVRChannelGroup(CPVRChannelsPath(group.IsRadio(), group.GroupName()), group.GroupID(), GetGroupAll()));
m_groups.push_back(updateGroup);
}
- updateGroup->SetRadio(group.IsRadio());
+ updateGroup->SetPath(group.GetPath());
updateGroup->SetGroupID(group.GroupID());
- updateGroup->SetGroupName(group.GroupName());
updateGroup->SetGroupType(group.GroupType());
updateGroup->SetPosition(group.GetPosition());
@@ -123,31 +123,16 @@ void CPVRChannelGroups::SortGroups()
}
}
-std::shared_ptr<CPVRChannel> CPVRChannelGroups::GetByPath(const std::string& strInPath) const
+std::shared_ptr<CPVRChannel> CPVRChannelGroups::GetByPath(const CPVRChannelsPath& path) const
{
- std::string strPath = strInPath;
- URIUtils::RemoveSlashAtEnd(strPath);
- std::string strCheckPath;
-
- CSingleLock lock(m_critSection);
- for (const auto& group : m_groups)
+ if (path.IsChannel())
{
- // check if the path matches
- strCheckPath = group->GetPath();
- if (URIUtils::PathHasParent(strPath, strCheckPath))
- {
- strPath.erase(0, strCheckPath.size());
- std::vector<std::string> split(StringUtils::Split(strPath, '_', 2));
- if (split.size() == 2)
- {
- const CPVRChannelPtr channel = group->GetByUniqueID(atoi(split[1].c_str()), CServiceBroker::GetPVRManager().Clients()->GetClientId(split[0]));
- if (channel)
- return channel;
- }
- }
+ const std::shared_ptr<CPVRChannelGroup> group = GetByName(path.GetGroupName());
+ if (group)
+ return group->GetByUniqueID(path.GetChannelUID(),
+ CServiceBroker::GetPVRManager().Clients()->GetClientId(path.GetClientID()));
}
- // no match
return {};
}
@@ -179,16 +164,15 @@ std::vector<CPVRChannelGroupPtr> CPVRChannelGroups::GetGroupsByChannel(const CPV
std::shared_ptr<CPVRChannelGroup> CPVRChannelGroups::GetGroupByPath(const std::string& strInPath) const
{
- // group paths returned by CPVRChannelGroup::GetPath() are always terminated by a "/"
- std::string strPath = strInPath;
- if (!strPath.empty() && strPath[strPath.size() - 1] != '/')
- strPath += '/';
-
- CSingleLock lock(m_critSection);
- for (const auto& group : m_groups)
+ const CPVRChannelsPath path(strInPath);
+ if (path.IsChannelGroup())
{
- if (group->GetPath() == strPath)
- return group;
+ CSingleLock lock(m_critSection);
+ for (const auto& group : m_groups)
+ {
+ if (group->GetPath() == path)
+ return group;
+ }
}
return {};
}
@@ -503,7 +487,7 @@ bool CPVRChannelGroups::AddGroup(const std::string &strName)
if (!group)
{
// create a new group
- group.reset(new CPVRChannelGroup(m_bRadio, CPVRChannelGroup::INVALID_GROUP_ID, strName, GetGroupAll()));
+ group.reset(new CPVRChannelGroup(CPVRChannelsPath(m_bRadio, strName), CPVRChannelGroup::INVALID_GROUP_ID, GetGroupAll()));
m_groups.push_back(group);
bPersist = true;
diff --git a/xbmc/pvr/channels/PVRChannelGroups.h b/xbmc/pvr/channels/PVRChannelGroups.h
index b8221252de..0f2b88a238 100644
--- a/xbmc/pvr/channels/PVRChannelGroups.h
+++ b/xbmc/pvr/channels/PVRChannelGroups.h
@@ -69,7 +69,7 @@ namespace PVR
* @param strPath The path to the channel
* @return The channel, or nullptr if not found
*/
- std::shared_ptr<CPVRChannel> GetByPath(const std::string& strPath) const;
+ std::shared_ptr<CPVRChannel> GetByPath(const CPVRChannelsPath& path) const;
/*!
* @brief Get a pointer to a channel group given its ID.
diff --git a/xbmc/pvr/channels/PVRChannelGroupsContainer.cpp b/xbmc/pvr/channels/PVRChannelGroupsContainer.cpp
index 8cf93af1c7..cf1701afa3 100644
--- a/xbmc/pvr/channels/PVRChannelGroupsContainer.cpp
+++ b/xbmc/pvr/channels/PVRChannelGroupsContainer.cpp
@@ -110,17 +110,16 @@ std::shared_ptr<CPVRChannel> CPVRChannelGroupsContainer::GetChannelForEpgTag(con
if (!epgTag)
return {};
- const CPVRChannelGroups* groups = epgTag->IsRadio() ? m_groupsRadio : m_groupsTV;
- return groups->GetGroupAll()->GetByUniqueID(epgTag->UniqueChannelID(), epgTag->ClientID());
+ return Get(epgTag->IsRadio())->GetGroupAll()->GetByUniqueID(epgTag->UniqueChannelID(), epgTag->ClientID());
}
std::shared_ptr<CPVRChannel> CPVRChannelGroupsContainer::GetByPath(const std::string& strPath) const
{
- const std::shared_ptr<CPVRChannel> channel = m_groupsTV->GetByPath(strPath);
- if (channel)
- return channel;
+ const CPVRChannelsPath path(strPath);
+ if (path.IsValid())
+ return Get(path.IsRadio())->GetByPath(path);
- return m_groupsRadio->GetByPath(strPath);
+ return {};
}
CPVRChannelGroupPtr CPVRChannelGroupsContainer::GetSelectedGroup(bool bRadio) const
diff --git a/xbmc/pvr/channels/PVRChannelsPath.cpp b/xbmc/pvr/channels/PVRChannelsPath.cpp
new file mode 100644
index 0000000000..c73b3916d5
--- /dev/null
+++ b/xbmc/pvr/channels/PVRChannelsPath.cpp
@@ -0,0 +1,169 @@
+/*
+ * 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 "PVRChannelsPath.h"
+
+#include "URL.h"
+#include "utils/StringUtils.h"
+#include "utils/URIUtils.h"
+#include "utils/log.h"
+
+#include <string>
+#include <vector>
+
+using namespace PVR;
+
+const std::string CPVRChannelsPath::PATH_TV_CHANNELS = "pvr://channels/tv/";
+const std::string CPVRChannelsPath::PATH_RADIO_CHANNELS = "pvr://channels/radio/";
+
+
+CPVRChannelsPath::CPVRChannelsPath(const std::string& strPath)
+{
+ std::string strVarPath = TrimSlashes(strPath);
+ const std::vector<std::string> segments = URIUtils::SplitPath(strVarPath);
+
+ for (const std::string& segment : segments)
+ {
+ switch (m_kind)
+ {
+ case Kind::INVALID:
+ if (segment == "pvr://")
+ m_kind = Kind::PROTO; // pvr:// followed by something => go on
+ else if (segment == "pvr:" && segments.size() == 1) // just pvr:// => invalid
+ strVarPath = "pvr:/";
+ break;
+
+ case Kind::PROTO:
+ if (segment == "channels")
+ m_kind = Kind::EMPTY; // pvr://channels
+ else
+ m_kind = Kind::INVALID;
+ break;
+
+ case Kind::EMPTY:
+ if (segment == "tv" || segment == "radio")
+ {
+ m_kind = Kind::ROOT; // pvr://channels/(tv|radio)
+ m_bRadio = (segment == "radio");
+ }
+ else
+ {
+ CLog::LogF(LOGERROR, "Invalid channels path '%s' - channel root segment syntax error.", strPath.c_str());
+ m_kind = Kind::INVALID;
+ }
+ break;
+
+ case Kind::ROOT:
+ m_kind = Kind::GROUP; // pvr://channels/(tv|radio)/<groupname>
+ m_group = CURL::Decode(segment);
+ break;
+
+ case Kind::GROUP:
+ {
+ std::vector<std::string> tokens = StringUtils::Split(segment, "_");
+ if (tokens.size() == 2)
+ {
+ m_clientID = tokens[0];
+ tokens = StringUtils::Split(tokens[1], ".");
+ if (tokens.size() == 2 && tokens[1] == "pvr")
+ {
+ std::string channelUID = tokens[0];
+ if (!channelUID.empty() && channelUID.find_first_not_of("0123456789") == std::string::npos)
+ m_iChannelUID = std::atoi(channelUID.c_str());
+ }
+ }
+
+ if (!m_clientID.empty() && m_iChannelUID >= 0)
+ {
+ m_kind = Kind::CHANNEL; // pvr://channels/(tv|radio)/<groupname>/<addonid>_<channeluid>.pvr
+ }
+ else
+ {
+ CLog::LogF(LOGERROR, "Invalid channels path '%s' - channel segment syntax error.", strPath.c_str());
+ m_kind = Kind::INVALID;
+ }
+ break;
+ }
+
+ case Kind::CHANNEL:
+ CLog::LogF(LOGERROR, "Invalid channels path '%s' - too many path segments.", strPath.c_str());
+ m_kind = Kind::INVALID; // too many segments
+ break;
+ }
+
+ if (m_kind == Kind::INVALID)
+ break;
+ }
+
+ // append slash to all folders
+ if (m_kind < Kind::CHANNEL)
+ strVarPath.append("/");
+
+ m_path = strVarPath;
+}
+
+CPVRChannelsPath::CPVRChannelsPath(bool bRadio, bool bHidden, const std::string& strGroupName)
+ : m_bRadio(bRadio)
+{
+ if (!bHidden && strGroupName.empty())
+ m_kind = Kind::EMPTY;
+ else
+ m_kind = Kind::GROUP;
+
+ m_group = bHidden ? ".hidden" : strGroupName;
+ m_path = StringUtils::Format("pvr://channels/%s/%s", bRadio ? "radio" : "tv", CURL::Encode(m_group).c_str());
+
+ if (!m_group.empty())
+ m_path.append("/");
+}
+
+CPVRChannelsPath::CPVRChannelsPath(bool bRadio, const std::string& strGroupName)
+ : m_bRadio(bRadio)
+{
+ if (strGroupName.empty())
+ m_kind = Kind::EMPTY;
+ else
+ m_kind = Kind::GROUP;
+
+ m_group = strGroupName;
+ m_path = StringUtils::Format("pvr://channels/%s/%s", bRadio ? "radio" : "tv", CURL::Encode(m_group).c_str());
+
+ if (!m_group.empty())
+ m_path.append("/");
+}
+
+CPVRChannelsPath::CPVRChannelsPath(bool bRadio, const std::string& strGroupName, const std::string& strClientID, int iChannelUID)
+ : m_bRadio(bRadio)
+{
+ if (!strGroupName.empty() && !strClientID.empty() && iChannelUID >= 0)
+ {
+ m_kind = Kind::CHANNEL;
+ m_group = strGroupName;
+ m_clientID = strClientID;
+ m_iChannelUID = iChannelUID;
+ m_path = StringUtils::Format("pvr://channels/%s/%s/%s_%d.pvr",
+ bRadio ? "radio" : "tv", CURL::Encode(m_group).c_str(), m_clientID.c_str(), m_iChannelUID);
+ }
+}
+
+bool CPVRChannelsPath::IsHiddenChannelGroup() const
+{
+ return m_kind == Kind::GROUP && m_group == ".hidden";
+}
+
+std::string CPVRChannelsPath::TrimSlashes(const std::string& strString)
+{
+ std::string strTrimmed = strString;
+ while (!strTrimmed.empty() && strTrimmed.front() == '/')
+ strTrimmed.erase(0, 1);
+
+ while (!strTrimmed.empty() && strTrimmed.back() == '/')
+ strTrimmed.pop_back();
+
+ return strTrimmed;
+}
diff --git a/xbmc/pvr/channels/PVRChannelsPath.h b/xbmc/pvr/channels/PVRChannelsPath.h
new file mode 100644
index 0000000000..19e0a64ce6
--- /dev/null
+++ b/xbmc/pvr/channels/PVRChannelsPath.h
@@ -0,0 +1,67 @@
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include <string>
+
+class CDateTime;
+
+namespace PVR
+{
+ class CPVRChannelsPath
+ {
+ public:
+ static const std::string PATH_TV_CHANNELS;
+ static const std::string PATH_RADIO_CHANNELS;
+
+ explicit CPVRChannelsPath(const std::string& strPath);
+ CPVRChannelsPath(bool bRadio, const std::string& strGroupName);
+ CPVRChannelsPath(bool bRadio, bool bHidden, const std::string& strGroupName);
+ CPVRChannelsPath(bool bRadio, const std::string& strGroupName, const std::string& strClientID, int iChannelUID);
+
+ operator std::string() const { return m_path; }
+ bool operator ==(const CPVRChannelsPath& right) const { return m_path == right.m_path; }
+ bool operator !=(const CPVRChannelsPath& right) const { return !(*this == right); }
+
+ bool IsValid() const { return m_kind > Kind::PROTO; }
+
+ bool IsEmpty() const { return m_kind == Kind::EMPTY; }
+ bool IsChannelsRoot() const { return m_kind == Kind::ROOT; }
+ bool IsChannelGroup() const { return m_kind == Kind::GROUP; }
+ bool IsChannel() const { return m_kind == Kind::CHANNEL; }
+
+ bool IsHiddenChannelGroup() const;
+
+ bool IsRadio() const { return m_bRadio; }
+
+ const std::string& GetGroupName() const { return m_group; }
+ const std::string& GetClientID() const { return m_clientID; }
+ int GetChannelUID() const { return m_iChannelUID; }
+
+ private:
+ static std::string TrimSlashes(const std::string& strString);
+
+ enum class Kind
+ {
+ INVALID,
+ PROTO,
+ EMPTY,
+ ROOT,
+ GROUP,
+ CHANNEL,
+ };
+
+ Kind m_kind = Kind::INVALID;
+ bool m_bRadio = false;;
+ std::string m_path;
+ std::string m_group;
+ std::string m_clientID;
+ int m_iChannelUID = -1;
+ };
+}
diff --git a/xbmc/pvr/dialogs/GUIDialogPVRGroupManager.cpp b/xbmc/pvr/dialogs/GUIDialogPVRGroupManager.cpp
index 857902d67b..d6aa404e14 100644
--- a/xbmc/pvr/dialogs/GUIDialogPVRGroupManager.cpp
+++ b/xbmc/pvr/dialogs/GUIDialogPVRGroupManager.cpp
@@ -170,7 +170,7 @@ bool CGUIDialogPVRGroupManager::ActionButtonRenameGroup(CGUIMessage &message)
if (!strGroupName.empty())
{
ClearSelectedGroupsThumbnail();
- m_selectedGroup->SetGroupName(strGroupName, true);
+ m_selectedGroup->SetGroupName(strGroupName);
Update();
}
}
diff --git a/xbmc/pvr/windows/GUIWindowPVRChannels.cpp b/xbmc/pvr/windows/GUIWindowPVRChannels.cpp
index 3398fc5b31..b97116fdf2 100644
--- a/xbmc/pvr/windows/GUIWindowPVRChannels.cpp
+++ b/xbmc/pvr/windows/GUIWindowPVRChannels.cpp
@@ -27,6 +27,7 @@
#include "pvr/channels/PVRChannel.h"
#include "pvr/channels/PVRChannelGroup.h"
#include "pvr/channels/PVRChannelGroupsContainer.h"
+#include "pvr/channels/PVRChannelsPath.h"
#include "pvr/dialogs/GUIDialogPVRChannelManager.h"
#include "pvr/dialogs/GUIDialogPVRGroupManager.h"
#include "pvr/epg/Epg.h"
@@ -351,8 +352,7 @@ CGUIWindowPVRTVChannels::CGUIWindowPVRTVChannels()
std::string CGUIWindowPVRTVChannels::GetDirectoryPath()
{
- return StringUtils::Format("pvr://channels/tv/%s/",
- m_bShowHiddenChannels ? ".hidden" : GetChannelGroup()->GroupName().c_str());
+ return CPVRChannelsPath(false, m_bShowHiddenChannels, GetChannelGroup()->GroupName());
}
CGUIWindowPVRRadioChannels::CGUIWindowPVRRadioChannels()
@@ -362,6 +362,5 @@ CGUIWindowPVRRadioChannels::CGUIWindowPVRRadioChannels()
std::string CGUIWindowPVRRadioChannels::GetDirectoryPath()
{
- return StringUtils::Format("pvr://channels/radio/%s/",
- m_bShowHiddenChannels ? ".hidden" : GetChannelGroup()->GroupName().c_str());
+ return CPVRChannelsPath(true, m_bShowHiddenChannels, GetChannelGroup()->GroupName());
}
diff --git a/xbmc/utils/URIUtils.cpp b/xbmc/utils/URIUtils.cpp
index 5bbef50794..f0f84e4517 100644
--- a/xbmc/utils/URIUtils.cpp
+++ b/xbmc/utils/URIUtils.cpp
@@ -13,6 +13,7 @@
#include "filesystem/SpecialProtocol.h"
#include "filesystem/StackDirectory.h"
#include "network/DNSNameCache.h"
+#include "pvr/channels/PVRChannelsPath.h"
#include "settings/AdvancedSettings.h"
#include "URL.h"
#include "utils/FileExtensionProvider.h"
@@ -29,6 +30,7 @@
#include <netinet/in.h>
#include <arpa/inet.h>
+using namespace PVR;
using namespace XFILE;
const CAdvancedSettings* URIUtils::m_advancedSettings = nullptr;
@@ -964,7 +966,15 @@ bool URIUtils::IsPVRChannel(const std::string& strFile)
if (IsStack(strFile))
return IsPVRChannel(CStackDirectory::GetFirstStackedFile(strFile));
- return StringUtils::StartsWithNoCase(strFile, "pvr://channels");
+ return IsProtocol(strFile, "pvr") && CPVRChannelsPath(strFile).IsChannel();
+}
+
+bool URIUtils::IsPVRChannelGroup(const std::string& strFile)
+{
+ if (IsStack(strFile))
+ return IsPVRChannelGroup(CStackDirectory::GetFirstStackedFile(strFile));
+
+ return IsProtocol(strFile, "pvr") && CPVRChannelsPath(strFile).IsChannelGroup();
}
bool URIUtils::IsPVRGuideItem(const std::string& strFile)
diff --git a/xbmc/utils/URIUtils.h b/xbmc/utils/URIUtils.h
index 5794149cd3..f10e4a2042 100644
--- a/xbmc/utils/URIUtils.h
+++ b/xbmc/utils/URIUtils.h
@@ -154,6 +154,7 @@ public:
static bool IsLibraryContent(const std::string& strFile);
static bool IsPVR(const std::string& strFile);
static bool IsPVRChannel(const std::string& strFile);
+ static bool IsPVRChannelGroup(const std::string& strFile);
static bool IsPVRGuideItem(const std::string& strFile);
static bool IsUsingFastSwitch(const std::string& strFile);