diff options
author | Ryan Rector <rmrector@gmail.com> | 2019-04-06 10:05:12 -0600 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-04-06 10:05:12 -0600 |
commit | 60521a904ba8a8ea4f4f1281c5bbc636549f65b6 (patch) | |
tree | 324ca8104a3ed0c940235c6cb6f67d831d8d8ac3 | |
parent | 4eb34ebe68452821b97befbcc4a8fcb663924f5b (diff) | |
parent | c900963c2a1b395a5e66c0a97f036b8565aace7b (diff) |
Merge pull request #15857 from rmrector/fill-video-arttypes
Add available artwork to the video 'Choose art type' dialog
-rw-r--r-- | xbmc/video/VideoDatabase.cpp | 111 | ||||
-rw-r--r-- | xbmc/video/VideoDatabase.h | 8 | ||||
-rw-r--r-- | xbmc/video/dialogs/GUIDialogVideoInfo.cpp | 112 | ||||
-rw-r--r-- | xbmc/video/dialogs/GUIDialogVideoInfo.h | 4 |
4 files changed, 201 insertions, 34 deletions
diff --git a/xbmc/video/VideoDatabase.cpp b/xbmc/video/VideoDatabase.cpp index 7c8d0b09ed..1b96904146 100644 --- a/xbmc/video/VideoDatabase.cpp +++ b/xbmc/video/VideoDatabase.cpp @@ -4668,6 +4668,117 @@ bool CVideoDatabase::GetArtTypes(const MediaType &mediaType, std::vector<std::st return false; } +namespace +{ +std::vector<std::string> GetBasicItemAvailableArtTypes(const CVideoInfoTag& tag) +{ + std::vector<std::string> result; + + //! @todo artwork: fanart stored separately, doesn't need to be + if (tag.m_fanart.GetNumFanarts() && std::find(result.cbegin(), result.cend(), "fanart") == result.cend()) + result.push_back("fanart"); + + // all other images + for (const auto& urlEntry : tag.m_strPictureURL.m_url) + { + std::string artType = urlEntry.m_aspect; + if (artType.empty()) + artType = tag.m_type == MediaTypeEpisode ? "thumb" : "poster"; + if (urlEntry.m_type == CScraperUrl::URL_TYPE_GENERAL && // exclude season artwork for TV shows + !StringUtils::StartsWith(artType, "set.") && // exclude movie set artwork for movies + std::find(result.cbegin(), result.cend(), artType) == result.cend()) + { + result.push_back(artType); + } + } + return result; +} + +std::vector<std::string> GetSeasonAvailableArtTypes(int mediaId, CVideoDatabase& db) +{ + CVideoInfoTag tag; + db.GetSeasonInfo(mediaId, tag); + + std::vector<std::string> result; + + CVideoInfoTag sourceShow; + db.GetTvShowInfo("", sourceShow, tag.m_iIdShow); + for (const auto& urlEntry : sourceShow.m_strPictureURL.m_url) + { + std::string artType = urlEntry.m_aspect; + if (artType.empty()) + artType = "poster"; + if (urlEntry.m_type == CScraperUrl::URL_TYPE_SEASON && urlEntry.m_season == tag.m_iSeason && + std::find(result.cbegin(), result.cend(), artType) == result.cend()) + { + result.push_back(artType); + } + } + return result; +} + +std::vector<std::string> GetMovieSetAvailableArtTypes(int mediaId, CVideoDatabase& db) +{ + std::vector<std::string> result; + CFileItemList items; + std::string baseDir = StringUtils::Format("videodb://movies/sets/%d", mediaId); + if (db.GetMoviesNav(baseDir, items)) + { + for (const auto& item : items) + { + CVideoInfoTag* pTag = item->GetVideoInfoTag(); + pTag->m_strPictureURL.Parse(); + //! @todo artwork: fanart stored separately, doesn't need to be + pTag->m_fanart.Unpack(); + if (pTag->m_fanart.GetNumFanarts() && + std::find(result.cbegin(), result.cend(), "fanart") == result.cend()) + { + result.push_back("fanart"); + } + + // all other images + for (const auto& urlEntry : pTag->m_strPictureURL.m_url) + { + std::string artType = urlEntry.m_aspect; + if (artType.empty()) + artType = "poster"; + else if (StringUtils::StartsWith(artType, "set.")) + artType = artType.substr(4); + + if (std::find(result.cbegin(), result.cend(), artType) == result.cend()) + result.push_back(artType); + } + } + } + return result; +} +} + +std::vector<std::string> CVideoDatabase::GetAvailableArtTypesForItem(int mediaId, + const MediaType& mediaType) +{ + VIDEODB_CONTENT_TYPE dbType{VIDEODB_CONTENT_UNKNOWN}; + if (mediaType == MediaTypeTvShow) + dbType = VIDEODB_CONTENT_TVSHOWS; + else if (mediaType == MediaTypeMovie) + dbType = VIDEODB_CONTENT_MOVIES; + else if (mediaType == MediaTypeEpisode) + dbType = VIDEODB_CONTENT_EPISODES; + else if (mediaType == MediaTypeMusicVideo) + dbType = VIDEODB_CONTENT_MUSICVIDEOS; + + if (dbType != VIDEODB_CONTENT_UNKNOWN) + { + CVideoInfoTag tag = GetDetailsByTypeAndId(dbType, mediaId); + return GetBasicItemAvailableArtTypes(tag); + } + if (mediaType == MediaTypeSeason) + return GetSeasonAvailableArtTypes(mediaId, *this); + if (mediaType == MediaTypeVideoCollection) + return GetMovieSetAvailableArtTypes(mediaId, *this); + return {}; +} + /// \brief GetStackTimes() obtains any saved video times for the stacked file /// \retval Returns true if the stack times exist, false otherwise. bool CVideoDatabase::GetStackTimes(const std::string &filePath, std::vector<uint64_t> ×) diff --git a/xbmc/video/VideoDatabase.h b/xbmc/video/VideoDatabase.h index 5ed2303f45..addc77e798 100644 --- a/xbmc/video/VideoDatabase.h +++ b/xbmc/video/VideoDatabase.h @@ -848,6 +848,14 @@ public: bool GetTvShowSeasonArt(int mediaId, std::map<int, std::map<std::string, std::string> > &seasonArt); bool GetArtTypes(const MediaType &mediaType, std::vector<std::string> &artTypes); + /*! \brief Fetch the distinct types of available-but-unassigned art held in the + database for a specific media item. + \param mediaId the id in the media table. + \param mediaType the type of media, which corresponds to the table the item resides in. + \return the types of art e.g. "thumb", "fanart", etc. + */ + std::vector<std::string> GetAvailableArtTypesForItem(int mediaId, const MediaType& mediaType); + int AddTag(const std::string &tag); void AddTagToItem(int idItem, int idTag, const std::string &type); void RemoveTagFromItem(int idItem, int idTag, const std::string &type); diff --git a/xbmc/video/dialogs/GUIDialogVideoInfo.cpp b/xbmc/video/dialogs/GUIDialogVideoInfo.cpp index 091472544b..14935c1283 100644 --- a/xbmc/video/dialogs/GUIDialogVideoInfo.cpp +++ b/xbmc/video/dialogs/GUIDialogVideoInfo.cpp @@ -620,7 +620,73 @@ void CGUIDialogVideoInfo::Play(bool resume) } } -std::string CGUIDialogVideoInfo::ChooseArtType(const CFileItem &videoItem, std::map<std::string, std::string> ¤tArt) +namespace +{ +// Add art types required in Kodi and configured by the user +void AddHardCodedAndExtendedArtTypes(std::vector<std::string>& artTypes, const CVideoInfoTag& tag) +{ + for (const auto& artType : CVideoThumbLoader::GetArtTypes(tag.m_type)) + { + if (find(artTypes.cbegin(), artTypes.cend(), artType) == artTypes.cend()) + artTypes.emplace_back(artType); + } +} + +// Add art types currently assigned to the media item +void AddCurrentArtTypes(std::vector<std::string>& artTypes, const CVideoInfoTag& tag, + CVideoDatabase& db) +{ + std::map<std::string, std::string> currentArt; + db.GetArtForItem(tag.m_iDbId, tag.m_type, currentArt); + for (const auto& art : currentArt) + { + if (!art.second.empty() && find(artTypes.cbegin(), artTypes.cend(), art.first) == artTypes.cend()) + artTypes.push_back(art.first); + } +} + +// Add art types that exist for other media items of the same type +void AddMediaTypeArtTypes(std::vector<std::string>& artTypes, const CVideoInfoTag& tag, + CVideoDatabase& db) +{ + std::vector<std::string> dbArtTypes; + db.GetArtTypes(tag.m_type, dbArtTypes); + for (const auto& artType : dbArtTypes) + { + if (find(artTypes.cbegin(), artTypes.cend(), artType) == artTypes.cend()) + artTypes.push_back(artType); + } +} + +// Add art types from available but unassigned artwork for this media item +void AddAvailableArtTypes(std::vector<std::string>& artTypes, const CVideoInfoTag& tag, + CVideoDatabase& db) +{ + for (const auto& artType : db.GetAvailableArtTypesForItem(tag.m_iDbId, tag.m_type)) + { + if (find(artTypes.cbegin(), artTypes.cend(), artType) == artTypes.cend()) + artTypes.push_back(artType); + } +} + +std::vector<std::string> GetArtTypesList(const CVideoInfoTag& tag) +{ + CVideoDatabase db; + db.Open(); + + std::vector<std::string> artTypes; + + AddHardCodedAndExtendedArtTypes(artTypes, tag); + AddCurrentArtTypes(artTypes, tag, db); + AddMediaTypeArtTypes(artTypes, tag, db); + AddAvailableArtTypes(artTypes, tag, db); + + db.Close(); + return artTypes; +} +} + +std::string CGUIDialogVideoInfo::ChooseArtType(const CFileItem &videoItem) { // prompt for choice CGUIDialogSelect *dialog = CServiceBroker::GetGUI()->GetWindowManager().GetWindow<CGUIDialogSelect>(WINDOW_DIALOG_SELECT); @@ -633,27 +699,7 @@ std::string CGUIDialogVideoInfo::ChooseArtType(const CFileItem &videoItem, std:: dialog->SetUseDetails(true); dialog->EnableButton(true, 13516); - CVideoDatabase db; - db.Open(); - - std::vector<std::string> artTypes = CVideoThumbLoader::GetArtTypes(videoItem.GetVideoInfoTag()->m_type); - - // add in any stored art for this item that is non-empty. - db.GetArtForItem(videoItem.GetVideoInfoTag()->m_iDbId, videoItem.GetVideoInfoTag()->m_type, currentArt); - for (CGUIListItem::ArtMap::iterator i = currentArt.begin(); i != currentArt.end(); ++i) - { - if (!i->second.empty() && find(artTypes.begin(), artTypes.end(), i->first) == artTypes.end()) - artTypes.push_back(i->first); - } - - // add any art types that exist for other media items of the same type - std::vector<std::string> dbArtTypes; - db.GetArtTypes(videoItem.GetVideoInfoTag()->m_type, dbArtTypes); - for (std::vector<std::string>::const_iterator it = dbArtTypes.begin(); it != dbArtTypes.end(); ++it) - { - if (find(artTypes.begin(), artTypes.end(), *it) == artTypes.end()) - artTypes.push_back(*it); - } + std::vector<std::string> artTypes = GetArtTypesList(*videoItem.GetVideoInfoTag()); for (std::vector<std::string>::const_iterator i = artTypes.begin(); i != artTypes.end(); ++i) { @@ -693,8 +739,7 @@ std::string CGUIDialogVideoInfo::ChooseArtType(const CFileItem &videoItem, std:: void CGUIDialogVideoInfo::OnGetArt() { - std::map<std::string, std::string> currentArt; - std::string type = ChooseArtType(*m_movieItem, currentArt); + std::string type = ChooseArtType(*m_movieItem); if (type.empty()) return; // cancelled @@ -714,10 +759,10 @@ void CGUIDialogVideoInfo::OnGetArt() item->SetLabel(g_localizeStrings.Get(13512)); items.Add(item); } - else if ((type == "poster" || type == "banner") && currentArt.find("thumb") != currentArt.end()) + else if ((type == "poster" || type == "banner") && m_movieItem->HasArt("thumb")) { // add the 'thumb' type in CFileItemPtr item(new CFileItem("thumb://Thumb", false)); - item->SetArt("thumb", currentArt["thumb"]); + item->SetArt("thumb", m_movieItem->GetArt("thumb")); item->SetIconImage("DefaultPicture.png"); item->SetLabel(g_localizeStrings.Get(13512)); items.Add(item); @@ -794,7 +839,7 @@ void CGUIDialogVideoInfo::OnGetArt() newThumb = thumbs[number]; } else if (result == "thumb://Thumb") - newThumb = currentArt["thumb"]; + newThumb = m_movieItem->GetArt("thumb"); else if (result == "thumb://Local") newThumb = localThumb; else if (result == "thumb://Embedded") @@ -1802,18 +1847,17 @@ bool CGUIDialogVideoInfo::ManageVideoItemArtwork(const CFileItemPtr &item, const currentThumb = videodb.GetArtForItem(item->GetVideoInfoTag()->m_iDbId, item->GetVideoInfoTag()->m_type, artType); else { // SEASON, SET - std::map<std::string, std::string> currentArt; - artType = ChooseArtType(*item, currentArt); + artType = ChooseArtType(*item); if (artType.empty()) return false; if (artType == "fanart") return OnGetFanart(item); - if (currentArt.find(artType) != currentArt.end()) - currentThumb = currentArt[artType]; - else if ((artType == "poster" || artType == "banner") && currentArt.find("thumb") != currentArt.end()) - currentThumb = currentArt["thumb"]; + if (item->HasArt(artType)) + currentThumb = item->GetArt(artType); + else if ((artType == "poster" || artType == "banner") && item->HasArt("thumb")) + currentThumb = item->GetArt("thumb"); } if (!currentThumb.empty()) @@ -1955,6 +1999,8 @@ bool CGUIDialogVideoInfo::ManageVideoItemArtwork(const CFileItemPtr &item, const musicdb.SetArtForItem(idArtist, MediaTypeArtist, artType, result); } + item->SetArt(artType, result); + CUtil::DeleteVideoDatabaseDirectoryCache(); CGUIMessage msg(GUI_MSG_NOTIFY_ALL, 0, 0, GUI_MSG_REFRESH_THUMBS); CServiceBroker::GetGUI()->GetWindowManager().SendMessage(msg); diff --git a/xbmc/video/dialogs/GUIDialogVideoInfo.h b/xbmc/video/dialogs/GUIDialogVideoInfo.h index 0976541b1c..574309d863 100644 --- a/xbmc/video/dialogs/GUIDialogVideoInfo.h +++ b/xbmc/video/dialogs/GUIDialogVideoInfo.h @@ -33,7 +33,6 @@ public: const CFileItemList& CurrentDirectory() const { return *m_castList; }; bool HasListItems() const override { return true; }; - static std::string ChooseArtType(const CFileItem &item, std::map<std::string, std::string> ¤tArt); static void AddItemPathToFileBrowserSources(VECSOURCES &sources, const CFileItem &item); static int ManageVideoItem(const CFileItemPtr &item); @@ -103,4 +102,7 @@ protected: bool m_hasUpdatedThumb = false; bool m_hasUpdatedUserrating = false; int m_startUserrating = -1; + +private: + static std::string ChooseArtType(const CFileItem& item); }; |