bool CAudioLibrary::FillFileItemList(const CVariant ¶meterObject, CFileItemList &list) { CMusicDatabase musicdatabase; if (!musicdatabase.Open()) return false; CStdString file = parameterObject["file"].asString(); int artistID = (int)parameterObject["artistid"].asInteger(-1); int albumID = (int)parameterObject["albumid"].asInteger(-1); int genreID = (int)parameterObject["genreid"].asInteger(-1); bool success = false; CFileItemPtr fileItem(new CFileItem()); if (FillFileItem(file, fileItem, parameterObject)) { success = true; list.Add(fileItem); } if (artistID != -1 || albumID != -1 || genreID != -1) success |= musicdatabase.GetSongsNav("musicdb://4/", list, genreID, artistID, albumID); int songID = (int)parameterObject["songid"].asInteger(-1); if (songID != -1) { CSong song; if (musicdatabase.GetSongById(songID, song)) { list.Add(CFileItemPtr(new CFileItem(song))); success = true; } } if (success) { // If we retrieved the list of songs by "artistid" // we sort by album (and implicitly by track number) if (artistID != -1) list.Sort(SORT_METHOD_ALBUM_IGNORE_THE, SortOrderAscending); // If we retrieve the list of songs by "genreid" // we sort by artist (and implicitly by album and track number) else if (genreID != -1) list.Sort(SORT_METHOD_ARTIST_IGNORE_THE, SortOrderAscending); // otherwise we sort by track number else list.Sort(SORT_METHOD_TRACKNUM, SortOrderAscending); } return success; }
bool CAudioLibrary::FillFileItemList(const CVariant ¶meterObject, CFileItemList &list) { CMusicDatabase musicdatabase; if (!musicdatabase.Open()) return false; std::string file = parameterObject["file"].asString(); int artistID = (int)parameterObject["artistid"].asInteger(-1); int albumID = (int)parameterObject["albumid"].asInteger(-1); int genreID = (int)parameterObject["genreid"].asInteger(-1); bool success = false; CFileItemPtr fileItem(new CFileItem()); if (FillFileItem(file, fileItem, parameterObject)) { success = true; list.Add(fileItem); } if (artistID != -1 || albumID != -1 || genreID != -1) success |= musicdatabase.GetSongsNav("musicdb://songs/", list, genreID, artistID, albumID); int songID = (int)parameterObject["songid"].asInteger(-1); if (songID != -1) { CSong song; if (musicdatabase.GetSong(songID, song)) { list.Add(CFileItemPtr(new CFileItem(song))); success = true; } } if (success) { // If we retrieved the list of songs by "artistid" // we sort by album (and implicitly by track number) if (artistID != -1) list.Sort(SortByAlbum, SortOrderAscending, CSettings::GetInstance().GetBool(CSettings::SETTING_FILELISTS_IGNORETHEWHENSORTING) ? SortAttributeIgnoreArticle : SortAttributeNone); // If we retrieve the list of songs by "genreid" // we sort by artist (and implicitly by album and track number) else if (genreID != -1) list.Sort(SortByArtist, SortOrderAscending, CSettings::GetInstance().GetBool(CSettings::SETTING_FILELISTS_IGNORETHEWHENSORTING) ? SortAttributeIgnoreArticle : SortAttributeNone); // otherwise we sort by track number else list.Sort(SortByTrackNumber, SortOrderAscending); } return success; }
void CAddonInstaller::PrunePackageCache() { std::map<CStdString,CFileItemList*> packs; int64_t size = EnumeratePackageFolder(packs); int64_t limit = (int64_t)g_advancedSettings.m_addonPackageFolderSize*1024*1024; if (size < limit) return; // Prune packages // 1. Remove the largest packages, leaving at least 2 for each add-on CFileItemList items; for (std::map<CStdString,CFileItemList*>::const_iterator it = packs.begin(); it != packs.end();++it) { it->second->Sort(SortByLabel, SortOrderDescending); for (int j=2;j<it->second->Size();++j) items.Add(CFileItemPtr(new CFileItem(*it->second->Get(j)))); } items.Sort(SortBySize, SortOrderDescending); int i=0; while (size > limit && i < items.Size()) { size -= items[i]->m_dwSize; CFileUtils::DeleteItem(items[i++],true); } if (size > limit) { // 2. Remove the oldest packages (leaving least 1 for each add-on) items.Clear(); for (std::map<CStdString,CFileItemList*>::iterator it = packs.begin(); it != packs.end();++it) { if (it->second->Size() > 1) items.Add(CFileItemPtr(new CFileItem(*it->second->Get(1)))); } items.Sort(SortByDate, SortOrderAscending); i=0; while (size > limit && i < items.Size()) { size -= items[i]->m_dwSize; CFileUtils::DeleteItem(items[i++],true); } } // clean up our mess for (std::map<CStdString,CFileItemList*>::iterator it = packs.begin(); it != packs.end();++it) delete it->second; }
void CGUIDialogAddonInfo::GrabRollbackVersions() { CFileItemList items; XFILE::CDirectory::GetDirectory("special://home/addons/packages/",items,".zip",DIR_FLAG_NO_FILE_DIRS); items.Sort(SortByLabel, SortOrderAscending); CAddonDatabase db; db.Open(); for (int i=0;i<items.Size();++i) { if (items[i]->m_bIsFolder) continue; std::string ID, version; AddonVersion::SplitFileName(ID,version,items[i]->GetLabel()); if (ID == m_localAddon->ID()) { std::string hash, path(items[i]->GetPath()); if (db.GetPackageHash(m_localAddon->ID(), path, hash)) { std::string md5 = CUtil::GetFileMD5(path); if (md5 == hash) m_rollbackVersions.push_back(version); else /* The package has been corrupted */ { CLog::Log(LOGWARNING, "%s: Removing corrupt addon package %s.", __FUNCTION__, path.c_str()); CFile::Delete(path); db.RemovePackage(path); } } } } }
void CGUIWindowSlideShow::AddItems(const std::string &strPath, path_set *recursivePaths, SortBy method, SortOrder order, SortAttribute sortAttributes) { // check whether we've already added this path if (recursivePaths) { std::string path(strPath); URIUtils::RemoveSlashAtEnd(path); if (recursivePaths->find(path) != recursivePaths->end()) return; recursivePaths->insert(path); } CFileItemList items; CGUIViewStateWindowPictures viewState(items); // fetch directory and sort accordingly if (!CDirectory::GetDirectory(strPath, items, viewState.GetExtensions(), DIR_FLAG_NO_FILE_DIRS, true)) return; items.Sort(method, order, sortAttributes); // need to go into all subdirs for (int i = 0; i < items.Size(); i++) { CFileItemPtr item = items[i]; if (item->m_bIsFolder && recursivePaths) { AddItems(item->GetPath(), recursivePaths); } else if (!item->m_bIsFolder && !URIUtils::IsRAR(item->GetPath()) && !URIUtils::IsZIP(item->GetPath())) { // add to the slideshow Add(item.get()); } } }
virtual bool DoWork() { CFileItemList items; if (CDirectory::GetDirectory(m_url, items, "")) { // sort the items if necessary if (m_sort.sortBy != SortByNone) items.Sort(m_sort); // limit must not exceed the number of items int limit = (m_limit == 0) ? items.Size() : std::min((int) m_limit, items.Size()); // convert to CGUIStaticItem's and set visibility and targets m_items.reserve(limit); for (int i = 0; i < limit; i++) { CGUIStaticItemPtr item(new CGUIStaticItem(*items[i])); if (item->HasProperty("node.visible")) item->SetVisibleCondition(item->GetProperty("node.visible").asString(), m_parentID); getThumbLoader(item)->LoadItem(item.get()); m_items.push_back(item); } m_target = items.GetProperty("node.target").asString(); } return true; }
void CGUIWindowSlideShow::AddItems(const CStdString &strPath, path_set *recursivePaths, SORT_METHOD method, SORT_ORDER order) { // check whether we've already added this path if (recursivePaths) { CStdString path(strPath); URIUtils::RemoveSlashAtEnd(path); if (recursivePaths->find(path) != recursivePaths->end()) return; recursivePaths->insert(path); } // fetch directory and sort accordingly CFileItemList items; if (!CDirectory::GetDirectory(strPath, items, m_strExtensions.IsEmpty()?g_settings.m_pictureExtensions:m_strExtensions,false,false,DIR_CACHE_ONCE,true,true)) return; items.Sort(method, order); // need to go into all subdirs for (int i = 0; i < items.Size(); i++) { CFileItemPtr item = items[i]; if (item->m_bIsFolder && recursivePaths) { AddItems(item->GetPath(), recursivePaths); } else if (!item->m_bIsFolder && !URIUtils::IsRAR(item->GetPath()) && !URIUtils::IsZIP(item->GetPath())) { // add to the slideshow Add(item.get()); } } }
bool CGUIWindowPVRCommon::PlayRecording(CFileItem *item, bool bPlayMinimized /* = false */) { if (item->GetPath().Left(17) != "pvr://recordings/") return false; CStdString stream = item->GetPVRRecordingInfoTag()->m_strStreamURL; if (stream == "") return false; /* Isolate the folder from the filename */ size_t found = stream.find_last_of("/"); if (found == CStdString::npos) found = stream.find_last_of("\\"); if (found != CStdString::npos) { /* Check here for asterisk at the begin of the filename */ if (stream[found+1] == '*') { /* Create a "stack://" url with all files matching the extension */ CStdString ext = URIUtils::GetExtension(stream); CStdString dir = stream.substr(0, found).c_str(); CFileItemList items; CDirectory::GetDirectory(dir, items); items.Sort(SORT_METHOD_FILE ,SORT_ORDER_ASC); vector<int> stack; for (int i = 0; i < items.Size(); ++i) { if (URIUtils::GetExtension(items[i]->GetPath()) == ext) stack.push_back(i); } if (stack.size() > 0) { /* If we have a stack change the path of the item to it */ CStackDirectory dir; CStdString stackPath = dir.ConstructStackPath(items, stack); item->SetPath(stackPath); } } else { /* If no asterisk is present play only the given stream URL */ item->SetPath(stream); } } else { CLog::Log(LOGERROR, "PVRManager - %s - can't open recording: no valid filename", __FUNCTION__); CGUIDialogOK::ShowAndGetInput(19033,0,19036,0); return false; } g_application.getApplicationMessenger().PlayFile(*item, false); return true; }
bool CTextureCleanupJob::DoWork() { CTextureDatabase db; if (db.Open()) { std::string path; std::string fn; std::string prevPath = ""; std::vector<std::string> pathContent; XFILE::CSpecialProtocolDirectory thumbDir; CFileItemList files; int fileIdx = 0; int totFileDel = 0; int totDbDel = 0; auto deleteFile = [&]() { std::string todel = files.Get(fileIdx)->GetPath(); CLog::Log(LOGDEBUG, "CTextureCleanupJob: deleting %s", todel.c_str()); XFILE::CFile::Delete(todel); totFileDel++; fileIdx++; }; std::vector<std::pair<int, std::string>> urls = db.GetCachedTextureUrls(); for (const auto &url : urls) { std::string cachedurl = url.second; URIUtils::Split(cachedurl, path, fn); std::string cmpurl = "special://thumbnails/" + cachedurl; if (path != prevPath) { while (fileIdx < files.Size()) deleteFile(); files.Clear(); thumbDir.GetDirectory(CURL("special://thumbnails/" + path), files); files.Sort(SortByPath, SortOrderAscending); prevPath = path; fileIdx = 0; } while (fileIdx < files.Size() && files.Get(fileIdx)->GetPath() < cmpurl) deleteFile(); if (fileIdx < files.Size() && files.Get(fileIdx)->GetPath() == cmpurl) fileIdx++; else { // No file for current entry; delete it CLog::Log(LOGDEBUG, "CTextureCleanupJob: deleting from Db: %d / %s", url.first, cachedurl.c_str()); db.ClearCachedTexture(url.first, cachedurl); totDbDel++; } } while (fileIdx < files.Size()) deleteFile(); CLog::Log(LOGDEBUG, "CTextureCleanupJob: %d thumbnails deleted / %d db entries removed", totFileDel, totDbDel); } return true; }
void CFileItemHandler::Sort(CFileItemList &items, const CVariant ¶meterObject) { SortDescription sorting; if (!ParseSorting(parameterObject, sorting.sortBy, sorting.sortOrder, sorting.sortAttributes)) return; items.Sort(sorting); }
bool GroupUtils::GroupAndSort(GroupBy groupBy, const std::string &baseDir, const CFileItemList &items, const SortDescription &sortDescription, CFileItemList &groupedItems, GroupAttribute groupAttributes /* = GroupAttributeNone */) { if (!Group(groupBy, baseDir, items, groupedItems, groupAttributes)) return false; groupedItems.Sort(sortDescription); return true; }
void CGUIWindowVideoNav::OnLinkMovieToTvShow(int itemnumber, bool bRemove) { CFileItemList list; if (bRemove) { vector<int> ids; if (!m_database.GetLinksToTvShow(m_vecItems->Get(itemnumber)->GetVideoInfoTag()->m_iDbId,ids)) return; for (unsigned int i=0;i<ids.size();++i) { CVideoInfoTag tag; m_database.GetTvShowInfo("",tag,ids[i]); CFileItemPtr show(new CFileItem(tag)); list.Add(show); } } else { m_database.GetTvShowsNav("videodb://2/2",list); // remove already linked shows vector<int> ids; if (!m_database.GetLinksToTvShow(m_vecItems->Get(itemnumber)->GetVideoInfoTag()->m_iDbId,ids)) return; for (int i=0;i<list.Size();) { unsigned int j; for (j=0;j<ids.size();++j) { if (list[i]->GetVideoInfoTag()->m_iDbId == ids[j]) break; } if (j == ids.size()) i++; else list.Remove(i); } } int iSelectedLabel = 0; if (list.Size() > 1) { list.Sort(g_guiSettings.GetBool("filelists.ignorethewhensorting") ? SORT_METHOD_LABEL_IGNORE_THE : SORT_METHOD_LABEL, SORT_ORDER_ASC); CGUIDialogSelect* pDialog = (CGUIDialogSelect*)g_windowManager.GetWindow(WINDOW_DIALOG_SELECT); pDialog->Reset(); pDialog->SetItems(&list); pDialog->SetHeading(20356); pDialog->DoModal(); iSelectedLabel = pDialog->GetSelectedLabel(); } if (iSelectedLabel > -1) { m_database.LinkMovieToTvshow(m_vecItems->Get(itemnumber)->GetVideoInfoTag()->m_iDbId, list[iSelectedLabel]->GetVideoInfoTag()->m_iDbId, bRemove); CUtil::DeleteVideoDatabaseDirectoryCache(); } }
// \brief Sorts Fileitems based on the sort method and sort oder provided by guiViewState void CGUIMediaWindow::SortItems(CFileItemList &items) { auto_ptr<CGUIViewState> guiState(CGUIViewState::GetViewState(GetID(), items)); if (guiState.get()) { items.Sort(guiState->GetSortMethod(), guiState->GetDisplaySortOrder()); // Should these items be saved to the hdd if (items.CacheToDiscAlways()) items.Save(GetID()); } }
bool CMediaManager::HashDVD(const CStdString& dvdpath, uint32_t& crc) { CFileItemList vecItemsTS; bool success = false; // first try to open the VIDEO_TS folder of the DVD if (!CDirectory::GetDirectory( dvdpath, vecItemsTS, ".ifo" )) { CLog::Log(LOGERROR, "%s - Cannot open dvd VIDEO_TS folder -- ABORTING", __FUNCTION__); return false; } Crc32 crc32; bool dataRead = false; vecItemsTS.Sort(SORT_METHOD_FILE, SortOrderAscending); for (int i = 0; i < vecItemsTS.Size(); i++) { CFileItemPtr videoTSItem = vecItemsTS[i]; success = true; // get the file name for logging purposes CStdString fileName = URIUtils::GetFileName(videoTSItem->GetPath()); CLog::Log(LOGDEBUG, "%s - Adding file content for dvd file: %s", __FUNCTION__, fileName.c_str()); CFile file; if(!file.Open(videoTSItem->GetPath())) { CLog::Log(LOGERROR, "%s - Cannot open dvd file: %s -- ABORTING", __FUNCTION__, fileName.c_str()); return false; } int res; char buf[2048]; while( (res = file.Read(buf, sizeof(buf))) > 0) { dataRead = true; crc32.Compute(buf, res); } file.Close(); } if (!dataRead) { CLog::Log(LOGERROR, "%s - Did not read any data from the IFO files -- ABORTING", __FUNCTION__); return false; } // put result back in reference parameter crc = (uint32_t) crc32; return success; }
void CFileItemHandler::Sort(CFileItemList &items, const CVariant ¶meterObject) { CStdString method = parameterObject["method"].asString(); CStdString order = parameterObject["order"].asString(); method = method.ToLower(); order = order.ToLower(); SORT_METHOD sortmethod = SORT_METHOD_NONE; SORT_ORDER sortorder = SORT_ORDER_ASC; if (ParseSortMethods(method, parameterObject["ignorearticle"].asBoolean(), order, sortmethod, sortorder)) items.Sort(sortmethod, sortorder); }
/// \brief Search the current directory for a string got from the virtual keyboard void CGUIWindowVideoInfo::OnSearch(CStdString& strSearch) { if (m_dlgProgress) { m_dlgProgress->SetHeading(194); m_dlgProgress->SetLine(0, strSearch); m_dlgProgress->SetLine(1, ""); m_dlgProgress->SetLine(2, ""); m_dlgProgress->StartModal(); m_dlgProgress->Progress(); } CFileItemList items; DoSearch(strSearch, items); if (items.Size()) { CGUIDialogSelect* pDlgSelect = (CGUIDialogSelect*)m_gWindowManager.GetWindow(WINDOW_DIALOG_SELECT); pDlgSelect->Reset(); pDlgSelect->SetHeading(283); items.Sort(SORT_METHOD_LABEL, SORT_ORDER_ASC); for (int i = 0; i < (int)items.Size(); i++) { CFileItem* pItem = items[i]; pDlgSelect->Add(pItem->GetLabel()); } pDlgSelect->DoModal(); int iItem = pDlgSelect->GetSelectedLabel(); if (iItem < 0) { if (m_dlgProgress) m_dlgProgress->Close(); return ; } CFileItem* pSelItem = new CFileItem(*items[iItem]); OnSearchItemFound(pSelItem); delete pSelItem; if (m_dlgProgress) m_dlgProgress->Close(); } else { if (m_dlgProgress) m_dlgProgress->Close(); CGUIDialogOK::ShowAndGetInput(194, 284, 0, 0); } }
void CGUIDialogAddonInfo::GrabRollbackVersions() { CFileItemList items; XFILE::CDirectory::GetDirectory("special://home/addons/packages/",items,".zip",DIR_FLAG_NO_FILE_DIRS); items.Sort(SortByLabel, SortOrderAscending); for (int i=0;i<items.Size();++i) { if (items[i]->m_bIsFolder) continue; CStdString ID, version; AddonVersion::SplitFileName(ID,version,items[i]->GetLabel()); if (ID.Equals(m_localAddon->ID())) m_rollbackVersions.push_back(version); } }
void CGUIDialogAddonInfo::GrabRollbackVersions() { CFileItemList items; XFILE::CDirectory::GetDirectory("special://home/addons/packages/",items,".zip",false); items.Sort(SORT_METHOD_LABEL,SORT_ORDER_ASC); for (int i=0;i<items.Size();++i) { if (items[i]->m_bIsFolder) continue; CStdString ID, version; AddonVersion::SplitFileName(ID,version,items[i]->GetLabel()); if (ID.Equals(m_localAddon->ID())) m_rollbackVersions.push_back(version); } }
void CFileItemHandler::Sort(CFileItemList &items, const Value ¶meterObject) { Value sort = parameterObject["sort"]; if (sort.isObject()) { CStdString method = sort["method"].isString() ? sort["method"].asString() : "none"; CStdString order = sort["order"].isString() ? sort["order"].asString() : "ascending"; bool ignorethe = sort["ignorethe"].isBool() ? sort["ignorethe"].asBool() : false; method = method.ToLower(); order = order.ToLower(); SORT_METHOD sortmethod = SORT_METHOD_NONE; SORT_ORDER sortorder = SORT_ORDER_ASC; if (ParseSortMethods(method, ignorethe, order, sortmethod, sortorder)) items.Sort(sortmethod, sortorder); } }
/** * 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 CStdString& strDrive, int& nAddedToPlaylist, bool bRoot, bool bypassSettings /* = false */, bool startFromBeginning /* = false */) { bool bPlaying(false); CFileItemList vecItems; if ( !pDir->GetDirectory( strDrive, 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::Get().GetCurrentProfile().videoLocked(); // bAllowPictures = !CProfilesManager::Get().GetCurrentProfile().picturesLocked(); bAllowMusic = !CProfilesManager::Get().GetCurrentProfile().musicLocked(); } // is this a root folder we have to check the content to determine a disc type if( bRoot ) { CStdString 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() != "..") { CStdString name = pItem->GetPath(); URIUtils::RemoveSlashAtEnd(name); name = URIUtils::GetFileName(name); // Check if the current foldername indicates a DVD structure (name is "VIDEO_TS") if (name.Equals("VIDEO_TS") && bAllowVideo && (bypassSettings || CSettings::Get().GetBool("dvds.autorun"))) { CStdString 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; g_playlistPlayer.ClearPlaylist(PLAYLIST_VIDEO); g_playlistPlayer.SetShuffle (PLAYLIST_VIDEO, false); g_playlistPlayer.Add(PLAYLIST_VIDEO, item); g_playlistPlayer.SetCurrentPlaylist(PLAYLIST_VIDEO); g_playlistPlayer.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 beeing, the DVD autorun settings are used to determine if the BR should be started automatically. if (name.Equals("BDMV") && bAllowVideo && (bypassSettings || CSettings::Get().GetBool("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; g_playlistPlayer.ClearPlaylist(PLAYLIST_VIDEO); g_playlistPlayer.SetShuffle (PLAYLIST_VIDEO, false); g_playlistPlayer.Add(PLAYLIST_VIDEO, item); g_playlistPlayer.SetCurrentPlaylist(PLAYLIST_VIDEO); g_playlistPlayer.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 beeing, 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 (name.Equals("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 (name.Equals("HVDVD_TS") && bAllowVideo && (bypassSettings || CSettings::Get().GetBool("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; } 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 CStdString hddvdplayer = CPlayerCoreFactory::Get().GetPlayerName(CPlayerCoreFactory::Get().GetDefaultPlayer(item)); // Single *.xpl or *.ifo files require an external player to handle playback. // If no matching rule was found, DVDPlayer will be default player. if (hddvdplayer != "DVDPlayer") { CLog::Log(LOGINFO,"HD DVD: External singlefile playback initiated: %s",hddvdname.c_str()); g_application.PlayFile(item, 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."); g_playlistPlayer.ClearPlaylist(PLAYLIST_VIDEO); g_playlistPlayer.SetShuffle (PLAYLIST_VIDEO, false); g_playlistPlayer.Add(PLAYLIST_VIDEO, items); g_playlistPlayer.SetCurrentPlaylist(PLAYLIST_VIDEO); g_playlistPlayer.Play(0); return true; } // Video CDs can have multiple file formats. First we need to determine which one is used on the CD CStdString strExt; if (name.Equals("MPEGAV")) strExt = ".dat"; if (name.Equals("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 || CSettings::Get().GetBool("dvds.autorun"))) { CFileItemList items; CDirectory::GetDirectory(pItem->GetPath(), items, strExt); if (items.Size()) { items.Sort(SortByLabel, SortOrderAscending); g_playlistPlayer.ClearPlaylist(PLAYLIST_VIDEO); g_playlistPlayer.Add(PLAYLIST_VIDEO, items); g_playlistPlayer.SetCurrentPlaylist(PLAYLIST_VIDEO); g_playlistPlayer.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; CStdString strExec = StringUtils::Format("XBMC.RecursiveSlideShow(%s)", pItem->GetPath().c_str()); CBuiltins::Execute(strExec); return true; } */ } } } // check video first if (!nAddedToPlaylist && !bPlaying && (bypassSettings || CSettings::Get().GetBool("dvds.autorun"))) { // stack video files CFileItemList tempItems; tempItems.Append(vecItems); if (CSettings::Get().GetBool("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->GetPath(), items); itemlist.Append(items); } else itemlist.Add(pItem); } } if (itemlist.Size()) { if (!bAllowVideo) { if (!bypassSettings) return false; if (g_windowManager.GetActiveWindow() != WINDOW_VIDEO_FILES) if (!g_passwordManager.IsMasterLockUnlocked(true)) return false; } g_playlistPlayer.ClearPlaylist(PLAYLIST_VIDEO); g_playlistPlayer.Add(PLAYLIST_VIDEO, itemlist); g_playlistPlayer.SetCurrentPlaylist(PLAYLIST_VIDEO); g_playlistPlayer.Play(0); } } // then music if (!bPlaying && (bypassSettings || CSettings::Get().GetInt("audiocds.autoaction") == AUTOCD_PLAY) && bAllowMusic) { for (int i = 0; i < vecItems.Size(); i++) { CFileItemPtr pItem = vecItems[i]; if (!pItem->m_bIsFolder && pItem->IsAudio()) { nAddedToPlaylist++; g_playlistPlayer.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; CStdString strExec = StringUtils::Format("XBMC.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; }
bool CButtonTranslator::Load() { deviceMappings.clear(); //directories to search for keymaps //they're applied in this order, //so keymaps in profile/keymaps/ //override e.g. system/keymaps static const char* DIRS_TO_CHECK[] = { "special://xbmc/system/keymaps/", "special://masterprofile/keymaps/", "special://profile/keymaps/" }; bool success = false; for(unsigned int dirIndex = 0; dirIndex < sizeof(DIRS_TO_CHECK)/sizeof(DIRS_TO_CHECK[0]); ++dirIndex) { if( XFILE::CDirectory::Exists(DIRS_TO_CHECK[dirIndex]) ) { CFileItemList files; XFILE::CDirectory::GetDirectory(DIRS_TO_CHECK[dirIndex], files, "*.xml"); //sort the list for filesystem based prioties, e.g. 01-keymap.xml, 02-keymap-overrides.xml files.Sort(SORT_METHOD_FILE, SORT_ORDER_ASC); for(int fileIndex = 0; fileIndex<files.Size(); ++fileIndex) success |= LoadKeymap(files[fileIndex]->GetPath()); } } if (!success) { CLog::Log(LOGERROR, "Error loading keymaps from: %s or %s or %s", DIRS_TO_CHECK[0], DIRS_TO_CHECK[1], DIRS_TO_CHECK[2]); return false; } #if defined(HAS_LIRC) || defined(HAS_IRSERVERSUITE) #ifdef _LINUX #define REMOTEMAP "Lircmap.xml" #else #define REMOTEMAP "IRSSmap.xml" #endif CStdString lircmapPath; URIUtils::AddFileToFolder("special://xbmc/system/", REMOTEMAP, lircmapPath); lircRemotesMap.clear(); if(CFile::Exists(lircmapPath)) success |= LoadLircMap(lircmapPath); else CLog::Log(LOGDEBUG, "CButtonTranslator::Load - no system %s found, skipping", REMOTEMAP); lircmapPath = g_settings.GetUserDataItem(REMOTEMAP); if(CFile::Exists(lircmapPath)) success |= LoadLircMap(lircmapPath); else CLog::Log(LOGDEBUG, "CButtonTranslator::Load - no userdata %s found, skipping", REMOTEMAP); if (!success) CLog::Log(LOGERROR, "CButtonTranslator::Load - unable to load remote map %s", REMOTEMAP); // don't return false - it is to only indicate a fatal error (which this is not) #endif // Done! return true; }
void CGUIDialogSmartPlaylistRule::OnBrowse() { CFileItemList items; CMusicDatabase database; database.Open(); CVideoDatabase videodatabase; videodatabase.Open(); VIDEODB_CONTENT_TYPE type = VIDEODB_CONTENT_MOVIES; if (m_type.Equals("tvshows")) type = VIDEODB_CONTENT_TVSHOWS; else if (m_type.Equals("musicvideos")) type = VIDEODB_CONTENT_MUSICVIDEOS; else if (m_type.Equals("episodes")) type = VIDEODB_CONTENT_EPISODES; int iLabel = 0; if (m_rule.m_field == FieldGenre) { if (m_type.Equals("tvshows") || m_type.Equals("episodes") || m_type.Equals("movies")) videodatabase.GetGenresNav("videodb://2/1/",items,type); else if (m_type.Equals("songs") || m_type.Equals("albums") || m_type.Equals("artists") || m_type.Equals("mixed")) database.GetGenresNav("musicdb://1/",items); if (m_type.Equals("musicvideos") || m_type.Equals("mixed")) { CFileItemList items2; videodatabase.GetGenresNav("videodb://3/1/",items2,VIDEODB_CONTENT_MUSICVIDEOS); items.Append(items2); } iLabel = 515; } else if (m_rule.m_field == FieldCountry) { videodatabase.GetCountriesNav("videodb://2/1/",items,type); iLabel = 574; } else if (m_rule.m_field == FieldArtist || m_rule.m_field == FieldAlbumArtist) { if (m_type.Equals("songs") || m_type.Equals("mixed") || m_type.Equals("albums") || m_type.Equals("artists")) database.GetArtistsNav("musicdb://2/", items, m_rule.m_field == FieldAlbumArtist, -1); if (m_type.Equals("musicvideos") || m_type.Equals("mixed")) { CFileItemList items2; videodatabase.GetMusicVideoArtistsByName("",items2); items.Append(items2); } iLabel = 557; } else if (m_rule.m_field == FieldAlbum) { if (m_type.Equals("songs") || m_type.Equals("mixed") || m_type.Equals("albums")) database.GetAlbumsNav("musicdb://3/", items); if (m_type.Equals("musicvideos") || m_type.Equals("mixed")) { CFileItemList items2; videodatabase.GetMusicVideoAlbumsByName("",items2); items.Append(items2); } iLabel = 558; } else if (m_rule.m_field == FieldActor) { videodatabase.GetActorsNav("",items,type); iLabel = 20337; } else if (m_rule.m_field == FieldYear) { if (m_type.Equals("songs") || m_type.Equals("mixed") || m_type.Equals("albums")) database.GetYearsNav("musicdb://9/", items); if (!m_type.Equals("songs") && !m_type.Equals("albums")) { CFileItemList items2; videodatabase.GetYearsNav("", items2, type); items.Append(items2); } iLabel = 562; } else if (m_rule.m_field == FieldDirector) { videodatabase.GetDirectorsNav("",items,type); iLabel = 20339; } else if (m_rule.m_field == FieldStudio) { videodatabase.GetStudiosNav("",items,type); iLabel = 572; } else if (m_rule.m_field == FieldWriter) { videodatabase.GetWritersNav("",items,type); iLabel = 20417; } else if (m_rule.m_field == FieldTvShowTitle) { videodatabase.GetTvShowsNav("videodb://2/2/",items); iLabel = 20343; } else if (m_rule.m_field == FieldPlaylist) { // 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 CStdString path = "special://videoplaylists/"; if (m_type.Equals("songs") || m_type.Equals("albums")) path = "special://musicplaylists/"; XFILE::CDirectory::GetDirectory(path, items, ".xsp", XFILE::DIR_FLAG_NO_FILE_DIRS); for (int i = 0; i < items.Size(); i++) { CFileItemPtr item = items[i]; CSmartPlaylist playlist; if (playlist.OpenAndReadName(item->GetPath())) item->SetLabel(playlist.GetName()); } iLabel = 559; } else if (m_rule.m_field == FieldPath) { VECSOURCES sources; if (m_type == "songs" || m_type == "mixed") sources = *g_settings.GetSourcesFromType("music"); if (m_type != "songs") { VECSOURCES sources2 = *g_settings.GetSourcesFromType("video"); sources.insert(sources.end(),sources2.begin(),sources2.end()); } g_mediaManager.GetLocalDrives(sources); CStdString path = m_rule.GetLocalizedParameter(m_type); CGUIDialogFileBrowser::ShowAndGetDirectory(sources, g_localizeStrings.Get(657), path, false); if (m_rule.m_parameter.size() > 0) m_rule.m_parameter.clear(); if (!path.empty()) m_rule.m_parameter.push_back(path); UpdateButtons(); return; } else if (m_rule.m_field == FieldSet) { videodatabase.GetSetsNav("videodb://1/7/", items, VIDEODB_CONTENT_MOVIES); iLabel = 20434; } else if (m_rule.m_field == FieldTag) { if (m_type == "movies") videodatabase.GetTagsNav("videodb://1/9/", items, VIDEODB_CONTENT_MOVIES); else return; iLabel = 20459; } else { // TODO: Add browseability in here. assert(false); } // sort the items items.Sort(SORT_METHOD_LABEL, SortOrderAscending); CGUIDialogSelect* pDialog = (CGUIDialogSelect*)g_windowManager.GetWindow(WINDOW_DIALOG_SELECT); pDialog->Reset(); pDialog->SetItems(&items); CStdString strHeading; strHeading.Format(g_localizeStrings.Get(13401),g_localizeStrings.Get(iLabel)); pDialog->SetHeading(strHeading); pDialog->SetMultiSelection(true); if (!m_rule.m_parameter.empty()) pDialog->SetSelected(m_rule.m_parameter); pDialog->DoModal(); if (pDialog->IsConfirmed()) { const CFileItemList &items = pDialog->GetSelectedItems(); m_rule.m_parameter.clear(); for (int index = 0; index < items.Size(); index++) m_rule.m_parameter.push_back(items[index]->GetLabel()); UpdateButtons(); } pDialog->Reset(); }
void CMultiPathDirectory::MergeItems(CFileItemList &items) { CLog::Log(LOGDEBUG, "CMultiPathDirectory::MergeItems, items = %i", (int)items.Size()); unsigned int time = CTimeUtils::GetTimeMS(); if (items.Size() == 0) return; // sort items by label // folders are before files in this sort method items.Sort(SORT_METHOD_LABEL, SORT_ORDER_ASC); int i = 0; // if first item in the sorted list is a file, just abort if (!items.Get(i)->m_bIsFolder) return; while (i + 1 < items.Size()) { // there are no more folders left, so exit the loop CFileItemPtr pItem1 = items.Get(i); if (!pItem1->m_bIsFolder) break; vector<int> stack; stack.push_back(i); CLog::Log(LOGDEBUG,"Testing path: [%03i] %s", i, pItem1->m_strPath.c_str()); int j = i + 1; do { CFileItemPtr pItem2 = items.Get(j); if (!pItem2->GetLabel().Equals(pItem1->GetLabel())) break; // ignore any filefolders which may coincidently have // the same label as a true folder if (!pItem2->IsFileFolder()) { stack.push_back(j); CLog::Log(LOGDEBUG," Adding path: [%03i] %s", j, pItem2->m_strPath.c_str()); } j++; } while (j < items.Size()); // do we have anything to combine? if (stack.size() > 1) { // we have a multipath so remove the items and add the new item CStdString newPath = ConstructMultiPath(items, stack); for (unsigned int k = stack.size() - 1; k > 0; --k) items.Remove(stack[k]); pItem1->m_strPath = newPath; CLog::Log(LOGDEBUG," New path: %s", pItem1->m_strPath.c_str()); } i++; } CLog::Log(LOGDEBUG, "CMultiPathDirectory::MergeItems, items = %i, took %d ms", items.Size(), CTimeUtils::GetTimeMS() - time); }
int CGUIWindowAddonBrowser::SelectAddonID(const std::vector<ADDON::TYPE> &types, std::vector<std::string> &addonIDs, bool showNone /* = false */, bool showDetails /* = true */, bool multipleSelection /* = true */, bool showInstalled /* = true */, bool showInstallable /* = false */, bool showMore /* = true */) { // if we shouldn't show neither installed nor installable addons the list will be empty if (!showInstalled && !showInstallable) return -1; // can't show the "Get More" button if we already show installable addons if (showInstallable) showMore = false; CGUIDialogSelect *dialog = g_windowManager.GetWindow<CGUIDialogSelect>(); if (!dialog) return -1; // get rid of any invalid addon types std::vector<ADDON::TYPE> validTypes(types.size()); std::copy_if(types.begin(), types.end(), validTypes.begin(), [](ADDON::TYPE type) { return type != ADDON_UNKNOWN; }); if (validTypes.empty()) return -1; // get all addons to show VECADDONS addons; if (showInstalled) { for (std::vector<ADDON::TYPE>::const_iterator type = validTypes.begin(); type != validTypes.end(); ++type) { VECADDONS typeAddons; if (*type == ADDON_AUDIO) CAddonsDirectory::GetScriptsAndPlugins("audio", typeAddons); else if (*type == ADDON_EXECUTABLE) CAddonsDirectory::GetScriptsAndPlugins("executable", typeAddons); else if (*type == ADDON_IMAGE) CAddonsDirectory::GetScriptsAndPlugins("image", typeAddons); else if (*type == ADDON_VIDEO) CAddonsDirectory::GetScriptsAndPlugins("video", typeAddons); else if (*type == ADDON_GAME) CAddonsDirectory::GetScriptsAndPlugins("game", typeAddons); else CAddonMgr::GetInstance().GetAddons(typeAddons, *type); addons.insert(addons.end(), typeAddons.begin(), typeAddons.end()); } } if (showInstallable || showMore) { VECADDONS installableAddons; if (CAddonMgr::GetInstance().GetInstallableAddons(installableAddons)) { for (ADDON::IVECADDONS addon = installableAddons.begin(); addon != installableAddons.end();) { AddonPtr pAddon = *addon; // check if the addon matches one of the provided addon types bool matchesType = false; for (std::vector<ADDON::TYPE>::const_iterator type = validTypes.begin(); type != validTypes.end(); ++type) { if (pAddon->IsType(*type)) { matchesType = true; break; } } if (matchesType) { ++addon; continue; } addon = installableAddons.erase(addon); } if (showInstallable) addons.insert(addons.end(), installableAddons.begin(), installableAddons.end()); else if (showMore) showMore = !installableAddons.empty(); } } if (addons.empty() && !showNone) return -1; // turn the addons into items std::map<std::string, AddonPtr> addonMap; CFileItemList items; for (ADDON::IVECADDONS addon = addons.begin(); addon != addons.end(); ++addon) { CFileItemPtr item(CAddonsDirectory::FileItemFromAddon(*addon, (*addon)->ID())); item->SetLabel2((*addon)->Summary()); if (!items.Contains(item->GetPath())) { items.Add(item); addonMap.insert(std::make_pair(item->GetPath(), *addon)); } } if (items.IsEmpty() && !showNone) return -1; std::string heading; for (std::vector<ADDON::TYPE>::const_iterator type = validTypes.begin(); type != validTypes.end(); ++type) { if (!heading.empty()) heading += ", "; heading += TranslateType(*type, true); } dialog->SetHeading(CVariant{std::move(heading)}); dialog->Reset(); dialog->SetUseDetails(showDetails); if (multipleSelection) { showNone = false; showMore = false; dialog->EnableButton(true, 186); } else if (showMore) dialog->EnableButton(true, 21452); if (showNone) { CFileItemPtr item(new CFileItem("", false)); item->SetLabel(g_localizeStrings.Get(231)); item->SetLabel2(g_localizeStrings.Get(24040)); item->SetIconImage("DefaultAddonNone.png"); item->SetSpecialSort(SortSpecialOnTop); items.Add(item); } items.Sort(SortByLabel, SortOrderAscending); if (!addonIDs.empty()) { for (std::vector<std::string>::const_iterator it = addonIDs.begin(); it != addonIDs.end() ; ++it) { CFileItemPtr item = items.Get(*it); if (item) item->Select(true); } } dialog->SetItems(items); dialog->SetMultiSelection(multipleSelection); dialog->Open(); // if the "Get More" button has been pressed and we haven't shown the // installable addons so far show a list of installable addons if (showMore&& dialog->IsButtonPressed()) return SelectAddonID(types, addonIDs, showNone, showDetails, multipleSelection, false, true, false); if (!dialog->IsConfirmed()) return 0; addonIDs.clear(); for (int i : dialog->GetSelectedItems()) { const CFileItemPtr& item = items.Get(i); // check if one of the selected addons needs to be installed if (showInstallable) { std::map<std::string, AddonPtr>::const_iterator itAddon = addonMap.find(item->GetPath()); if (itAddon != addonMap.end()) { const AddonPtr& addon = itAddon->second; // if the addon isn't installed we need to install it if (!CAddonMgr::GetInstance().IsAddonInstalled(addon->ID())) { AddonPtr installedAddon; if (!CAddonInstaller::GetInstance().InstallModal(addon->ID(), installedAddon, false)) continue; } // if the addon is disabled we need to enable it if (CAddonMgr::GetInstance().IsAddonDisabled(addon->ID())) CAddonMgr::GetInstance().EnableAddon(addon->ID()); } } addonIDs.push_back(item->GetPath()); } return 1; }
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 == 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 referencable 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.size() > 0) m_rule.m_parameter.clear(); if (!path.empty()) m_rule.m_parameter.push_back(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, CSettings::GetInstance().GetBool(CSettings::SETTING_FILELISTS_IGNORETHEWHENSORTING) ? SortAttributeIgnoreArticle : SortAttributeNone); CGUIDialogSelect* pDialog = (CGUIDialogSelect*)g_windowManager.GetWindow(WINDOW_DIALOG_SELECT); 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 CGUIWindowPVRBase::PlayRecording(CFileItem *item, bool bPlayMinimized /* = false */, bool bCheckResume /* = true */) { if (!item->HasPVRRecordingInfoTag()) return false; std::string stream = item->GetPVRRecordingInfoTag()->m_strStreamURL; if (stream.empty()) { if (bCheckResume) CheckResumeRecording(item); CApplicationMessenger::GetInstance().PostMsg(TMSG_MEDIA_PLAY, 0, 0, static_cast<void*>(new CFileItem(*item))); return true; } /* Isolate the folder from the filename */ size_t found = stream.find_last_of("/"); if (found == std::string::npos) found = stream.find_last_of("\\"); if (found != std::string::npos) { /* Check here for asterisk at the begin of the filename */ if (stream[found+1] == '*') { /* Create a "stack://" url with all files matching the extension */ std::string ext = URIUtils::GetExtension(stream); std::string dir = stream.substr(0, found); CFileItemList items; XFILE::CDirectory::GetDirectory(dir, items); items.Sort(SortByFile, SortOrderAscending); std::vector<int> stack; for (int i = 0; i < items.Size(); ++i) { if (URIUtils::HasExtension(items[i]->GetPath(), ext)) stack.push_back(i); } if (stack.empty()) { /* If we have a stack change the path of the item to it */ XFILE::CStackDirectory dir; std::string stackPath = dir.ConstructStackPath(items, stack); item->SetPath(stackPath); } } else { /* If no asterisk is present play only the given stream URL */ item->SetPath(stream); } } else { CLog::Log(LOGERROR, "CGUIWindowPVRCommon - %s - can't open recording: no valid filename", __FUNCTION__); CGUIDialogOK::ShowAndGetInput(CVariant{19033}, CVariant{19036}); return false; } if (bCheckResume) CheckResumeRecording(item); CApplicationMessenger::GetInstance().PostMsg(TMSG_MEDIA_PLAY, 0, 0, static_cast<void*>(new CFileItem(*item))); return true; }
bool CMusicInfoScanner::DoScan(const CStdString& strDirectory) { if (m_handle) m_handle->SetText(Prettify(strDirectory)); /* * remove this path from the list we're processing. This must be done prior to * the check for file or folder exclusion to prevent an infinite while loop * in Process(). */ set<CStdString>::iterator it = m_pathsToScan.find(strDirectory); if (it != m_pathsToScan.end()) m_pathsToScan.erase(it); // Discard all excluded files defined by m_musicExcludeRegExps CStdStringArray regexps = g_advancedSettings.m_audioExcludeFromScanRegExps; if (CUtil::ExcludeFileOrFolder(strDirectory, regexps)) return true; // load subfolder CFileItemList items; CDirectory::GetDirectory(strDirectory, items, g_settings.m_musicExtensions + "|.jpg|.tbn|.lrc|.cdg"); // sort and get the path hash. Note that we don't filter .cue sheet items here as we want // to detect changes in the .cue sheet as well. The .cue sheet items only need filtering // if we have a changed hash. items.Sort(SORT_METHOD_LABEL, SortOrderAscending); CStdString hash; GetPathHash(items, hash); // check whether we need to rescan or not CStdString dbHash; if ((m_flags & SCAN_RESCAN) || !m_musicDatabase.GetPathHash(strDirectory, dbHash) || dbHash != hash) { // path has changed - rescan if (dbHash.IsEmpty()) CLog::Log(LOGDEBUG, "%s Scanning dir '%s' as not in the database", __FUNCTION__, strDirectory.c_str()); else CLog::Log(LOGDEBUG, "%s Rescanning dir '%s' due to change", __FUNCTION__, strDirectory.c_str()); // filter items in the sub dir (for .cue sheet support) items.FilterCueItems(); items.Sort(SORT_METHOD_LABEL, SortOrderAscending); // and then scan in the new information if (RetrieveMusicInfo(items, strDirectory) > 0) { if (m_handle) OnDirectoryScanned(strDirectory); } // save information about this folder m_musicDatabase.SetPathHash(strDirectory, hash); } else { // path is the same - no need to rescan CLog::Log(LOGDEBUG, "%s Skipping dir '%s' due to no change", __FUNCTION__, strDirectory.c_str()); m_currentItem += CountFiles(items, false); // false for non-recursive // updated the dialog with our progress if (m_handle) { if (m_itemCount>0) m_handle->SetPercentage(m_currentItem/(float)m_itemCount*100); OnDirectoryScanned(strDirectory); } } // now scan the subfolders for (int i = 0; i < items.Size(); ++i) { CFileItemPtr pItem = items[i]; if (m_bStop) break; // if we have a directory item (non-playlist) we then recurse into that folder if (pItem->m_bIsFolder && !pItem->IsParentFolder() && !pItem->IsPlayList()) { CStdString strPath=pItem->GetPath(); if (!DoScan(strPath)) { m_bStop = true; } } } return !m_bStop; }
bool CFileOperations::FillFileItemList(const CVariant ¶meterObject, CFileItemList &list) { if (parameterObject.isMember("directory")) { CStdString media = parameterObject["media"].asString(); media = media.ToLower(); CStdString strPath = parameterObject["directory"].asString(); if (!strPath.empty()) { CFileItemList items; CStdString extensions = ""; CStdStringArray regexps; if (media.Equals("video")) { regexps = g_advancedSettings.m_videoExcludeFromListingRegExps; extensions = g_settings.m_videoExtensions; } else if (media.Equals("music")) { regexps = g_advancedSettings.m_audioExcludeFromListingRegExps; extensions = g_settings.m_musicExtensions; } else if (media.Equals("pictures")) { regexps = g_advancedSettings.m_pictureExcludeFromListingRegExps; extensions = g_settings.m_pictureExtensions; } CDirectory directory; if (directory.GetDirectory(strPath, items, extensions)) { items.Sort(SORT_METHOD_FILE, SortOrderAscending); CFileItemList filteredDirectories; for (unsigned int i = 0; i < (unsigned int)items.Size(); i++) { if (CUtil::ExcludeFileOrFolder(items[i]->GetPath(), regexps)) continue; if (items[i]->m_bIsFolder) filteredDirectories.Add(items[i]); else if ((media == "video" && items[i]->HasVideoInfoTag()) || (media == "music" && items[i]->HasMusicInfoTag())) list.Add(items[i]); else { CFileItem fileItem; if (FillFileItem(items[i], fileItem, media)) list.Add(CFileItemPtr(new CFileItem(fileItem))); else if (media == "files") list.Add(items[i]); } } if (parameterObject.isMember("recursive") && parameterObject["recursive"].isBoolean()) { for (int i = 0; i < filteredDirectories.Size(); i++) { CVariant val = parameterObject; val["directory"] = filteredDirectories[i]->GetPath(); FillFileItemList(val, list); } } return true; } } } return false; }
void CPictureThumbLoader::ProcessFoldersAndArchives(CFileItem *pItem) { if (pItem->HasThumbnail()) return; CTextureDatabase db; db.Open(); if (pItem->IsCBR() || pItem->IsCBZ()) { CStdString strTBN(URIUtils::ReplaceExtension(pItem->GetPath(),".tbn")); if (CFile::Exists(strTBN)) { db.SetTextureForPath(pItem->GetPath(), "thumb", strTBN); CTextureCache::Get().BackgroundCacheImage(strTBN); pItem->SetThumbnailImage(strTBN); return; } } if ((pItem->m_bIsFolder || pItem->IsCBR() || pItem->IsCBZ()) && !pItem->m_bIsShareOrDrive && !pItem->IsParentFolder()) { // first check for a folder.jpg CStdString thumb = "folder.jpg"; CStdString strPath = pItem->GetPath(); if (pItem->IsCBR()) { URIUtils::CreateArchivePath(strPath,"rar",pItem->GetPath(),""); thumb = "cover.jpg"; } if (pItem->IsCBZ()) { URIUtils::CreateArchivePath(strPath,"zip",pItem->GetPath(),""); thumb = "cover.jpg"; } if (pItem->IsMultiPath()) strPath = CMultiPathDirectory::GetFirstPath(pItem->GetPath()); thumb = URIUtils::AddFileToFolder(strPath, thumb); if (CFile::Exists(thumb)) { db.SetTextureForPath(pItem->GetPath(), "thumb", thumb); CTextureCache::Get().BackgroundCacheImage(thumb); pItem->SetThumbnailImage(thumb); return; } if (!pItem->IsPlugin()) { // we load the directory, grab 4 random thumb files (if available) and then generate // the thumb. CFileItemList items; CDirectory::GetDirectory(strPath, items, g_settings.m_pictureExtensions, DIR_FLAG_NO_FILE_DIRS); // create the folder thumb by choosing 4 random thumbs within the folder and putting // them into one thumb. // count the number of images for (int i=0; i < items.Size();) { if (!items[i]->IsPicture() || items[i]->IsZIP() || items[i]->IsRAR() || items[i]->IsPlayList()) { items.Remove(i); } else i++; } if (items.IsEmpty()) { if (pItem->IsCBZ() || pItem->IsCBR()) { CDirectory::GetDirectory(strPath, items, g_settings.m_pictureExtensions, DIR_FLAG_NO_FILE_DIRS); for (int i=0;i<items.Size();++i) { CFileItemPtr item = items[i]; if (item->m_bIsFolder) { ProcessFoldersAndArchives(item.get()); pItem->SetThumbnailImage(items[i]->GetThumbnailImage()); pItem->SetIconImage(items[i]->GetIconImage()); return; } } } return; // no images in this folder } // randomize them items.Randomize(); if (items.Size() < 4 || pItem->IsCBR() || pItem->IsCBZ()) { // less than 4 items, so just grab the first thumb items.Sort(SORT_METHOD_LABEL, SORT_ORDER_ASC); CStdString thumb = CTextureCache::GetWrappedThumbURL(items[0]->GetPath()); db.SetTextureForPath(pItem->GetPath(), "thumb", thumb); CTextureCache::Get().BackgroundCacheImage(thumb); pItem->SetThumbnailImage(thumb); } else { // ok, now we've got the files to get the thumbs from, lets create it... // we basically load the 4 images and combine them vector<string> files; for (int thumb = 0; thumb < 4; thumb++) files.push_back(items[thumb]->GetPath()); CStdString thumb = CTextureCache::GetWrappedImageURL(pItem->GetPath(), "picturefolder"); CStdString relativeCacheFile = CTextureCache::GetCacheFile(thumb) + ".png"; if (CPicture::CreateTiledThumb(files, CTextureCache::GetCachedPath(relativeCacheFile))) { CTextureDetails details; details.file = relativeCacheFile; details.width = g_advancedSettings.m_thumbSize; details.height = g_advancedSettings.m_thumbSize; CTextureCache::Get().AddCachedTexture(thumb, details); db.SetTextureForPath(pItem->GetPath(), "thumb", thumb); pItem->SetThumbnailImage(CTextureCache::GetCachedPath(relativeCacheFile)); } } } // refill in the icon to get it to update pItem->FillInDefaultIcon(); } }
/*! \brief Start playback of media. * \param params The parameters. * \details params[0] = URL to media to play (optional). * params[1,...] = "isdir" if media is a directory (optional). * params[1,...] = "1" to start playback in fullscreen (optional). * params[1,...] = "resume" to force resuming (optional). * params[1,...] = "noresume" to force not resuming (optional). * params[1,...] = "playoffset=<offset>" to start playback from a given position in a playlist (optional). */ static int PlayMedia(const std::vector<std::string>& params) { CFileItem item(params[0], false); if (URIUtils::HasSlashAtEnd(params[0])) item.m_bIsFolder = true; // restore to previous window if needed if( CServiceBroker::GetGUI()->GetWindowManager().GetActiveWindow() == WINDOW_SLIDESHOW || CServiceBroker::GetGUI()->GetWindowManager().GetActiveWindow() == WINDOW_FULLSCREEN_VIDEO || CServiceBroker::GetGUI()->GetWindowManager().GetActiveWindow() == WINDOW_FULLSCREEN_GAME || CServiceBroker::GetGUI()->GetWindowManager().GetActiveWindow() == WINDOW_VISUALISATION ) CServiceBroker::GetGUI()->GetWindowManager().PreviousWindow(); // reset screensaver g_application.ResetScreenSaver(); g_application.WakeUpScreenSaverAndDPMS(); // ask if we need to check guisettings to resume bool askToResume = true; int playOffset = 0; for (unsigned int i = 1 ; i < params.size() ; i++) { if (StringUtils::EqualsNoCase(params[i], "isdir")) item.m_bIsFolder = true; else if (params[i] == "1") // set fullscreen or windowed CMediaSettings::GetInstance().SetVideoStartWindowed(true); else if (StringUtils::EqualsNoCase(params[i], "resume")) { // force the item to resume (if applicable) (see CApplication::PlayMedia) item.m_lStartOffset = STARTOFFSET_RESUME; askToResume = false; } else if (StringUtils::EqualsNoCase(params[i], "noresume")) { // force the item to start at the beginning (m_lStartOffset is initialized to 0) askToResume = false; } else if (StringUtils::StartsWithNoCase(params[i], "playoffset=")) { playOffset = atoi(params[i].substr(11).c_str()) - 1; item.SetProperty("playlist_starting_track", playOffset); } } if (!item.m_bIsFolder && item.IsPlugin()) item.SetProperty("IsPlayable", true); if ( askToResume == true ) { if ( CGUIWindowVideoBase::ShowResumeMenu(item) == false ) return false; } if (item.m_bIsFolder) { CFileItemList items; std::string extensions = CServiceBroker::GetFileExtensionProvider().GetVideoExtensions() + "|" + CServiceBroker::GetFileExtensionProvider().GetMusicExtensions(); XFILE::CDirectory::GetDirectory(item.GetPath(), items, extensions, XFILE::DIR_FLAG_DEFAULTS); bool containsMusic = false, containsVideo = false; for (int i = 0; i < items.Size(); i++) { bool isVideo = items[i]->IsVideo(); containsMusic |= !isVideo; containsVideo |= isVideo; if (containsMusic && containsVideo) break; } std::unique_ptr<CGUIViewState> state(CGUIViewState::GetViewState(containsVideo ? WINDOW_VIDEO_NAV : WINDOW_MUSIC_NAV, items)); if (state.get()) items.Sort(state->GetSortMethod()); else items.Sort(SortByLabel, SortOrderAscending); int playlist = containsVideo? PLAYLIST_VIDEO : PLAYLIST_MUSIC;; if (containsMusic && containsVideo) //mixed content found in the folder { for (int i = items.Size() - 1; i >= 0; i--) //remove music entries { if (!items[i]->IsVideo()) items.Remove(i); } } CServiceBroker::GetPlaylistPlayer().ClearPlaylist(playlist); CServiceBroker::GetPlaylistPlayer().Add(playlist, items); CServiceBroker::GetPlaylistPlayer().SetCurrentPlaylist(playlist); CServiceBroker::GetPlaylistPlayer().Play(playOffset, ""); } else if (item.IsAudio() || item.IsVideo()) CServiceBroker::GetPlaylistPlayer().Play(std::make_shared<CFileItem>(item), ""); else g_application.PlayMedia(item, "", PLAYLIST_NONE); return 0; }