std::string CSmartPlaylistDirectory::GetPlaylistByName(const std::string& name, const std::string& playlistType) { CFileItemList list; bool filesExist = false; if (CSmartPlaylist::IsMusicType(playlistType)) filesExist = CDirectory::GetDirectory("special://musicplaylists/", list, ".xsp", false); else // all others are video filesExist = CDirectory::GetDirectory("special://videoplaylists/", list, ".xsp", false); if (filesExist) { for (int i = 0; i < list.Size(); i++) { CFileItemPtr item = list[i]; CSmartPlaylist playlist; if (playlist.OpenAndReadName(item->GetURL())) { if (StringUtils::EqualsNoCase(playlist.GetName(), name)) return item->GetPath(); } } for (int i = 0; i < list.Size(); i++) { // check based on filename CFileItemPtr item = list[i]; if (URIUtils::GetFileName(item->GetPath()) == name) { // found :) return item->GetPath(); } } } return ""; }
bool CGUIWindowPictures::OnClick(int iItem) { if ( iItem < 0 || iItem >= (int)m_vecItems->Size() ) return true; CFileItemPtr pItem = m_vecItems->Get(iItem); if (pItem->IsCBZ() || pItem->IsCBR()) { CURL pathToUrl; if (pItem->IsCBZ()) pathToUrl = URIUtils::CreateArchivePath("zip", pItem->GetURL(), ""); else pathToUrl = URIUtils::CreateArchivePath("rar", pItem->GetURL(), ""); OnShowPictureRecursive(pathToUrl.Get()); return true; } else if (CGUIMediaWindow::OnClick(iItem)) return true; return false; }
bool CDirectory::GetDirectory(const CURL& url, CFileItemList &items, const CHints &hints, bool allowThreads) { try { CURL realURL = URIUtils::SubstitutePath(url); std::shared_ptr<IDirectory> pDirectory(CDirectoryFactory::Create(realURL)); if (!pDirectory.get()) return false; // check our cache for this path if (g_directoryCache.GetDirectory(realURL.Get(), items, (hints.flags & DIR_FLAG_READ_CACHE) == DIR_FLAG_READ_CACHE)) items.SetURL(url); else { // need to clear the cache (in case the directory fetch fails) // and (re)fetch the folder if (!(hints.flags & DIR_FLAG_BYPASS_CACHE)) g_directoryCache.ClearDirectory(realURL.Get()); pDirectory->SetFlags(hints.flags); bool result = false, cancel = false; while (!result && !cancel) { const std::string pathToUrl(url.Get()); if (g_application.IsCurrentThread() && allowThreads && !URIUtils::IsSpecial(pathToUrl)) { CSingleExit ex(g_graphicsContext); CGetDirectory get(pDirectory, realURL, url); if(!get.Wait(TIME_TO_BUSY_DIALOG)) { CGUIDialogBusy* dialog = (CGUIDialogBusy*)g_windowManager.GetWindow(WINDOW_DIALOG_BUSY); if (dialog) { dialog->Open(); while(!get.Wait(10)) { CSingleLock lock(g_graphicsContext); // update progress float progress = pDirectory->GetProgress(); if (progress > 0) dialog->SetProgress(progress); if (dialog->IsCanceled()) { cancel = true; pDirectory->CancelDirectory(); break; } lock.Leave(); // prevent an occasional deadlock on exit g_windowManager.ProcessRenderLoop(false); } dialog->Close(); } } result = get.GetDirectory(items); } else { items.SetURL(url); result = pDirectory->GetDirectory(realURL, items); } if (!result) { if (!cancel && g_application.IsCurrentThread() && pDirectory->ProcessRequirements()) continue; CLog::Log(LOGERROR, "%s - Error getting %s", __FUNCTION__, url.GetRedacted().c_str()); return false; } } // cache the directory, if necessary if (!(hints.flags & DIR_FLAG_BYPASS_CACHE)) g_directoryCache.SetDirectory(realURL.Get(), items, pDirectory->GetCacheType(url)); } // now filter for allowed files if (!pDirectory->AllowAll()) { pDirectory->SetMask(hints.mask); for (int i = 0; i < items.Size(); ++i) { CFileItemPtr item = items[i]; if (!item->m_bIsFolder && !pDirectory->IsAllowed(item->GetURL())) { items.Remove(i); i--; // don't confuse loop } } } // filter hidden files // TODO: we shouldn't be checking the gui setting here, callers should use getHidden instead if (!CSettings::Get().GetBool("filelists.showhidden") && !(hints.flags & DIR_FLAG_GET_HIDDEN)) { for (int i = 0; i < items.Size(); ++i) { if (items[i]->GetProperty("file:hidden").asBoolean()) { items.Remove(i); i--; // don't confuse loop } } } // Should any of the files we read be treated as a directory? // Disable for database folders, as they already contain the extracted items if (!(hints.flags & DIR_FLAG_NO_FILE_DIRS) && !items.IsMusicDb() && !items.IsVideoDb() && !items.IsSmartPlayList()) FilterFileDirectories(items, hints.mask); // Correct items for path substitution const std::string pathToUrl(url.Get()); const std::string pathToUrl2(realURL.Get()); if (pathToUrl != pathToUrl2) { for (int i = 0; i < items.Size(); ++i) { CFileItemPtr item = items[i]; item->SetPath(URIUtils::SubstitutePath(item->GetPath(), true)); } } return true; } XBMCCOMMONS_HANDLE_UNCHECKED catch (...) { CLog::Log(LOGERROR, "%s - Unhandled exception", __FUNCTION__); } CLog::Log(LOGERROR, "%s - Error getting %s", __FUNCTION__, url.GetRedacted().c_str()); return false; }
/** * This method tries to determine what type of disc is located in the given drive and starts to play the content appropriately. */ bool CAutorun::RunDisc(IDirectory* pDir, const std::string& strDrive, int& nAddedToPlaylist, bool bRoot, bool bypassSettings /* = false */, bool startFromBeginning /* = false */) { bool bPlaying(false); CFileItemList vecItems; const CURL pathToUrl(strDrive); if ( !pDir->GetDirectory( pathToUrl, vecItems ) ) { return false; } // Sorting necessary for easier HDDVD handling vecItems.Sort(SortByLabel, SortOrderAscending); bool bAllowVideo = true; // bool bAllowPictures = true; bool bAllowMusic = true; if (!g_passwordManager.IsMasterLockUnlocked(false)) { bAllowVideo = !CProfilesManager::GetInstance().GetCurrentProfile().videoLocked(); // bAllowPictures = !CProfilesManager::GetInstance().GetCurrentProfile().picturesLocked(); bAllowMusic = !CProfilesManager::GetInstance().GetCurrentProfile().musicLocked(); } // is this a root folder we have to check the content to determine a disc type if( bRoot ) { std::string hddvdname = ""; CFileItemPtr phddvdItem; // check root folders next, for normal structured dvd's for (int i = 0; i < vecItems.Size(); i++) { CFileItemPtr pItem = vecItems[i]; // is the current item a (non system) folder? if (pItem->m_bIsFolder && pItem->GetPath() != "." && pItem->GetPath() != "..") { std::string name = pItem->GetPath(); URIUtils::RemoveSlashAtEnd(name); name = URIUtils::GetFileName(name); // Check if the current foldername indicates a DVD structure (name is "VIDEO_TS") if (StringUtils::EqualsNoCase(name, "VIDEO_TS") && bAllowVideo && (bypassSettings || CServiceBroker::GetSettings().GetBool(CSettings::SETTING_DVDS_AUTORUN))) { std::string path = URIUtils::AddFileToFolder(pItem->GetPath(), "VIDEO_TS.IFO"); if(!CFile::Exists(path)) path = URIUtils::AddFileToFolder(pItem->GetPath(), "video_ts.ifo"); CFileItemPtr item(new CFileItem(path, false)); item->SetLabel(g_mediaManager.GetDiskLabel(strDrive)); item->GetVideoInfoTag()->m_strFileNameAndPath = g_mediaManager.GetDiskUniqueId(strDrive); if (!startFromBeginning && !item->GetVideoInfoTag()->m_strFileNameAndPath.empty()) item->m_lStartOffset = STARTOFFSET_RESUME; CServiceBroker::GetPlaylistPlayer().ClearPlaylist(PLAYLIST_VIDEO); CServiceBroker::GetPlaylistPlayer().SetShuffle (PLAYLIST_VIDEO, false); CServiceBroker::GetPlaylistPlayer().Add(PLAYLIST_VIDEO, item); CServiceBroker::GetPlaylistPlayer().SetCurrentPlaylist(PLAYLIST_VIDEO); CServiceBroker::GetPlaylistPlayer().Play(0, ""); return true; } // Check if the current foldername indicates a Blu-Ray structure (default is "BDMV"). // A BR should also include an "AACS" folder for encryption, Sony-BRs can also include update folders for PS3 (PS3_UPDATE / PS3_VPRM). //! @todo for the time being, the DVD autorun settings are used to determine if the BR should be started automatically. if (StringUtils::EqualsNoCase(name, "BDMV") && bAllowVideo && (bypassSettings || CServiceBroker::GetSettings().GetBool(CSettings::SETTING_DVDS_AUTORUN))) { CFileItemPtr item(new CFileItem(URIUtils::AddFileToFolder(pItem->GetPath(), "index.bdmv"), false)); item->SetLabel(g_mediaManager.GetDiskLabel(strDrive)); item->GetVideoInfoTag()->m_strFileNameAndPath = g_mediaManager.GetDiskUniqueId(strDrive); if (!startFromBeginning && !item->GetVideoInfoTag()->m_strFileNameAndPath.empty()) item->m_lStartOffset = STARTOFFSET_RESUME; CServiceBroker::GetPlaylistPlayer().ClearPlaylist(PLAYLIST_VIDEO); CServiceBroker::GetPlaylistPlayer().SetShuffle (PLAYLIST_VIDEO, false); CServiceBroker::GetPlaylistPlayer().Add(PLAYLIST_VIDEO, item); CServiceBroker::GetPlaylistPlayer().SetCurrentPlaylist(PLAYLIST_VIDEO); CServiceBroker::GetPlaylistPlayer().Play(0, ""); return true; } // Check if the current foldername indicates a HD DVD structure (default is "HVDVD_TS"). // Most HD DVD will also include an "ADV_OBJ" folder for advanced content. This folder should be handled first. //! @todo for the time being, the DVD autorun settings are used to determine if the HD DVD should be started automatically. CFileItemList items, sitems; // Advanced Content HD DVD (most discs?) if (StringUtils::EqualsNoCase(name, "ADV_OBJ")) { CLog::Log(LOGINFO,"HD DVD: Checking for playlist."); // find playlist file CDirectory::GetDirectory(pItem->GetPath(), items, "*.xpl"); if (items.Size()) { // HD DVD Standard says the highest numbered playlist has to be handled first. CLog::Log(LOGINFO,"HD DVD: Playlist found. Set filetypes to *.xpl for external player."); items.Sort(SortByLabel, SortOrderDescending); phddvdItem = pItem; hddvdname = URIUtils::GetFileName(items[0]->GetPath()); CLog::Log(LOGINFO,"HD DVD: %s", items[0]->GetPath().c_str()); } } // Standard Content HD DVD (few discs?) if (StringUtils::EqualsNoCase(name, "HVDVD_TS") && bAllowVideo && (bypassSettings || CServiceBroker::GetSettings().GetBool(CSettings::SETTING_DVDS_AUTORUN))) { if (hddvdname == "") { CLog::Log(LOGINFO,"HD DVD: Checking for ifo."); // find Video Manager or Title Set Information CDirectory::GetDirectory(pItem->GetPath(), items, "HV*.ifo"); if (items.Size()) { // HD DVD Standard says the lowest numbered ifo has to be handled first. CLog::Log(LOGINFO,"HD DVD: IFO found. Set filename to HV* and filetypes to *.ifo for external player."); items.Sort(SortByLabel, SortOrderAscending); phddvdItem = pItem; hddvdname = URIUtils::GetFileName(items[0]->GetPath()); CLog::Log(LOGINFO,"HD DVD: %s",items[0]->GetPath().c_str()); } } // Find and sort *.evo files for internal playback. // While this algorithm works for all of my HD DVDs, it may fail on other discs. If there are very large extras which are // alphabetically before the main movie they will be sorted to the top of the playlist and get played first. CDirectory::GetDirectory(pItem->GetPath(), items, "*.evo"); if (items.Size()) { // Sort *.evo files in alphabetical order. items.Sort(SortByLabel, SortOrderAscending); int64_t asize = 0; int ecount = 0; // calculate average size of elements above 1gb for (int j = 0; j < items.Size(); j++) if (items[j]->m_dwSize > 1000000000) { ecount++; asize = asize + items[j]->m_dwSize; } if (ecount > 0) asize = asize / ecount; // Put largest files in alphabetical order to top of new list. for (int j = 0; j < items.Size(); j++) if (items[j]->m_dwSize >= asize) sitems.Add (items[j]); // Sort *.evo files by size. items.Sort(SortBySize, SortOrderDescending); // Add other files with descending size to bottom of new list. for (int j = 0; j < items.Size(); j++) if (items[j]->m_dwSize < asize) sitems.Add (items[j]); // Replace list with optimized list. items.Clear(); items.Copy (sitems); sitems.Clear(); } if (hddvdname != "") { CFileItem item(URIUtils::AddFileToFolder(phddvdItem->GetPath(), hddvdname), false); item.SetLabel(g_mediaManager.GetDiskLabel(strDrive)); item.GetVideoInfoTag()->m_strFileNameAndPath = g_mediaManager.GetDiskUniqueId(strDrive); if (!startFromBeginning && !item.GetVideoInfoTag()->m_strFileNameAndPath.empty()) item.m_lStartOffset = STARTOFFSET_RESUME; // get playername std::string hdVideoPlayer = CPlayerCoreFactory::GetInstance().GetDefaultPlayer(item); // Single *.xpl or *.ifo files require an external player to handle playback. // If no matching rule was found, VideoPlayer will be default player. if (hdVideoPlayer != "VideoPlayer") { CLog::Log(LOGINFO,"HD DVD: External singlefile playback initiated: %s",hddvdname.c_str()); g_application.PlayFile(item, hdVideoPlayer, false); return true; } else CLog::Log(LOGINFO,"HD DVD: No external player found. Fallback to internal one."); } // internal *.evo playback. CLog::Log(LOGINFO,"HD DVD: Internal multifile playback initiated."); CServiceBroker::GetPlaylistPlayer().ClearPlaylist(PLAYLIST_VIDEO); CServiceBroker::GetPlaylistPlayer().SetShuffle (PLAYLIST_VIDEO, false); CServiceBroker::GetPlaylistPlayer().Add(PLAYLIST_VIDEO, items); CServiceBroker::GetPlaylistPlayer().SetCurrentPlaylist(PLAYLIST_VIDEO); CServiceBroker::GetPlaylistPlayer().Play(0, ""); return true; } // Video CDs can have multiple file formats. First we need to determine which one is used on the CD std::string strExt; if (StringUtils::EqualsNoCase(name, "MPEGAV")) strExt = ".dat"; if (StringUtils::EqualsNoCase(name, "MPEG2")) strExt = ".mpg"; // If a file format was extracted we are sure this is a VCD. Autoplay if settings indicate we should. if (!strExt.empty() && bAllowVideo && (bypassSettings || CServiceBroker::GetSettings().GetBool(CSettings::SETTING_DVDS_AUTORUN))) { CFileItemList items; CDirectory::GetDirectory(pItem->GetPath(), items, strExt); if (items.Size()) { items.Sort(SortByLabel, SortOrderAscending); CServiceBroker::GetPlaylistPlayer().ClearPlaylist(PLAYLIST_VIDEO); CServiceBroker::GetPlaylistPlayer().Add(PLAYLIST_VIDEO, items); CServiceBroker::GetPlaylistPlayer().SetCurrentPlaylist(PLAYLIST_VIDEO); CServiceBroker::GetPlaylistPlayer().Play(0, ""); return true; } } /* Probably want this if/when we add some automedia action dialog... else if (pItem->GetPath().Find("PICTURES") != -1 && bAllowPictures && (bypassSettings)) { bPlaying = true; std::string strExec = StringUtils::Format("RecursiveSlideShow(%s)", pItem->GetPath().c_str()); CBuiltins::Execute(strExec); return true; } */ } } } // check video first if (!nAddedToPlaylist && !bPlaying && (bypassSettings || CServiceBroker::GetSettings().GetBool(CSettings::SETTING_DVDS_AUTORUN))) { // stack video files CFileItemList tempItems; tempItems.Append(vecItems); if (CServiceBroker::GetSettings().GetBool(CSettings::SETTING_MYVIDEOS_STACKVIDEOS)) tempItems.Stack(); CFileItemList itemlist; for (int i = 0; i < tempItems.Size(); i++) { CFileItemPtr pItem = tempItems[i]; if (!pItem->m_bIsFolder && pItem->IsVideo()) { bPlaying = true; if (pItem->IsStack()) { //! @todo remove this once the app/player is capable of handling stacks immediately CStackDirectory dir; CFileItemList items; dir.GetDirectory(pItem->GetURL(), items); itemlist.Append(items); } else itemlist.Add(pItem); } } if (itemlist.Size()) { if (!bAllowVideo) { if (!bypassSettings) return false; if (!g_passwordManager.IsMasterLockUnlocked(true)) return false; } CServiceBroker::GetPlaylistPlayer().ClearPlaylist(PLAYLIST_VIDEO); CServiceBroker::GetPlaylistPlayer().Add(PLAYLIST_VIDEO, itemlist); CServiceBroker::GetPlaylistPlayer().SetCurrentPlaylist(PLAYLIST_VIDEO); CServiceBroker::GetPlaylistPlayer().Play(0, ""); } } // then music if (!bPlaying && (bypassSettings || CServiceBroker::GetSettings().GetInt(CSettings::SETTING_AUDIOCDS_AUTOACTION) == AUTOCD_PLAY) && bAllowMusic) { for (int i = 0; i < vecItems.Size(); i++) { CFileItemPtr pItem = vecItems[i]; if (!pItem->m_bIsFolder && pItem->IsAudio()) { nAddedToPlaylist++; CServiceBroker::GetPlaylistPlayer().Add(PLAYLIST_MUSIC, pItem); } } } /* Probably want this if/when we add some automedia action dialog... // and finally pictures if (!nAddedToPlaylist && !bPlaying && bypassSettings && bAllowPictures) { for (int i = 0; i < vecItems.Size(); i++) { CFileItemPtr pItem = vecItems[i]; if (!pItem->m_bIsFolder && pItem->IsPicture()) { bPlaying = true; std::string strExec = StringUtils::Format("RecursiveSlideShow(%s)", strDrive.c_str()); CBuiltins::Execute(strExec); break; } } } */ // check subdirs if we are not playing yet if (!bPlaying) { for (int i = 0; i < vecItems.Size(); i++) { CFileItemPtr pItem = vecItems[i]; if (pItem->m_bIsFolder) { if (pItem->GetPath() != "." && pItem->GetPath() != ".." ) { if (RunDisc(pDir, pItem->GetPath(), nAddedToPlaylist, false, bypassSettings, startFromBeginning)) { bPlaying = true; break; } } } // if (non system) folder } // for all items in directory } // if root folder return bPlaying; }
void CGUIWindowFileManager::OnClick(int iList, int iItem) { if ( iList < 0 || iList >= 2) return ; if ( iItem < 0 || iItem >= m_vecItems[iList]->Size() ) return ; CFileItemPtr pItem = m_vecItems[iList]->Get(iItem); if (pItem->GetPath() == "add" && pItem->GetLabel() == g_localizeStrings.Get(1026)) // 'add source button' in empty root { if (CGUIDialogMediaSource::ShowAndAddMediaSource("files")) { m_rootDir.SetSources(*CMediaSourceSettings::Get().GetSources("files")); Update(0,m_Directory[0]->GetPath()); Update(1,m_Directory[1]->GetPath()); } return; } if (!pItem->m_bIsFolder && pItem->IsFileFolder(EFILEFOLDER_MASK_ALL)) { XFILE::IFileDirectory *pFileDirectory = NULL; pFileDirectory = XFILE::CFileDirectoryFactory::Create(pItem->GetURL(), pItem.get(), ""); if(pFileDirectory) pItem->m_bIsFolder = true; else if(pItem->m_bIsFolder) pItem->m_bIsFolder = false; delete pFileDirectory; } if (pItem->m_bIsFolder) { // save path + drive type because of the possible refresh CStdString strPath = pItem->GetPath(); int iDriveType = pItem->m_iDriveType; if ( pItem->m_bIsShareOrDrive ) { if ( !g_passwordManager.IsItemUnlocked( pItem.get(), "files" ) ) { Refresh(); return ; } if ( !HaveDiscOrConnection( strPath, iDriveType ) ) return ; } if (!Update(iList, strPath)) ShowShareErrorMessage(pItem.get()); } else if (pItem->IsZIP() || pItem->IsCBZ()) // mount zip archive { CURL pathToUrl = URIUtils::CreateArchivePath("zip", pItem->GetURL(), ""); Update(iList, pathToUrl.Get()); } else if (pItem->IsRAR() || pItem->IsCBR()) { CURL pathToUrl = URIUtils::CreateArchivePath("rar", pItem->GetURL(), ""); Update(iList, pathToUrl.Get()); } else { OnStart(pItem.get()); return ; } // UpdateButtons(); }
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::Get().GetBool("filelists.ignorethewhensorting")) sorting.sortAttributes = (SortAttribute)(sorting.sortAttributes | SortAttributeIgnoreArticle); items.SetSortIgnoreFolders((sorting.sortAttributes & SortAttributeIgnoreFolders) == SortAttributeIgnoreFolders); std::string option = !filter ? "xsp" : "filter"; const 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; // 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, SortAttributeIgnoreArticle); // 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; }