From 0f3541c91ef5822da32514b30e3fe603960705d0 Mon Sep 17 00:00:00 2001 From: Sam Stenvall Date: Sun, 20 Jul 2014 21:54:43 +0300 Subject: [pvr] remove the "All recordings" folder in favor of a "Group Items" option in the side blade --- language/English/strings.po | 4 +- xbmc/pvr/recordings/PVRRecordings.cpp | 183 ++++++++-------------------- xbmc/pvr/recordings/PVRRecordings.h | 11 +- xbmc/pvr/windows/GUIWindowPVRBase.h | 1 + xbmc/pvr/windows/GUIWindowPVRRecordings.cpp | 77 +++++------- xbmc/pvr/windows/GUIWindowPVRRecordings.h | 3 +- 6 files changed, 92 insertions(+), 187 deletions(-) diff --git a/language/English/strings.po b/language/English/strings.po index 73f4610656..8c014080c6 100755 --- a/language/English/strings.po +++ b/language/English/strings.po @@ -8516,8 +8516,10 @@ msgctxt "#19269" msgid "Do not show 'connection lost' warnings" msgstr "" +#. Label of the option to switch between a grouped recordings list and a non-grouped recordings list. +#: skin.confluence msgctxt "#19270" -msgid "* All recordings" +msgid "Group Items" msgstr "" msgctxt "#19271" diff --git a/xbmc/pvr/recordings/PVRRecordings.cpp b/xbmc/pvr/recordings/PVRRecordings.cpp index f46c8e1c87..a193bd95c8 100644 --- a/xbmc/pvr/recordings/PVRRecordings.cpp +++ b/xbmc/pvr/recordings/PVRRecordings.cpp @@ -40,7 +40,8 @@ using namespace PVR; CPVRRecordings::CPVRRecordings(void) : m_bIsUpdating(false), - m_iLastId(0) + m_iLastId(0), + m_bGroupItems(true) { } @@ -88,51 +89,15 @@ const std::string CPVRRecordings::GetDirectoryFromPath(const std::string &strPat return TrimSlashes(strReturn); } -bool CPVRRecordings::IsDirectoryMember(const std::string &strDirectory, const std::string &strEntryDirectory, bool bDirectMember /* = true */) const +bool CPVRRecordings::IsDirectoryMember(const std::string &strDirectory, const std::string &strEntryDirectory) const { std::string strUseDirectory = TrimSlashes(strDirectory); std::string strUseEntryDirectory = TrimSlashes(strEntryDirectory); /* Case-insensitive comparison since sub folders are created with case-insensitive matching (GetSubDirectories) */ - return StringUtils::StartsWithNoCase(strUseEntryDirectory, strUseDirectory) && - (!bDirectMember || strUseEntryDirectory == strUseDirectory); -} - -void CPVRRecordings::GetContents(const std::string &strDirectory, CFileItemList *results) -{ - for (PVR_RECORDINGMAP_CITR it = m_recordings.begin(); it != m_recordings.end(); it++) - { - CPVRRecordingPtr current = it->second; - bool directMember = !HasAllRecordingsPathExtension(strDirectory); - if (!IsDirectoryMember(RemoveAllRecordingsPathExtension(strDirectory), current->m_strDirectory, directMember)) - continue; - - current->UpdateMetadata(); - CFileItemPtr pFileItem(new CFileItem(*current)); - pFileItem->SetLabel2(current->RecordingTimeAsLocalTime().GetAsLocalizedDateTime(true, false)); - pFileItem->m_dateTime = current->RecordingTimeAsLocalTime(); - pFileItem->SetPath(current->m_strFileNameAndPath); - - // Set art - if (!current->m_strIconPath.empty()) - { - pFileItem->SetIconImage(current->m_strIconPath); - pFileItem->SetArt("icon", current->m_strIconPath); - } - - if (!current->m_strThumbnailPath.empty()) - pFileItem->SetArt("thumb", current->m_strThumbnailPath); - - if (!current->m_strFanartPath.empty()) - pFileItem->SetArt("fanart", current->m_strFanartPath); - - // Use the channel icon as a fallback when a thumbnail is not available - pFileItem->SetArtFallback("thumb", "icon"); - - pFileItem->SetOverlayImage(CGUIListItem::ICON_OVERLAY_UNWATCHED, pFileItem->GetPVRRecordingInfoTag()->m_playCount > 0); - - results->Add(pFileItem); - } + return m_bGroupItems ? + StringUtils::EqualsNoCase(strUseDirectory, strUseEntryDirectory) : + StringUtils::StartsWithNoCase(strUseEntryDirectory, strUseDirectory); } void CPVRRecordings::GetSubDirectories(const std::string &strBase, CFileItemList *results) @@ -190,81 +155,6 @@ void CPVRRecordings::GetSubDirectories(const std::string &strBase, CFileItemList } } } - - int subDirectories = results->Size(); - CFileItemList files; - GetContents(strBase, &files); - - if (results->Size() == 1 && files.Size() == 0) - { - std::string strGetPath = StringUtils::Format("%s/%s/", strUseBase.c_str(), results->Get(0)->GetLabel().c_str()); - - results->Clear(); - - CLog::Log(LOGDEBUG, "CPVRRecordings - %s - '%s' only has 1 subdirectory, selecting that directory ('%s')", - __FUNCTION__, strUseBase.c_str(), strGetPath.c_str()); - GetSubDirectories(strGetPath, results); - return; - } - - results->Append(files); - - // Add 'All Recordings' item (if we have at least one subdirectory in the list) - if (subDirectories > 0) - { - std::string strLabel(g_localizeStrings.Get(19270)); // "* All recordings" - CFileItemPtr pItem(new CFileItem(strLabel)); - std::string strAllPath; - if(strUseBase.empty()) - strAllPath = "pvr://recordings"; - else - strAllPath = StringUtils::Format("pvr://recordings/%s", strUseBase.c_str()); - pItem->SetPath(AddAllRecordingsPathExtension(strAllPath)); - pItem->SetSpecialSort(SortSpecialOnTop); - pItem->SetLabelPreformated(true); - pItem->m_bIsFolder = true; - pItem->m_bIsShareOrDrive = false; - for(int i=0; iSize(); ++i) - { - if(pItem->m_dateTime < results->Get(i)->m_dateTime) - pItem->m_dateTime = results->Get(i)->m_dateTime; - } - results->AddFront(pItem, 0); - } -} - -bool CPVRRecordings::HasAllRecordingsPathExtension(const std::string &strDirectory) const -{ - std::string strUseDir = TrimSlashes(strDirectory); - std::string strAllRecordingsPathExtension(PVR_ALL_RECORDINGS_PATH_EXTENSION); - - if (strUseDir.size() < strAllRecordingsPathExtension.size()) - return false; - - if (strUseDir.size() == strAllRecordingsPathExtension.size()) - return (strUseDir == strAllRecordingsPathExtension); - - return StringUtils::EndsWith(strUseDir, "/" + strAllRecordingsPathExtension); -} - -std::string CPVRRecordings::AddAllRecordingsPathExtension(const std::string &strDirectory) -{ - if (HasAllRecordingsPathExtension(strDirectory)) - return strDirectory; - - std::string strResult = strDirectory; - if (!StringUtils::EndsWith(strDirectory, "/")) - strResult = strResult + "/"; - - return strResult + PVR_ALL_RECORDINGS_PATH_EXTENSION + "/"; -} - -std::string CPVRRecordings::RemoveAllRecordingsPathExtension(const std::string &strDirectory) -{ - if (!HasAllRecordingsPathExtension(strDirectory)) - return strDirectory; - - return strDirectory.substr(0, strDirectory.size() - strlen(PVR_ALL_RECORDINGS_PATH_EXTENSION) - 1); } int CPVRRecordings::Load(void) @@ -317,11 +207,6 @@ int CPVRRecordings::GetRecordings(CFileItemList* results) return m_recordings.size(); } -bool CPVRRecordings::IsAllRecordingsDirectory(const CFileItem& item) const -{ - return HasAllRecordingsPathExtension(item.GetPath()); -} - bool CPVRRecordings::Delete(const CFileItem& item) { return item.m_bIsFolder ? DeleteDirectory(item) : DeleteRecording(item); @@ -423,24 +308,60 @@ bool CPVRRecordings::SetRecordingsPlayCount(const CFileItemPtr &item, int count) bool CPVRRecordings::GetDirectory(const std::string& strPath, CFileItemList &items) { - bool bSuccess(false); + CSingleLock lock(m_critSection); + + CURL url(strPath); + std::string strDirectoryPath = url.GetFileName(); + URIUtils::RemoveSlashAtEnd(strDirectoryPath); + if (StringUtils::StartsWith(strDirectoryPath, "recordings")) { - CSingleLock lock(m_critSection); + strDirectoryPath.erase(0, 10); - CURL url(strPath); - std::string strFileName = url.GetFileName(); - URIUtils::RemoveSlashAtEnd(strFileName); + // get the directory structure if in non-flatten mode + if (m_bGroupItems) + GetSubDirectories(strDirectoryPath, &items); - if (StringUtils::StartsWith(strFileName, "recordings")) + // get all files of the currrent directory or recursively all files starting at the current directory if in flatten mode + for (PVR_RECORDINGMAP_CITR it = m_recordings.begin(); it != m_recordings.end(); it++) { - strFileName.erase(0, 10); - GetSubDirectories(strFileName, &items); - bSuccess = true; + CPVRRecordingPtr current = it->second; + + // skip items that are not members of the target directory + if (!IsDirectoryMember(strDirectoryPath, current->m_strDirectory)) + continue; + + current->UpdateMetadata(); + CFileItemPtr pFileItem(new CFileItem(*current)); + pFileItem->SetLabel2(current->RecordingTimeAsLocalTime().GetAsLocalizedDateTime(true, false)); + pFileItem->m_dateTime = current->RecordingTimeAsLocalTime(); + pFileItem->SetPath(current->m_strFileNameAndPath); + + // Set art + if (!current->m_strIconPath.empty()) + { + pFileItem->SetIconImage(current->m_strIconPath); + pFileItem->SetArt("icon", current->m_strIconPath); + } + + if (!current->m_strThumbnailPath.empty()) + pFileItem->SetArt("thumb", current->m_strThumbnailPath); + + if (!current->m_strFanartPath.empty()) + pFileItem->SetArt("fanart", current->m_strFanartPath); + + // Use the channel icon as a fallback when a thumbnail is not available + pFileItem->SetArtFallback("thumb", "icon"); + + pFileItem->SetOverlayImage(CGUIListItem::ICON_OVERLAY_UNWATCHED, pFileItem->GetPVRRecordingInfoTag()->m_playCount > 0); + + items.Add(pFileItem); } + + return true; } - return bSuccess; + return false; } void CPVRRecordings::SetPlayCount(const CFileItem &item, int iPlayCount) diff --git a/xbmc/pvr/recordings/PVRRecordings.h b/xbmc/pvr/recordings/PVRRecordings.h index 8aaaf8b01b..cd6585d16b 100644 --- a/xbmc/pvr/recordings/PVRRecordings.h +++ b/xbmc/pvr/recordings/PVRRecordings.h @@ -39,17 +39,14 @@ namespace PVR bool m_bIsUpdating; PVR_RECORDINGMAP m_recordings; unsigned int m_iLastId; + bool m_bGroupItems; virtual void UpdateFromClients(void); virtual std::string TrimSlashes(const std::string &strOrig) const; virtual const std::string GetDirectoryFromPath(const std::string &strPath, const std::string &strBase) const; - virtual bool IsDirectoryMember(const std::string &strDirectory, const std::string &strEntryDirectory, bool bDirectMember = true) const; - virtual void GetContents(const std::string &strDirectory, CFileItemList *results); + virtual bool IsDirectoryMember(const std::string &strDirectory, const std::string &strEntryDirectory) const; virtual void GetSubDirectories(const std::string &strBase, CFileItemList *results); - std::string AddAllRecordingsPathExtension(const std::string &strDirectory); - std::string RemoveAllRecordingsPathExtension(const std::string &strDirectory); - /** * @brief recursively deletes all recordings in the specified directory * @param item the directory @@ -85,7 +82,6 @@ namespace PVR bool RenameRecording(CFileItem &item, std::string &strNewName); bool SetRecordingsPlayCount(const CFileItemPtr &item, int count); - bool IsAllRecordingsDirectory(const CFileItem &item) const; bool GetDirectory(const std::string& strPath, CFileItemList &items); CFileItemPtr GetByPath(const std::string &path); CPVRRecordingPtr GetById(int iClientId, const std::string &strRecordingId) const; @@ -93,6 +89,7 @@ namespace PVR void GetAll(CFileItemList &items); CFileItemPtr GetById(unsigned int iId) const; - bool HasAllRecordingsPathExtension(const std::string &strDirectory) const; + void SetGroupItems(bool value) { m_bGroupItems = value; }; + bool IsGroupItems() const { return m_bGroupItems; }; }; } diff --git a/xbmc/pvr/windows/GUIWindowPVRBase.h b/xbmc/pvr/windows/GUIWindowPVRBase.h index d4d745e240..d2d7851e1e 100644 --- a/xbmc/pvr/windows/GUIWindowPVRBase.h +++ b/xbmc/pvr/windows/GUIWindowPVRBase.h @@ -24,6 +24,7 @@ #include "pvr/channels/PVRChannelGroupsContainer.h" #define CONTROL_BTNVIEWASICONS 2 +#define CONTROL_BTNGROUPITEMS 5 #define CONTROL_BTNCHANNELGROUPS 28 #define CONTROL_LABEL_HEADER1 29 diff --git a/xbmc/pvr/windows/GUIWindowPVRRecordings.cpp b/xbmc/pvr/windows/GUIWindowPVRRecordings.cpp index c5427b0e86..c603aab721 100644 --- a/xbmc/pvr/windows/GUIWindowPVRRecordings.cpp +++ b/xbmc/pvr/windows/GUIWindowPVRRecordings.cpp @@ -22,6 +22,7 @@ #include "guilib/GUIKeyboardFactory.h" #include "dialogs/GUIDialogYesNo.h" +#include "guilib/GUIRadioButtonControl.h" #include "guilib/GUIWindowManager.h" #include "guilib/Key.h" #include "guilib/LocalizeStrings.h" @@ -61,6 +62,11 @@ void CGUIWindowPVRRecordings::ResetObservers(void) g_infoManager.RegisterObserver(this); } +void CGUIWindowPVRRecordings::OnWindowLoaded() +{ + CONTROL_SELECT(CONTROL_BTNGROUPITEMS); +} + std::string CGUIWindowPVRRecordings::GetDirectoryPath(void) { if (StringUtils::StartsWith(m_vecItems->GetPath(), "pvr://recordings/")) @@ -130,9 +136,7 @@ void CGUIWindowPVRRecordings::GetContextButtons(int itemNumber, CContextButtons buttons.Add(CONTEXT_BUTTON_RENAME, 118); /* Rename this recording */ } - // Add delete button for all items except the All recordings directory - if (!g_PVRRecordings->IsAllRecordingsDirectory(*pItem.get())) - buttons.Add(CONTEXT_BUTTON_DELETE, 117); + buttons.Add(CONTEXT_BUTTON_DELETE, 117); if (pItem->HasPVRRecordingInfoTag() && g_PVRClients->HasMenuHooks(pItem->GetPVRRecordingInfoTag()->m_iClientId, PVR_MENUHOOK_RECORDING)) @@ -171,11 +175,7 @@ bool CGUIWindowPVRRecordings::Update(const std::string &strDirectory, bool updat { m_thumbLoader.StopThread(); - bool bReturn = CGUIWindowPVRBase::Update(strDirectory); - - AfterUpdate(*m_unfilteredItems); - - return bReturn; + return CGUIWindowPVRBase::Update(strDirectory); } bool CGUIWindowPVRRecordings::OnMessage(CGUIMessage &message) @@ -228,6 +228,12 @@ bool CGUIWindowPVRRecordings::OnMessage(CGUIMessage &message) } } } + else if (message.GetSenderId() == CONTROL_BTNGROUPITEMS) + { + CGUIRadioButtonControl *radioButton = (CGUIRadioButtonControl*) GetControl(CONTROL_BTNGROUPITEMS); + g_PVRRecordings->SetGroupItems(radioButton->IsSelected()); + Refresh(true); + } break; case GUI_MSG_REFRESH_LIST: switch(message.GetParam1()) @@ -334,49 +340,26 @@ bool CGUIWindowPVRRecordings::OnContextButtonMarkWatched(const CFileItemPtr &ite return bReturn; } -void CGUIWindowPVRRecordings::AfterUpdate(CFileItemList& items) +void CGUIWindowPVRRecordings::OnPrepareFileItems(CFileItemList& items) { - if (!items.IsEmpty()) + if (items.IsEmpty()) + return; + + CFileItemList files; + VECFILEITEMS vecItems = items.GetList(); + for (VECFILEITEMS::const_iterator it = vecItems.begin(); it != vecItems.end(); ++it) { - CFileItemList files; - for (int i = 0; i < items.Size(); i++) - { - CFileItemPtr pItem = items[i]; - if (!pItem->m_bIsFolder) - files.Add(pItem); - } + if (!(*it)->m_bIsFolder) + files.Add((*it)); + } - if (!files.IsEmpty()) + if (!files.IsEmpty()) + { + if (m_database.Open()) { - files.SetPath(items.GetPath()); - if (m_database.Open()) - { - if (g_PVRRecordings->HasAllRecordingsPathExtension(files.GetPath())) - { - // Build a map of all files belonging to common subdirectories and call - // LoadVideoInfo for each item list - typedef boost::shared_ptr CFileItemListPtr; - typedef std::map DirectoryMap; - - DirectoryMap directory_map; - for (int i = 0; i < files.Size(); i++) - { - std::string strDirectory = URIUtils::GetDirectory(files[i]->GetPath()); - DirectoryMap::iterator it = directory_map.find(strDirectory); - if (it == directory_map.end()) - it = directory_map.insert(std::make_pair( - strDirectory, CFileItemListPtr(new CFileItemList(strDirectory)))).first; - it->second->Add(files[i]); - } - - for (DirectoryMap::iterator it = directory_map.begin(); it != directory_map.end(); it++) - CGUIWindowVideoNav::LoadVideoInfo(*it->second, m_database, false); - } - else - CGUIWindowVideoNav::LoadVideoInfo(files, m_database, false); - m_database.Close(); - } - m_thumbLoader.Load(files); + CGUIWindowVideoNav::LoadVideoInfo(files, m_database, false); + m_database.Close(); } + m_thumbLoader.Load(files); } } diff --git a/xbmc/pvr/windows/GUIWindowPVRRecordings.h b/xbmc/pvr/windows/GUIWindowPVRRecordings.h index 49fdecc606..936ffff0fa 100644 --- a/xbmc/pvr/windows/GUIWindowPVRRecordings.h +++ b/xbmc/pvr/windows/GUIWindowPVRRecordings.h @@ -34,6 +34,7 @@ namespace PVR static std::string GetResumeString(const CFileItem& item); + void OnWindowLoaded(); bool OnMessage(CGUIMessage& message); bool OnAction(const CAction &action); void GetContextButtons(int itemNumber, CContextButtons &buttons); @@ -44,7 +45,7 @@ namespace PVR protected: std::string GetDirectoryPath(void); - virtual void AfterUpdate(CFileItemList& items); + void OnPrepareFileItems(CFileItemList &items); private: bool OnContextButtonDelete(CFileItem *item, CONTEXT_BUTTON button); -- cgit v1.2.3