bool CVideoDatabaseDirectory::GetDirectory(const CURL& url, CFileItemList &items) { std::string path = CLegacyPathTranslation::TranslateVideoDbPath(url); items.SetPath(path); items.m_dwSize = -1; // No size std::unique_ptr<CDirectoryNode> pNode(CDirectoryNode::ParseURL(path)); if (!pNode.get()) return false; bool bResult = pNode->GetChilds(items); for (int i=0;i<items.Size();++i) { CFileItemPtr item = items[i]; if (item->m_bIsFolder && !item->HasIcon() && !item->HasArt("thumb")) { std::string strImage = GetIcon(item->GetPath()); if (!strImage.empty() && g_TextureManager.HasTexture(strImage)) item->SetIconImage(strImage); } if (item->GetVideoInfoTag()) { item->SetDynPath(item->GetVideoInfoTag()->GetPath()); } } items.SetLabel(pNode->GetLocalizedName()); return bResult; }
bool CGUIWindowMusicNav::GetSongsFromPlayList(const CStdString& strPlayList, CFileItemList &items) { CStdString strParentPath=m_history.GetParentPath(); if (m_guiState.get() && !m_guiState->HideParentDirItems()) { CFileItemPtr pItem(new CFileItem("..")); pItem->SetPath(strParentPath); items.Add(pItem); } items.SetPath(strPlayList); CLog::Log(LOGDEBUG,"CGUIWindowMusicNav, opening playlist [%s]", strPlayList.c_str()); auto_ptr<CPlayList> pPlayList (CPlayListFactory::Create(strPlayList)); if ( NULL != pPlayList.get()) { // load it if (!pPlayList->Load(strPlayList)) { CGUIDialogOK::ShowAndGetInput(6, 0, 477, 0); return false; //hmmm unable to load playlist? } CPlayList playlist = *pPlayList; // convert playlist items to songs for (int i = 0; i < (int)playlist.size(); ++i) { items.Add(playlist[i]); } } return true; }
bool CGUIWindowMusicNav::GetSongsFromPlayList(const std::string& strPlayList, CFileItemList &items) { std::string strParentPath=m_history.GetParentPath(); if (m_guiState.get() && !m_guiState->HideParentDirItems()) { CFileItemPtr pItem(new CFileItem("..")); pItem->SetPath(strParentPath); items.Add(pItem); } items.SetPath(strPlayList); CLog::Log(LOGDEBUG,"CGUIWindowMusicNav, opening playlist [%s]", strPlayList.c_str()); std::unique_ptr<CPlayList> pPlayList (CPlayListFactory::Create(strPlayList)); if ( NULL != pPlayList.get()) { // load it if (!pPlayList->Load(strPlayList)) { HELPERS::ShowOKDialogText(CVariant{6}, CVariant{477}); return false; //hmmm unable to load playlist? } CPlayList playlist = *pPlayList; // convert playlist items to songs for (int i = 0; i < playlist.size(); ++i) { items.Add(playlist[i]); } } return true; }
bool CGUIWindowMusicPlaylistEditor::GetDirectory(const std::string &strDirectory, CFileItemList &items) { items.Clear(); if (strDirectory.empty()) { // root listing - list files:// and musicdb:// CFileItemPtr files(new CFileItem("files://", true)); files->SetLabel(g_localizeStrings.Get(744)); files->SetLabelPreformated(true); files->m_bIsShareOrDrive = true; items.Add(files); CFileItemPtr db(new CFileItem("musicdb://", true)); db->SetLabel(g_localizeStrings.Get(14022)); db->SetLabelPreformated(true); db->m_bIsShareOrDrive = true; items.SetPath(""); items.Add(db); return true; } if (!CGUIWindowMusicBase::GetDirectory(strDirectory, items)) return false; // check for .CUE files here. items.FilterCueItems(); return true; }
bool CMusicSearchDirectory::GetDirectory(const CStdString& strPath, CFileItemList &items) { // break up our path // format is: musicsearch://<url encoded search string> CURL url(strPath); CStdString search(url.GetHostName()); if (search.IsEmpty()) return false; // and retrieve the search details items.SetPath(strPath); //spotify perform a search in spotify. //TODO search all addons providing search functionality g_spotify->Search(search, items); unsigned int time = XbmcThreads::SystemClockMillis(); CMusicDatabase db; db.Open(); db.Search(search, items); db.Close(); CLog::Log(LOGDEBUG, "%s (%s) took %u ms", __FUNCTION__, strPath.c_str(), XbmcThreads::SystemClockMillis() - time); items.SetLabel(g_localizeStrings.Get(137)); // Search return true; }
void CGUIWindowPVRRecordings::AfterUpdate(CFileItemList& items) { if (!items.IsEmpty()) { CFileItemList files; for (int i = 0; i < items.Size(); i++) { CFileItemPtr pItem = items[i]; if (!pItem->m_bIsFolder) files.Add(pItem); } if (!files.IsEmpty()) { files.SetPath(items.GetPath()); if(m_database.Open()) { if (g_PVRRecordings->HasAllRecordingsPathExtension(files.GetPath())) { // Build a map of all files belonging to common subdirectories and call // LoadVideoInfo for each item list typedef boost::shared_ptr<CFileItemList> CFileItemListPtr; typedef std::map<CStdString, CFileItemListPtr> DirectoryMap; DirectoryMap directory_map; for (int i = 0; i < files.Size(); i++) { CStdString strDirectory = URIUtils::GetDirectory(files[i]->GetPath()); DirectoryMap::iterator it = directory_map.find(strDirectory); if (it == directory_map.end()) it = directory_map.insert(std::make_pair( strDirectory, CFileItemListPtr(new CFileItemList(strDirectory)))).first; it->second->Add(files[i]); } for (DirectoryMap::iterator it = directory_map.begin(); it != directory_map.end(); it++) CGUIWindowVideoNav::LoadVideoInfo(*it->second, m_database, false); } else CGUIWindowVideoNav::LoadVideoInfo(files, m_database, false); m_database.Close(); } m_thumbLoader.Load(files); } } }
bool CSpecialProtocolDirectory::GetDirectory(const CStdString& strPath, CFileItemList &items) { CStdString untranslatedPath = strPath; // Why do I need a copy??? - the GetDirectory() call below will override strPath??? CStdString translatedPath = CSpecialProtocol::TranslatePath(strPath); if (CDirectory::GetDirectory(translatedPath, items, m_strFileMask, m_flags | DIR_FLAG_GET_HIDDEN)) { // replace our paths as necessary items.SetPath(untranslatedPath); for (int i = 0; i < items.Size(); i++) { CFileItemPtr item = items[i]; if (strnicmp(item->GetPath().c_str(), translatedPath.c_str(), translatedPath.GetLength()) == 0) item->SetPath(URIUtils::AddFileToFolder(untranslatedPath, item->GetPath().Mid(translatedPath.GetLength()))); } return true; } return false; }
bool CVirtualDirectory::GetDirectory(const CStdString& strPath, CFileItemList &items, bool bUseFileDirectories) { if (!strPath.IsEmpty() && strPath != "files://") return CDirectory::GetDirectory(strPath, items, m_strFileMask, bUseFileDirectories, m_allowPrompting, m_cacheDirectory, m_extFileInfo, m_allowThreads); // if strPath is blank, clear the list (to avoid parent items showing up) if (strPath.IsEmpty()) items.Clear(); // return the root listing items.SetPath(strPath); // grab our shares VECSOURCES shares; GetSources(shares); CSourcesDirectory dir; return dir.GetDirectory(shares, items); }
bool CGUIWindowAddonBrowser::GetDirectory(const CStdString& strDirectory, CFileItemList& items) { bool result; if (strDirectory.Equals("addons://downloading/")) { VECADDONS addons; CAddonInstaller::Get().GetInstallList(addons); CURL url(strDirectory); CAddonsDirectory::GenerateListing(url,addons,items); result = true; items.SetProperty("reponame",g_localizeStrings.Get(24067)); items.SetPath(strDirectory); if (m_guiState.get() && !m_guiState->HideParentDirItems()) { CFileItemPtr pItem(new CFileItem("..")); pItem->SetPath(m_history.GetParentPath()); pItem->m_bIsFolder = true; pItem->m_bIsShareOrDrive = false; items.AddFront(pItem, 0); } } else result = CGUIMediaWindow::GetDirectory(strDirectory,items); if (strDirectory.IsEmpty() && CAddonInstaller::Get().IsDownloading()) { CFileItemPtr item(new CFileItem("addons://downloading/",true)); item->SetLabel(g_localizeStrings.Get(24067)); item->SetLabelPreformated(true); item->SetIconImage("DefaultNetwork.png"); items.Add(item); } items.SetContent("addons"); for (int i=0;i<items.Size();++i) SetItemLabel2(items[i]); return result; }
bool CDirectoryNodeSeasons::GetContent(CFileItemList& items) const { CVideoDatabase videodatabase; if (!videodatabase.Open()) return false; CQueryParams params; CollectQueryParams(params); int iFlatten = CSettings::Get().GetInt("videolibrary.flattentvshows"); bool bSuccess=videodatabase.GetSeasonsNav(BuildPath(), items, params.GetActorId(), params.GetDirectorId(), params.GetGenreId(), params.GetYear(), params.GetTvShowId()); bool bFlatten = (items.GetObjectCount() == 1 && iFlatten == 1) || iFlatten == 2; if (items.GetObjectCount() == 2 && iFlatten == 1) if (items[0]->GetVideoInfoTag()->m_iSeason == 0 || items[1]->GetVideoInfoTag()->m_iSeason == 0) bFlatten = true; // flatten if one season + specials if (iFlatten > 0 && !bFlatten && CMediaSettings::Get().GetWatchedMode("tvshows") == WatchedModeUnwatched) { int count = 0; for(int i = 0; i < items.Size(); i++) { if (items[i]->GetProperty("unwatchedepisodes").asInteger() != 0 && items[i]->GetVideoInfoTag()->m_iSeason != 0) count++; } bFlatten = (count < 2); // flatten if there is only 1 unwatched season (not counting specials) } if (bFlatten) { // flatten if one season or flatten always items.Clear(); CVideoDbUrl videoUrl; if (!videoUrl.FromString(BuildPath())) return false; videoUrl.AppendPath("-2/"); bSuccess=videodatabase.GetEpisodesNav(videoUrl.ToString(), items, params.GetGenreId(), params.GetYear(), params.GetActorId(), params.GetDirectorId(), params.GetTvShowId()); items.SetPath(videoUrl.ToString()); } videodatabase.Close(); return bSuccess; }
bool CVirtualDirectory::GetDirectory(const CStdString& strPath, CFileItemList &items, bool bUseFileDirectories) { int flags = m_flags; if (!bUseFileDirectories) flags |= DIR_FLAG_NO_FILE_DIRS; if (!strPath.IsEmpty() && strPath != "files://") return CDirectory::GetDirectory(strPath, items, m_strFileMask, flags, m_allowThreads); // if strPath is blank, clear the list (to avoid parent items showing up) if (strPath.IsEmpty()) items.Clear(); // return the root listing items.SetPath(strPath); // grab our shares VECSOURCES shares; GetSources(shares); CSourcesDirectory dir; return dir.GetDirectory(shares, items); }
bool CVFSEntry::ContainsFiles(const CURL& url, CFileItemList& items) { if (!m_struct.toAddon.contains_files || !m_struct.toAddon.free_directory) return false; VFSDirEntry* entries = nullptr; int num_entries = 0; CVFSURLWrapper url2(url); char rootpath[ADDON_STANDARD_STRING_LENGTH]; rootpath[0] = 0; bool ret = m_struct.toAddon.contains_files(&m_struct, &url2.url, &entries, &num_entries, rootpath); if (!ret) return false; VFSDirEntriesToCFileItemList(num_entries, entries, items); m_struct.toAddon.free_directory(&m_struct, entries, num_entries); if (strlen(rootpath)) items.SetPath(rootpath); return true; }
bool CMusicDatabaseDirectory::GetDirectory(const CStdString& strPath, CFileItemList &items) { CStdString path = CLegacyPathTranslation::TranslateMusicDbPath(strPath); items.SetPath(path); auto_ptr<CDirectoryNode> pNode(CDirectoryNode::ParseURL(path)); if (!pNode.get()) return false; bool bResult = pNode->GetChilds(items); for (int i=0;i<items.Size();++i) { CFileItemPtr item = items[i]; if (item->m_bIsFolder && !item->HasIcon() && !item->HasArt("thumb")) { CStdString strImage = GetIcon(item->GetPath()); if (!strImage.IsEmpty() && g_TextureManager.HasTexture(strImage)) item->SetIconImage(strImage); } } items.SetLabel(pNode->GetLocalizedName()); return bResult; }
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; }
bool CGUIMediaWindow::OnMessage(CGUIMessage& message) { switch ( message.GetMessage() ) { case GUI_MSG_WINDOW_DEINIT: { m_iSelectedItem = m_viewControl.GetSelectedItem(); m_iLastControl = GetFocusedControlID(); CGUIWindow::OnMessage(message); // Call ClearFileItems() after our window has finished doing any WindowClose // animations ClearFileItems(); return true; } break; case GUI_MSG_CLICKED: { int iControl = message.GetSenderId(); if (iControl == CONTROL_BTNVIEWASICONS) { // view as control could be a select button int viewMode = 0; const CGUIControl *control = GetControl(CONTROL_BTNVIEWASICONS); if (control && control->GetControlType() != CGUIControl::GUICONTROL_BUTTON) { CGUIMessage msg(GUI_MSG_ITEM_SELECTED, GetID(), CONTROL_BTNVIEWASICONS); OnMessage(msg); viewMode = m_viewControl.GetViewModeNumber(msg.GetParam1()); } else viewMode = m_viewControl.GetNextViewMode(); if (m_guiState.get()) m_guiState->SaveViewAsControl(viewMode); UpdateButtons(); return true; } else if (iControl == CONTROL_BTNSORTASC) // sort asc { if (m_guiState.get()) m_guiState->SetNextSortOrder(); UpdateFileList(); return true; } else if (iControl == CONTROL_BTNSORTBY) // sort by { if (m_guiState.get()) m_guiState->SetNextSortMethod(); UpdateFileList(); return true; } else if (iControl == CONTROL_BTN_FILTER) { if (GetControl(iControl)->GetControlType() == CGUIControl::GUICONTROL_EDIT) { // filter updated CGUIMessage selected(GUI_MSG_ITEM_SELECTED, GetID(), CONTROL_BTN_FILTER); OnMessage(selected); OnFilterItems(selected.GetLabel()); return true; } if (GetProperty("filter").empty()) { CStdString filter = GetProperty("filter").asString(); CGUIDialogKeyboard::ShowAndGetFilter(filter, false); SetProperty("filter", filter); } else OnFilterItems(""); return true; } else if (m_viewControl.HasControl(iControl)) // list/thumb control { int iItem = m_viewControl.GetSelectedItem(); int iAction = message.GetParam1(); if (iItem < 0) break; if (iAction == ACTION_SELECT_ITEM || iAction == ACTION_MOUSE_LEFT_CLICK) { OnSelect(iItem); } else if (iAction == ACTION_CONTEXT_MENU || iAction == ACTION_MOUSE_RIGHT_CLICK) { OnPopupMenu(iItem); return true; } } } break; case GUI_MSG_SETFOCUS: { if (m_viewControl.HasControl(message.GetControlId()) && m_viewControl.GetCurrentControl() != message.GetControlId()) { m_viewControl.SetFocused(); return true; } } break; case GUI_MSG_NOTIFY_ALL: { // Message is received even if this window is inactive if (message.GetParam1() == GUI_MSG_WINDOW_RESET) { m_vecItems->SetPath("?"); return true; } else if ( message.GetParam1() == GUI_MSG_REFRESH_THUMBS ) { for (int i = 0; i < m_vecItems->Size(); i++) m_vecItems->Get(i)->FreeMemory(true); break; // the window will take care of any info images } else if (message.GetParam1() == GUI_MSG_REMOVED_MEDIA) { if ((m_vecItems->IsVirtualDirectoryRoot() || m_vecItems->IsSourcesPath()) && IsActive()) { int iItem = m_viewControl.GetSelectedItem(); Update(m_vecItems->GetPath()); m_viewControl.SetSelectedItem(iItem); } else if (m_vecItems->IsRemovable()) { // check that we have this removable share still if (!m_rootDir.IsInSource(m_vecItems->GetPath())) { // don't have this share any more if (IsActive()) Update(""); else { m_history.ClearPathHistory(); m_vecItems->SetPath(""); } } } return true; } else if (message.GetParam1()==GUI_MSG_UPDATE_SOURCES) { // State of the sources changed, so update our view if ((m_vecItems->IsVirtualDirectoryRoot() || m_vecItems->IsSourcesPath()) && IsActive()) { int iItem = m_viewControl.GetSelectedItem(); Update(m_vecItems->GetPath()); m_viewControl.SetSelectedItem(iItem); } return true; } else if (message.GetParam1()==GUI_MSG_UPDATE && IsActive()) { if (message.GetNumStringParams()) { m_vecItems->SetPath(message.GetStringParam()); if (message.GetParam2()) // param2 is used for resetting the history SetHistoryForPath(m_vecItems->GetPath()); } // clear any cached listing m_vecItems->RemoveDiscCache(GetID()); Update(m_vecItems->GetPath()); } else if (message.GetParam1()==GUI_MSG_UPDATE_ITEM && message.GetItem()) { CFileItemPtr newItem = boost::static_pointer_cast<CFileItem>(message.GetItem()); if (IsActive()) { if (m_vecItems->UpdateItem(newItem.get()) && message.GetParam2() == 1) { // need the list updated as well UpdateFileList(); } } else if (newItem) { // need to remove the disc cache CFileItemList items; CStdString path; URIUtils::GetDirectory(newItem->GetPath(), path); items.SetPath(path); items.RemoveDiscCache(GetID()); } } else if (message.GetParam1()==GUI_MSG_UPDATE_PATH) { if (IsActive()) { if((message.GetStringParam() == m_vecItems->GetPath()) || (m_vecItems->IsMultiPath() && XFILE::CMultiPathDirectory::HasPath(m_vecItems->GetPath(), message.GetStringParam()))) { Update(m_vecItems->GetPath()); } } } else if (message.GetParam1() == GUI_MSG_FILTER_ITEMS && IsActive()) { CStdString filter(GetProperty("filter").asString()); if (message.GetParam2() == 1) // append filter += message.GetStringParam(); else if (message.GetParam2() == 2) { // delete if (filter.size()) filter = filter.Left(filter.size() - 1); } else filter = message.GetStringParam(); OnFilterItems(filter); return true; } else return CGUIWindow::OnMessage(message); return true; } break; case GUI_MSG_PLAYBACK_STARTED: case GUI_MSG_PLAYBACK_ENDED: case GUI_MSG_PLAYBACK_STOPPED: case GUI_MSG_PLAYLIST_CHANGED: case GUI_MSG_PLAYLISTPLAYER_STOPPED: case GUI_MSG_PLAYLISTPLAYER_STARTED: case GUI_MSG_PLAYLISTPLAYER_CHANGED: { // send a notify all to all controls on this window CGUIMessage msg(GUI_MSG_NOTIFY_ALL, GetID(), 0, GUI_MSG_REFRESH_LIST); OnMessage(msg); break; } case GUI_MSG_CHANGE_VIEW_MODE: { int viewMode = 0; if (message.GetParam1()) // we have an id viewMode = m_viewControl.GetViewModeByID(message.GetParam1()); else if (message.GetParam2()) viewMode = m_viewControl.GetNextViewMode((int)message.GetParam2()); if (m_guiState.get()) m_guiState->SaveViewAsControl(viewMode); UpdateButtons(); return true; } break; case GUI_MSG_CHANGE_SORT_METHOD: { if (m_guiState.get()) { if (message.GetParam1()) m_guiState->SetCurrentSortMethod((int)message.GetParam1()); else if (message.GetParam2()) m_guiState->SetNextSortMethod((int)message.GetParam2()); } UpdateFileList(); return true; } break; case GUI_MSG_CHANGE_SORT_DIRECTION: { if (m_guiState.get()) m_guiState->SetNextSortOrder(); UpdateFileList(); return true; } break; case GUI_MSG_WINDOW_INIT: { if (m_vecItems->GetPath() == "?") m_vecItems->SetPath(""); CStdString dir = message.GetStringParam(0); const CStdString &ret = message.GetStringParam(1); bool returning = ret.CompareNoCase("return") == 0; if (!dir.IsEmpty()) { m_history.ClearPathHistory(); // ensure our directory is valid dir = GetStartFolder(dir); if (!returning || m_vecItems->GetPath().Left(dir.GetLength()) != dir) { // we're not returning to the same path, so set our directory to the requested path m_vecItems->SetPath(dir); } // check for network up if (URIUtils::IsRemote(m_vecItems->GetPath()) && !WaitForNetwork()) m_vecItems->SetPath(""); SetHistoryForPath(m_vecItems->GetPath()); } if (message.GetParam1() != WINDOW_INVALID) { // first time to this window - make sure we set the root path m_startDirectory = returning ? dir : ""; } } break; } return CGUIWindow::OnMessage(message); }
bool CDirectory::GetDirectory(const CStdString& strPath, CFileItemList &items, const CHints &hints, bool allowThreads) { try { CStdString realPath = URIUtils::SubstitutePath(strPath); boost::shared_ptr<IDirectory> pDirectory(CDirectoryFactory::Create(realPath)); if (!pDirectory.get()) return false; // check our cache for this path if (g_directoryCache.GetDirectory(realPath, items, (hints.flags & DIR_FLAG_READ_CACHE) == DIR_FLAG_READ_CACHE)) items.SetPath(strPath); 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(realPath); pDirectory->SetFlags(hints.flags); bool result = false, cancel = false; while (!result && !cancel) { if (g_application.IsCurrentThread() && allowThreads && !URIUtils::IsSpecial(strPath)) { CSingleExit ex(g_graphicsContext); CGetDirectory get(pDirectory, realPath); if(!get.Wait(TIME_TO_BUSY_DIALOG)) { CGUIDialogBusy* dialog = (CGUIDialogBusy*)g_windowManager.GetWindow(WINDOW_DIALOG_BUSY); dialog->Show(); 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); } if(dialog) dialog->Close(); } result = get.GetDirectory(items); } else { items.SetPath(strPath); result = pDirectory->GetDirectory(realPath, items); } if (!result) { if (!cancel && g_application.IsCurrentThread() && pDirectory->ProcessRequirements()) continue; CLog::Log(LOGERROR, "%s - Error getting %s", __FUNCTION__, strPath.c_str()); return false; } } // cache the directory, if necessary if (!(hints.flags & DIR_FLAG_BYPASS_CACHE)) g_directoryCache.SetDirectory(realPath, items, pDirectory->GetCacheType(strPath)); } // now filter for allowed files pDirectory->SetMask(hints.mask); for (int i = 0; i < items.Size(); ++i) { CFileItemPtr item = items[i]; // TODO: we shouldn't be checking the gui setting here; // callers should use getHidden instead if ((!item->m_bIsFolder && !pDirectory->IsAllowed(item->GetPath())) || (item->GetProperty("file:hidden").asBoolean() && !(hints.flags & DIR_FLAG_GET_HIDDEN) && !CSettings::Get().GetBool("filelists.showhidden"))) { 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); return true; } XBMCCOMMONS_HANDLE_UNCHECKED catch (...) { CLog::Log(LOGERROR, "%s - Unhandled exception", __FUNCTION__); } CLog::Log(LOGERROR, "%s - Error getting %s", __FUNCTION__, strPath.c_str()); return false; }
bool CDirectory::GetDirectory(const CStdString& strPath, CFileItemList &items, CStdString strMask /*=""*/, bool bUseFileDirectories /* = true */, bool allowPrompting /* = false */, DIR_CACHE_TYPE cacheDirectory /* = DIR_CACHE_ONCE */, bool extFileInfo /* = true */, bool allowThreads /* = false */, bool getHidden /* = false */) { try { CStdString realPath = URIUtils::SubstitutePath(strPath); boost::shared_ptr<IDirectory> pDirectory(CFactoryDirectory::Create(realPath)); if (!pDirectory.get()) return false; // check our cache for this path if (g_directoryCache.GetDirectory(strPath, items, cacheDirectory == DIR_CACHE_ALWAYS)) items.SetPath(strPath); else { // need to clear the cache (in case the directory fetch fails) // and (re)fetch the folder if (cacheDirectory != DIR_CACHE_NEVER) g_directoryCache.ClearDirectory(strPath); pDirectory->SetAllowPrompting(allowPrompting); pDirectory->SetCacheDirectory(cacheDirectory); pDirectory->SetUseFileDirectories(bUseFileDirectories); pDirectory->SetExtFileInfo(extFileInfo); bool result = false, cancel = false; while (!result && !cancel) { if (g_application.IsCurrentThread() && allowThreads && !URIUtils::IsSpecial(strPath)) { CSingleExit ex(g_graphicsContext); CGetDirectory get(pDirectory, realPath); if(!get.Wait(TIME_TO_BUSY_DIALOG)) { CGUIDialogBusy* dialog = (CGUIDialogBusy*)g_windowManager.GetWindow(WINDOW_DIALOG_BUSY); dialog->Show(); while(!get.Wait(10)) { CSingleLock lock(g_graphicsContext); if(dialog->IsCanceled()) { cancel = true; break; } g_windowManager.ProcessRenderLoop(false); } if(dialog) dialog->Close(); } result = get.GetDirectory(items); } else { items.SetPath(strPath); result = pDirectory->GetDirectory(realPath, items); } if (!result) { if (!cancel && g_application.IsCurrentThread() && pDirectory->ProcessRequirements()) continue; CLog::Log(LOGERROR, "%s - Error getting %s", __FUNCTION__, strPath.c_str()); return false; } } // cache the directory, if necessary if (cacheDirectory != DIR_CACHE_NEVER) g_directoryCache.SetDirectory(strPath, items, pDirectory->GetCacheType(strPath)); } // now filter for allowed files pDirectory->SetMask(strMask); for (int i = 0; i < items.Size(); ++i) { CFileItemPtr item = items[i]; // TODO: we shouldn't be checking the gui setting here; // callers should use getHidden instead if ((!item->m_bIsFolder && !pDirectory->IsAllowed(item->GetPath())) || (item->GetPropertyBOOL("file:hidden") && !getHidden && !g_guiSettings.GetBool("filelists.showhidden"))) { 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 (bUseFileDirectories && !items.IsMusicDb() && !items.IsVideoDb() && !items.IsSmartPlayList()) FilterFileDirectories(items, strMask); return true; } #ifndef _LINUX catch (const win32_exception &e) { e.writelog(__FUNCTION__); } #endif catch (...) { CLog::Log(LOGERROR, "%s - Unhandled exception", __FUNCTION__); } CLog::Log(LOGERROR, "%s - Error getting %s", __FUNCTION__, strPath.c_str()); return false; }
bool CRSSDirectory::GetDirectory(const CURL& url, CFileItemList &items) { const std::string pathToUrl(url.Get()); std::string strPath(pathToUrl); URIUtils::RemoveSlashAtEnd(strPath); std::map<std::string,CDateTime>::iterator it; items.SetPath(strPath); CSingleLock lock(m_section); if ((it=m_cache.find(strPath)) != m_cache.end()) { if (it->second > CDateTime::GetCurrentDateTime() && items.Load()) return true; m_cache.erase(it); } lock.Leave(); CXBMCTinyXML xmlDoc; if (!xmlDoc.LoadFile(strPath)) { CLog::Log(LOGERROR,"failed to load xml from <%s>. error: <%d>", strPath.c_str(), xmlDoc.ErrorId()); return false; } if (xmlDoc.Error()) { CLog::Log(LOGERROR,"error parsing xml doc from <%s>. error: <%d>", strPath.c_str(), xmlDoc.ErrorId()); return false; } TiXmlElement* rssXmlNode = xmlDoc.RootElement(); if (!rssXmlNode) return false; TiXmlHandle docHandle( &xmlDoc ); TiXmlElement* channelXmlNode = docHandle.FirstChild( "rss" ).FirstChild( "channel" ).Element(); if (channelXmlNode) ParseItem(&items, channelXmlNode, pathToUrl); else return false; TiXmlElement* child = NULL; for (child = channelXmlNode->FirstChildElement("item"); child; child = child->NextSiblingElement()) { // Create new item, CFileItemPtr item(new CFileItem()); ParseItem(item.get(), child, pathToUrl); item->SetProperty("isrss", "1"); // Use channel image if item doesn't have one if (!item->HasArt("thumb") && items.HasArt("thumb")) item->SetArt("thumb", items.GetArt("thumb")); if (!item->GetPath().empty()) items.Add(item); } items.AddSortMethod(SortByNone , 231, LABEL_MASKS("%L", "%D", "%L", "")); // FileName, Duration | Foldername, empty items.AddSortMethod(SortByLabel , 551, LABEL_MASKS("%L", "%D", "%L", "")); // FileName, Duration | Foldername, empty items.AddSortMethod(SortBySize , 553, LABEL_MASKS("%L", "%I", "%L", "%I")); // FileName, Size | Foldername, Size items.AddSortMethod(SortByDate , 552, LABEL_MASKS("%L", "%J", "%L", "%J")); // FileName, Date | Foldername, Date CDateTime time = CDateTime::GetCurrentDateTime(); int mins = 60; TiXmlElement* ttl = docHandle.FirstChild("rss").FirstChild("ttl").Element(); if (ttl) mins = strtol(ttl->FirstChild()->Value(),NULL,10); time += CDateTimeSpan(0,0,mins,0); items.SetPath(strPath); items.Save(); CSingleLock lock2(m_section); m_cache.insert(make_pair(strPath,time)); return true; }
bool CAddonsDirectory::GetDirectory(const CStdString& strPath, CFileItemList &items) { CStdString path1(strPath); URIUtils::RemoveSlashAtEnd(path1); CURL path(path1); items.ClearProperties(); items.SetContent("addons"); VECADDONS addons; // get info from repository bool reposAsFolders = true; if (path.GetHostName().Equals("enabled")) { CAddonMgr::Get().GetAllAddons(addons, true); items.SetProperty("reponame",g_localizeStrings.Get(24062)); items.SetLabel(g_localizeStrings.Get(24062)); } else if (path.GetHostName().Equals("disabled")) { // grab all disabled addons, including disabled repositories reposAsFolders = false; CAddonMgr::Get().GetAllAddons(addons, false, true); items.SetProperty("reponame",g_localizeStrings.Get(24039)); items.SetLabel(g_localizeStrings.Get(24039)); } else if (path.GetHostName().Equals("outdated")) { reposAsFolders = false; CAddonMgr::Get().GetAllOutdatedAddons(addons); items.SetProperty("reponame",g_localizeStrings.Get(24043)); items.SetLabel(g_localizeStrings.Get(24043)); } else if (path.GetHostName().Equals("repos")) { CAddonMgr::Get().GetAddons(ADDON_REPOSITORY,addons,true); items.SetLabel(g_localizeStrings.Get(24033)); // Get Add-ons } else if (path.GetHostName().Equals("sources")) { return GetScriptsAndPlugins(path.GetFileName(), items); } else if (path.GetHostName().Equals("all")) { CAddonDatabase database; database.Open(); database.GetAddons(addons); items.SetProperty("reponame",g_localizeStrings.Get(24032)); items.SetLabel(g_localizeStrings.Get(24032)); } else if (path.GetHostName().Equals("search")) { CStdString search(path.GetFileName()); if (search.IsEmpty() && !GetKeyboardInput(16017, search)) return false; items.SetProperty("reponame",g_localizeStrings.Get(283)); items.SetLabel(g_localizeStrings.Get(283)); CAddonDatabase database; database.Open(); database.Search(search, addons); GenerateListing(path, addons, items, true); path.SetFileName(search); items.SetPath(path.Get()); return true; } else { reposAsFolders = false; AddonPtr addon; CAddonMgr::Get().GetAddon(path.GetHostName(),addon); if (!addon) return false; // ensure our repos are up to date CAddonInstaller::Get().UpdateRepos(false, true); CAddonDatabase database; database.Open(); database.GetRepository(addon->ID(),addons); items.SetProperty("reponame",addon->Name()); items.SetLabel(addon->Name()); } if (path.GetFileName().IsEmpty()) { if (!path.GetHostName().Equals("repos")) { for (int i=ADDON_UNKNOWN+1;i<ADDON_VIZ_LIBRARY;++i) { for (unsigned int j=0;j<addons.size();++j) { if (addons[j]->IsType((TYPE)i)) { CFileItemPtr item(new CFileItem(TranslateType((TYPE)i,true))); item->SetPath(URIUtils::AddFileToFolder(strPath,TranslateType((TYPE)i,false))); item->m_bIsFolder = true; CStdString thumb = GetIcon((TYPE)i); if (!thumb.IsEmpty() && g_TextureManager.HasTexture(thumb)) item->SetArt("thumb", thumb); items.Add(item); break; } } } items.SetPath(strPath); return true; } } else { TYPE type = TranslateType(path.GetFileName()); items.SetProperty("addoncategory",TranslateType(type, true)); items.SetLabel(TranslateType(type, true)); items.SetPath(strPath); // FIXME: Categorisation of addons needs adding here for (unsigned int j=0;j<addons.size();++j) { if (!addons[j]->IsType(type)) addons.erase(addons.begin()+j--); } } items.SetPath(strPath); GenerateListing(path, addons, items, reposAsFolders); // check for available updates if (path.GetHostName().Equals("enabled")) { CAddonDatabase database; database.Open(); for (int i=0;i<items.Size();++i) { AddonPtr addon2; database.GetAddon(items[i]->GetProperty("Addon.ID").asString(),addon2); if (addon2 && addon2->Version() > AddonVersion(items[i]->GetProperty("Addon.Version").asString()) && !database.IsAddonBlacklisted(addon2->ID(),addon2->Version().c_str())) { items[i]->SetProperty("Addon.Status",g_localizeStrings.Get(24068)); items[i]->SetProperty("Addon.UpdateAvail", true); } } } if (path.GetHostName().Equals("repos") && items.Size() > 1) { CFileItemPtr item(new CFileItem("addons://all/",true)); item->SetLabel(g_localizeStrings.Get(24032)); items.Add(item); } return true; }
bool CVideoLibraryRefreshingJob::Work(CVideoDatabase &db) { if (m_item == nullptr) return false; // determine the scraper for the item's path VIDEO::SScanSettings scanSettings; ADDON::ScraperPtr scraper = db.GetScraperForPath(m_item->GetPath(), scanSettings); if (scraper == nullptr) return false; // copy the scraper in case we need it again ADDON::ScraperPtr originalScraper(scraper); // get the item's correct title std::string itemTitle = m_searchTitle; if (itemTitle.empty()) itemTitle = m_item->GetMovieName(scanSettings.parent_name); CScraperUrl scraperUrl; VIDEO::CVideoInfoScanner scanner; bool needsRefresh = m_forceRefresh; bool hasDetails = false; bool ignoreNfo = m_ignoreNfo; // run this in a loop in case we need to refresh again bool failure = false; do { if (!ignoreNfo) { // check if there's an NFO for the item CNfoFile::NFOResult nfoResult = scanner.CheckForNFOFile(m_item.get(), scanSettings.parent_name_root, scraper, scraperUrl); // if there's no NFO remember it in case we have to refresh again if (nfoResult == CNfoFile::ERROR_NFO) ignoreNfo = true; else if (nfoResult != CNfoFile::NO_NFO) hasDetails = true; // if we are performing a forced refresh ask the user to choose between using a valid NFO and a valid scraper if (needsRefresh && IsModal() && !scraper->IsNoop() && (nfoResult == CNfoFile::URL_NFO || nfoResult == CNfoFile::COMBINED_NFO || nfoResult == CNfoFile::FULL_NFO)) { int heading = 20159; if (scraper->Content() == CONTENT_MOVIES) heading = 13346; else if (scraper->Content() == CONTENT_TVSHOWS) heading = m_item->m_bIsFolder ? 20351 : 20352; else if (scraper->Content() == CONTENT_MUSICVIDEOS) heading = 20393; if (CGUIDialogYesNo::ShowAndGetInput(heading, 20446)) { hasDetails = false; ignoreNfo = true; scraperUrl.Clear(); scraper = originalScraper; } } } // no need to re-fetch the episode guide for episodes if (scraper->Content() == CONTENT_TVSHOWS && !m_item->m_bIsFolder) hasDetails = true; // if we don't have an url or need to refresh anyway do the web search if (!hasDetails && (needsRefresh || scraperUrl.m_url.empty())) { SetTitle(StringUtils::Format(g_localizeStrings.Get(197).c_str(), scraper->Name().c_str())); SetText(itemTitle); SetProgress(0); // clear any cached data from the scraper scraper->ClearCache(); // create the info downloader for the scraper CVideoInfoDownloader infoDownloader(scraper); // try to find a matching item MOVIELIST itemResultList; int result = infoDownloader.FindMovie(itemTitle, itemResultList, GetProgressDialog()); // close the progress dialog MarkFinished(); if (result > 0) { // there are multiple matches for the item if (!itemResultList.empty()) { // choose the first match if (!IsModal()) scraperUrl = itemResultList.at(0); else { // ask the user what to do CGUIDialogSelect* selectDialog = static_cast<CGUIDialogSelect*>(g_windowManager.GetWindow(WINDOW_DIALOG_SELECT)); selectDialog->Reset(); selectDialog->SetHeading(scraper->Content() == CONTENT_TVSHOWS ? 20356 : 196); for (const auto& itemResult : itemResultList) selectDialog->Add(itemResult.strTitle); selectDialog->EnableButton(true, 413); // "Manual" selectDialog->Open(); // check if the user has chosen one of the results int selectedItem = selectDialog->GetSelectedItem(); if (selectedItem >= 0) scraperUrl = itemResultList.at(selectedItem); // the user hasn't chosen one of the results and but has chosen to manually enter a title to use else if (selectDialog->IsButtonPressed()) { // ask the user to input a title to use if (!CGUIKeyboardFactory::ShowAndGetInput(itemTitle, g_localizeStrings.Get(scraper->Content() == CONTENT_TVSHOWS ? 20357 : 16009), false)) return false; // go through the whole process again needsRefresh = true; continue; } // nothing else we can do else return false; } CLog::Log(LOGDEBUG, "CVideoLibraryRefreshingJob: user selected item '%s' with URL '%s'", scraperUrl.strTitle.c_str(), scraperUrl.m_url.at(0).m_url.c_str()); } } else if (result < 0 || !VIDEO::CVideoInfoScanner::DownloadFailed(GetProgressDialog())) { failure = true; break; } } // if the URL is still empty, check whether or not we're allowed // to prompt and ask the user to input a new search title if (!hasDetails && scraperUrl.m_url.empty()) { if (IsModal()) { // ask the user to input a title to use if (!CGUIKeyboardFactory::ShowAndGetInput(itemTitle, g_localizeStrings.Get(scraper->Content() == CONTENT_TVSHOWS ? 20357 : 16009), false)) return false; // go through the whole process again needsRefresh = true; continue; } // nothing else we can do failure = true; break; } // before we start downloading all the necessary information cleanup any existing artwork and hashes CTextureDatabase textureDb; if (textureDb.Open()) { for (const auto& artwork : m_item->GetArt()) textureDb.InvalidateCachedTexture(artwork.second); textureDb.Close(); } m_item->ClearArt(); // put together the list of items to refresh std::string path = m_item->GetPath(); CFileItemList items; if (m_item->HasVideoInfoTag() && m_item->GetVideoInfoTag()->m_iDbId > 0) { // for a tvshow we need to handle all paths of it std::vector<std::string> tvshowPaths; if (CMediaTypes::IsMediaType(m_item->GetVideoInfoTag()->m_type, MediaTypeTvShow) && m_refreshAll && db.GetPathsLinkedToTvShow(m_item->GetVideoInfoTag()->m_iDbId, tvshowPaths)) { for (const auto& tvshowPath : tvshowPaths) { CFileItemPtr tvshowItem(new CFileItem(*m_item->GetVideoInfoTag())); tvshowItem->SetPath(tvshowPath); items.Add(tvshowItem); } } // otherwise just add a copy of the item else items.Add(CFileItemPtr(new CFileItem(*m_item->GetVideoInfoTag()))); // update the path to the real path (instead of a videodb:// one) path = m_item->GetVideoInfoTag()->m_strPath; } else items.Add(CFileItemPtr(new CFileItem(*m_item))); // set the proper path of the list of items to lookup items.SetPath(m_item->m_bIsFolder ? URIUtils::GetParentPath(path) : URIUtils::GetDirectory(path)); int headingLabel = 198; if (scraper->Content() == CONTENT_TVSHOWS) { if (m_item->m_bIsFolder) headingLabel = 20353; else headingLabel = 20361; } else if (scraper->Content() == CONTENT_MUSICVIDEOS) headingLabel = 20394; // prepare the progress dialog for downloading all the necessary information SetTitle(g_localizeStrings.Get(headingLabel)); SetText(scraperUrl.strTitle); SetProgress(0); // remove any existing data for the item we're going to refresh if (m_item->GetVideoInfoTag()->m_iDbId > 0) { int dbId = m_item->GetVideoInfoTag()->m_iDbId; if (scraper->Content() == CONTENT_MOVIES) db.DeleteMovie(dbId); else if (scraper->Content() == CONTENT_MUSICVIDEOS) db.DeleteMusicVideo(dbId); else if (scraper->Content() == CONTENT_TVSHOWS) { if (!m_item->m_bIsFolder) db.DeleteEpisode(dbId); else if (m_refreshAll) db.DeleteTvShow(dbId); else db.DeleteDetailsForTvShow(dbId); } } // finally download the information for the item if (!scanner.RetrieveVideoInfo(items, scanSettings.parent_name, scraper->Content(), !ignoreNfo, &scraperUrl, m_refreshAll, GetProgressDialog())) { // something went wrong MarkFinished(); // check if the user cancelled if (!IsCancelled() && IsModal()) CGUIDialogOK::ShowAndGetInput(195, itemTitle); return false; } // retrieve the updated information from the database if (scraper->Content() == CONTENT_MOVIES) db.GetMovieInfo(m_item->GetPath(), *m_item->GetVideoInfoTag()); else if (scraper->Content() == CONTENT_MUSICVIDEOS) db.GetMusicVideoInfo(m_item->GetPath(), *m_item->GetVideoInfoTag()); else if (scraper->Content() == CONTENT_TVSHOWS) { // update tvshow info to get updated episode numbers if (m_item->m_bIsFolder) db.GetTvShowInfo(m_item->GetPath(), *m_item->GetVideoInfoTag()); else db.GetEpisodeInfo(m_item->GetPath(), *m_item->GetVideoInfoTag()); } // we're finally done MarkFinished(); break; } while (needsRefresh); if (failure && IsModal()) CGUIDialogOK::ShowAndGetInput(195, itemTitle); return true; }
bool CGUIWindowAddonBrowser::GetDirectory(const std::string& strDirectory, CFileItemList& items) { bool result; if (URIUtils::PathEquals(strDirectory, "addons://downloading/")) { VECADDONS addons; CAddonInstaller::GetInstance().GetInstallList(addons); CURL url(strDirectory); CAddonsDirectory::GenerateAddonListing(url, addons, items, g_localizeStrings.Get(24067)); result = true; items.SetPath(strDirectory); if (m_guiState.get() && !m_guiState->HideParentDirItems()) { CFileItemPtr pItem(new CFileItem("..")); pItem->SetPath(m_history.GetParentPath()); pItem->m_bIsFolder = true; pItem->m_bIsShareOrDrive = false; items.AddFront(pItem, 0); } } else { result = CGUIMediaWindow::GetDirectory(strDirectory, items); if (result && CAddonsDirectory::IsRepoDirectory(CURL(strDirectory))) { if (CSettings::GetInstance().GetBool(CSettings::SETTING_GENERAL_ADDONFOREIGNFILTER)) { int i = 0; while (i < items.Size()) { auto prop = items[i]->GetProperty("Addon.Language"); if (!prop.isNull() && IsForeign(prop.asString())) items.Remove(i); else ++i; } } if (CSettings::GetInstance().GetBool(CSettings::SETTING_GENERAL_ADDONBROKENFILTER)) { for (int i = items.Size() - 1; i >= 0; i--) { if (!items[i]->GetProperty("Addon.Broken").empty()) { //check if it's installed AddonPtr addon; if (!CAddonMgr::GetInstance().GetAddon(items[i]->GetProperty("Addon.ID").asString(), addon)) items.Remove(i); } } } } } if (strDirectory.empty() && CAddonInstaller::GetInstance().IsDownloading()) { CFileItemPtr item(new CFileItem("addons://downloading/", true)); item->SetLabel(g_localizeStrings.Get(24067)); item->SetLabelPreformated(true); item->SetIconImage("DefaultNetwork.png"); items.Add(item); } for (int i = 0; i < items.Size(); ++i) SetItemLabel2(items[i]); return result; }
bool CGUIWindowAddonBrowser::GetDirectory(const std::string& strDirectory, CFileItemList& items) { bool result; if (URIUtils::PathEquals(strDirectory, "addons://downloading/")) { VECADDONS addons; CAddonInstaller::Get().GetInstallList(addons); CURL url(strDirectory); CAddonsDirectory::GenerateAddonListing(url, addons, items, g_localizeStrings.Get(24067)); result = true; items.SetPath(strDirectory); if (m_guiState.get() && !m_guiState->HideParentDirItems()) { CFileItemPtr pItem(new CFileItem("..")); pItem->SetPath(m_history.GetParentPath()); pItem->m_bIsFolder = true; pItem->m_bIsShareOrDrive = false; items.AddFront(pItem, 0); } } else { result = CGUIMediaWindow::GetDirectory(strDirectory, items); if (CAddonsDirectory::IsRepoDirectory(CURL(strDirectory))) { if (CSettings::Get().GetBool("general.addonforeignfilter")) { int i=0; while (i < items.Size()) { if (!FilterVar(true, items[i]->GetProperty("Addon.Language"), "en") || !FilterVar(true, items[i]->GetProperty("Addon.Language"), g_langInfo.GetLocale().GetLanguageCode()) || !FilterVar(true, items[i]->GetProperty("Addon.Language"), g_langInfo.GetLocale().ToShortString())) { i++; } else items.Remove(i); } } if (CSettings::Get().GetBool("general.addonbrokenfilter")) { for (int i = items.Size() - 1; i >= 0; i--) { if (!items[i]->GetProperty("Addon.Broken").empty()) { //check if it's installed AddonPtr addon; if (!CAddonMgr::Get().GetAddon(items[i]->GetProperty("Addon.ID").asString(), addon)) items.Remove(i); } } } } } if (strDirectory.empty() && CAddonInstaller::Get().IsDownloading()) { CFileItemPtr item(new CFileItem("addons://downloading/",true)); item->SetLabel(g_localizeStrings.Get(24067)); item->SetLabelPreformated(true); item->SetIconImage("DefaultNetwork.png"); items.Add(item); } items.SetContent("addons"); for (int i=0;i<items.Size();++i) SetItemLabel2(items[i]); return result; }
bool CLibraryDirectory::GetDirectory(const CStdString& strPath, CFileItemList &items) { std::string libNode = GetNode(strPath); if (libNode.empty()) return false; if (URIUtils::HasExtension(libNode, ".xml")) { // a filter or folder node TiXmlElement *node = LoadXML(libNode); if (node) { CStdString type = node->Attribute("type"); if (type == "filter") { CSmartPlaylist playlist; CStdString type, label; XMLUtils::GetString(node, "content", type); if (type.IsEmpty()) { CLog::Log(LOGERROR, "<content> tag must not be empty for type=\"filter\" node '%s'", libNode.c_str()); return false; } if (XMLUtils::GetString(node, "label", label)) label = CGUIControlFactory::FilterLabel(label); playlist.SetType(type); playlist.SetName(label); if (playlist.LoadFromXML(node) && CSmartPlaylistDirectory::GetDirectory(playlist, items)) { items.SetProperty("library.filter", "true"); items.SetPath(items.GetProperty("path.db").asString()); return true; } } else if (type == "folder") { CStdString path; XMLUtils::GetPath(node, "path", path); if (!path.IsEmpty()) { URIUtils::AddSlashAtEnd(path); return CDirectory::GetDirectory(path, items, m_strFileMask, m_flags); } } } return false; } // just a plain node - read the folder for XML nodes and other folders CFileItemList nodes; if (!CDirectory::GetDirectory(libNode, nodes, ".xml", DIR_FLAG_NO_FILE_DIRS)) return false; // iterate over our nodes for (int i = 0; i < nodes.Size(); i++) { const TiXmlElement *node = NULL; CStdString xml = nodes[i]->GetPath(); if (nodes[i]->m_bIsFolder) node = LoadXML(URIUtils::AddFileToFolder(xml, "index.xml")); else { node = LoadXML(xml); if (node && URIUtils::GetFileName(xml).Equals("index.xml")) { // set the label on our items CStdString label; if (XMLUtils::GetString(node, "label", label)) label = CGUIControlFactory::FilterLabel(label); items.SetLabel(label); continue; } } if (node) { CStdString label, icon; if (XMLUtils::GetString(node, "label", label)) label = CGUIControlFactory::FilterLabel(label); XMLUtils::GetString(node, "icon", icon); int order = 0; node->Attribute("order", &order); // create item URIUtils::RemoveSlashAtEnd(xml); CStdString folder = URIUtils::GetFileName(xml); CFileItemPtr item(new CFileItem(URIUtils::AddFileToFolder(strPath, folder), true)); item->SetLabel(label); if (!icon.IsEmpty() && g_TextureManager.HasTexture(icon)) item->SetIconImage(icon); item->m_iprogramCount = order; items.Add(item); } } items.Sort(SortByPlaylistOrder, SortOrderAscending); return true; }
bool CGUIWindowPrograms::GetDirectory(const CStdString &strDirectory, CFileItemList &items) { bool bFlattened=false; if (URIUtils::IsDVD(strDirectory)) { CStdString strPath; URIUtils::AddFileToFolder(strDirectory,"default.xbe",strPath); if (CFile::Exists(strPath)) // flatten dvd { CFileItemPtr item(new CFileItem("default.xbe")); item->SetPath(strPath); items.Add(item); items.SetPath(strDirectory); bFlattened = true; } } if (!bFlattened) if (!CGUIMediaWindow::GetDirectory(strDirectory, items)) return false; if (items.IsVirtualDirectoryRoot()) { items.SetLabel(""); return true; } if (strDirectory.Equals("plugin://programs/")) { items.SetContent("plugins"); items.SetLabel(g_localizeStrings.Get(24001)); } // flatten any folders m_database.BeginTransaction(); DWORD dwTick=timeGetTime(); bool bProgressVisible = false; for (int i = 0; i < items.Size(); i++) { CStdString shortcutPath; CFileItemPtr item = items[i]; if (!bProgressVisible && timeGetTime()-dwTick>1500 && m_dlgProgress) { // tag loading takes more then 1.5 secs, show a progress dialog m_dlgProgress->SetHeading(189); m_dlgProgress->SetLine(0, 20120); m_dlgProgress->SetLine(1,""); m_dlgProgress->SetLine(2, item->GetLabel()); if (!g_guiSettings.GetBool("mygames.slowgameparsing")) { m_dlgProgress->StartModal(); } bProgressVisible = true; } if (bProgressVisible) { m_dlgProgress->SetLine(2,item->GetLabel()); m_dlgProgress->Progress(); } if (item->m_bIsFolder && !item->IsParentFolder() && !item->IsPlugin() && g_guiSettings.GetBool("mygames.slowgameparsing")) { // folder item - let's check for a default.xbe file, and flatten if we have one CStdString defaultXBE; URIUtils::AddFileToFolder(item->GetPath(), "default.xbe", defaultXBE); item->SetPath(defaultXBE); item->m_bIsFolder = false; } if (item->m_bIsFolder && !item->IsParentFolder() && !item->IsPlugin() && !g_guiSettings.GetBool("mygames.slowgameparsing")) { // folder item - let's check for a default.xbe file, and flatten if we have one CStdString defaultXBE; URIUtils::AddFileToFolder(item->GetPath(), "default.xbe", defaultXBE); if (CFile::Exists(defaultXBE)) { // yes, format the item up item->SetPath(defaultXBE); item->m_bIsFolder = false; } } else if (item->IsShortCut()) { // resolve the shortcut to set it's description etc. // and save the old shortcut path (so we can reassign it later) CShortcut cut; if (cut.Create(item->GetPath())) { shortcutPath = item->GetPath(); item->SetPath(cut.m_strPath); item->SetThumbnailImage(cut.m_strThumb); LABEL_MASKS labelMasks; m_guiState->GetSortMethodLabelMasks(labelMasks); CLabelFormatter formatter("", labelMasks.m_strLabel2File); if (!cut.m_strLabel.IsEmpty()) { item->SetLabel(cut.m_strLabel); __stat64 stat; if (CFile::Stat(item->GetPath(),&stat) == 0) item->m_dwSize = stat.st_size; formatter.FormatLabel2(item.get()); item->SetLabelPreformated(true); } } } if (item->IsXBE()) { if (URIUtils::GetFileName(item->GetPath()).Equals("default_ffp.xbe")) { m_vecItems->Remove(i--); continue; } // add to database if not already there DWORD dwTitleID = item->IsOnDVD() ? 0 : m_database.GetProgramInfo(item.get()); if (!dwTitleID) { CStdString description; if (CUtil::GetXBEDescription(item->GetPath(), description) && (!item->IsLabelPreformated() && !item->GetLabel().IsEmpty())) { item->SetLabel(description); if (!g_guiSettings.GetBool("mygames.slowgameparsing")) { CLog::Log(LOGNOTICE,"Added to database: %s",description.c_str()); } } dwTitleID = CUtil::GetXbeID(item->GetPath()); if (!item->IsOnDVD()) m_database.AddProgramInfo(item.get(), dwTitleID); } // SetOverlayIcons() if (m_database.ItemHasTrainer(dwTitleID)) { if (m_database.GetActiveTrainer(dwTitleID) != "") item->SetOverlayImage(CGUIListItem::ICON_OVERLAY_TRAINED); else item->SetOverlayImage(CGUIListItem::ICON_OVERLAY_HAS_TRAINER); } } if (!shortcutPath.IsEmpty()) item->SetPath(shortcutPath); } m_database.CommitTransaction(); // set the cached thumbs items.SetThumbnailImage(""); items.SetCachedProgramThumbs(); items.SetCachedProgramThumb(); if (!items.HasThumbnail()) items.SetUserProgramThumb(); if (bProgressVisible) m_dlgProgress->Close(); return true; }