bool CGUIControlButtonSetting::GetPath(CSettingPath *pathSetting) { if (pathSetting == NULL) return false; CStdString path = pathSetting->GetValue(); VECSOURCES shares; const std::vector<std::string>& sources = pathSetting->GetSources(); for (std::vector<std::string>::const_iterator source = sources.begin(); source != sources.end(); ++source) { VECSOURCES *sources = CMediaSourceSettings::Get().GetSources(*source); if (sources != NULL) shares.insert(shares.end(), sources->begin(), sources->end()); } g_mediaManager.GetNetworkLocations(shares); g_mediaManager.GetLocalDrives(shares); if (!CGUIDialogFileBrowser::ShowAndGetDirectory(shares, g_localizeStrings.Get(pathSetting->GetHeading()), path, pathSetting->Writable())) return false; return pathSetting->SetValue(path); }
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 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(); }
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 == CSmartPlaylistRule::FIELD_GENRE) { 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("mixed")) database.GetGenresNav("musicdb://4/",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 == CSmartPlaylistRule::FIELD_COUNTRY) { videodatabase.GetCountriesNav("videodb://2/1/",items,type); iLabel = 574; } else if (m_rule.m_field == CSmartPlaylistRule::FIELD_ARTIST || m_rule.m_field == CSmartPlaylistRule::FIELD_ALBUMARTIST) { if (m_type.Equals("songs") || m_type.Equals("mixed") || m_type.Equals("albums")) database.GetArtistsNav("musicdb://5/",items,-1,m_rule.m_field == CSmartPlaylistRule::FIELD_ALBUMARTIST); 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 == CSmartPlaylistRule::FIELD_ALBUM) { if (m_type.Equals("songs") || m_type.Equals("mixed") || m_type.Equals("albums")) database.GetAlbumsNav("musicdb://6/",items,-1,-1,-1,-1); 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 == CSmartPlaylistRule::FIELD_ACTOR) { videodatabase.GetActorsNav("",items,type); iLabel = 20337; } else if (m_rule.m_field == CSmartPlaylistRule::FIELD_DIRECTOR) { videodatabase.GetDirectorsNav("",items,type); iLabel = 20339; } else if (m_rule.m_field == CSmartPlaylistRule::FIELD_STUDIO) { videodatabase.GetStudiosNav("",items,type); iLabel = 572; } else if (m_rule.m_field == CSmartPlaylistRule::FIELD_WRITER) { videodatabase.GetWritersNav("",items,type); iLabel = 20417; } else if (m_rule.m_field == CSmartPlaylistRule::FIELD_TVSHOWTITLE) { videodatabase.GetTvShowsNav("",items); iLabel = 20343; } else if (m_rule.m_field == CSmartPlaylistRule::FIELD_PLAYLIST) { // 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",false,false,XFILE::DIR_CACHE_ONCE,true,true); iLabel = 559; } else if (m_rule.m_field == CSmartPlaylistRule::FIELD_PATH) { 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); CGUIDialogFileBrowser::ShowAndGetDirectory(sources,g_localizeStrings.Get(657),m_rule.m_parameter,false); UpdateButtons(); return; } else { // TODO: Add browseability in here. assert(false); } // sort the items items.Sort(SORT_METHOD_LABEL, SORT_ORDER_ASC); 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->DoModal(); if (pDialog->GetSelectedLabel() > -1) { m_rule.m_parameter = pDialog->GetSelectedLabelText(); UpdateButtons(); } pDialog->Reset(); }
bool CGUIDialogFileBrowser::ShowAndGetSource(std::string &path, bool allowNetworkShares, VECSOURCES* additionalShare /* = NULL */, const std::string& strType /* = "" */) { // Technique is // 1. Show Filebrowser with currently defined local, and optionally the network locations. // 2. Have the "Add Network Location" option in addition. // 3a. If the "Add Network Location" is pressed, then: // a) Fire up the network location dialog to grab the new location // b) Check the location by doing a GetDirectory() - if it fails, prompt the user // to allow them to add currently disconnected network shares. // c) Save this location to our xml file (network.xml) // d) Return to 1. // 3b. If the "Add Source" is pressed, then: // a) Fire up the media source dialog to add the new location // 4. Optionally allow user to browse the local and network locations for their share. // 5. On OK, return. // Create a new filebrowser window CGUIDialogFileBrowser *browser = new CGUIDialogFileBrowser(); if (!browser) return false; // Add it to our window manager CServiceBroker::GetGUI()->GetWindowManager().AddUniqueInstance(browser); VECSOURCES shares; if (!strType.empty()) { if (additionalShare) shares = *additionalShare; browser->m_addSourceType = strType; } else { browser->SetHeading(g_localizeStrings.Get(1023)); g_mediaManager.GetLocalDrives(shares); // Now the additional share if appropriate if (additionalShare) { shares.insert(shares.end(),additionalShare->begin(),additionalShare->end()); } // Now add the network shares... if (allowNetworkShares) { g_mediaManager.GetNetworkLocations(shares); } } browser->SetSources(shares); browser->m_rootDir.SetMask("/"); browser->m_rootDir.AllowNonLocalSources(false); // don't allow plug n play shares browser->m_browsingForFolders = 1; browser->m_addNetworkShareEnabled = allowNetworkShares; browser->m_selectedPath = ""; browser->Open(); bool confirmed = browser->IsConfirmed(); if (confirmed) path = browser->m_selectedPath; CServiceBroker::GetGUI()->GetWindowManager().Remove(browser->GetID()); delete browser; return confirmed; }
void CAndroidStorageProvider::GetRemovableDrives(VECSOURCES &removableDrives) { // Uses non-public API: be extra carefull bool inError = false; VECSOURCES droidDrives; CJNIStorageManager manager(CJNIContext::getSystemService("storage")); if (xbmc_jnienv()->ExceptionCheck()) { xbmc_jnienv()->ExceptionClear(); inError = true; } if (!inError) { CJNIStorageVolumes vols = manager.getVolumeList(); if (xbmc_jnienv()->ExceptionCheck()) { xbmc_jnienv()->ExceptionClear(); inError = true; } if (!inError) { for (auto vol : vols) { // CLog::Log(LOGDEBUG, "-- Volume: %s(%s) -- %s", vol.getPath().c_str(), vol.getUserLabel().c_str(), vol.getState().c_str()); bool removable = vol.isRemovable(); if (xbmc_jnienv()->ExceptionCheck()) { xbmc_jnienv()->ExceptionClear(); inError = true; break; } std::string state = vol.getState(); if (xbmc_jnienv()->ExceptionCheck()) { xbmc_jnienv()->ExceptionClear(); inError = true; break; } if (removable && state == CJNIEnvironment::MEDIA_MOUNTED) { CMediaSource share; share.strPath = vol.getPath(); if (xbmc_jnienv()->ExceptionCheck()) { xbmc_jnienv()->ExceptionClear(); inError = true; break; } share.strName = vol.getUserLabel(); if (xbmc_jnienv()->ExceptionCheck()) { xbmc_jnienv()->ExceptionClear(); inError = true; break; } StringUtils::Trim(share.strName); if (share.strName.empty() || share.strName == "?" || StringUtils::CompareNoCase(share.strName, "null") == 0) share.strName = URIUtils::GetFileName(share.strPath); share.m_ignore = true; droidDrives.push_back(share); } } } } if (!inError) removableDrives.insert(removableDrives.end(), droidDrives.begin(), droidDrives.end()); else { for (const auto& mountStr : GetRemovableDrivesLinux()) { // Reject unreadable if (XFILE::CDirectory::Exists(mountStr)) { CMediaSource share; share.strPath = unescape(mountStr); share.strName = URIUtils::GetFileName(mountStr); share.m_ignore = true; removableDrives.push_back(share); } } } }