bool CGUIWindowMusicNav::OnContextButton(int itemNumber, CONTEXT_BUTTON button) { CFileItemPtr item; if (itemNumber >= 0 && itemNumber < m_vecItems->Size()) item = m_vecItems->Get(itemNumber); switch (button) { case CONTEXT_BUTTON_INFO: { if (!item->IsVideoDb()) return CGUIWindowMusicBase::OnContextButton(itemNumber,button); // music videos - artists if (item->GetPath().Left(14).Equals("videodb://3/4/")) { long idArtist = m_musicdatabase.GetArtistByName(item->GetLabel()); if (idArtist == -1) return false; CStdString path; path.Format("musicdb://2/%ld/", idArtist); CArtist artist; m_musicdatabase.GetArtistInfo(idArtist,artist,false); *item = CFileItem(artist); item->SetPath(path); CGUIWindowMusicBase::OnContextButton(itemNumber,button); Refresh(); m_viewControl.SetSelectedItem(itemNumber); return true; } // music videos - albums if (item->GetPath().Left(14).Equals("videodb://3/5/")) { long idAlbum = m_musicdatabase.GetAlbumByName(item->GetLabel()); if (idAlbum == -1) return false; CStdString path; path.Format("musicdb://3/%ld/", idAlbum); CAlbum album; m_musicdatabase.GetAlbumInfo(idAlbum,album,NULL); *item = CFileItem(path,album); item->SetPath(path); CGUIWindowMusicBase::OnContextButton(itemNumber,button); Refresh(); m_viewControl.SetSelectedItem(itemNumber); return true; } if (item->HasVideoInfoTag() && !item->GetVideoInfoTag()->m_strTitle.IsEmpty()) { CGUIWindowVideoNav* pWindow = (CGUIWindowVideoNav*)g_windowManager.GetWindow(WINDOW_VIDEO_NAV); if (pWindow) { ADDON::ScraperPtr info; pWindow->OnInfo(item.get(),info); Refresh(); } } return true; } case CONTEXT_BUTTON_INFO_ALL: OnInfoAll(itemNumber); return true; case CONTEXT_BUTTON_UPDATE_LIBRARY: { g_application.StartMusicScan(""); return true; } case CONTEXT_BUTTON_SET_DEFAULT: g_settings.m_defaultMusicLibSource = GetQuickpathName(item->GetPath()); g_settings.Save(); return true; case CONTEXT_BUTTON_CLEAR_DEFAULT: g_settings.m_defaultMusicLibSource.Empty(); g_settings.Save(); return true; case CONTEXT_BUTTON_GO_TO_ARTIST: { CStdString strPath; CVideoDatabase database; database.Open(); strPath.Format("videodb://3/4/%ld/",database.GetMatchingMusicVideo(StringUtils::Join(item->GetMusicInfoTag()->GetArtist(), g_advancedSettings.m_musicItemSeparator))); g_windowManager.ActivateWindow(WINDOW_VIDEO_NAV,strPath); return true; } case CONTEXT_BUTTON_PLAY_OTHER: { CVideoDatabase database; database.Open(); CVideoInfoTag details; database.GetMusicVideoInfo("",details,database.GetMatchingMusicVideo(StringUtils::Join(item->GetMusicInfoTag()->GetArtist(), g_advancedSettings.m_musicItemSeparator),item->GetMusicInfoTag()->GetAlbum(),item->GetMusicInfoTag()->GetTitle())); CApplicationMessenger::Get().PlayFile(CFileItem(details)); return true; } case CONTEXT_BUTTON_MARK_WATCHED: CGUIWindowVideoBase::MarkWatched(item,true); CUtil::DeleteVideoDatabaseDirectoryCache(); Refresh(); return true; case CONTEXT_BUTTON_MARK_UNWATCHED: CGUIWindowVideoBase::MarkWatched(item,false); CUtil::DeleteVideoDatabaseDirectoryCache(); Refresh(); return true; case CONTEXT_BUTTON_RENAME: CGUIWindowVideoBase::UpdateVideoTitle(item.get()); CUtil::DeleteVideoDatabaseDirectoryCache(); Refresh(); return true; case CONTEXT_BUTTON_DELETE: if (item->IsPlayList() || item->IsSmartPlayList()) { item->m_bIsFolder = false; CFileUtils::DeleteItem(item); } else { CGUIWindowVideoNav::DeleteItem(item.get()); CUtil::DeleteVideoDatabaseDirectoryCache(); } Refresh(); return true; case CONTEXT_BUTTON_SET_CONTENT: { ADDON::ScraperPtr scraper; CStdString path(item->GetPath()); CQueryParams params; CDirectoryNode::GetDatabaseInfo(item->GetPath(), params); CONTENT_TYPE content = CONTENT_ALBUMS; if (params.GetAlbumId() != -1) path.Format("musicdb://3/%i/",params.GetAlbumId()); else if (params.GetArtistId() != -1) { path.Format("musicdb://2/%i/",params.GetArtistId()); content = CONTENT_ARTISTS; } if (m_vecItems->GetPath().Equals("musicdb://1/") || item->GetPath().Equals("musicdb://2/")) { content = CONTENT_ARTISTS; } if (!m_musicdatabase.GetScraperForPath(path, scraper, ADDON::ScraperTypeFromContent(content))) { ADDON::AddonPtr defaultScraper; if (ADDON::CAddonMgr::Get().GetDefault(ADDON::ScraperTypeFromContent(content), defaultScraper)) { scraper = boost::dynamic_pointer_cast<ADDON::CScraper>(defaultScraper->Clone(defaultScraper)); } } if (CGUIDialogContentSettings::Show(scraper, content)) { m_musicdatabase.SetScraperForPath(path,scraper); if (CGUIDialogYesNo::ShowAndGetInput(20442,20443,20444,20022)) { OnInfoAll(itemNumber,true,true); } } return true; } default: break; } return CGUIWindowMusicBase::OnContextButton(itemNumber, button); }
void CGUIDialogSmartPlaylistRule::OnBrowse() { CFileItemList items; CMusicDatabase database; database.Open(); CVideoDatabase videodatabase; videodatabase.Open(); std::string basePath; if (CSmartPlaylist::IsMusicType(m_type)) basePath = "musicdb://"; else basePath = "videodb://"; VIDEODB_CONTENT_TYPE type = VIDEODB_CONTENT_MOVIES; if (m_type == "movies") basePath += "movies/"; else if (m_type == "tvshows") { type = VIDEODB_CONTENT_TVSHOWS; basePath += "tvshows/"; } else if (m_type == "musicvideos") { type = VIDEODB_CONTENT_MUSICVIDEOS; basePath += "musicvideos/"; } else if (m_type == "episodes") { if (m_rule.m_field == FieldGenre || m_rule.m_field == FieldYear || m_rule.m_field == FieldStudio) type = VIDEODB_CONTENT_TVSHOWS; else type = VIDEODB_CONTENT_EPISODES; basePath += "tvshows/"; } int iLabel = 0; if (m_rule.m_field == FieldGenre) { if (m_type == "tvshows" || m_type == "episodes" || m_type == "movies") videodatabase.GetGenresNav(basePath + "genres/", items, type); else if (m_type == "songs" || m_type == "albums" || m_type == "artists" || m_type == "mixed") database.GetGenresNav("musicdb://genres/",items); if (m_type == "musicvideos" || m_type == "mixed") { CFileItemList items2; videodatabase.GetGenresNav("videodb://musicvideos/genres/",items2,VIDEODB_CONTENT_MUSICVIDEOS); items.Append(items2); } iLabel = 515; } else if (m_rule.m_field == FieldRole) { if (m_type == "artists" || m_type == "mixed") { database.GetRolesNav("musicdb://songs/", items); iLabel = 38033; } } else if (m_rule.m_field == FieldCountry) { videodatabase.GetCountriesNav(basePath, items, type); iLabel = 574; } else if (m_rule.m_field == FieldArtist || m_rule.m_field == FieldAlbumArtist) { if (CSmartPlaylist::IsMusicType(m_type)) database.GetArtistsNav("musicdb://artists/", items, m_rule.m_field == FieldAlbumArtist, -1); if (m_type == "musicvideos" || m_type == "mixed") { CFileItemList items2; videodatabase.GetMusicVideoArtistsByName("", items2); items.Append(items2); } iLabel = 557; } else if (m_rule.m_field == FieldAlbum) { if (CSmartPlaylist::IsMusicType(m_type)) database.GetAlbumsNav("musicdb://albums/", items); if (m_type == "musicvideos" || m_type == "mixed") { CFileItemList items2; videodatabase.GetMusicVideoAlbumsByName("", items2); items.Append(items2); } iLabel = 558; } else if (m_rule.m_field == FieldActor) { videodatabase.GetActorsNav(basePath + "actors/",items,type); iLabel = 20337; } else if (m_rule.m_field == FieldYear) { if (CSmartPlaylist::IsMusicType(m_type)) database.GetYearsNav("musicdb://years/", items); if (CSmartPlaylist::IsVideoType(m_type)) { CFileItemList items2; videodatabase.GetYearsNav(basePath + "years/", items2, type); items.Append(items2); } iLabel = 562; } else if (m_rule.m_field == FieldDirector) { videodatabase.GetDirectorsNav(basePath + "directors/", items, type); iLabel = 20339; } else if (m_rule.m_field == FieldStudio) { videodatabase.GetStudiosNav(basePath + "studios/", items, type); iLabel = 572; } else if (m_rule.m_field == FieldWriter) { videodatabase.GetWritersNav(basePath, items, type); iLabel = 20417; } else if (m_rule.m_field == FieldTvShowTitle || (m_type == "tvshows" && m_rule.m_field == FieldTitle)) { videodatabase.GetTvShowsNav(basePath + "titles/", items); iLabel = 20343; } else if (m_rule.m_field == FieldTitle) { if (m_type == "songs" || m_type == "mixed") { database.GetSongsNav("musicdb://songs/", items, -1, -1, -1); iLabel = 134; } if (m_type == "movies") { videodatabase.GetMoviesNav(basePath + "titles/", items); iLabel = 20342; } if (m_type == "episodes") { videodatabase.GetEpisodesNav(basePath + "titles/-1/-1/", items); // we need to replace the db label (<season>x<episode> <title>) with the title only CLabelFormatter format("%T", ""); for (int i = 0; i < items.Size(); i++) format.FormatLabel(items[i].get()); iLabel = 20360; } if (m_type == "musicvideos" || m_type == "mixed") { videodatabase.GetMusicVideosNav(basePath + "titles/", items); iLabel = 20389; } } else if (m_rule.m_field == FieldPlaylist || m_rule.m_field == FieldVirtualFolder) { // use filebrowser to grab another smart playlist // Note: This can cause infinite loops (playlist that refers to the same playlist) but I don't // think there's any decent way to deal with this, as the infinite loop may be an arbitrary // number of playlists deep, eg playlist1 -> playlist2 -> playlist3 ... -> playlistn -> playlist1 if (CSmartPlaylist::IsVideoType(m_type)) XFILE::CDirectory::GetDirectory("special://videoplaylists/", items, ".xsp", XFILE::DIR_FLAG_NO_FILE_DIRS); if (CSmartPlaylist::IsMusicType(m_type)) { CFileItemList items2; XFILE::CDirectory::GetDirectory("special://musicplaylists/", items2, ".xsp", XFILE::DIR_FLAG_NO_FILE_DIRS); items.Append(items2); } for (int i = 0; i < items.Size(); i++) { CFileItemPtr item = items[i]; CSmartPlaylist playlist; // don't list unloadable smartplaylists or any referenceable smartplaylists // which do not match the type of the current smartplaylist if (!playlist.Load(item->GetPath()) || (m_rule.m_field == FieldPlaylist && (!CSmartPlaylist::CheckTypeCompatibility(m_type, playlist.GetType()) || (!playlist.GetGroup().empty() || playlist.IsGroupMixed())))) { items.Remove(i); i -= 1; continue; } if (!playlist.GetName().empty()) item->SetLabel(playlist.GetName()); } iLabel = 559; } else if (m_rule.m_field == FieldPath) { VECSOURCES sources; if (m_type == "songs" || m_type == "mixed") sources = *CMediaSourceSettings::GetInstance().GetSources("music"); if (CSmartPlaylist::IsVideoType(m_type)) { VECSOURCES sources2 = *CMediaSourceSettings::GetInstance().GetSources("video"); sources.insert(sources.end(),sources2.begin(),sources2.end()); } g_mediaManager.GetLocalDrives(sources); std::string path = m_rule.GetParameter(); CGUIDialogFileBrowser::ShowAndGetDirectory(sources, g_localizeStrings.Get(657), path, false); if (!m_rule.m_parameter.empty()) m_rule.m_parameter.clear(); if (!path.empty()) m_rule.m_parameter.emplace_back(std::move(path)); UpdateButtons(); return; } else if (m_rule.m_field == FieldSet) { videodatabase.GetSetsNav("videodb://movies/sets/", items, VIDEODB_CONTENT_MOVIES); iLabel = 20434; } else if (m_rule.m_field == FieldTag) { VIDEODB_CONTENT_TYPE type = VIDEODB_CONTENT_MOVIES; if (m_type == "tvshows" || m_type == "episodes") type = VIDEODB_CONTENT_TVSHOWS; else if (m_type == "musicvideos") type = VIDEODB_CONTENT_MUSICVIDEOS; else if (m_type != "movies") return; videodatabase.GetTagsNav(basePath + "tags/", items, type); iLabel = 20459; } else { //! @todo Add browseability in here. assert(false); } // sort the items items.Sort(SortByLabel, SortOrderAscending, CServiceBroker::GetSettings().GetBool(CSettings::SETTING_FILELISTS_IGNORETHEWHENSORTING) ? SortAttributeIgnoreArticle : SortAttributeNone); CGUIDialogSelect* pDialog = g_windowManager.GetWindow<CGUIDialogSelect>(); pDialog->Reset(); pDialog->SetItems(items); std::string strHeading = StringUtils::Format(g_localizeStrings.Get(13401).c_str(), g_localizeStrings.Get(iLabel).c_str()); pDialog->SetHeading(CVariant{std::move(strHeading)}); pDialog->SetMultiSelection(m_rule.m_field != FieldPlaylist && m_rule.m_field != FieldVirtualFolder); if (!m_rule.m_parameter.empty()) pDialog->SetSelected(m_rule.m_parameter); pDialog->Open(); if (pDialog->IsConfirmed()) { m_rule.m_parameter.clear(); for (int i : pDialog->GetSelectedItems()) m_rule.m_parameter.push_back(items.Get(i)->GetLabel()); UpdateButtons(); } pDialog->Reset(); }
bool CVideoLibraryRefreshingJob::Work(CVideoDatabase &db) { if (m_item == nullptr) return false; // determine the scraper for the item's path VIDEO::SScanSettings scanSettings; ADDON::ScraperPtr scraper = db.GetScraperForPath(m_item->GetPath(), scanSettings); if (scraper == nullptr) return false; // copy the scraper in case we need it again ADDON::ScraperPtr originalScraper(scraper); // get the item's correct title std::string itemTitle = m_searchTitle; if (itemTitle.empty()) itemTitle = m_item->GetMovieName(scanSettings.parent_name); CScraperUrl scraperUrl; VIDEO::CVideoInfoScanner scanner; bool needsRefresh = m_forceRefresh; bool hasDetails = false; bool ignoreNfo = m_ignoreNfo; // run this in a loop in case we need to refresh again bool failure = false; do { if (!ignoreNfo) { // check if there's an NFO for the item CNfoFile::NFOResult nfoResult = scanner.CheckForNFOFile(m_item.get(), scanSettings.parent_name_root, scraper, scraperUrl); // if there's no NFO remember it in case we have to refresh again if (nfoResult == CNfoFile::ERROR_NFO) ignoreNfo = true; else if (nfoResult != CNfoFile::NO_NFO) hasDetails = true; // if we are performing a forced refresh ask the user to choose between using a valid NFO and a valid scraper if (needsRefresh && IsModal() && !scraper->IsNoop() && nfoResult != CNfoFile::ERROR_NFO) { int heading = 20159; if (scraper->Content() == CONTENT_MOVIES) heading = 13346; else if (scraper->Content() == CONTENT_TVSHOWS) heading = m_item->m_bIsFolder ? 20351 : 20352; else if (scraper->Content() == CONTENT_MUSICVIDEOS) heading = 20393; if (CGUIDialogYesNo::ShowAndGetInput(heading, 20446)) { hasDetails = false; ignoreNfo = true; scraperUrl.Clear(); scraper = originalScraper; } } } // no need to re-fetch the episode guide for episodes if (scraper->Content() == CONTENT_TVSHOWS && !m_item->m_bIsFolder) hasDetails = true; // if we don't have an url or need to refresh anyway do the web search if (!hasDetails && (needsRefresh || scraperUrl.m_url.empty())) { SetTitle(StringUtils::Format(g_localizeStrings.Get(197).c_str(), scraper->Name().c_str())); SetText(itemTitle); SetProgress(0); // clear any cached data from the scraper scraper->ClearCache(); // create the info downloader for the scraper CVideoInfoDownloader infoDownloader(scraper); // try to find a matching item MOVIELIST itemResultList; int result = infoDownloader.FindMovie(itemTitle, itemResultList, GetProgressDialog()); // close the progress dialog MarkFinished(); if (result > 0) { // there are multiple matches for the item if (!itemResultList.empty()) { // choose the first match if (!IsModal()) scraperUrl = itemResultList.at(0); else { // ask the user what to do CGUIDialogSelect* selectDialog = g_windowManager.GetWindow<CGUIDialogSelect>(WINDOW_DIALOG_SELECT); selectDialog->Reset(); selectDialog->SetHeading(scraper->Content() == CONTENT_TVSHOWS ? 20356 : 196); for (const auto& itemResult : itemResultList) selectDialog->Add(itemResult.strTitle); selectDialog->EnableButton(true, 413); // "Manual" selectDialog->Open(); // check if the user has chosen one of the results int selectedItem = selectDialog->GetSelectedItem(); if (selectedItem >= 0) scraperUrl = itemResultList.at(selectedItem); // the user hasn't chosen one of the results and but has chosen to manually enter a title to use else if (selectDialog->IsButtonPressed()) { // ask the user to input a title to use if (!CGUIKeyboardFactory::ShowAndGetInput(itemTitle, g_localizeStrings.Get(scraper->Content() == CONTENT_TVSHOWS ? 20357 : 16009), false)) return false; // go through the whole process again needsRefresh = true; continue; } // nothing else we can do else return false; } CLog::Log(LOGDEBUG, "CVideoLibraryRefreshingJob: user selected item '%s' with URL '%s'", scraperUrl.strTitle.c_str(), scraperUrl.m_url.at(0).m_url.c_str()); } } else if (result < 0 || !VIDEO::CVideoInfoScanner::DownloadFailed(GetProgressDialog())) { failure = true; break; } } // if the URL is still empty, check whether or not we're allowed // to prompt and ask the user to input a new search title if (!hasDetails && scraperUrl.m_url.empty()) { if (IsModal()) { // ask the user to input a title to use if (!CGUIKeyboardFactory::ShowAndGetInput(itemTitle, g_localizeStrings.Get(scraper->Content() == CONTENT_TVSHOWS ? 20357 : 16009), false)) return false; // go through the whole process again needsRefresh = true; continue; } // nothing else we can do failure = true; break; } // before we start downloading all the necessary information cleanup any existing artwork and hashes CTextureDatabase textureDb; if (textureDb.Open()) { for (const auto& artwork : m_item->GetArt()) textureDb.InvalidateCachedTexture(artwork.second); textureDb.Close(); } m_item->ClearArt(); // put together the list of items to refresh std::string path = m_item->GetPath(); CFileItemList items; if (m_item->HasVideoInfoTag() && m_item->GetVideoInfoTag()->m_iDbId > 0) { // for a tvshow we need to handle all paths of it std::vector<std::string> tvshowPaths; if (CMediaTypes::IsMediaType(m_item->GetVideoInfoTag()->m_type, MediaTypeTvShow) && m_refreshAll && db.GetPathsLinkedToTvShow(m_item->GetVideoInfoTag()->m_iDbId, tvshowPaths)) { for (const auto& tvshowPath : tvshowPaths) { CFileItemPtr tvshowItem(new CFileItem(*m_item->GetVideoInfoTag())); tvshowItem->SetPath(tvshowPath); items.Add(tvshowItem); } } // otherwise just add a copy of the item else items.Add(CFileItemPtr(new CFileItem(*m_item->GetVideoInfoTag()))); // update the path to the real path (instead of a videodb:// one) path = m_item->GetVideoInfoTag()->m_strPath; } else items.Add(CFileItemPtr(new CFileItem(*m_item))); // set the proper path of the list of items to lookup items.SetPath(m_item->m_bIsFolder ? URIUtils::GetParentPath(path) : URIUtils::GetDirectory(path)); int headingLabel = 198; if (scraper->Content() == CONTENT_TVSHOWS) { if (m_item->m_bIsFolder) headingLabel = 20353; else headingLabel = 20361; } else if (scraper->Content() == CONTENT_MUSICVIDEOS) headingLabel = 20394; // prepare the progress dialog for downloading all the necessary information SetTitle(g_localizeStrings.Get(headingLabel)); SetText(scraperUrl.strTitle); SetProgress(0); // remove any existing data for the item we're going to refresh if (m_item->GetVideoInfoTag()->m_iDbId > 0) { int dbId = m_item->GetVideoInfoTag()->m_iDbId; if (scraper->Content() == CONTENT_MOVIES) db.DeleteMovie(dbId); else if (scraper->Content() == CONTENT_MUSICVIDEOS) db.DeleteMusicVideo(dbId); else if (scraper->Content() == CONTENT_TVSHOWS) { if (!m_item->m_bIsFolder) db.DeleteEpisode(dbId); else if (m_refreshAll) db.DeleteTvShow(dbId); else db.DeleteDetailsForTvShow(dbId); } } // finally download the information for the item if (!scanner.RetrieveVideoInfo(items, scanSettings.parent_name, scraper->Content(), !ignoreNfo, scraperUrl.m_url.empty() ? NULL : &scraperUrl, m_refreshAll, GetProgressDialog())) { // something went wrong MarkFinished(); // check if the user cancelled if (!IsCancelled() && IsModal()) CGUIDialogOK::ShowAndGetInput(195, itemTitle); return false; } // retrieve the updated information from the database if (scraper->Content() == CONTENT_MOVIES) db.GetMovieInfo(m_item->GetPath(), *m_item->GetVideoInfoTag()); else if (scraper->Content() == CONTENT_MUSICVIDEOS) db.GetMusicVideoInfo(m_item->GetPath(), *m_item->GetVideoInfoTag()); else if (scraper->Content() == CONTENT_TVSHOWS) { // update tvshow info to get updated episode numbers if (m_item->m_bIsFolder) db.GetTvShowInfo(m_item->GetPath(), *m_item->GetVideoInfoTag()); else db.GetEpisodeInfo(m_item->GetPath(), *m_item->GetVideoInfoTag()); } // we're finally done MarkFinished(); break; } while (needsRefresh); if (failure && IsModal()) CGUIDialogOK::ShowAndGetInput(195, itemTitle); return true; }
bool CSmartPlaylistDirectory::GetDirectory(const CSmartPlaylist &playlist, CFileItemList& items, const std::string &strBaseDir /* = "" */, bool filter /* = false */) { bool success = false, success2 = false; std::vector<std::string> virtualFolders; SortDescription sorting; sorting.limitEnd = playlist.GetLimit(); sorting.sortBy = playlist.GetOrder(); sorting.sortOrder = playlist.GetOrderAscending() ? SortOrderAscending : SortOrderDescending; sorting.sortAttributes = playlist.GetOrderAttributes(); if (CSettings::GetInstance().GetBool(CSettings::SETTING_FILELISTS_IGNORETHEWHENSORTING)) sorting.sortAttributes = (SortAttribute)(sorting.sortAttributes | SortAttributeIgnoreArticle); items.SetSortIgnoreFolders((sorting.sortAttributes & SortAttributeIgnoreFolders) == SortAttributeIgnoreFolders); std::string option = !filter ? "xsp" : "filter"; std::string group = playlist.GetGroup(); bool isGrouped = !group.empty() && !StringUtils::EqualsNoCase(group, "none") && !playlist.IsGroupMixed(); // get all virtual folders and add them to the item list playlist.GetVirtualFolders(virtualFolders); for (std::vector<std::string>::const_iterator virtualFolder = virtualFolders.begin(); virtualFolder != virtualFolders.end(); ++virtualFolder) { CFileItemPtr pItem = CFileItemPtr(new CFileItem(*virtualFolder, true)); IFileDirectory *dir = CFileDirectoryFactory::Create(pItem->GetURL(), pItem.get()); if (dir != NULL) { pItem->SetSpecialSort(SortSpecialOnTop); items.Add(pItem); delete dir; } } if (playlist.GetType() == "movies" || playlist.GetType() == "tvshows" || playlist.GetType() == "episodes") { CVideoDatabase db; if (db.Open()) { MediaType mediaType = MediaTypes::FromString(playlist.GetType()); std::string baseDir = strBaseDir; if (strBaseDir.empty()) { if (mediaType == MediaTypeTvShow || mediaType == MediaTypeEpisode) baseDir = "videodb://tvshows/"; else if (mediaType == MediaTypeMovie) baseDir = "videodb://movies/"; else return false; if (!isGrouped) baseDir += "titles"; else baseDir += group; URIUtils::AddSlashAtEnd(baseDir); if (mediaType == MediaTypeEpisode) baseDir += "-1/-1/"; } CVideoDbUrl videoUrl; if (!videoUrl.FromString(baseDir)) return false; // store the smartplaylist as JSON in the URL as well std::string xsp; if (!playlist.IsEmpty(filter)) { if (!playlist.SaveAsJson(xsp, !filter)) return false; } if (!xsp.empty()) videoUrl.AddOption(option, xsp); else videoUrl.RemoveOption(option); CDatabase::Filter dbfilter; success = db.GetItems(videoUrl.ToString(), items, dbfilter, sorting); db.Close(); // if we retrieve a list of episodes and we didn't receive // a pre-defined base path, we need to fix it if (strBaseDir.empty() && mediaType == MediaTypeEpisode && !isGrouped) videoUrl.AppendPath("-1/-1/"); items.SetProperty(PROPERTY_PATH_DB, videoUrl.ToString()); } } else if (playlist.IsMusicType() || playlist.GetType().empty()) { CMusicDatabase db; if (db.Open()) { CSmartPlaylist plist(playlist); if (playlist.GetType() == "mixed" || playlist.GetType().empty()) plist.SetType("songs"); MediaType mediaType = MediaTypes::FromString(plist.GetType()); std::string baseDir = strBaseDir; if (strBaseDir.empty()) { baseDir = "musicdb://"; if (!isGrouped) { if (mediaType == MediaTypeArtist) baseDir += "artists"; else if (mediaType == MediaTypeAlbum) baseDir += "albums"; else if (mediaType == MediaTypeSong) baseDir += "songs"; else return false; } else baseDir += group; URIUtils::AddSlashAtEnd(baseDir); } CMusicDbUrl musicUrl; if (!musicUrl.FromString(baseDir)) return false; // store the smartplaylist as JSON in the URL as well std::string xsp; if (!plist.IsEmpty(filter)) { if (!plist.SaveAsJson(xsp, !filter)) return false; } if (!xsp.empty()) musicUrl.AddOption(option, xsp); else musicUrl.RemoveOption(option); CDatabase::Filter dbfilter; success = db.GetItems(musicUrl.ToString(), items, dbfilter, sorting); db.Close(); items.SetProperty(PROPERTY_PATH_DB, musicUrl.ToString()); } } if (playlist.GetType() == "musicvideos" || playlist.GetType() == "mixed") { CVideoDatabase db; if (db.Open()) { CSmartPlaylist mvidPlaylist(playlist); if (playlist.GetType() == "mixed") mvidPlaylist.SetType("musicvideos"); std::string baseDir = strBaseDir; if (baseDir.empty()) { baseDir = "videodb://musicvideos/"; if (!isGrouped) baseDir += "titles"; else baseDir += group; URIUtils::AddSlashAtEnd(baseDir); } CVideoDbUrl videoUrl; if (!videoUrl.FromString(baseDir)) return false; // adjust the group in case we're retrieving a grouped playlist // based on artists. This is needed because the video library // is using the actorslink table for artists. if (isGrouped && group == "artists") { group = "actors"; mvidPlaylist.SetGroup(group); } // store the smartplaylist as JSON in the URL as well std::string xsp; if (!mvidPlaylist.IsEmpty(filter)) { if (!mvidPlaylist.SaveAsJson(xsp, !filter)) return false; } if (!xsp.empty()) videoUrl.AddOption(option, xsp); else videoUrl.RemoveOption(option); CFileItemList items2; CDatabase::Filter dbfilter; success2 = db.GetItems(videoUrl.ToString(), items2, dbfilter, sorting); db.Close(); if (items.Size() <= 0) items.SetPath(videoUrl.ToString()); items.Append(items2); if (items2.Size()) { if (items.Size() > items2.Size()) items.SetContent("mixed"); else items.SetContent("musicvideos"); } items.SetProperty(PROPERTY_PATH_DB, videoUrl.ToString()); } } items.SetLabel(playlist.GetName()); if (isGrouped) items.SetContent(group); else items.SetContent(playlist.GetType()); items.SetProperty(PROPERTY_SORT_ORDER, (int)playlist.GetOrder()); items.SetProperty(PROPERTY_SORT_ASCENDING, playlist.GetOrderDirection() == SortOrderAscending); if (!group.empty()) { items.SetProperty(PROPERTY_GROUP_BY, group); items.SetProperty(PROPERTY_GROUP_MIXED, playlist.IsGroupMixed()); } // sort grouped list by label if (items.Size() > 1 && !group.empty()) items.Sort(SortByLabel, SortOrderAscending, CSettings::GetInstance().GetBool(CSettings::SETTING_FILELISTS_IGNORETHEWHENSORTING) ? SortAttributeIgnoreArticle : SortAttributeNone); // go through and set the playlist order for (int i = 0; i < items.Size(); i++) { CFileItemPtr item = items[i]; item->m_iprogramCount = i; // hack for playlist order } if (playlist.GetType() == "mixed") return success || success2; else if (playlist.GetType() == "musicvideos") return success2; else return success; }
void CSaveFileState::DoWork(CFileItem& item, CBookmark& bookmark, bool updatePlayCount) { std::string progressTrackingFile = item.GetPath(); if (item.HasVideoInfoTag() && StringUtils::StartsWith(item.GetVideoInfoTag()->m_strFileNameAndPath, "removable://")) progressTrackingFile = item.GetVideoInfoTag()->m_strFileNameAndPath; // this variable contains removable:// suffixed by disc label+uniqueid or is empty if label not uniquely identified else if (item.HasProperty("original_listitem_url")) { // only use original_listitem_url for Python, UPnP and Bluray sources std::string original = item.GetProperty("original_listitem_url").asString(); if (URIUtils::IsPlugin(original) || URIUtils::IsUPnP(original) || URIUtils::IsBluray(item.GetPath())) progressTrackingFile = original; } if (!progressTrackingFile.empty()) { #ifdef HAS_UPNP // checks if UPnP server of this file is available and supports updating if (URIUtils::IsUPnP(progressTrackingFile) && UPNP::CUPnP::SaveFileState(item, bookmark, updatePlayCount)) { return; } #endif if (item.IsVideo()) { std::string redactPath = CURL::GetRedacted(progressTrackingFile); CLog::Log(LOGDEBUG, "%s - Saving file state for video item %s", __FUNCTION__, redactPath.c_str()); CVideoDatabase videodatabase; if (!videodatabase.Open()) { CLog::Log(LOGWARNING, "%s - Unable to open video database. Can not save file state!", __FUNCTION__); } else { bool updateListing = false; // No resume & watched status for livetv if (!item.IsLiveTV()) { if (updatePlayCount) { // no watched for not yet finished pvr recordings if (!item.IsInProgressPVRRecording()) { CLog::Log(LOGDEBUG, "%s - Marking video item %s as watched", __FUNCTION__, redactPath.c_str()); // consider this item as played videodatabase.IncrementPlayCount(item); item.GetVideoInfoTag()->IncrementPlayCount(); item.SetOverlayImage(CGUIListItem::ICON_OVERLAY_UNWATCHED, true); updateListing = true; if (item.HasVideoInfoTag()) { CVariant data; data["id"] = item.GetVideoInfoTag()->m_iDbId; data["type"] = item.GetVideoInfoTag()->m_type; ANNOUNCEMENT::CAnnouncementManager::GetInstance().Announce(ANNOUNCEMENT::VideoLibrary, "xbmc", "OnUpdate", data); } } } else videodatabase.UpdateLastPlayed(item); if (!item.HasVideoInfoTag() || item.GetVideoInfoTag()->GetResumePoint().timeInSeconds != bookmark.timeInSeconds) { if (bookmark.timeInSeconds <= 0.0f) videodatabase.ClearBookMarksOfFile(progressTrackingFile, CBookmark::RESUME); else videodatabase.AddBookMarkToFile(progressTrackingFile, bookmark, CBookmark::RESUME); if (item.HasVideoInfoTag()) item.GetVideoInfoTag()->SetResumePoint(bookmark); // UPnP announce resume point changes to clients // however not if playcount is modified as that already announces if (item.HasVideoInfoTag() && !updatePlayCount) { CVariant data; data["id"] = item.GetVideoInfoTag()->m_iDbId; data["type"] = item.GetVideoInfoTag()->m_type; ANNOUNCEMENT::CAnnouncementManager::GetInstance().Announce(ANNOUNCEMENT::VideoLibrary, "xbmc", "OnUpdate", data); } updateListing = true; } } if (item.HasVideoInfoTag() && item.GetVideoInfoTag()->HasStreamDetails()) { CFileItem dbItem(item); // Check whether the item's db streamdetails need updating if (!videodatabase.GetStreamDetails(dbItem) || dbItem.GetVideoInfoTag()->m_streamDetails != item.GetVideoInfoTag()->m_streamDetails) { videodatabase.SetStreamDetailsForFile(item.GetVideoInfoTag()->m_streamDetails, progressTrackingFile); updateListing = true; } } // for ISO stacks, the bookmark is saved onto the part. In order to properly update the the list, we need to refresh the stack's resume point if (item.GetStack() != nullptr && item.m_lStackTotalTime == 0) videodatabase.GetResumePoint(*(item.GetStack()->GetVideoInfoTag())); videodatabase.Close(); if (updateListing) { CUtil::DeleteVideoDatabaseDirectoryCache(); CFileItemPtr msgItem(new CFileItem(item)); if (item.HasProperty("original_listitem_url")) msgItem->SetPath(item.GetProperty("original_listitem_url").asString()); CGUIMessage message(GUI_MSG_NOTIFY_ALL, g_windowManager.GetActiveWindow(), 0, GUI_MSG_UPDATE_ITEM, 1, msgItem); // 1 to update the listing as well g_windowManager.SendThreadMessage(message); } } } if (item.IsAudio()) { std::string redactPath = CURL::GetRedacted(progressTrackingFile); CLog::Log(LOGDEBUG, "%s - Saving file state for audio item %s", __FUNCTION__, redactPath.c_str()); CMusicDatabase musicdatabase; if (updatePlayCount) { if (!musicdatabase.Open()) { CLog::Log(LOGWARNING, "%s - Unable to open music database. Can not save file state!", __FUNCTION__); } else { // consider this item as played CLog::Log(LOGDEBUG, "%s - Marking audio item %s as listened", __FUNCTION__, redactPath.c_str()); musicdatabase.IncrementPlayCount(item); musicdatabase.Close(); // UPnP announce resume point changes to clients // however not if playcount is modified as that already announces if (item.IsMusicDb()) { CVariant data; data["id"] = item.GetMusicInfoTag()->GetDatabaseId(); data["type"] = item.GetMusicInfoTag()->GetType(); ANNOUNCEMENT::CAnnouncementManager::GetInstance().Announce(ANNOUNCEMENT::AudioLibrary, "xbmc", "OnUpdate", data); } } } if (item.IsAudioBook()) { musicdatabase.Open(); musicdatabase.SetResumeBookmarkForAudioBook(item, item.m_lStartOffset+bookmark.timeInSeconds*75); musicdatabase.Close(); } } } }
bool CGUIWindowVideoNav::OnClick(int iItem, const std::string &player) { CFileItemPtr item = m_vecItems->Get(iItem); if (!item->m_bIsFolder && item->IsVideoDb() && !item->Exists()) { CLog::Log(LOGDEBUG, "%s called on '%s' but file doesn't exist", __FUNCTION__, item->GetPath().c_str()); if (CProfilesManager::GetInstance().GetCurrentProfile().canWriteDatabases() || g_passwordManager.bMasterUser) { if (!CGUIDialogVideoInfo::DeleteVideoItemFromDatabase(item, true)) return true; // update list Refresh(true); m_viewControl.SetSelectedItem(iItem); return true; } else { CGUIDialogOK::ShowAndGetInput(CVariant{257}, CVariant{662}); return true; } } else if (StringUtils::StartsWithNoCase(item->GetPath(), "newtag://")) { // dont allow update while scanning if (g_application.IsVideoScanning()) { CGUIDialogOK::ShowAndGetInput(CVariant{257}, CVariant{14057}); return true; } //Get the new title std::string strTag; if (!CGUIKeyboardFactory::ShowAndGetInput(strTag, CVariant{g_localizeStrings.Get(20462)}, false)) return true; CVideoDatabase videodb; if (!videodb.Open()) return true; // get the media type and convert from plural to singular (by removing the trailing "s") std::string mediaType = item->GetPath().substr(9); mediaType = mediaType.substr(0, mediaType.size() - 1); std::string localizedType = CGUIDialogVideoInfo::GetLocalizedVideoType(mediaType); if (localizedType.empty()) return true; if (!videodb.GetSingleValue("tag", "tag.tag_id", videodb.PrepareSQL("tag.name = '%s' AND tag.tag_id IN (SELECT tag_link.tag_id FROM tag_link WHERE tag_link.media_type = '%s')", strTag.c_str(), mediaType.c_str())).empty()) { std::string strError = StringUtils::Format(g_localizeStrings.Get(20463).c_str(), strTag.c_str()); CGUIDialogOK::ShowAndGetInput(CVariant{20462}, CVariant{std::move(strError)}); return true; } int idTag = videodb.AddTag(strTag); CFileItemList items; std::string strLabel = StringUtils::Format(g_localizeStrings.Get(20464).c_str(), localizedType.c_str()); if (CGUIDialogVideoInfo::GetItemsForTag(strLabel, mediaType, items, idTag)) { for (int index = 0; index < items.Size(); index++) { if (!items[index]->HasVideoInfoTag() || items[index]->GetVideoInfoTag()->m_iDbId <= 0) continue; videodb.AddTagToItem(items[index]->GetVideoInfoTag()->m_iDbId, idTag, mediaType); } } Refresh(true); return true; } return CGUIWindowVideoBase::OnClick(iItem, player); }
void CGUIWindowVideoNav::GetContextButtons(int itemNumber, CContextButtons &buttons) { CFileItemPtr item; if (itemNumber >= 0 && itemNumber < m_vecItems->Size()) item = m_vecItems->Get(itemNumber); CGUIWindowVideoBase::GetContextButtons(itemNumber, buttons); if (item && item->GetProperty("pluginreplacecontextitems").asBoolean()) return; CVideoDatabaseDirectory dir; NODE_TYPE node = dir.GetDirectoryChildType(m_vecItems->GetPath()); if (!item) { // nothing to do here } else if (m_vecItems->IsPath("sources://video/")) { // get the usual shares CGUIDialogContextMenu::GetContextButtons("video", item, buttons); if (!item->IsDVD() && item->GetPath() != "add" && !item->IsParentFolder() && (CProfilesManager::GetInstance().GetCurrentProfile().canWriteDatabases() || g_passwordManager.bMasterUser)) { CVideoDatabase database; database.Open(); ADDON::ScraperPtr info = database.GetScraperForPath(item->GetPath()); if (!item->IsLiveTV() && !item->IsPlugin() && !item->IsAddonsPath() && !URIUtils::IsUPnP(item->GetPath())) { if (info && info->Content() != CONTENT_NONE) { buttons.Add(CONTEXT_BUTTON_SET_CONTENT, 20442); buttons.Add(CONTEXT_BUTTON_SCAN, 13349); } else buttons.Add(CONTEXT_BUTTON_SET_CONTENT, 20333); } } } else { // are we in the playlists location? bool inPlaylists = m_vecItems->IsPath(CUtil::VideoPlaylistsLocation()) || m_vecItems->IsPath("special://videoplaylists/"); if (item->HasVideoInfoTag() && !item->GetVideoInfoTag()->m_artist.empty()) { CMusicDatabase database; database.Open(); if (database.GetArtistByName(StringUtils::Join(item->GetVideoInfoTag()->m_artist, g_advancedSettings.m_videoItemSeparator)) > -1) buttons.Add(CONTEXT_BUTTON_GO_TO_ARTIST, 20396); } if (item->HasVideoInfoTag() && !item->GetVideoInfoTag()->m_strAlbum.empty()) { CMusicDatabase database; database.Open(); if (database.GetAlbumByName(item->GetVideoInfoTag()->m_strAlbum) > -1) buttons.Add(CONTEXT_BUTTON_GO_TO_ALBUM, 20397); } if (item->HasVideoInfoTag() && !item->GetVideoInfoTag()->m_strAlbum.empty() && !item->GetVideoInfoTag()->m_artist.empty() && !item->GetVideoInfoTag()->m_strTitle.empty()) { CMusicDatabase database; database.Open(); if (database.GetSongByArtistAndAlbumAndTitle(StringUtils::Join(item->GetVideoInfoTag()->m_artist, g_advancedSettings.m_videoItemSeparator), item->GetVideoInfoTag()->m_strAlbum, item->GetVideoInfoTag()->m_strTitle) > -1) { buttons.Add(CONTEXT_BUTTON_PLAY_OTHER, 20398); } } if (!item->IsParentFolder()) { ADDON::ScraperPtr info; VIDEO::SScanSettings settings; GetScraperForItem(item.get(), info, settings); // can we update the database? if (CProfilesManager::GetInstance().GetCurrentProfile().canWriteDatabases() || g_passwordManager.bMasterUser) { if (!g_application.IsVideoScanning() && item->IsVideoDb() && item->HasVideoInfoTag() && (item->GetVideoInfoTag()->m_type == MediaTypeMovie || // movies item->GetVideoInfoTag()->m_type == MediaTypeTvShow || // tvshows item->GetVideoInfoTag()->m_type == MediaTypeSeason || // seasons item->GetVideoInfoTag()->m_type == MediaTypeEpisode || // episodes item->GetVideoInfoTag()->m_type == MediaTypeMusicVideo || // musicvideos item->GetVideoInfoTag()->m_type == "tag" || // tags item->GetVideoInfoTag()->m_type == MediaTypeVideoCollection)) // sets { buttons.Add(CONTEXT_BUTTON_EDIT, 16106); } if (node == NODE_TYPE_TITLE_TVSHOWS) { buttons.Add(CONTEXT_BUTTON_SCAN, 13349); } if (node == NODE_TYPE_ACTOR && !dir.IsAllItem(item->GetPath()) && item->m_bIsFolder) { if (StringUtils::StartsWithNoCase(m_vecItems->GetPath(), "videodb://musicvideos")) // mvids buttons.Add(CONTEXT_BUTTON_SET_ARTIST_THUMB, 13359); else buttons.Add(CONTEXT_BUTTON_SET_ACTOR_THUMB, 20403); } } if (!m_vecItems->IsVideoDb() && !m_vecItems->IsVirtualDirectoryRoot()) { // non-video db items, file operations are allowed if ((CSettings::GetInstance().GetBool(CSettings::SETTING_FILELISTS_ALLOWFILEDELETION) && CUtil::SupportsWriteFileOperations(item->GetPath())) || (inPlaylists && URIUtils::GetFileName(item->GetPath()) != "PartyMode-Video.xsp" && (item->IsPlayList() || item->IsSmartPlayList()))) { buttons.Add(CONTEXT_BUTTON_DELETE, 117); buttons.Add(CONTEXT_BUTTON_RENAME, 118); } // add "Set/Change content" to folders if (item->m_bIsFolder && !item->IsVideoDb() && !item->IsPlayList() && !item->IsSmartPlayList() && !item->IsLibraryFolder() && !item->IsLiveTV() && !item->IsPlugin() && !item->IsAddonsPath() && !URIUtils::IsUPnP(item->GetPath())) { if (info && info->Content() != CONTENT_NONE) buttons.Add(CONTEXT_BUTTON_SET_CONTENT, 20442); else buttons.Add(CONTEXT_BUTTON_SET_CONTENT, 20333); if (info && info->Content() != CONTENT_NONE) buttons.Add(CONTEXT_BUTTON_SCAN, 13349); } } } } }
void CGUIDialogAudioSubtitleSettings::OnSettingChanged(SettingInfo &setting) { // check and update anything that needs it if (setting.id == AUDIO_SETTINGS_VOLUME) { g_settings.m_nVolumeLevel = (long)(m_volume * 100.0f); g_application.SetVolume(int(((float)(g_settings.m_nVolumeLevel - VOLUME_MINIMUM)) / (VOLUME_MAXIMUM - VOLUME_MINIMUM)*100.0f + 0.5f)); } else if (setting.id == AUDIO_SETTINGS_VOLUME_AMPLIFICATION) { if (g_application.m_pPlayer) g_application.m_pPlayer->SetDynamicRangeCompression((long)(g_settings.m_currentVideoSettings.m_VolumeAmplification * 100)); } else if (setting.id == AUDIO_SETTINGS_DELAY) { if (g_application.m_pPlayer) g_application.m_pPlayer->SetAVDelay(g_settings.m_currentVideoSettings.m_AudioDelay); } else if (setting.id == AUDIO_SETTINGS_STREAM) { // first check if it's a stereo track that we can change between stereo, left and right if (g_application.m_pPlayer->GetAudioStreamCount() == 1) { if (setting.max == 2) { // we're in the case we want - call the code to switch channels etc. // update the screen setting... g_settings.m_currentVideoSettings.m_AudioStream = -1 - m_audioStream; // call monkeyh1's code here... //bool bAudioOnAllSpeakers = (g_guiSettings.GetInt("audiooutput.mode") == AUDIO_IEC958) && g_settings.m_currentVideoSettings.m_OutputToAllSpeakers; return; } } // only change the audio stream if a different one has been asked for if (g_application.m_pPlayer->GetAudioStream() != m_audioStream) { g_settings.m_currentVideoSettings.m_AudioStream = m_audioStream; g_application.m_pPlayer->SetAudioStream(m_audioStream); // Set the audio stream to the one selected EnableSettings(AUDIO_SETTINGS_VOLUME, !g_application.m_pPlayer->IsPassthrough()); } } else if (setting.id == AUDIO_SETTINGS_OUTPUT_TO_ALL_SPEAKERS) { g_application.Restart(); } else if (setting.id == AUDIO_SETTINGS_DIGITAL_ANALOG) { bool bitstream = false; switch(m_outputmode) { case 0: g_guiSettings.SetInt("audiooutput.mode", AUDIO_ANALOG ); break; case 1: g_guiSettings.SetInt("audiooutput.mode", AUDIO_IEC958 ); bitstream = true; break; case 2: g_guiSettings.SetInt("audiooutput.mode", AUDIO_HDMI ); bitstream = true; break; } EnableSettings(AUDIO_SETTINGS_OUTPUT_TO_ALL_SPEAKERS, bitstream); g_application.Restart(); EnableSettings(AUDIO_SETTINGS_VOLUME, !g_application.m_pPlayer->IsPassthrough()); } else if (setting.id == SUBTITLE_SETTINGS_ENABLE) { g_settings.m_currentVideoSettings.m_SubtitleOn = m_subtitleVisible; g_application.m_pPlayer->SetSubtitleVisible(g_settings.m_currentVideoSettings.m_SubtitleOn); } else if (setting.id == SUBTITLE_SETTINGS_DELAY) { g_application.m_pPlayer->SetSubTitleDelay(g_settings.m_currentVideoSettings.m_SubtitleDelay); } else if (setting.id == SUBTITLE_SETTINGS_STREAM && setting.max > 0) { g_settings.m_currentVideoSettings.m_SubtitleStream = m_subtitleStream; g_application.m_pPlayer->SetSubtitle(m_subtitleStream); } else if (setting.id == SUBTITLE_SETTINGS_BROWSER) { CStdString strPath; if (URIUtils::IsInRAR(g_application.CurrentFileItem().GetPath()) || URIUtils::IsInZIP(g_application.CurrentFileItem().GetPath())) { CURL url(g_application.CurrentFileItem().GetPath()); strPath = url.GetHostName(); } else strPath = g_application.CurrentFileItem().GetPath(); CStdString strMask = ".utf|.utf8|.utf-8|.sub|.srt|.smi|.rt|.txt|.ssa|.aqt|.jss|.ass|.idx|.rar|.zip"; if (g_application.GetCurrentPlayer() == EPC_DVDPLAYER) strMask = ".srt|.rar|.zip|.ifo|.smi|.sub|.idx|.ass|.ssa|.txt"; VECSOURCES shares(g_settings.m_videoSources); if (g_settings.iAdditionalSubtitleDirectoryChecked != -1 && !g_guiSettings.GetString("subtitles.custompath").IsEmpty()) { CMediaSource share; std::vector<CStdString> paths; CStdString strPath1; URIUtils::GetDirectory(strPath,strPath1); paths.push_back(strPath1); strPath1 = g_guiSettings.GetString("subtitles.custompath"); paths.push_back(g_guiSettings.GetString("subtitles.custompath")); share.FromNameAndPaths("video",g_localizeStrings.Get(21367),paths); shares.push_back(share); strPath = share.strPath; URIUtils::AddSlashAtEnd(strPath); } if (CGUIDialogFileBrowser::ShowAndGetFile(shares,strMask,g_localizeStrings.Get(293),strPath,false,true)) // "subtitles" { if (URIUtils::GetExtension(strPath) == ".sub") if (CFile::Exists(URIUtils::ReplaceExtension(strPath, ".idx"))) strPath = URIUtils::ReplaceExtension(strPath, ".idx"); int id = g_application.m_pPlayer->AddSubtitle(strPath); if(id >= 0) { m_subtitleStream = id; g_application.m_pPlayer->SetSubtitle(m_subtitleStream); g_application.m_pPlayer->SetSubtitleVisible(true); } g_settings.m_currentVideoSettings.m_SubtitleCached = true; Close(); } } else if (setting.id == AUDIO_SETTINGS_MAKE_DEFAULT) { if (g_settings.GetCurrentProfile().settingsLocked() && g_settings.GetMasterProfile().getLockMode() != ::LOCK_MODE_EVERYONE) if (!g_passwordManager.IsMasterLockUnlocked(true)) return; // prompt user if they are sure if (CGUIDialogYesNo::ShowAndGetInput(12376, 750, 0, 12377)) { // reset the settings CVideoDatabase db; db.Open(); db.EraseVideoSettings(); db.Close(); g_settings.m_defaultVideoSettings = g_settings.m_currentVideoSettings; g_settings.m_defaultVideoSettings.m_SubtitleStream = -1; g_settings.m_defaultVideoSettings.m_AudioStream = -1; g_settings.Save(); } } }
void CGUIWindowMusicNav::GetContextButtons(int itemNumber, CContextButtons &buttons) { CFileItemPtr item; if (itemNumber >= 0 && itemNumber < m_vecItems->Size()) item = m_vecItems->Get(itemNumber); if (item) { // are we in the playlists location? bool inPlaylists = m_vecItems->IsPath(CUtil::MusicPlaylistsLocation()) || m_vecItems->IsPath("special://musicplaylists/"); if (m_vecItems->IsPath("sources://music/")) { // get the usual music shares, and anything for all media windows CGUIDialogContextMenu::GetContextButtons("music", item, buttons); #ifdef HAS_DVD_DRIVE // enable Rip CD an audio disc if (g_mediaManager.IsDiscInDrive() && item->IsCDDA()) { // those cds can also include Audio Tracks: CDExtra and MixedMode! MEDIA_DETECT::CCdInfo *pCdInfo = g_mediaManager.GetCdInfo(); if (pCdInfo->IsAudio(1) || pCdInfo->IsCDExtra(1) || pCdInfo->IsMixedMode(1)) { if (CJobManager::GetInstance().IsProcessing("cdrip")) buttons.Add(CONTEXT_BUTTON_CANCEL_RIP_CD, 14100); else buttons.Add(CONTEXT_BUTTON_RIP_CD, 600); } } #endif // Add the scan button(s) if (g_application.IsMusicScanning()) buttons.Add(CONTEXT_BUTTON_STOP_SCANNING, 13353); // Stop Scanning else if (!inPlaylists && !m_vecItems->IsInternetStream() && !item->IsPath("add") && !item->IsParentFolder() && !item->IsPlugin() && !StringUtils::StartsWithNoCase(item->GetPath(), "addons://") && (CProfilesManager::GetInstance().GetCurrentProfile().canWriteDatabases() || g_passwordManager.bMasterUser)) { buttons.Add(CONTEXT_BUTTON_SCAN, 13352); } CGUIMediaWindow::GetContextButtons(itemNumber, buttons); } else { CGUIWindowMusicBase::GetContextButtons(itemNumber, buttons); CMusicDatabaseDirectory dir; // enable query all albums button only in album view if (dir.HasAlbumInfo(item->GetPath()) && !dir.IsAllItem(item->GetPath()) && item->m_bIsFolder && !item->IsVideoDb() && !item->IsParentFolder() && !item->IsPlugin() && !StringUtils::StartsWithNoCase(item->GetPath(), "musicsearch://")) { buttons.Add(CONTEXT_BUTTON_INFO_ALL, 20059); } // enable query all artist button only in album view if (dir.IsArtistDir(item->GetPath()) && !dir.IsAllItem(item->GetPath()) && item->m_bIsFolder && !item->IsVideoDb()) { ADDON::ScraperPtr info; if(m_musicdatabase.GetScraperForPath(item->GetPath(), info, ADDON::ADDON_SCRAPER_ARTISTS)) { if (info && info->Supports(CONTENT_ARTISTS)) buttons.Add(CONTEXT_BUTTON_INFO_ALL, 21884); } } //Set default or clear default NODE_TYPE nodetype = dir.GetDirectoryType(item->GetPath()); if (!item->IsParentFolder() && !inPlaylists && (nodetype == NODE_TYPE_ROOT || nodetype == NODE_TYPE_OVERVIEW || nodetype == NODE_TYPE_TOP100)) { if (!item->IsPath(CSettings::GetInstance().GetString(CSettings::SETTING_MYMUSIC_DEFAULTLIBVIEW))) buttons.Add(CONTEXT_BUTTON_SET_DEFAULT, 13335); // set default if (!CSettings::GetInstance().GetString(CSettings::SETTING_MYMUSIC_DEFAULTLIBVIEW).empty()) buttons.Add(CONTEXT_BUTTON_CLEAR_DEFAULT, 13403); // clear default } NODE_TYPE childtype = dir.GetDirectoryChildType(item->GetPath()); if (childtype == NODE_TYPE_ALBUM || childtype == NODE_TYPE_ARTIST || nodetype == NODE_TYPE_GENRE || nodetype == NODE_TYPE_ALBUM || nodetype == NODE_TYPE_ALBUM_RECENTLY_ADDED || nodetype == NODE_TYPE_ALBUM_COMPILATIONS) { // we allow the user to set content for // 1. general artist and album nodes // 2. specific per genre // 3. specific per artist // 4. specific per album buttons.Add(CONTEXT_BUTTON_SET_CONTENT, 20195); } if (item->HasMusicInfoTag() && !item->GetMusicInfoTag()->GetArtistString().empty()) { CVideoDatabase database; database.Open(); if (database.GetMatchingMusicVideo(item->GetMusicInfoTag()->GetArtistString()) > -1) buttons.Add(CONTEXT_BUTTON_GO_TO_ARTIST, 20400); } if (item->HasMusicInfoTag() && !item->GetMusicInfoTag()->GetArtistString().empty() && !item->GetMusicInfoTag()->GetAlbum().empty() && !item->GetMusicInfoTag()->GetTitle().empty()) { CVideoDatabase database; database.Open(); if (database.GetMatchingMusicVideo(item->GetMusicInfoTag()->GetArtistString(), item->GetMusicInfoTag()->GetAlbum(), item->GetMusicInfoTag()->GetTitle()) > -1) buttons.Add(CONTEXT_BUTTON_PLAY_OTHER, 20401); } if (item->HasVideoInfoTag() && !item->m_bIsFolder) { if ((CProfilesManager::GetInstance().GetCurrentProfile().canWriteDatabases() || g_passwordManager.bMasterUser) && !item->IsPlugin()) { buttons.Add(CONTEXT_BUTTON_RENAME, 16105); buttons.Add(CONTEXT_BUTTON_DELETE, 646); } } if (inPlaylists && URIUtils::GetFileName(item->GetPath()) != "PartyMode.xsp" && (item->IsPlayList() || item->IsSmartPlayList())) buttons.Add(CONTEXT_BUTTON_DELETE, 117); if (!item->IsReadOnly() && CSettings::GetInstance().GetBool("filelists.allowfiledeletion")) { buttons.Add(CONTEXT_BUTTON_DELETE, 117); buttons.Add(CONTEXT_BUTTON_RENAME, 118); } } } // noncontextual buttons CGUIWindowMusicBase::GetNonContextButtons(buttons); }
bool CPartyModeManager::AddRandomSongs(int iSongs /* = 0 */) { int iPlaylist = PLAYLIST_MUSIC; if (m_bIsVideo) iPlaylist = PLAYLIST_VIDEO; CPlayList& playlist = g_playlistPlayer.GetPlaylist(iPlaylist); int iMissingSongs = QUEUE_DEPTH - playlist.size(); if (iSongs <= 0) iSongs = iMissingSongs; // distribute between types if mixed int iSongsToAdd=iSongs; int iVidsToAdd=iSongs; if (StringUtils::EqualsNoCase(m_type, "mixed")) { if (iSongs == 1) { if (rand() % 10 < 7) // 70 % chance of grabbing a song iVidsToAdd = 0; else iSongsToAdd = 0; } if (iSongs > 1) // grab 70 % songs, 30 % mvids { iSongsToAdd = (int).7f*iSongs; iVidsToAdd = (int).3f*iSongs; while (iSongsToAdd+iVidsToAdd < iSongs) // correct any rounding by adding songs iSongsToAdd++; } } // add songs to fill queue if (StringUtils::EqualsNoCase(m_type, "songs") || StringUtils::EqualsNoCase(m_type, "mixed")) { CMusicDatabase database; if (database.Open()) { // Method: // 1. Grab a random entry from the database using a where clause // 2. Iterate on iSongs. // Note: At present, this method is faster than the alternative, which is to grab // all valid songids, then select a random number of them (as done in AddInitialSongs()). // The reason for this is simply the number of songs we are requesting - we generally // only want one here. Any more than about 3 songs and it is more efficient // to use the technique in AddInitialSongs. As it's unlikely that we'll require // more than 1 song at a time here, this method is faster. bool error(false); for (int i = 0; i < iSongsToAdd; i++) { std::pair<std::string,std::string> whereClause = GetWhereClauseWithHistory(); CFileItemPtr item(new CFileItem); int songID; if (database.GetRandomSong(item.get(), songID, whereClause.first)) { // success Add(item); AddToHistory(1,songID); } else { error = true; break; } } if (error) { database.Close(); OnError(16034, (std::string)"Cannot get songs from database. Aborting."); return false; } } else { OnError(16033, (std::string)"Party mode could not open database. Aborting."); return false; } database.Close(); } if (StringUtils::EqualsNoCase(m_type, "musicvideos") || StringUtils::EqualsNoCase(m_type, "mixed")) { CVideoDatabase database; if (database.Open()) { // Method: // 1. Grab a random entry from the database using a where clause // 2. Iterate on iSongs. // Note: At present, this method is faster than the alternative, which is to grab // all valid songids, then select a random number of them (as done in AddInitialSongs()). // The reason for this is simply the number of songs we are requesting - we generally // only want one here. Any more than about 3 songs and it is more efficient // to use the technique in AddInitialSongs. As it's unlikely that we'll require // more than 1 song at a time here, this method is faster. bool error(false); for (int i = 0; i < iVidsToAdd; i++) { std::pair<std::string,std::string> whereClause = GetWhereClauseWithHistory(); CFileItemPtr item(new CFileItem); int songID; if (database.GetRandomMusicVideo(item.get(), songID, whereClause.second)) { // success Add(item); AddToHistory(2,songID); } else { error = true; break; } } if (error) { database.Close(); OnError(16034, (std::string)"Cannot get songs from database. Aborting."); return false; } } else { OnError(16033, (std::string)"Party mode could not open database. Aborting."); return false; } database.Close(); } return true; }
bool CPartyModeManager::Enable(PartyModeContext context /*= PARTYMODECONTEXT_MUSIC*/, const std::string& strXspPath /*= ""*/) { // Filter using our PartyMode xml file CSmartPlaylist playlist; std::string partyModePath; bool playlistLoaded; m_bIsVideo = context == PARTYMODECONTEXT_VIDEO; if (!strXspPath.empty()) //if a path to a smartplaylist is supplied use it partyModePath = strXspPath; else if (m_bIsVideo) partyModePath = CProfilesManager::GetInstance().GetUserDataItem("PartyMode-Video.xsp"); else partyModePath = CProfilesManager::GetInstance().GetUserDataItem("PartyMode.xsp"); playlistLoaded=playlist.Load(partyModePath); if ( playlistLoaded ) { m_type = playlist.GetType(); if (context == PARTYMODECONTEXT_UNKNOWN) { //get it from the xsp file m_bIsVideo = (StringUtils::EqualsNoCase(m_type, "video") || StringUtils::EqualsNoCase(m_type, "musicvideos") || StringUtils::EqualsNoCase(m_type, "mixed")); } if (StringUtils::EqualsNoCase(m_type, "mixed")) playlist.SetType("songs"); if (StringUtils::EqualsNoCase(m_type, "mixed")) playlist.SetType("video"); playlist.SetType(m_type); } else { m_strCurrentFilterMusic.clear(); m_strCurrentFilterVideo.clear(); m_type = m_bIsVideo ? "musicvideos" : "songs"; } CGUIDialogProgress* pDialog = (CGUIDialogProgress*)g_windowManager.GetWindow(WINDOW_DIALOG_PROGRESS); int iHeading = (m_bIsVideo ? 20250 : 20121); int iLine0 = (m_bIsVideo ? 20251 : 20123); pDialog->SetHeading(CVariant{iHeading}); pDialog->SetLine(0, CVariant{iLine0}); pDialog->SetLine(1, CVariant{""}); pDialog->SetLine(2, CVariant{""}); pDialog->Open(); ClearState(); unsigned int time = XbmcThreads::SystemClockMillis(); std::vector< std::pair<int,int> > songIDs; if (StringUtils::EqualsNoCase(m_type, "songs") || StringUtils::EqualsNoCase(m_type, "mixed")) { CMusicDatabase db; if (db.Open()) { std::set<std::string> playlists; if ( playlistLoaded ) m_strCurrentFilterMusic = playlist.GetWhereClause(db, playlists); CLog::Log(LOGINFO, "PARTY MODE MANAGER: Registering filter:[%s]", m_strCurrentFilterMusic.c_str()); m_iMatchingSongs = (int)db.GetSongIDs(m_strCurrentFilterMusic, songIDs); if (m_iMatchingSongs < 1 && StringUtils::EqualsNoCase(m_type, "songs")) { pDialog->Close(); db.Close(); OnError(16031, (std::string)"Party mode found no matching songs. Aborting."); return false; } } else { pDialog->Close(); OnError(16033, (std::string)"Party mode could not open database. Aborting."); return false; } db.Close(); } if (StringUtils::EqualsNoCase(m_type, "musicvideos") || StringUtils::EqualsNoCase(m_type, "mixed")) { std::vector< std::pair<int,int> > songIDs2; CVideoDatabase db; if (db.Open()) { std::set<std::string> playlists; if ( playlistLoaded ) m_strCurrentFilterVideo = playlist.GetWhereClause(db, playlists); CLog::Log(LOGINFO, "PARTY MODE MANAGER: Registering filter:[%s]", m_strCurrentFilterVideo.c_str()); m_iMatchingSongs += (int)db.GetMusicVideoIDs(m_strCurrentFilterVideo, songIDs2); if (m_iMatchingSongs < 1) { pDialog->Close(); db.Close(); OnError(16031, (std::string)"Party mode found no matching songs. Aborting."); return false; } } else { pDialog->Close(); OnError(16033, (std::string)"Party mode could not open database. Aborting."); return false; } db.Close(); songIDs.insert(songIDs.end(),songIDs2.begin(),songIDs2.end()); } // calculate history size if (m_iMatchingSongs < 50) m_songsInHistory = 0; else m_songsInHistory = (int)(m_iMatchingSongs/2); if (m_songsInHistory > 200) m_songsInHistory = 200; CLog::Log(LOGINFO,"PARTY MODE MANAGER: Matching songs = %i, History size = %i", m_iMatchingSongs, m_songsInHistory); CLog::Log(LOGINFO,"PARTY MODE MANAGER: Party mode enabled!"); int iPlaylist = m_bIsVideo ? PLAYLIST_VIDEO : PLAYLIST_MUSIC; g_playlistPlayer.ClearPlaylist(iPlaylist); g_playlistPlayer.SetShuffle(iPlaylist, false); g_playlistPlayer.SetRepeat(iPlaylist, PLAYLIST::REPEAT_NONE); pDialog->SetLine(0, CVariant{m_bIsVideo ? 20252 : 20124}); pDialog->Progress(); // add initial songs if (!AddInitialSongs(songIDs)) { pDialog->Close(); return false; } CLog::Log(LOGDEBUG, "%s time for song fetch: %u", __FUNCTION__, XbmcThreads::SystemClockMillis() - time); // start playing g_playlistPlayer.SetCurrentPlaylist(iPlaylist); Play(0); pDialog->Close(); // open now playing window if (StringUtils::EqualsNoCase(m_type, "songs")) { if (g_windowManager.GetActiveWindow() != WINDOW_MUSIC_PLAYLIST) g_windowManager.ActivateWindow(WINDOW_MUSIC_PLAYLIST); } // done m_bEnabled = true; Announce(); return true; }
bool CSaveFileStateJob::DoWork() { std::string progressTrackingFile = m_item.GetPath(); if (m_item.HasVideoInfoTag() && StringUtils::StartsWith(m_item.GetVideoInfoTag()->m_strFileNameAndPath, "removable://")) progressTrackingFile = m_item.GetVideoInfoTag()->m_strFileNameAndPath; // this variable contains removable:// suffixed by disc label+uniqueid or is empty if label not uniquely identified else if (m_item.HasProperty("original_listitem_url")) { // only use original_listitem_url for Python, UPnP and Bluray sources std::string original = m_item.GetProperty("original_listitem_url").asString(); if (URIUtils::IsPlugin(original) || URIUtils::IsUPnP(original) || URIUtils::IsBluray(m_item.GetPath())) progressTrackingFile = original; } if (progressTrackingFile != "") { #ifdef HAS_UPNP // checks if UPnP server of this file is available and supports updating if (URIUtils::IsUPnP(progressTrackingFile) && UPNP::CUPnP::SaveFileState(m_item, m_bookmark, m_updatePlayCount)) { return true; } #endif if (m_item.IsVideo()) { std::string redactPath = CURL::GetRedacted(progressTrackingFile); CLog::Log(LOGDEBUG, "%s - Saving file state for video item %s", __FUNCTION__, redactPath.c_str()); CVideoDatabase videodatabase; if (!videodatabase.Open()) { CLog::Log(LOGWARNING, "%s - Unable to open video database. Can not save file state!", __FUNCTION__); } else { bool updateListing = false; // No resume & watched status for livetv if (!m_item.IsLiveTV()) { if (m_updatePlayCount) { CLog::Log(LOGDEBUG, "%s - Marking video item %s as watched", __FUNCTION__, redactPath.c_str()); // consider this item as played videodatabase.IncrementPlayCount(m_item); m_item.GetVideoInfoTag()->m_playCount++; // PVR: Set recording's play count on the backend (if supported) if (m_item.HasPVRRecordingInfoTag()) m_item.GetPVRRecordingInfoTag()->IncrementPlayCount(); m_item.SetOverlayImage(CGUIListItem::ICON_OVERLAY_UNWATCHED, true); updateListing = true; } else videodatabase.UpdateLastPlayed(m_item); if (!m_item.HasVideoInfoTag() || m_item.GetVideoInfoTag()->m_resumePoint.timeInSeconds != m_bookmark.timeInSeconds) { if (m_bookmark.timeInSeconds <= 0.0f) videodatabase.ClearBookMarksOfFile(progressTrackingFile, CBookmark::RESUME); else videodatabase.AddBookMarkToFile(progressTrackingFile, m_bookmark, CBookmark::RESUME); if (m_item.HasVideoInfoTag()) m_item.GetVideoInfoTag()->m_resumePoint = m_bookmark; // PVR: Set/clear recording's resume bookmark on the backend (if supported) if (m_item.HasPVRRecordingInfoTag()) { PVR::CPVRRecordingPtr recording = m_item.GetPVRRecordingInfoTag(); recording->SetLastPlayedPosition(m_bookmark.timeInSeconds <= 0.0f ? 0 : (int)m_bookmark.timeInSeconds); recording->m_resumePoint = m_bookmark; } // UPnP announce resume point changes to clients // however not if playcount is modified as that already announces if (m_item.IsVideoDb() && !m_updatePlayCount) { CVariant data; data["id"] = m_item.GetVideoInfoTag()->m_iDbId; data["type"] = m_item.GetVideoInfoTag()->m_type; ANNOUNCEMENT::CAnnouncementManager::Get().Announce(ANNOUNCEMENT::VideoLibrary, "xbmc", "OnUpdate", data); } updateListing = true; } } if (m_videoSettings != CMediaSettings::Get().GetDefaultVideoSettings()) { videodatabase.SetVideoSettings(progressTrackingFile, m_videoSettings); } if (m_item.HasVideoInfoTag() && m_item.GetVideoInfoTag()->HasStreamDetails()) { CFileItem dbItem(m_item); // Check whether the item's db streamdetails need updating if (!videodatabase.GetStreamDetails(dbItem) || dbItem.GetVideoInfoTag()->m_streamDetails != m_item.GetVideoInfoTag()->m_streamDetails) { videodatabase.SetStreamDetailsForFile(m_item.GetVideoInfoTag()->m_streamDetails, progressTrackingFile); updateListing = true; } } // in order to properly update the the list, we need to update the stack item which is held in g_application.m_stackFileItemToUpdate if (m_item.HasProperty("stackFileItemToUpdate")) { m_item = m_item_discstack; // as of now, the item is replaced by the discstack item videodatabase.GetResumePoint(*m_item.GetVideoInfoTag()); } videodatabase.Close(); if (updateListing) { CUtil::DeleteVideoDatabaseDirectoryCache(); CFileItemPtr msgItem(new CFileItem(m_item)); if (m_item.HasProperty("original_listitem_url")) msgItem->SetPath(m_item.GetProperty("original_listitem_url").asString()); CGUIMessage message(GUI_MSG_NOTIFY_ALL, g_windowManager.GetActiveWindow(), 0, GUI_MSG_UPDATE_ITEM, 1, msgItem); // 1 to update the listing as well g_windowManager.SendThreadMessage(message); } } } if (m_item.IsAudio()) { std::string redactPath = CURL::GetRedacted(progressTrackingFile); CLog::Log(LOGDEBUG, "%s - Saving file state for audio item %s", __FUNCTION__, redactPath.c_str()); if (m_updatePlayCount) { #if 0 // Can't write to the musicdatabase while scanning for music info CGUIDialogMusicScan *dialog = (CGUIDialogMusicScan *)g_windowManager.GetWindow(WINDOW_DIALOG_MUSIC_SCAN); if (dialog && !dialog->IsDialogRunning()) #endif { CMusicDatabase musicdatabase; if (!musicdatabase.Open()) { CLog::Log(LOGWARNING, "%s - Unable to open music database. Can not save file state!", __FUNCTION__); } else { // consider this item as played CLog::Log(LOGDEBUG, "%s - Marking audio item %s as listened", __FUNCTION__, redactPath.c_str()); musicdatabase.IncrementPlayCount(m_item); musicdatabase.Close(); } } } } } return true; }
bool CGUIWindowMusicNav::OnContextButton(int itemNumber, CONTEXT_BUTTON button) { CFileItemPtr item; if (itemNumber >= 0 && itemNumber < m_vecItems->Size()) item = m_vecItems->Get(itemNumber); switch (button) { case CONTEXT_BUTTON_INFO: { if (!item->IsVideoDb()) return CGUIWindowMusicBase::OnContextButton(itemNumber,button); if (item->m_strPath.Left(14).Equals("videodb://3/4/")) { long idArtist = m_musicdatabase.GetArtistByName(item->GetLabel()); if (idArtist == -1) return false; item->m_strPath.Format("musicdb://2/%ld/", m_musicdatabase.GetArtistByName(item->GetLabel())); CGUIWindowMusicBase::OnContextButton(itemNumber,button); Update(m_vecItems->m_strPath); m_viewControl.SetSelectedItem(itemNumber); return true; } CGUIWindowVideoNav* pWindow = (CGUIWindowVideoNav*)m_gWindowManager.GetWindow(WINDOW_VIDEO_NAV); if (pWindow) { SScraperInfo info; pWindow->OnInfo(item.get(),info); Update(m_vecItems->m_strPath); } return true; } case CONTEXT_BUTTON_INFO_ALL: OnInfoAll(itemNumber); return true; case CONTEXT_BUTTON_SET_ARTIST_THUMB: case CONTEXT_BUTTON_SET_PLUGIN_THUMB: SetThumb(itemNumber, button); return true; case CONTEXT_BUTTON_UPDATE_LIBRARY: { CGUIDialogMusicScan *scanner = (CGUIDialogMusicScan *)m_gWindowManager.GetWindow(WINDOW_DIALOG_MUSIC_SCAN); if (scanner) scanner->StartScanning(""); return true; } case CONTEXT_BUTTON_SET_DEFAULT: g_settings.m_defaultMusicLibSource = GetQuickpathName(item->m_strPath); g_settings.Save(); return true; case CONTEXT_BUTTON_CLEAR_DEFAULT: g_settings.m_defaultMusicLibSource.Empty(); g_settings.Save(); return true; case CONTEXT_BUTTON_GO_TO_ARTIST: { CStdString strPath; CVideoDatabase database; database.Open(); strPath.Format("videodb://3/4/%ld/",database.GetMatchingMusicVideo(item->GetMusicInfoTag()->GetArtist())); m_gWindowManager.ActivateWindow(WINDOW_VIDEO_NAV,strPath); return true; } case CONTEXT_BUTTON_PLAY_OTHER: { CVideoDatabase database; database.Open(); CVideoInfoTag details; database.GetMusicVideoInfo("",details,database.GetMatchingMusicVideo(item->GetMusicInfoTag()->GetArtist(),item->GetMusicInfoTag()->GetAlbum(),item->GetMusicInfoTag()->GetTitle())); g_application.getApplicationMessenger().PlayFile(CFileItem(details)); return true; } case CONTEXT_BUTTON_MARK_WATCHED: CGUIWindowVideoBase::MarkWatched(item); CUtil::DeleteVideoDatabaseDirectoryCache(); Update(m_vecItems->m_strPath); return true; case CONTEXT_BUTTON_MARK_UNWATCHED: CGUIWindowVideoBase::MarkUnWatched(item); CUtil::DeleteVideoDatabaseDirectoryCache(); Update(m_vecItems->m_strPath); return true; case CONTEXT_BUTTON_RENAME: CGUIWindowVideoBase::UpdateVideoTitle(item.get()); CUtil::DeleteVideoDatabaseDirectoryCache(); Update(m_vecItems->m_strPath); return true; case CONTEXT_BUTTON_DELETE: CGUIWindowVideoNav::DeleteItem(item.get()); CUtil::DeleteVideoDatabaseDirectoryCache(); Update(m_vecItems->m_strPath); return true; case CONTEXT_BUTTON_SET_CONTENT: { bool bScan=false; SScraperInfo info; if (!m_musicdatabase.GetScraperForPath(item->m_strPath,info)) info.strContent = "albums"; int iLabel=132; // per genre or for all artists if (m_vecItems->m_strPath.Equals("musicdb://1/") || item->m_strPath.Equals("musicdb://2/")) { iLabel = 133; } if (CGUIDialogContentSettings::Show(info, bScan,iLabel)) { m_musicdatabase.SetScraperForPath(item->m_strPath,info); if (bScan) OnInfoAll(itemNumber,true); } return true; } default: break; } return CGUIWindowMusicBase::OnContextButton(itemNumber, button); }
void CGUIWindowMusicNav::GetContextButtons(int itemNumber, CContextButtons &buttons) { CGUIWindowMusicBase::GetContextButtons(itemNumber, buttons); CGUIDialogMusicScan *musicScan = (CGUIDialogMusicScan *)m_gWindowManager.GetWindow(WINDOW_DIALOG_MUSIC_SCAN); CFileItemPtr item; if (itemNumber >= 0 && itemNumber < m_vecItems->Size()) item = m_vecItems->Get(itemNumber); if (item && (item->GetExtraInfo().Find("lastfm") < 0)) { // are we in the playlists location? bool inPlaylists = m_vecItems->m_strPath.Equals(CUtil::MusicPlaylistsLocation()) || m_vecItems->m_strPath.Equals("special://musicplaylists/"); CMusicDatabaseDirectory dir; SScraperInfo info; m_musicdatabase.GetScraperForPath(item->m_strPath,info); // enable music info button on an album or on a song. if (item->IsAudio() && !item->IsPlayList() && !item->IsSmartPlayList() && !item->IsLastFM() && !item->IsShoutCast()) { buttons.Add(CONTEXT_BUTTON_SONG_INFO, 658); } else if (item->IsVideoDb()) { if (!item->m_bIsFolder) // music video buttons.Add(CONTEXT_BUTTON_INFO, 20393); if (item->m_strPath.Left(14).Equals("videodb://3/4/") && item->m_strPath.size() > 14 && item->m_bIsFolder) { long idArtist = m_musicdatabase.GetArtistByName(m_vecItems->Get(itemNumber)->GetLabel()); if (idArtist > - 1) buttons.Add(CONTEXT_BUTTON_INFO,21891); } } else if (!inPlaylists && (dir.HasAlbumInfo(item->m_strPath)|| dir.IsArtistDir(item->m_strPath) ) && !dir.IsAllItem(item->m_strPath) && !item->IsParentFolder() && !item->IsLastFM() && !item->IsShoutCast() && !item->m_strPath.Left(14).Equals("musicsearch://")) { if (dir.IsArtistDir(item->m_strPath)) buttons.Add(CONTEXT_BUTTON_INFO, 21891); else buttons.Add(CONTEXT_BUTTON_INFO, 13351); } // enable query all albums button only in album view if (dir.HasAlbumInfo(item->m_strPath) && !dir.IsAllItem(item->m_strPath) && item->m_bIsFolder && !item->IsVideoDb() && !item->IsParentFolder() && !item->IsLastFM() && !item->IsShoutCast() && !item->m_strPath.Left(14).Equals("musicsearch://")) { buttons.Add(CONTEXT_BUTTON_INFO_ALL, 20059); } // enable query all artist button only in album view if (dir.IsArtistDir(item->m_strPath) && !dir.IsAllItem(item->m_strPath) && item->m_bIsFolder && !item->IsVideoDb() && !info.strContent.IsEmpty()) { buttons.Add(CONTEXT_BUTTON_INFO_ALL, 21884); } // turn off set artist image if not at artist listing. if (dir.IsArtistDir(item->m_strPath) && !dir.IsAllItem(item->m_strPath) || (item->m_strPath.Left(14).Equals("videodb://3/4/") && item->m_strPath.size() > 14 && item->m_bIsFolder)) { buttons.Add(CONTEXT_BUTTON_SET_ARTIST_THUMB, 13359); } if (m_vecItems->m_strPath.Equals("plugin://music/")) buttons.Add(CONTEXT_BUTTON_SET_PLUGIN_THUMB, 1044); //Set default or clear default NODE_TYPE nodetype = dir.GetDirectoryType(item->m_strPath); if (!item->IsParentFolder() && !inPlaylists && (nodetype == NODE_TYPE_ROOT || nodetype == NODE_TYPE_OVERVIEW || nodetype == NODE_TYPE_TOP100)) { if (!item->m_strPath.Equals(g_settings.m_defaultMusicLibSource)) buttons.Add(CONTEXT_BUTTON_SET_DEFAULT, 13335); // set default if (strcmp(g_settings.m_defaultMusicLibSource, "")) buttons.Add(CONTEXT_BUTTON_CLEAR_DEFAULT, 13403); // clear default } NODE_TYPE childtype = dir.GetDirectoryChildType(item->m_strPath); if (childtype == NODE_TYPE_ALBUM || childtype == NODE_TYPE_ARTIST || nodetype == NODE_TYPE_GENRE || nodetype == NODE_TYPE_ALBUM) { // we allow the user to set content for // 1. general artist and album nodes // 2. specific per genre // 3. specific per artist // 4. specific per album buttons.Add(CONTEXT_BUTTON_SET_CONTENT,20195); } if (item->HasMusicInfoTag() && item->GetMusicInfoTag()->GetArtist().size() > 0) { CVideoDatabase database; database.Open(); if (database.GetMatchingMusicVideo(item->GetMusicInfoTag()->GetArtist()) > -1) buttons.Add(CONTEXT_BUTTON_GO_TO_ARTIST, 20400); } if (item->HasMusicInfoTag() && item->GetMusicInfoTag()->GetArtist().size() > 0 && item->GetMusicInfoTag()->GetAlbum().size() > 0 && item->GetMusicInfoTag()->GetTitle().size() > 0) { CVideoDatabase database; database.Open(); if (database.GetMatchingMusicVideo(item->GetMusicInfoTag()->GetArtist(),item->GetMusicInfoTag()->GetAlbum(),item->GetMusicInfoTag()->GetTitle()) > -1) buttons.Add(CONTEXT_BUTTON_PLAY_OTHER, 20401); } if (item->HasVideoInfoTag() && !item->m_bIsFolder) { if (item->GetVideoInfoTag()->m_playCount > 0) buttons.Add(CONTEXT_BUTTON_MARK_UNWATCHED, 16104); //Mark as UnWatched else buttons.Add(CONTEXT_BUTTON_MARK_WATCHED, 16103); //Mark as Watched if (g_settings.m_vecProfiles[g_settings.m_iLastLoadedProfileIndex].canWriteDatabases() || g_passwordManager.bMasterUser) { buttons.Add(CONTEXT_BUTTON_RENAME, 16105); buttons.Add(CONTEXT_BUTTON_DELETE, 646); } } } // noncontextual buttons if (musicScan && musicScan->IsScanning()) buttons.Add(CONTEXT_BUTTON_STOP_SCANNING, 13353); // Stop Scanning else if (musicScan) buttons.Add(CONTEXT_BUTTON_UPDATE_LIBRARY, 653); CGUIWindowMusicBase::GetNonContextButtons(buttons); }
bool CGUIDialogVideoInfo::OnMessage(CGUIMessage& message) { switch ( message.GetMessage() ) { case GUI_MSG_WINDOW_DEINIT: { ClearCastList(); } break; case GUI_MSG_WINDOW_INIT: { m_dlgProgress = (CGUIDialogProgress*)g_windowManager.GetWindow(WINDOW_DIALOG_PROGRESS); m_bRefresh = false; m_bRefreshAll = true; m_hasUpdatedThumb = false; CGUIDialog::OnMessage(message); m_bViewReview = true; CVideoDatabase database; ADDON::ScraperPtr scraper; if(database.Open()) { scraper = database.GetScraperForPath(m_movieItem->GetVideoInfoTag()->GetPath()); database.Close(); } CONTROL_ENABLE_ON_CONDITION(CONTROL_BTN_REFRESH, (g_settings.GetCurrentProfile().canWriteDatabases() || g_passwordManager.bMasterUser) && !m_movieItem->GetVideoInfoTag()->m_strIMDBNumber.Left(2).Equals("xx") && scraper); CONTROL_ENABLE_ON_CONDITION(CONTROL_BTN_GET_THUMB, (g_settings.GetCurrentProfile().canWriteDatabases() || g_passwordManager.bMasterUser) && !m_movieItem->GetVideoInfoTag()->m_strIMDBNumber.Mid(2).Equals("plugin")); VIDEODB_CONTENT_TYPE type = (VIDEODB_CONTENT_TYPE)m_movieItem->GetVideoContentType(); if (type == VIDEODB_CONTENT_TVSHOWS || type == VIDEODB_CONTENT_MOVIES) CONTROL_ENABLE_ON_CONDITION(CONTROL_BTN_GET_FANART, (g_settings.GetCurrentProfile().canWriteDatabases() || g_passwordManager.bMasterUser) && !m_movieItem->GetVideoInfoTag()->m_strIMDBNumber.Mid(2).Equals("plugin")); else CONTROL_DISABLE(CONTROL_BTN_GET_FANART); Update(); return true; } break; case GUI_MSG_CLICKED: { int iControl = message.GetSenderId(); if (iControl == CONTROL_BTN_REFRESH) { if (m_movieItem->GetVideoInfoTag()->m_iSeason < 0 && !m_movieItem->GetVideoInfoTag()->m_strShowTitle.IsEmpty()) // tv show { bool bCanceled=false; if (CGUIDialogYesNo::ShowAndGetInput(20377,20378,-1,-1,bCanceled)) { m_bRefreshAll = true; CVideoDatabase db; if (db.Open()) { db.SetPathHash(m_movieItem->GetVideoInfoTag()->m_strPath,""); db.Close(); } } else m_bRefreshAll = false; if (bCanceled) return false; } m_bRefresh = true; Close(); return true; } else if (iControl == CONTROL_BTN_TRACKS) { m_bViewReview = !m_bViewReview; Update(); } else if (iControl == CONTROL_BTN_PLAY) { Play(); } else if (iControl == CONTROL_BTN_RESUME) { Play(true); } else if (iControl == CONTROL_BTN_GET_THUMB) { OnGetThumb(); } else if (iControl == CONTROL_BTN_PLAY_TRAILER) { PlayTrailer(); } else if (iControl == CONTROL_BTN_GET_FANART) { OnGetFanart(); } else if (iControl == CONTROL_BTN_DIRECTOR) { CStdString strDirector = StringUtils::Join(m_movieItem->GetVideoInfoTag()->m_director, g_advancedSettings.m_videoItemSeparator); OnSearch(strDirector); } else if (iControl == CONTROL_LIST) { int iAction = message.GetParam1(); if (ACTION_SELECT_ITEM == iAction || ACTION_MOUSE_LEFT_CLICK == iAction) { CGUIMessage msg(GUI_MSG_ITEM_SELECTED, GetID(), iControl); OnMessage(msg); int iItem = msg.GetParam1(); if (iItem < 0 || iItem >= m_castList->Size()) break; CStdString strItem = m_castList->Get(iItem)->GetLabel(); CStdString strFind; strFind.Format(" %s ",g_localizeStrings.Get(20347)); int iPos = strItem.Find(strFind); if (iPos == -1) iPos = strItem.size(); CStdString tmp = strItem.Left(iPos); OnSearch(tmp); } } } break; case GUI_MSG_NOTIFY_ALL: { if (IsActive() && message.GetParam1() == GUI_MSG_UPDATE_ITEM && message.GetItem()) { CFileItemPtr item = boost::static_pointer_cast<CFileItem>(message.GetItem()); if (item && m_movieItem->GetPath().Equals(item->GetPath())) { // Just copy over the stream details and the thumb if we don't already have one if (!m_movieItem->HasThumbnail()) m_movieItem->SetThumbnailImage(item->GetThumbnailImage()); m_movieItem->GetVideoInfoTag()->m_streamDetails = item->GetVideoInfoTag()->m_streamDetails; } return true; } } } return CGUIDialog::OnMessage(message); }
bool CGUIWindowMusicNav::OnContextButton(int itemNumber, CONTEXT_BUTTON button) { CFileItemPtr item; if (itemNumber >= 0 && itemNumber < m_vecItems->Size()) item = m_vecItems->Get(itemNumber); switch (button) { case CONTEXT_BUTTON_INFO: { if (!item->IsVideoDb()) return CGUIWindowMusicBase::OnContextButton(itemNumber,button); // music videos - artists if (StringUtils::StartsWithNoCase(item->GetPath(), "videodb://musicvideos/artists/")) { long idArtist = m_musicdatabase.GetArtistByName(item->GetLabel()); if (idArtist == -1) return false; std::string path = StringUtils::Format("musicdb://artists/%ld/", idArtist); CArtist artist; m_musicdatabase.GetArtist(idArtist, artist, false); *item = CFileItem(artist); item->SetPath(path); CGUIWindowMusicBase::OnContextButton(itemNumber,button); Refresh(); m_viewControl.SetSelectedItem(itemNumber); return true; } // music videos - albums if (StringUtils::StartsWithNoCase(item->GetPath(), "videodb://musicvideos/albums/")) { long idAlbum = m_musicdatabase.GetAlbumByName(item->GetLabel()); if (idAlbum == -1) return false; std::string path = StringUtils::Format("musicdb://albums/%ld/", idAlbum); CAlbum album; m_musicdatabase.GetAlbum(idAlbum, album, false); *item = CFileItem(path,album); item->SetPath(path); CGUIWindowMusicBase::OnContextButton(itemNumber,button); Refresh(); m_viewControl.SetSelectedItem(itemNumber); return true; } if (item->HasVideoInfoTag() && !item->GetVideoInfoTag()->m_strTitle.empty()) { CGUIWindowVideoNav* pWindow = (CGUIWindowVideoNav*)g_windowManager.GetWindow(WINDOW_VIDEO_NAV); if (pWindow) { ADDON::ScraperPtr info; pWindow->OnItemInfo(item.get(),info); Refresh(); } } return true; } case CONTEXT_BUTTON_INFO_ALL: OnItemInfoAll(itemNumber); return true; case CONTEXT_BUTTON_SET_DEFAULT: CSettings::GetInstance().SetString(CSettings::SETTING_MYMUSIC_DEFAULTLIBVIEW, GetQuickpathName(item->GetPath())); CSettings::GetInstance().Save(); return true; case CONTEXT_BUTTON_CLEAR_DEFAULT: CSettings::GetInstance().SetString(CSettings::SETTING_MYMUSIC_DEFAULTLIBVIEW, ""); CSettings::GetInstance().Save(); return true; case CONTEXT_BUTTON_GO_TO_ARTIST: { std::string strPath; CVideoDatabase database; database.Open(); strPath = StringUtils::Format("videodb://musicvideos/artists/%i/", database.GetMatchingMusicVideo(item->GetMusicInfoTag()->GetArtistString())); g_windowManager.ActivateWindow(WINDOW_VIDEO_NAV,strPath); return true; } case CONTEXT_BUTTON_PLAY_OTHER: { CVideoDatabase database; database.Open(); CVideoInfoTag details; database.GetMusicVideoInfo("", details, database.GetMatchingMusicVideo(item->GetMusicInfoTag()->GetArtistString(), item->GetMusicInfoTag()->GetAlbum(), item->GetMusicInfoTag()->GetTitle())); CApplicationMessenger::GetInstance().PostMsg(TMSG_MEDIA_PLAY, 0, 0, static_cast<void*>(new CFileItem(details))); return true; } case CONTEXT_BUTTON_RENAME: if (!item->IsVideoDb() && !item->IsReadOnly()) OnRenameItem(itemNumber); CGUIDialogVideoInfo::UpdateVideoItemTitle(item); CUtil::DeleteVideoDatabaseDirectoryCache(); Refresh(); return true; case CONTEXT_BUTTON_DELETE: if (item->IsPlayList() || item->IsSmartPlayList()) { item->m_bIsFolder = false; CFileUtils::DeleteItem(item); } else if (!item->IsVideoDb()) OnDeleteItem(itemNumber); else { CGUIDialogVideoInfo::DeleteVideoItemFromDatabase(item); CUtil::DeleteVideoDatabaseDirectoryCache(); } Refresh(); return true; case CONTEXT_BUTTON_SET_CONTENT: { ADDON::ScraperPtr scraper; std::string path(item->GetPath()); CQueryParams params; CDirectoryNode::GetDatabaseInfo(item->GetPath(), params); CONTENT_TYPE content = CONTENT_ALBUMS; if (params.GetAlbumId() != -1) path = StringUtils::Format("musicdb://albums/%li/",params.GetAlbumId()); else if (params.GetArtistId() != -1) { path = StringUtils::Format("musicdb://artists/%li/",params.GetArtistId()); content = CONTENT_ARTISTS; } if (m_vecItems->IsPath("musicdb://genres/") || item->IsPath("musicdb://artists/")) { content = CONTENT_ARTISTS; } if (!m_musicdatabase.GetScraperForPath(path, scraper, ADDON::ScraperTypeFromContent(content))) { ADDON::AddonPtr defaultScraper; if (ADDON::CAddonMgr::GetInstance().GetDefault(ADDON::ScraperTypeFromContent(content), defaultScraper)) { scraper = std::dynamic_pointer_cast<ADDON::CScraper>(defaultScraper); } } if (CGUIDialogContentSettings::Show(scraper, content)) { m_musicdatabase.SetScraperForPath(path,scraper); if (CGUIDialogYesNo::ShowAndGetInput(CVariant{20442}, CVariant{20443})) { OnItemInfoAll(itemNumber,true,true); } } return true; } default: break; } return CGUIWindowMusicBase::OnContextButton(itemNumber, button); }
bool CThumbExtractor::DoWork() { if (m_item.IsLiveTV() // Due to a pvr addon api design flaw (no support for multiple concurrent streams // per addon instance), pvr recording thumbnail extraction does not work (reliably). || m_item.IsPVRRecording() || URIUtils::IsUPnP(m_item.GetPath()) || URIUtils::IsBluray(m_item.GetPath()) || m_item.IsBDFile() || m_item.IsDVD() || m_item.IsDiscImage() || m_item.IsDVDFile(false, true) || m_item.IsInternetStream() || m_item.IsDiscStub() || m_item.IsPlayList()) return false; // For HTTP/FTP we only allow extraction when on a LAN if (URIUtils::IsRemote(m_item.GetPath()) && !URIUtils::IsOnLAN(m_item.GetPath()) && (URIUtils::IsFTP(m_item.GetPath()) || URIUtils::IsHTTP(m_item.GetPath()))) return false; bool result=false; if (m_thumb) { CLog::Log(LOGDEBUG,"%s - trying to extract thumb from video file %s", __FUNCTION__, CURL::GetRedacted(m_item.GetPath()).c_str()); // construct the thumb cache file CTextureDetails details; details.file = CTextureCache::GetCacheFile(m_target) + ".jpg"; result = CDVDFileInfo::ExtractThumb(m_item.GetPath(), details, m_fillStreamDetails ? &m_item.GetVideoInfoTag()->m_streamDetails : NULL, (int) m_pos); if(result) { CTextureCache::GetInstance().AddCachedTexture(m_target, details); m_item.SetProperty("HasAutoThumb", true); m_item.SetProperty("AutoThumbImage", m_target); m_item.SetArt("thumb", m_target); CVideoInfoTag* info = m_item.GetVideoInfoTag(); if (info->m_iDbId > 0 && !info->m_type.empty()) { CVideoDatabase db; if (db.Open()) { db.SetArtForItem(info->m_iDbId, info->m_type, "thumb", m_item.GetArt("thumb")); db.Close(); } } } } else if (!m_item.IsPlugin() && (!m_item.HasVideoInfoTag() || !m_item.GetVideoInfoTag()->HasStreamDetails())) { // No tag or no details set, so extract them CLog::Log(LOGDEBUG,"%s - trying to extract filestream details from video file %s", __FUNCTION__, CURL::GetRedacted(m_item.GetPath()).c_str()); result = CDVDFileInfo::GetFileStreamDetails(&m_item); } if (result) { CVideoInfoTag* info = m_item.GetVideoInfoTag(); CVideoDatabase db; if (db.Open()) { if (URIUtils::IsStack(m_listpath)) { // Don't know the total time of the stack, so set duration to zero to avoid confusion info->m_streamDetails.SetVideoDuration(0, 0); // Restore original stack path m_item.SetPath(m_listpath); } if (info->m_iFileId < 0) db.SetStreamDetailsForFile(info->m_streamDetails, !info->m_strFileNameAndPath.empty() ? info->m_strFileNameAndPath : static_cast<const std::string&>(m_item.GetPath())); else db.SetStreamDetailsForFileId(info->m_streamDetails, info->m_iFileId); // overwrite the runtime value if the one from streamdetails is available if (info->m_iDbId > 0 && info->m_duration > 0 && static_cast<size_t>(info->m_duration) != info->GetDuration()) { info->m_duration = info->GetDuration(); // store the updated information in the database db.SetDetailsForItem(info->m_iDbId, info->m_type, *info, m_item.GetArt()); } db.Close(); } return true; } return false; }
void CMediaSettings::OnSettingAction(const CSetting *setting) { if (setting == NULL) return; const std::string &settingId = setting->GetId(); if (settingId == "karaoke.export") { CContextButtons choices; choices.Add(1, g_localizeStrings.Get(22034)); choices.Add(2, g_localizeStrings.Get(22035)); int retVal = CGUIDialogContextMenu::ShowAndGetChoice(choices); if ( retVal > 0 ) { std::string path(CProfilesManager::Get().GetDatabaseFolder()); VECSOURCES shares; g_mediaManager.GetLocalDrives(shares); if (CGUIDialogFileBrowser::ShowAndGetDirectory(shares, g_localizeStrings.Get(661), path, true)) { CMusicDatabase musicdatabase; musicdatabase.Open(); if ( retVal == 1 ) { path = URIUtils::AddFileToFolder(path, "karaoke.html"); musicdatabase.ExportKaraokeInfo( path, true ); } else { path = URIUtils::AddFileToFolder(path, "karaoke.csv"); musicdatabase.ExportKaraokeInfo( path, false ); } musicdatabase.Close(); } } } else if (settingId == "karaoke.importcsv") { std::string path(CProfilesManager::Get().GetDatabaseFolder()); VECSOURCES shares; g_mediaManager.GetLocalDrives(shares); if (CGUIDialogFileBrowser::ShowAndGetFile(shares, "karaoke.csv", g_localizeStrings.Get(651) , path)) { CMusicDatabase musicdatabase; musicdatabase.Open(); musicdatabase.ImportKaraokeInfo(path); musicdatabase.Close(); } } else if (settingId == "musiclibrary.cleanup") { if (CGUIDialogYesNo::ShowAndGetInput(313, 333, 0, 0)) g_application.StartMusicCleanup(true); } else if (settingId == "musiclibrary.export") CBuiltins::Execute("exportlibrary(music)"); else if (settingId == "musiclibrary.import") { std::string path; VECSOURCES shares; g_mediaManager.GetLocalDrives(shares); if (CGUIDialogFileBrowser::ShowAndGetFile(shares, "musicdb.xml", g_localizeStrings.Get(651) , path)) { CMusicDatabase musicdatabase; musicdatabase.Open(); musicdatabase.ImportFromXML(path); musicdatabase.Close(); } } else if (settingId == "videolibrary.cleanup") { if (CGUIDialogYesNo::ShowAndGetInput(313, 333, 0, 0)) g_application.StartVideoCleanup(true); } else if (settingId == "videolibrary.export") CBuiltins::Execute("exportlibrary(video)"); else if (settingId == "videolibrary.import") { std::string path; VECSOURCES shares; g_mediaManager.GetLocalDrives(shares); if (CGUIDialogFileBrowser::ShowAndGetDirectory(shares, g_localizeStrings.Get(651) , path)) { CVideoDatabase videodatabase; videodatabase.Open(); videodatabase.ImportFromXML(path); videodatabase.Close(); } } }
void CGUIWindowVideoNav::LoadVideoInfo(CFileItemList &items, CVideoDatabase &database, bool allowReplaceLabels) { // TODO: this could possibly be threaded as per the music info loading, // we could also cache the info if (!items.GetContent().empty() && !items.IsPlugin()) return; // don't load for listings that have content set and weren't created from plugins std::string content = items.GetContent(); // determine content only if it isn't set if (content.empty()) { content = database.GetContentForPath(items.GetPath()); items.SetContent((content.empty() && !items.IsPlugin()) ? "files" : content); } /* If we have a matching item in the library, so we can assign the metadata to it. In addition, we can choose * whether the item is stacked down (eg in the case of folders representing a single item) * whether or not we assign the library's labels to the item, or leave the item as is. As certain users (read: certain developers) don't want either of these to occur, we compromise by stacking items down only if stacking is available and enabled. Similarly, we assign the "clean" library labels to the item only if the "Replace filenames with library titles" setting is enabled. */ const bool stackItems = items.GetProperty("isstacked").asBoolean() || (StackingAvailable(items) && CSettings::GetInstance().GetBool(CSettings::SETTING_MYVIDEOS_STACKVIDEOS)); const bool replaceLabels = allowReplaceLabels && CSettings::GetInstance().GetBool(CSettings::SETTING_MYVIDEOS_REPLACELABELS); CFileItemList dbItems; /* NOTE: In the future when GetItemsForPath returns all items regardless of whether they're "in the library" we won't need the fetchedPlayCounts code, and can "simply" do this directly on absense of content. */ bool fetchedPlayCounts = false; if (!content.empty()) { database.GetItemsForPath(content, items.GetPath(), dbItems); dbItems.SetFastLookup(true); } for (int i = 0; i < items.Size(); i++) { CFileItemPtr pItem = items[i]; CFileItemPtr match; if (!content.empty()) /* optical media will be stacked down, so it's path won't match the base path */ { std::string pathToMatch = pItem->IsOpticalMediaFile() ? pItem->GetLocalMetadataPath() : pItem->GetPath(); if (URIUtils::IsMultiPath(pathToMatch)) pathToMatch = CMultiPathDirectory::GetFirstPath(pathToMatch); match = dbItems.Get(pathToMatch); } if (match) { pItem->UpdateInfo(*match, replaceLabels); if (stackItems) { if (match->m_bIsFolder) pItem->SetPath(match->GetVideoInfoTag()->m_strPath); else pItem->SetPath(match->GetVideoInfoTag()->m_strFileNameAndPath); // if we switch from a file to a folder item it means we really shouldn't be sorting files and // folders separately if (pItem->m_bIsFolder != match->m_bIsFolder) { items.SetSortIgnoreFolders(true); pItem->m_bIsFolder = match->m_bIsFolder; } } } else { /* NOTE: Currently we GetPlayCounts on our items regardless of whether content is set as if content is set, GetItemsForPaths doesn't return anything not in the content tables. This code can be removed once the content tables are always filled */ if (!pItem->m_bIsFolder && !fetchedPlayCounts) { database.GetPlayCounts(items.GetPath(), items); fetchedPlayCounts = true; } // preferably use some information from PVR info tag if available if (pItem->HasPVRRecordingInfoTag()) pItem->GetPVRRecordingInfoTag()->CopyClientInfo(pItem->GetVideoInfoTag()); // set the watched overlay if (pItem->IsVideo()) pItem->SetOverlayImage(CGUIListItem::ICON_OVERLAY_UNWATCHED, pItem->HasVideoInfoTag() && pItem->GetVideoInfoTag()->m_playCount > 0); } } }
bool CVideoLibraryCleaningJob::Work(CVideoDatabase &db) { db.CleanDatabase(GetProgressBar(), m_paths, m_showDialog); return true; }
bool CSmartPlaylistDirectory::GetDirectory(const CSmartPlaylist &playlist, CFileItemList& items, const CStdString &strBaseDir /* = "" */, bool filter /* = false */) { bool success = false, success2 = false; std::set<CStdString> playlists; SortDescription sorting; sorting.limitEnd = playlist.GetLimit(); sorting.sortBy = playlist.GetOrder(); sorting.sortOrder = playlist.GetOrderAscending() ? SortOrderAscending : SortOrderDescending; if (g_guiSettings.GetBool("filelists.ignorethewhensorting")) sorting.sortAttributes = SortAttributeIgnoreArticle; std::string option = !filter ? "xsp" : "filter"; if (playlist.GetType().Equals("movies") || playlist.GetType().Equals("tvshows") || playlist.GetType().Equals("episodes")) { CVideoDatabase db; if (db.Open()) { MediaType mediaType = DatabaseUtils::MediaTypeFromString(playlist.GetType()); CStdString baseDir = strBaseDir; if (strBaseDir.empty()) { switch (mediaType) { case MediaTypeTvShow: case MediaTypeEpisode: baseDir = "videodb://2/2/"; break; case MediaTypeMovie: baseDir = "videodb://1/2/"; break; default: return false; } } CVideoDbUrl videoUrl; if (!videoUrl.FromString(baseDir)) return false; // store the smartplaylist as JSON in the URL as well CStdString xsp; if (!playlist.IsEmpty(filter)) { if (!playlist.SaveAsJson(xsp, !filter)) return false; } videoUrl.AddOption(option, xsp); CDatabase::Filter dbfilter; success = db.GetSortedVideos(mediaType, videoUrl.ToString(), sorting, items, dbfilter, true); db.Close(); // if we retrieve a list of episodes and we didn't receive // a pre-defined base path, we need to fix it if (strBaseDir.empty() && mediaType == MediaTypeEpisode) videoUrl.AppendPath("-1/-1/"); items.SetProperty(PROPERTY_PATH_DB, videoUrl.ToString()); } } else if (playlist.GetType().Equals("albums")) { CMusicDatabase db; if (db.Open()) { CMusicDbUrl musicUrl; if (!musicUrl.FromString(!strBaseDir.empty() ? strBaseDir : "musicdb://3/")) return false; // store the smartplaylist as JSON in the URL as well CStdString xsp; if (!playlist.IsEmpty(filter)) { if (!playlist.SaveAsJson(xsp, !filter)) return false; } musicUrl.AddOption(option, xsp); CDatabase::Filter dbfilter; success = db.GetAlbumsByWhere(musicUrl.ToString(), dbfilter, items, sorting); db.Close(); items.SetContent("albums"); items.SetProperty(PROPERTY_PATH_DB, musicUrl.ToString()); } } else if (playlist.GetType().Equals("artists")) { CMusicDatabase db; if (db.Open()) { CMusicDbUrl musicUrl; if (!musicUrl.FromString("musicdb://2/")) return false; // store the smartplaylist as JSON in the URL as well CStdString xsp; if (!playlist.IsEmpty(filter)) { if (!playlist.SaveAsJson(xsp, !filter)) return false; } musicUrl.AddOption(option, xsp); CDatabase::Filter dbfilter; success = db.GetArtistsNav(musicUrl.ToString(), items, !g_guiSettings.GetBool("musiclibrary.showcompilationartists"), -1, -1, -1, dbfilter, sorting); db.Close(); items.SetContent("artists"); items.SetProperty(PROPERTY_PATH_DB, musicUrl.ToString()); } } if (playlist.GetType().Equals("songs") || playlist.GetType().Equals("mixed") || playlist.GetType().IsEmpty()) { CMusicDatabase db; if (db.Open()) { CSmartPlaylist songPlaylist(playlist); if (playlist.GetType().IsEmpty() || playlist.GetType().Equals("mixed")) songPlaylist.SetType("songs"); CMusicDbUrl musicUrl; if (!musicUrl.FromString(!strBaseDir.empty() ? strBaseDir : "musicdb://4/")) return false; // store the smartplaylist as JSON in the URL as well CStdString xsp; if (!songPlaylist.IsEmpty(filter)) { if (!songPlaylist.SaveAsJson(xsp, !filter)) return false; } musicUrl.AddOption(option, xsp); CDatabase::Filter dbfilter; success = db.GetSongsByWhere(musicUrl.ToString(), dbfilter, items, sorting); db.Close(); items.SetContent("songs"); items.SetProperty(PROPERTY_PATH_DB, musicUrl.ToString()); } } if (playlist.GetType().Equals("musicvideos") || playlist.GetType().Equals("mixed")) { CVideoDatabase db; if (db.Open()) { CSmartPlaylist mvidPlaylist(playlist); if (playlist.GetType().Equals("mixed")) mvidPlaylist.SetType("musicvideos"); CVideoDbUrl videoUrl; if (!videoUrl.FromString(!strBaseDir.empty() ? strBaseDir : "videodb://3/2/")) return false; // store the smartplaylist as JSON in the URL as well CStdString xsp; if (!mvidPlaylist.IsEmpty(filter)) { if (!mvidPlaylist.SaveAsJson(xsp, !filter)) return false; } videoUrl.AddOption(option, xsp); CFileItemList items2; success2 = db.GetSortedVideos(MediaTypeMusicVideo, videoUrl.ToString(), sorting, items2); db.Close(); items.Append(items2); if (items2.Size()) { if (items.Size() > items2.Size()) items.SetContent("mixed"); else items.SetContent("musicvideos"); } items.SetProperty(PROPERTY_PATH_DB, videoUrl.ToString()); } } items.SetLabel(playlist.GetName()); // go through and set the playlist order for (int i = 0; i < items.Size(); i++) { CFileItemPtr item = items[i]; item->m_iprogramCount = i; // hack for playlist order } if (playlist.GetType().Equals("mixed")) return success || success2; else if (playlist.GetType().Equals("musicvideos")) return success2; else return success; }
JSON_STATUS CPlayerOperations::GetItem(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant ¶meterObject, CVariant &result) { PlayerType player = GetPlayer(parameterObject["playerid"]); CFileItemPtr fileItem; switch (player) { case Video: case Audio: { if (g_application.CurrentFileItem().GetLabel().empty()) { CFileItem tmpItem; if (player == Video) CVideoLibrary::FillFileItem(g_application.CurrentFile(), tmpItem); else CAudioLibrary::FillFileItem(g_application.CurrentFile(), tmpItem); fileItem = CFileItemPtr(new CFileItem(tmpItem)); } else fileItem = CFileItemPtr(new CFileItem(g_application.CurrentFileItem())); if (player == Video) { bool additionalInfo = false; for (CVariant::const_iterator_array itr = parameterObject["properties"].begin_array(); itr != parameterObject["properties"].end_array(); itr++) { CStdString fieldValue = itr->asString(); if (fieldValue == "cast" || fieldValue == "set" || fieldValue == "setid" || fieldValue == "showlink" || fieldValue == "resume") additionalInfo = true; } if (additionalInfo) { CVideoDatabase videodatabase; if (videodatabase.Open()) { switch (fileItem->GetVideoContentType()) { case VIDEODB_CONTENT_MOVIES: videodatabase.GetMovieInfo("", *(fileItem->GetVideoInfoTag()), fileItem->GetVideoInfoTag()->m_iDbId); break; case VIDEODB_CONTENT_MUSICVIDEOS: videodatabase.GetMusicVideoInfo("", *(fileItem->GetVideoInfoTag()), fileItem->GetVideoInfoTag()->m_iDbId); break; case VIDEODB_CONTENT_EPISODES: videodatabase.GetEpisodeInfo("", *(fileItem->GetVideoInfoTag()), fileItem->GetVideoInfoTag()->m_iDbId); break; case VIDEODB_CONTENT_TVSHOWS: case VIDEODB_CONTENT_MOVIE_SETS: default: break; } videodatabase.Close(); } } } break; } case Picture: { CGUIWindowSlideShow *slideshow = (CGUIWindowSlideShow*)g_windowManager.GetWindow(WINDOW_SLIDESHOW); if (!slideshow) return FailedToExecute; CFileItemList slides; slideshow->GetSlideShowContents(slides); fileItem = slides[slideshow->CurrentSlide() - 1]; break; } case None: default: return FailedToExecute; } HandleFileItem("id", true, "item", fileItem, parameterObject, parameterObject["properties"], result, false); return OK; }
/** * Look for a thumbnail for pItem. If one does not exist, look for an autogenerated * thumbnail. If that does not exist, attempt to autogenerate one. Finally, check * for the existance of fanart and set properties accordinly. * @return: true if pItem has been modified */ bool CVideoThumbLoader::LoadItem(CFileItem* pItem) { if (pItem->m_bIsShareOrDrive || pItem->IsParentFolder()) return false; if (pItem->HasVideoInfoTag() && pItem->GetVideoInfoTag()->m_resumePoint.totalTimeInSeconds == 0) { CVideoDatabase db; db.Open(); if (db.GetResumePoint(*pItem->GetVideoInfoTag())) pItem->SetInvalid(); db.Close(); } CStdString cachedThumb(pItem->GetCachedVideoThumb()); if (!pItem->HasProperty("fanart_image")) { if (pItem->CacheLocalFanart()) pItem->SetProperty("fanart_image",pItem->GetCachedFanart()); } if (!pItem->HasThumbnail()) { pItem->SetUserVideoThumb(); if (CFile::Exists(cachedThumb)) pItem->SetThumbnailImage(cachedThumb); else { CStdString strPath, strFileName; URIUtils::Split(cachedThumb, strPath, strFileName); // create unique thumb for auto generated thumbs cachedThumb = strPath + "auto-" + strFileName; if (CFile::Exists(cachedThumb)) { // this is abit of a hack to avoid loading zero sized images // which we know will fail. They will just display empty image // we should really have some way for the texture loader to // do fallbacks to default images for a failed image instead struct __stat64 st; if(CFile::Stat(cachedThumb, &st) == 0 && st.st_size > 0) { pItem->SetProperty("HasAutoThumb", true); pItem->SetProperty("AutoThumbImage", cachedThumb); pItem->SetThumbnailImage(cachedThumb); } } else if (!pItem->m_bIsFolder && pItem->IsVideo() && g_guiSettings.GetBool("myvideos.extractthumb") && g_guiSettings.GetBool("myvideos.extractflags")) { CFileItem item(*pItem); CStdString path(item.GetPath()); if (URIUtils::IsInRAR(item.GetPath())) SetupRarOptions(item,path); CThumbExtractor* extract = new CThumbExtractor(item, path, true, cachedThumb); AddJob(extract); return true; } } } else if (!pItem->GetThumbnailImage().Left(10).Equals("special://")) LoadRemoteThumb(pItem); if (!pItem->m_bIsFolder && pItem->HasVideoInfoTag() && g_guiSettings.GetBool("myvideos.extractflags") && (!pItem->GetVideoInfoTag()->HasStreamDetails() || pItem->GetVideoInfoTag()->m_streamDetails.GetVideoDuration() <= 0)) { CFileItem item(*pItem); CStdString path(item.GetPath()); if (URIUtils::IsInRAR(item.GetPath())) SetupRarOptions(item,path); CThumbExtractor* extract = new CThumbExtractor(item,path,false); AddJob(extract); } return true; }
void CGUIDialogVideoInfo::SetMovie(const CFileItem *item) { *m_movieItem = *item; // setup cast list + determine type. We need to do this here as it makes // sure that content type (among other things) is set correctly for the // old fixed id labels that we have floating around (they may be using // content type to determine visibility, so we'll set the wrong label) ClearCastList(); VIDEODB_CONTENT_TYPE type = (VIDEODB_CONTENT_TYPE)m_movieItem->GetVideoContentType(); if (type == VIDEODB_CONTENT_MUSICVIDEOS) { // music video const std::vector<std::string> &artists = m_movieItem->GetVideoInfoTag()->m_artist; for (std::vector<std::string>::const_iterator it = artists.begin(); it != artists.end(); ++it) { CFileItemPtr item(new CFileItem(*it)); if (CFile::Exists(item->GetCachedArtistThumb())) item->SetThumbnailImage(item->GetCachedArtistThumb()); item->SetIconImage("DefaultArtist.png"); m_castList->Add(item); } m_castList->SetContent("musicvideos"); } else { // movie/show/episode for (CVideoInfoTag::iCast it = m_movieItem->GetVideoInfoTag()->m_cast.begin(); it != m_movieItem->GetVideoInfoTag()->m_cast.end(); ++it) { CStdString character; if (it->strRole.IsEmpty()) character = it->strName; else character.Format("%s %s %s", it->strName.c_str(), g_localizeStrings.Get(20347).c_str(), it->strRole.c_str()); CFileItemPtr item(new CFileItem(it->strName)); if (!it->thumb.IsEmpty()) item->SetThumbnailImage(it->thumb); else { // backward compatibility CStdString thumb = CScraperUrl::GetThumbURL(it->thumbUrl.GetFirstThumb()); if (!thumb.IsEmpty()) { item->SetThumbnailImage(thumb); CTextureCache::Get().BackgroundCacheImage(thumb); } } item->SetIconImage("DefaultActor.png"); item->SetLabel(character); m_castList->Add(item); } // determine type: if (type == VIDEODB_CONTENT_TVSHOWS) { m_castList->SetContent("tvshows"); // special case stuff for shows (not currently retrieved from the library in filemode (ref: GetTvShowInfo vs GetTVShowsByWhere) m_movieItem->m_dateTime = m_movieItem->GetVideoInfoTag()->m_premiered; if(m_movieItem->GetVideoInfoTag()->m_iYear == 0 && m_movieItem->m_dateTime.IsValid()) m_movieItem->GetVideoInfoTag()->m_iYear = m_movieItem->m_dateTime.GetYear(); m_movieItem->SetProperty("totalepisodes", m_movieItem->GetVideoInfoTag()->m_iEpisode); m_movieItem->SetProperty("numepisodes", m_movieItem->GetVideoInfoTag()->m_iEpisode); // info view has no concept of current watched/unwatched filter as we could come here from files view, but set for consistency m_movieItem->SetProperty("watchedepisodes", m_movieItem->GetVideoInfoTag()->m_playCount); m_movieItem->SetProperty("unwatchedepisodes", m_movieItem->GetVideoInfoTag()->m_iEpisode - m_movieItem->GetVideoInfoTag()->m_playCount); m_movieItem->GetVideoInfoTag()->m_playCount = (m_movieItem->GetVideoInfoTag()->m_iEpisode == m_movieItem->GetVideoInfoTag()->m_playCount) ? 1 : 0; } else if (type == VIDEODB_CONTENT_EPISODES) { m_castList->SetContent("episodes"); // special case stuff for episodes (not currently retrieved from the library in filemode (ref: GetEpisodeInfo vs GetEpisodesByWhere) m_movieItem->m_dateTime = m_movieItem->GetVideoInfoTag()->m_firstAired; if(m_movieItem->GetVideoInfoTag()->m_iYear == 0 && m_movieItem->m_dateTime.IsValid()) m_movieItem->GetVideoInfoTag()->m_iYear = m_movieItem->m_dateTime.GetYear(); // retrieve the season thumb. // TODO: should we use the thumbloader for this? if (m_movieItem->GetVideoInfoTag()->m_iSeason > -1) { CVideoDatabase db; if (db.Open()) { int seasonID = db.GetSeasonId(m_movieItem->GetVideoInfoTag()->m_iIdShow, m_movieItem->GetVideoInfoTag()->m_iSeason); string thumb = db.GetArtForItem(seasonID, "season", "thumb"); if (!thumb.empty()) m_movieItem->SetProperty("seasonthumb", thumb); db.Close(); } } } else if (type == VIDEODB_CONTENT_MOVIES) { m_castList->SetContent("movies"); // local trailers should always override non-local, so check // for a local one if the registered trailer is online if (m_movieItem->GetVideoInfoTag()->m_strTrailer.IsEmpty() || URIUtils::IsInternetStream(m_movieItem->GetVideoInfoTag()->m_strTrailer)) { CStdString localTrailer = m_movieItem->FindTrailer(); if (!localTrailer.IsEmpty()) { m_movieItem->GetVideoInfoTag()->m_strTrailer = localTrailer; CVideoDatabase database; if(database.Open()) { database.SetDetail(m_movieItem->GetVideoInfoTag()->m_strTrailer, m_movieItem->GetVideoInfoTag()->m_iDbId, VIDEODB_ID_TRAILER, VIDEODB_CONTENT_MOVIES); database.Close(); CUtil::DeleteVideoDatabaseDirectoryCache(); } } } } } m_loader.LoadItem(m_movieItem.get()); }
JSONRPC_STATUS CPlayerOperations::GetItem(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant ¶meterObject, CVariant &result) { PlayerType player = GetPlayer(parameterObject["playerid"]); CFileItemPtr fileItem; switch (player) { case Video: case Audio: { fileItem = CFileItemPtr(new CFileItem(g_application.CurrentFileItem())); if (IsPVRChannel()) { CPVRChannelPtr currentChannel; if (g_PVRManager.GetCurrentChannel(currentChannel) && currentChannel.get() != NULL) fileItem = CFileItemPtr(new CFileItem(*currentChannel.get())); } else if (player == Video) { if (!CVideoLibrary::FillFileItem(g_application.CurrentFile(), fileItem, parameterObject)) { const CVideoInfoTag *currentVideoTag = g_infoManager.GetCurrentMovieTag(); if (currentVideoTag != NULL) { CStdString originalLabel = fileItem->GetLabel(); fileItem->SetFromVideoInfoTag(*currentVideoTag); if (fileItem->GetLabel().empty()) fileItem->SetLabel(originalLabel); } fileItem->SetPath(g_application.CurrentFileItem().GetPath()); } } else { if (!CAudioLibrary::FillFileItem(g_application.CurrentFile(), fileItem, parameterObject)) { const MUSIC_INFO::CMusicInfoTag *currentMusicTag = g_infoManager.GetCurrentSongTag(); if (currentMusicTag != NULL) { CStdString originalLabel = fileItem->GetLabel(); fileItem = CFileItemPtr(new CFileItem(*currentMusicTag)); if (fileItem->GetLabel().empty()) fileItem->SetLabel(originalLabel); } fileItem->SetPath(g_application.CurrentFileItem().GetPath()); } } if (IsPVRChannel()) break; if (player == Video) { bool additionalInfo = false; for (CVariant::const_iterator_array itr = parameterObject["properties"].begin_array(); itr != parameterObject["properties"].end_array(); itr++) { CStdString fieldValue = itr->asString(); if (fieldValue == "cast" || fieldValue == "set" || fieldValue == "setid" || fieldValue == "showlink" || fieldValue == "resume" || (fieldValue == "streamdetails" && !fileItem->GetVideoInfoTag()->m_streamDetails.HasItems())) additionalInfo = true; } CVideoDatabase videodatabase; if ((additionalInfo) && videodatabase.Open()) { if (additionalInfo) { switch (fileItem->GetVideoContentType()) { case VIDEODB_CONTENT_MOVIES: videodatabase.GetMovieInfo("", *(fileItem->GetVideoInfoTag()), fileItem->GetVideoInfoTag()->m_iDbId); break; case VIDEODB_CONTENT_MUSICVIDEOS: videodatabase.GetMusicVideoInfo("", *(fileItem->GetVideoInfoTag()), fileItem->GetVideoInfoTag()->m_iDbId); break; case VIDEODB_CONTENT_EPISODES: videodatabase.GetEpisodeInfo("", *(fileItem->GetVideoInfoTag()), fileItem->GetVideoInfoTag()->m_iDbId); break; case VIDEODB_CONTENT_TVSHOWS: case VIDEODB_CONTENT_MOVIE_SETS: default: break; } } videodatabase.Close(); } } else if (player == Audio) { if (fileItem->IsMusicDb()) { CMusicDatabase musicdb; CFileItemList items; items.Add(fileItem); CAudioLibrary::GetAdditionalSongDetails(parameterObject, items, musicdb); } } break; } case Picture: { CGUIWindowSlideShow *slideshow = (CGUIWindowSlideShow*)g_windowManager.GetWindow(WINDOW_SLIDESHOW); if (!slideshow) return FailedToExecute; CFileItemList slides; slideshow->GetSlideShowContents(slides); fileItem = slides[slideshow->CurrentSlide() - 1]; break; } case None: default: return FailedToExecute; } HandleFileItem("id", !IsPVRChannel(), "item", fileItem, parameterObject, parameterObject["properties"], result, false); return OK; }
// Get Thumb from user choice. // Options are: // 1. Current thumb // 2. IMDb thumb // 3. Local thumb // 4. No thumb (if no Local thumb is available) void CGUIDialogVideoInfo::OnGetThumb() { CFileItemList items; // Current thumb if (CFile::Exists(m_movieItem->GetThumbnailImage())) { CFileItemPtr item(new CFileItem("thumb://Current", false)); item->SetThumbnailImage(m_movieItem->GetThumbnailImage()); item->SetLabel(g_localizeStrings.Get(20016)); items.Add(item); } // Grab the thumbnails from the web vector<CStdString> thumbs; m_movieItem->GetVideoInfoTag()->m_strPictureURL.GetThumbURLs(thumbs); for (unsigned int i = 0; i < thumbs.size(); ++i) { CStdString strItemPath; strItemPath.Format("thumb://Remote%i", i); CFileItemPtr item(new CFileItem(strItemPath, false)); item->SetThumbnailImage(thumbs[i]); item->SetIconImage("DefaultPicture.png"); item->SetLabel(g_localizeStrings.Get(20015)); // TODO: Do we need to clear the cached image? // CTextureCache::Get().ClearCachedImage(thumb); items.Add(item); } CStdString localThumb(m_movieItem->GetUserVideoThumb()); if (CFile::Exists(localThumb)) { CFileItemPtr item(new CFileItem("thumb://Local", false)); item->SetThumbnailImage(localThumb); item->SetLabel(g_localizeStrings.Get(20017)); items.Add(item); } else { // no local thumb exists, so we are just using the IMDb thumb or cached thumb // which is probably the IMDb thumb. These could be wrong, so allow the user // to delete the incorrect thumb CFileItemPtr item(new CFileItem("thumb://None", false)); item->SetIconImage("DefaultVideo.png"); item->SetLabel(g_localizeStrings.Get(20018)); items.Add(item); } CStdString result; VECSOURCES sources(g_settings.m_videoSources); g_mediaManager.GetLocalDrives(sources); if (!CGUIDialogFileBrowser::ShowAndGetImage(items, sources, g_localizeStrings.Get(20019), result)) return; // user cancelled if (result == "thumb://Current") return; // user chose the one they have CStdString newThumb; // delete the thumbnail if that's what the user wants, else overwrite with the // new thumbnail CFileItem item(*m_movieItem->GetVideoInfoTag()); if (result.Left(14) == "thumb://Remote") { int number = atoi(result.Mid(14)); newThumb = thumbs[number]; } else if (result == "thumb://Local") newThumb = localThumb; else if (CFile::Exists(result)) newThumb = result; else // none newThumb = "-"; // force local thumbs to be ignored // update thumb in the database CVideoDatabase db; if (db.Open()) { db.SetArtForItem(m_movieItem->GetVideoInfoTag()->m_iDbId, m_movieItem->GetVideoInfoTag()->m_type, "thumb", newThumb); db.Close(); } CUtil::DeleteVideoDatabaseDirectoryCache(); // to get them new thumbs to show m_movieItem->SetThumbnailImage(newThumb); if (m_movieItem->HasProperty("set_folder_thumb")) { // have a folder thumb to set as well VIDEO::CVideoInfoScanner::ApplyThumbToFolder(m_movieItem->GetProperty("set_folder_thumb").asString(), newThumb); } m_hasUpdatedThumb = true; // Update our screen Update(); }
bool CGUIDialogVideoBookmarks::OnMessage(CGUIMessage& message) { switch ( message.GetMessage() ) { case GUI_MSG_WINDOW_DEINIT: { CUtil::DeleteVideoDatabaseDirectoryCache(); Clear(); } break; case GUI_MSG_WINDOW_INIT: { CGUIWindow::OnMessage(message); Update(); return true; } break; case GUI_MSG_CLICKED: { int iControl = message.GetSenderId(); if (iControl == CONTROL_ADD_BOOKMARK) { AddBookmark(); } else if (iControl == CONTROL_CLEAR_BOOKMARKS) { ClearBookmarks(); } else if (iControl == CONTROL_ADD_EPISODE_BOOKMARK) { AddEpisodeBookmark(); } else if (m_viewControl.HasControl(iControl)) // list/thumb control { int iItem = m_viewControl.GetSelectedItem(); int iAction = message.GetParam1(); if (iAction == ACTION_DELETE_ITEM) { if( (unsigned)iItem < m_bookmarks.size() ) { CVideoDatabase videoDatabase; videoDatabase.Open(); videoDatabase.ClearBookMarkOfFile(g_application.CurrentFile(),m_bookmarks[iItem],m_bookmarks[iItem].type); videoDatabase.Close(); CUtil::DeleteVideoDatabaseDirectoryCache(); } Update(); } else if (iAction == ACTION_SELECT_ITEM || iAction == ACTION_MOUSE_LEFT_CLICK) { GotoBookmark(iItem); } } } break; case GUI_MSG_SETFOCUS: { if (m_viewControl.HasControl(message.GetControlId()) && m_viewControl.GetCurrentControl() != message.GetControlId()) { m_viewControl.SetFocused(); return true; } } break; } return CGUIDialog::OnMessage(message); }
// Allow user to select a Fanart void CGUIDialogVideoInfo::OnGetFanart() { CFileItemList items; CFileItem item(*m_movieItem->GetVideoInfoTag()); if (item.HasProperty("fanart_image")) { CFileItemPtr itemCurrent(new CFileItem("fanart://Current",false)); itemCurrent->SetThumbnailImage(item.GetProperty("fanart_image").asString()); itemCurrent->SetLabel(g_localizeStrings.Get(20440)); items.Add(itemCurrent); } // ensure the fanart is unpacked m_movieItem->GetVideoInfoTag()->m_fanart.Unpack(); // Grab the thumbnails from the web for (unsigned int i = 0; i < m_movieItem->GetVideoInfoTag()->m_fanart.GetNumFanarts(); i++) { CStdString strItemPath; strItemPath.Format("fanart://Remote%i",i); CFileItemPtr item(new CFileItem(strItemPath, false)); CStdString thumb = m_movieItem->GetVideoInfoTag()->m_fanart.GetPreviewURL(i); item->SetThumbnailImage(CTextureCache::GetWrappedThumbURL(thumb)); item->SetIconImage("DefaultPicture.png"); item->SetLabel(g_localizeStrings.Get(20441)); // TODO: Do we need to clear the cached image? // CTextureCache::Get().ClearCachedImage(thumb); items.Add(item); } CStdString strLocal = item.GetLocalFanart(); if (!strLocal.IsEmpty()) { CFileItemPtr itemLocal(new CFileItem("fanart://Local",false)); itemLocal->SetThumbnailImage(strLocal); itemLocal->SetLabel(g_localizeStrings.Get(20438)); // TODO: Do we need to clear the cached image? CTextureCache::Get().ClearCachedImage(strLocal); items.Add(itemLocal); } else { CFileItemPtr itemNone(new CFileItem("fanart://None", false)); itemNone->SetIconImage("DefaultVideo.png"); itemNone->SetLabel(g_localizeStrings.Get(20439)); items.Add(itemNone); } CStdString result; VECSOURCES sources(g_settings.m_videoSources); g_mediaManager.GetLocalDrives(sources); bool flip=false; if (!CGUIDialogFileBrowser::ShowAndGetImage(items, sources, g_localizeStrings.Get(20437), result, &flip, 20445) || result.Equals("fanart://Current")) return; // user cancelled if (result.Equals("fanart://Local")) result = strLocal; if (result.Left(15) == "fanart://Remote") { int iFanart = atoi(result.Mid(15).c_str()); // set new primary fanart, and update our database accordingly m_movieItem->GetVideoInfoTag()->m_fanart.SetPrimaryFanart(iFanart); CVideoDatabase db; if (db.Open()) { db.UpdateFanart(*m_movieItem, (VIDEODB_CONTENT_TYPE)m_movieItem->GetVideoContentType()); db.Close(); } result = m_movieItem->GetVideoInfoTag()->m_fanart.GetImageURL(); } else if (result.Equals("fanart://None") || !CFile::Exists(result)) result.clear(); // set the fanart image if (flip && !result.IsEmpty()) result = CTextureCache::GetWrappedImageURL(result, "", "flipped"); CVideoDatabase db; if (db.Open()) { db.SetArtForItem(m_movieItem->GetVideoInfoTag()->m_iDbId, m_movieItem->GetVideoInfoTag()->m_type, "fanart", result); db.Close(); } CUtil::DeleteVideoDatabaseDirectoryCache(); // to get them new thumbs to show if (!result.IsEmpty()) m_movieItem->SetProperty("fanart_image", result); else m_movieItem->ClearProperty("fanart_image"); m_hasUpdatedThumb = true; // Update our screen Update(); }
bool CRecentlyAddedJob::UpdateVideo() { CGUIWindow* home = g_windowManager.GetWindow(WINDOW_HOME); if ( home == NULL ) return false; CLog::Log(LOGDEBUG, "CRecentlyAddedJob::UpdateVideos() - Running RecentlyAdded home screen update"); int i = 0; CFileItemList items; CVideoDatabase videodatabase; videodatabase.Open(); if (videodatabase.GetRecentlyAddedMoviesNav("videodb://4/", items, NUM_ITEMS)) { for (; i < items.Size(); ++i) { CFileItemPtr item = items.Get(i); CStdString value; CStdString strRating; value.Format("%i", i + 1); strRating.Format("%.1f", item->GetVideoInfoTag()->m_fRating); home->SetProperty("LatestMovie." + value + ".Title" , item->GetLabel()); home->SetProperty("LatestMovie." + value + ".Rating" , strRating); home->SetProperty("LatestMovie." + value + ".Year" , item->GetVideoInfoTag()->m_iYear); home->SetProperty("LatestMovie." + value + ".Plot" , item->GetVideoInfoTag()->m_strPlot); home->SetProperty("LatestMovie." + value + ".RunningTime" , item->GetVideoInfoTag()->m_strRuntime); home->SetProperty("LatestMovie." + value + ".Path" , item->GetVideoInfoTag()->m_strFileNameAndPath); home->SetProperty("LatestMovie." + value + ".Trailer" , item->GetVideoInfoTag()->m_strTrailer); if (!item->HasThumbnail()) m_thumbLoader.LoadItem(item.get()); home->SetProperty("LatestMovie." + value + ".Thumb" , item->GetThumbnailImage()); home->SetProperty("LatestMovie." + value + ".Fanart" , item->GetProperty("fanart_image")); } } for (; i < NUM_ITEMS; ++i) { CStdString value; value.Format("%i", i + 1); home->SetProperty("LatestMovie." + value + ".Title" , ""); home->SetProperty("LatestMovie." + value + ".Thumb" , ""); home->SetProperty("LatestMovie." + value + ".Rating" , ""); home->SetProperty("LatestMovie." + value + ".Year" , ""); home->SetProperty("LatestMovie." + value + ".Plot" , ""); home->SetProperty("LatestMovie." + value + ".RunningTime" , ""); home->SetProperty("LatestMovie." + value + ".Path" , ""); home->SetProperty("LatestMovie." + value + ".Trailer" , ""); home->SetProperty("LatestMovie." + value + ".Fanart" , ""); } i = 0; CFileItemList TVShowItems; if (videodatabase.GetRecentlyAddedEpisodesNav("videodb://5/", TVShowItems, NUM_ITEMS)) { for (; i < TVShowItems.Size(); ++i) { CFileItemPtr item = TVShowItems.Get(i); int EpisodeSeason = item->GetVideoInfoTag()->m_iSeason; int EpisodeNumber = item->GetVideoInfoTag()->m_iEpisode; CStdString EpisodeNo; CStdString value; CStdString strRating; EpisodeNo.Format("s%02de%02d", EpisodeSeason, EpisodeNumber); value.Format("%i", i + 1); strRating.Format("%.1f", item->GetVideoInfoTag()->m_fRating); CFileItem show(item->GetVideoInfoTag()->m_strShowPath, true); home->SetProperty("LatestEpisode." + value + ".ShowTitle" , item->GetVideoInfoTag()->m_strShowTitle); home->SetProperty("LatestEpisode." + value + ".EpisodeTitle" , item->GetVideoInfoTag()->m_strTitle); home->SetProperty("LatestEpisode." + value + ".Rating" , strRating); home->SetProperty("LatestEpisode." + value + ".Plot" , item->GetVideoInfoTag()->m_strPlot); home->SetProperty("LatestEpisode." + value + ".EpisodeNo" , EpisodeNo); home->SetProperty("LatestEpisode." + value + ".EpisodeSeason" , EpisodeSeason); home->SetProperty("LatestEpisode." + value + ".EpisodeNumber" , EpisodeNumber); home->SetProperty("LatestEpisode." + value + ".Path" , item->GetVideoInfoTag()->m_strFileNameAndPath); if (!item->HasThumbnail()) m_thumbLoader.LoadItem(item.get()); std::string seasonThumb; if (item->GetVideoInfoTag()->m_iIdSeason > 0) seasonThumb = videodatabase.GetArtForItem(item->GetVideoInfoTag()->m_iIdSeason, "season", "thumb"); home->SetProperty("LatestEpisode." + value + ".Thumb" , item->GetThumbnailImage()); home->SetProperty("LatestEpisode." + value + ".ShowThumb" , item->GetProperty("tvshowthumb")); home->SetProperty("LatestEpisode." + value + ".SeasonThumb" , seasonThumb); home->SetProperty("LatestEpisode." + value + ".Fanart" , item->GetProperty("fanart_image")); } } for (; i < NUM_ITEMS; ++i) { CStdString value; value.Format("%i", i + 1); home->SetProperty("LatestEpisode." + value + ".ShowTitle" , ""); home->SetProperty("LatestEpisode." + value + ".EpisodeTitle" , ""); home->SetProperty("LatestEpisode." + value + ".Rating" , ""); home->SetProperty("LatestEpisode." + value + ".Plot" , ""); home->SetProperty("LatestEpisode." + value + ".EpisodeNo" , ""); home->SetProperty("LatestEpisode." + value + ".EpisodeSeason" , ""); home->SetProperty("LatestEpisode." + value + ".EpisodeNumber" , ""); home->SetProperty("LatestEpisode." + value + ".Path" , ""); home->SetProperty("LatestEpisode." + value + ".Thumb" , ""); home->SetProperty("LatestEpisode." + value + ".ShowThumb" , ""); home->SetProperty("LatestEpisode." + value + ".SeasonThumb" , ""); home->SetProperty("LatestEpisode." + value + ".Fanart" , ""); } i = 0; CFileItemList MusicVideoItems; if (videodatabase.GetRecentlyAddedMusicVideosNav("videodb://6/", MusicVideoItems, NUM_ITEMS)) { for (; i < MusicVideoItems.Size(); ++i) { CFileItemPtr item = MusicVideoItems.Get(i); CStdString value; value.Format("%i", i + 1); home->SetProperty("LatestMusicVideo." + value + ".Title" , item->GetLabel()); home->SetProperty("LatestMusicVideo." + value + ".Year" , item->GetVideoInfoTag()->m_iYear); home->SetProperty("LatestMusicVideo." + value + ".Plot" , item->GetVideoInfoTag()->m_strPlot); home->SetProperty("LatestMusicVideo." + value + ".RunningTime" , item->GetVideoInfoTag()->m_strRuntime); home->SetProperty("LatestMusicVideo." + value + ".Path" , item->GetVideoInfoTag()->m_strFileNameAndPath); home->SetProperty("LatestMusicVideo." + value + ".Artist" , StringUtils::Join(item->GetVideoInfoTag()->m_artist, g_advancedSettings.m_videoItemSeparator)); if (!item->HasThumbnail()) m_thumbLoader.LoadItem(item.get()); home->SetProperty("LatestMusicVideo." + value + ".Thumb" , item->GetThumbnailImage()); home->SetProperty("LatestMusicVideo." + value + ".Fanart" , item->GetProperty("fanart_image")); } } for (; i < NUM_ITEMS; ++i) { CStdString value; value.Format("%i", i + 1); home->SetProperty("LatestMusicVideo." + value + ".Title" , ""); home->SetProperty("LatestMusicVideo." + value + ".Thumb" , ""); home->SetProperty("LatestMusicVideo." + value + ".Year" , ""); home->SetProperty("LatestMusicVideo." + value + ".Plot" , ""); home->SetProperty("LatestMusicVideo." + value + ".RunningTime" , ""); home->SetProperty("LatestMusicVideo." + value + ".Path" , ""); home->SetProperty("LatestMusicVideo." + value + ".Artist" , ""); home->SetProperty("LatestMusicVideo." + value + ".Fanart" , ""); } videodatabase.Close(); return true; }
void CGUIWindowMusicNav::GetContextButtons(int itemNumber, CContextButtons &buttons) { CGUIWindowMusicBase::GetContextButtons(itemNumber, buttons); CFileItemPtr item; if (itemNumber >= 0 && itemNumber < m_vecItems->Size()) item = m_vecItems->Get(itemNumber); if (item && !item->GetPath().Left(14).Equals("addons://more/")) { // are we in the playlists location? bool inPlaylists = m_vecItems->GetPath().Equals(CUtil::MusicPlaylistsLocation()) || m_vecItems->GetPath().Equals("special://musicplaylists/"); CMusicDatabaseDirectory dir; // enable music info button on an album or on a song. if (item->IsAudio() && !item->IsPlayList() && !item->IsSmartPlayList() && !item->m_bIsFolder) { buttons.Add(CONTEXT_BUTTON_SONG_INFO, 658); } else if (item->IsVideoDb()) { if (!item->m_bIsFolder) // music video buttons.Add(CONTEXT_BUTTON_INFO, 20393); if (item->GetPath().Left(14).Equals("videodb://3/4/") && item->GetPath().size() > 14 && item->m_bIsFolder) { long idArtist = m_musicdatabase.GetArtistByName(m_vecItems->Get(itemNumber)->GetLabel()); if (idArtist > - 1) buttons.Add(CONTEXT_BUTTON_INFO,21891); } } else if (!inPlaylists && (dir.HasAlbumInfo(item->GetPath())|| dir.IsArtistDir(item->GetPath()) ) && !dir.IsAllItem(item->GetPath()) && !item->IsParentFolder() && !item->IsPlugin() && !item->IsScript() && !item->GetPath().Left(14).Equals("musicsearch://")) { if (dir.IsArtistDir(item->GetPath())) buttons.Add(CONTEXT_BUTTON_INFO, 21891); else buttons.Add(CONTEXT_BUTTON_INFO, 13351); } // enable query all albums button only in album view if (dir.HasAlbumInfo(item->GetPath()) && !dir.IsAllItem(item->GetPath()) && item->m_bIsFolder && !item->IsVideoDb() && !item->IsParentFolder() && !item->IsPlugin() && !item->GetPath().Left(14).Equals("musicsearch://")) { buttons.Add(CONTEXT_BUTTON_INFO_ALL, 20059); } // enable query all artist button only in album view if (dir.IsArtistDir(item->GetPath()) && !dir.IsAllItem(item->GetPath()) && item->m_bIsFolder && !item->IsVideoDb()) { ADDON::ScraperPtr info; m_musicdatabase.GetScraperForPath(item->GetPath(), info, ADDON::ADDON_SCRAPER_ARTISTS); if (info && info->Supports(CONTENT_ARTISTS)) buttons.Add(CONTEXT_BUTTON_INFO_ALL, 21884); } //Set default or clear default NODE_TYPE nodetype = dir.GetDirectoryType(item->GetPath()); if (!item->IsParentFolder() && !inPlaylists && (nodetype == NODE_TYPE_ROOT || nodetype == NODE_TYPE_OVERVIEW || nodetype == NODE_TYPE_TOP100)) { if (!item->GetPath().Equals(g_settings.m_defaultMusicLibSource)) buttons.Add(CONTEXT_BUTTON_SET_DEFAULT, 13335); // set default if (strcmp(g_settings.m_defaultMusicLibSource, "")) buttons.Add(CONTEXT_BUTTON_CLEAR_DEFAULT, 13403); // clear default } NODE_TYPE childtype = dir.GetDirectoryChildType(item->GetPath()); if (childtype == NODE_TYPE_ALBUM || childtype == NODE_TYPE_ARTIST || nodetype == NODE_TYPE_GENRE || nodetype == NODE_TYPE_ALBUM || nodetype == NODE_TYPE_ALBUM_RECENTLY_ADDED || nodetype == NODE_TYPE_ALBUM_COMPILATIONS) { // we allow the user to set content for // 1. general artist and album nodes // 2. specific per genre // 3. specific per artist // 4. specific per album buttons.Add(CONTEXT_BUTTON_SET_CONTENT,20195); } if (item->HasMusicInfoTag() && item->GetMusicInfoTag()->GetArtist().size() > 0) { CVideoDatabase database; database.Open(); if (database.GetMatchingMusicVideo(StringUtils::Join(item->GetMusicInfoTag()->GetArtist(), g_advancedSettings.m_musicItemSeparator)) > -1) buttons.Add(CONTEXT_BUTTON_GO_TO_ARTIST, 20400); } if (item->HasMusicInfoTag() && item->GetMusicInfoTag()->GetArtist().size() > 0 && item->GetMusicInfoTag()->GetAlbum().size() > 0 && item->GetMusicInfoTag()->GetTitle().size() > 0) { CVideoDatabase database; database.Open(); if (database.GetMatchingMusicVideo(StringUtils::Join(item->GetMusicInfoTag()->GetArtist(), g_advancedSettings.m_musicItemSeparator),item->GetMusicInfoTag()->GetAlbum(),item->GetMusicInfoTag()->GetTitle()) > -1) buttons.Add(CONTEXT_BUTTON_PLAY_OTHER, 20401); } if (item->HasVideoInfoTag() && !item->m_bIsFolder) { if (item->GetVideoInfoTag()->m_playCount > 0) buttons.Add(CONTEXT_BUTTON_MARK_UNWATCHED, 16104); //Mark as UnWatched else buttons.Add(CONTEXT_BUTTON_MARK_WATCHED, 16103); //Mark as Watched if ((CProfilesManager::Get().GetCurrentProfile().canWriteDatabases() || g_passwordManager.bMasterUser) && !item->IsPlugin()) { buttons.Add(CONTEXT_BUTTON_RENAME, 16105); buttons.Add(CONTEXT_BUTTON_DELETE, 646); } } if (inPlaylists && !URIUtils::GetFileName(item->GetPath()).Equals("PartyMode.xsp") && (item->IsPlayList() || item->IsSmartPlayList())) buttons.Add(CONTEXT_BUTTON_DELETE, 117); if (item->IsPlugin() || item->IsScript() || m_vecItems->IsPlugin()) buttons.Add(CONTEXT_BUTTON_PLUGIN_SETTINGS, 1045); } // noncontextual buttons if (g_application.IsMusicScanning()) buttons.Add(CONTEXT_BUTTON_STOP_SCANNING, 13353); // Stop Scanning else { if (!m_vecItems->IsPlugin()) buttons.Add(CONTEXT_BUTTON_UPDATE_LIBRARY, 653); } CGUIWindowMusicBase::GetNonContextButtons(buttons); }