bool CMusicInfoScanner::DoScan(const CStdString& strDirectory) { if (m_handle) m_handle->SetText(Prettify(strDirectory)); std::set<std::string>::const_iterator it = m_seenPaths.find(strDirectory); if (it != m_seenPaths.end()) return true; m_seenPaths.insert(strDirectory); // Discard all excluded files defined by m_musicExcludeRegExps vector<string> regexps = g_advancedSettings.m_audioExcludeFromScanRegExps; if (CUtil::ExcludeFileOrFolder(strDirectory, regexps)) return true; // load subfolder CFileItemList items; CDirectory::GetDirectory(strDirectory, items, g_advancedSettings.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(SortByLabel, 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.empty()) 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(SortByLabel, SortOrderAscending); // and then scan in the new information if (RetrieveMusicInfo(strDirectory, items) > 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 CGUIDialogVideoInfo::OnMessage(CGUIMessage& message) { switch ( message.GetMessage() ) { case GUI_MSG_WINDOW_DEINIT: { ClearCastList(); } break; case GUI_MSG_CLICKED: { int iControl = message.GetSenderId(); if (iControl == CONTROL_BTN_REFRESH) { if (m_movieItem->GetVideoInfoTag()->m_iSeason < 0 && !m_movieItem->GetVideoInfoTag()->m_strShowTitle.IsEmpty()) // tv show { bool bCanceled=false; if (CGUIDialogYesNo::ShowAndGetInput(20377,20378,-1,-1,bCanceled)) { m_bRefreshAll = true; CVideoDatabase db; if (db.Open()) { db.SetPathHash(m_movieItem->GetVideoInfoTag()->m_strPath,""); db.Close(); } } else m_bRefreshAll = false; if (bCanceled) return false; } m_bRefresh = true; Close(); return true; } else if (iControl == CONTROL_BTN_TRACKS) { m_bViewReview = !m_bViewReview; Update(); } else if (iControl == CONTROL_BTN_PLAY) { Play(); } else if (iControl == CONTROL_BTN_RESUME) { Play(true); } else if (iControl == CONTROL_BTN_GET_THUMB) { OnGetArt(); } else if (iControl == CONTROL_BTN_PLAY_TRAILER) { PlayTrailer(); } else if (iControl == CONTROL_BTN_GET_FANART) { OnGetFanart(); } else if (iControl == CONTROL_BTN_DIRECTOR) { CStdString strDirector = StringUtils::Join(m_movieItem->GetVideoInfoTag()->m_director, g_advancedSettings.m_videoItemSeparator); OnSearch(strDirector); } else if (iControl == CONTROL_LIST) { int iAction = message.GetParam1(); if (ACTION_SELECT_ITEM == iAction || ACTION_MOUSE_LEFT_CLICK == iAction) { CGUIMessage msg(GUI_MSG_ITEM_SELECTED, GetID(), iControl); OnMessage(msg); int iItem = msg.GetParam1(); if (iItem < 0 || iItem >= m_castList->Size()) break; CStdString strItem = m_castList->Get(iItem)->GetLabel(); CStdString strFind; strFind.Format(" %s ",g_localizeStrings.Get(20347)); int iPos = strItem.Find(strFind); if (iPos == -1) iPos = strItem.size(); CStdString tmp = strItem.Left(iPos); OnSearch(tmp); } } } break; case GUI_MSG_NOTIFY_ALL: { if (IsActive() && message.GetParam1() == GUI_MSG_UPDATE_ITEM && message.GetItem()) { CFileItemPtr item = boost::static_pointer_cast<CFileItem>(message.GetItem()); if (item && m_movieItem->GetPath().Equals(item->GetPath())) { // Just copy over the stream details and the thumb if we don't already have one if (!m_movieItem->HasArt("thumb")) m_movieItem->SetArt("thumb", item->GetArt("thumb")); m_movieItem->GetVideoInfoTag()->m_streamDetails = item->GetVideoInfoTag()->m_streamDetails; } return true; } } } return CGUIDialog::OnMessage(message); }
void CPeripherals::OnSettingAction(const CSetting *setting) { if (setting == nullptr) return; const std::string &settingId = setting->GetId(); if (settingId == CSettings::SETTING_INPUT_PERIPHERALS) { CGUIDialogSelect* pDialog = (CGUIDialogSelect*)g_windowManager.GetWindow(WINDOW_DIALOG_SELECT); CFileItemList items; GetDirectory("peripherals://all/", items); int iPos = -1; do { pDialog->Reset(); pDialog->SetHeading(CVariant{35000}); pDialog->SetUseDetails(true); pDialog->SetItems(items); pDialog->SetSelected(iPos); pDialog->Open(); iPos = pDialog->IsConfirmed() ? pDialog->GetSelectedItem() : -1; if (iPos >= 0) { CFileItemPtr pItem = items.Get(iPos); // show an error if the peripheral doesn't have any settings PeripheralPtr peripheral = GetByPath(pItem->GetPath()); if (!peripheral || peripheral->GetSettings().empty()) { CGUIDialogOK::ShowAndGetInput(CVariant{35000}, CVariant{35004}); continue; } CGUIDialogPeripheralSettings *pSettingsDialog = (CGUIDialogPeripheralSettings *)g_windowManager.GetWindow(WINDOW_DIALOG_PERIPHERAL_SETTINGS); if (pItem && pSettingsDialog) { // pass peripheral item properties to settings dialog so skin authors // can use it to show more detailed information about the device pSettingsDialog->SetProperty("vendor", pItem->GetProperty("vendor")); pSettingsDialog->SetProperty("product", pItem->GetProperty("product")); pSettingsDialog->SetProperty("bus", pItem->GetProperty("bus")); pSettingsDialog->SetProperty("location", pItem->GetProperty("location")); pSettingsDialog->SetProperty("class", pItem->GetProperty("class")); pSettingsDialog->SetProperty("version", pItem->GetProperty("version")); // open settings dialog pSettingsDialog->SetFileItem(pItem.get()); pSettingsDialog->Open(); } } } while (pDialog->IsConfirmed()); } else if (settingId == CSettings::SETTING_INPUT_CONTROLLERCONFIG) g_windowManager.ActivateWindow(WINDOW_DIALOG_GAME_CONTROLLERS); else if (settingId == CSettings::SETTING_INPUT_TESTRUMBLE) TestFeature(FEATURE_RUMBLE); }
void CBackgroundInfoLoader::Run() { try { if (!m_vecItems.empty()) { OnLoaderStart(); // Stage 1: All "fast" stuff we have already cached for (std::vector<CFileItemPtr>::const_iterator iter = m_vecItems.begin(); iter != m_vecItems.end(); ++iter) { CFileItemPtr pItem = *iter; // Ask the callback if we should abort if ((m_pProgressCallback && m_pProgressCallback->Abort()) || m_bStop) break; try { if (LoadItemCached(pItem.get()) && m_pObserver) m_pObserver->OnItemLoaded(pItem.get()); } catch (...) { CLog::Log(LOGERROR, "CBackgroundInfoLoader::LoadItemCached - Unhandled exception for item %s", CURL::GetRedacted(pItem->GetPath()).c_str()); } } // Stage 2: All "slow" stuff that we need to lookup for (std::vector<CFileItemPtr>::const_iterator iter = m_vecItems.begin(); iter != m_vecItems.end(); ++iter) { CFileItemPtr pItem = *iter; // Ask the callback if we should abort if ((m_pProgressCallback && m_pProgressCallback->Abort()) || m_bStop) break; try { if (LoadItemLookup(pItem.get()) && m_pObserver) m_pObserver->OnItemLoaded(pItem.get()); } catch (...) { CLog::Log(LOGERROR, "CBackgroundInfoLoader::LoadItemLookup - Unhandled exception for item %s", CURL::GetRedacted(pItem->GetPath()).c_str()); } } } OnLoaderFinish(); m_bIsLoading = false; } catch (...) { m_bIsLoading = false; CLog::Log(LOGERROR, "%s - Unhandled exception", __FUNCTION__); } }
/// \brief Add unique file and folders and its subfolders to playlist /// \param pItem The file item to add void CGUIWindowMusicBase::AddItemToPlayList(const CFileItemPtr &pItem, CFileItemList &queuedItems) { if (!pItem->CanQueue() || pItem->IsRAR() || pItem->IsZIP() || pItem->IsParentFolder()) // no zip/rar enques thank you! return; // fast lookup is needed here queuedItems.SetFastLookup(true); if (pItem->IsMusicDb() && pItem->m_bIsFolder && !pItem->IsParentFolder()) { // we have a music database folder, just grab the "all" item underneath it CMusicDatabaseDirectory dir; if (!dir.ContainsSongs(pItem->GetPath())) { // grab the ALL item in this category // Genres will still require 2 lookups, and queuing the entire Genre folder // will require 3 lookups (genre, artist, album) CFileItemPtr item(new CFileItem(pItem->GetPath() + "-1/", true)); item->SetCanQueue(true); // workaround for CanQueue() check above AddItemToPlayList(item, queuedItems); return; } } if (pItem->m_bIsFolder || (g_windowManager.GetActiveWindow() == WINDOW_MUSIC_NAV && pItem->IsPlayList())) { // Check if we add a locked share if ( pItem->m_bIsShareOrDrive ) { CFileItem item = *pItem; if ( !g_passwordManager.IsItemUnlocked( &item, "music" ) ) return ; } // recursive CFileItemList items; GetDirectory(pItem->GetPath(), items); //OnRetrieveMusicInfo(items); FormatAndSort(items); SetupFanart(items); for (int i = 0; i < items.Size(); ++i) AddItemToPlayList(items[i], queuedItems); } else { if (pItem->IsPlayList()) { auto_ptr<CPlayList> pPlayList (CPlayListFactory::Create(*pItem)); if (pPlayList.get()) { // load it if (!pPlayList->Load(pItem->GetPath())) { CGUIDialogOK::ShowAndGetInput(6, 0, 477, 0); return; //hmmm unable to load playlist? } CPlayList playlist = *pPlayList; for (int i = 0; i < (int)playlist.size(); ++i) { AddItemToPlayList(playlist[i], queuedItems); } return; } } else if(pItem->IsInternetStream()) { // just queue the internet stream, it will be expanded on play queuedItems.Add(pItem); } else if (pItem->IsPlugin() && pItem->GetProperty("isplayable") == "true") { // python files can be played queuedItems.Add(pItem); } else if (!pItem->IsNFO() && pItem->IsAudio()) { CFileItemPtr itemCheck = queuedItems.Get(pItem->GetPath()); if (!itemCheck || itemCheck->m_lStartOffset != pItem->m_lStartOffset) { // add item CFileItemPtr item(new CFileItem(*pItem)); m_musicdatabase.SetPropertiesForFileItem(*item); queuedItems.Add(item); } } } }
bool CGUIDialogContextMenu::OnContextButton(const std::string &type, const CFileItemPtr& item, CONTEXT_BUTTON button) { // Add Source doesn't require a valid share if (button == CONTEXT_BUTTON_ADD_SOURCE) { if (CProfilesManager::Get().IsMasterProfile()) { if (!g_passwordManager.IsMasterLockUnlocked(true)) return false; } else if (!CProfilesManager::Get().GetCurrentProfile().canWriteSources() && !g_passwordManager.IsProfileLockUnlocked()) return false; return CGUIDialogMediaSource::ShowAndAddMediaSource(type); } // buttons that are available on both sources and autosourced items if (!item) return false; switch (button) { case CONTEXT_BUTTON_EJECT_DRIVE: return g_mediaManager.Eject(item->GetPath()); #ifdef HAS_DVD_DRIVE case CONTEXT_BUTTON_PLAY_DISC: return MEDIA_DETECT::CAutorun::PlayDisc(item->GetPath(), true, true); // restart case CONTEXT_BUTTON_RESUME_DISC: return MEDIA_DETECT::CAutorun::PlayDisc(item->GetPath(), true, false); // resume case CONTEXT_BUTTON_EJECT_DISC: g_mediaManager.ToggleTray(g_mediaManager.TranslateDevicePath(item->GetPath())[0]); #endif return true; default: break; } // the rest of the operations require a valid share CMediaSource *share = GetShare(type, item.get()); if (!share) return false; switch (button) { case CONTEXT_BUTTON_EDIT_SOURCE: if (CProfilesManager::Get().IsMasterProfile()) { if (!g_passwordManager.IsMasterLockUnlocked(true)) return false; } else if (!g_passwordManager.IsProfileLockUnlocked()) return false; return CGUIDialogMediaSource::ShowAndEditMediaSource(type, *share); case CONTEXT_BUTTON_REMOVE_SOURCE: { if (CProfilesManager::Get().IsMasterProfile()) { if (!g_passwordManager.IsMasterLockUnlocked(true)) return false; } else { if (!CProfilesManager::Get().GetCurrentProfile().canWriteSources() && !g_passwordManager.IsMasterLockUnlocked(false)) return false; if (CProfilesManager::Get().GetCurrentProfile().canWriteSources() && !g_passwordManager.IsProfileLockUnlocked()) return false; } // prompt user if they want to really delete the source if (!CGUIDialogYesNo::ShowAndGetInput(CVariant{751}, CVariant{750})) return false; // check default before we delete, as deletion will kill the share object std::string defaultSource(GetDefaultShareNameByType(type)); if (!defaultSource.empty()) { if (share->strName == defaultSource) ClearDefault(type); } CMediaSourceSettings::Get().DeleteSource(type, share->strName, share->strPath); return true; } case CONTEXT_BUTTON_SET_DEFAULT: if (CProfilesManager::Get().GetCurrentProfile().canWriteSources() && !g_passwordManager.IsProfileLockUnlocked()) return false; else if (!g_passwordManager.IsMasterLockUnlocked(true)) return false; // make share default SetDefault(type, share->strName); return true; case CONTEXT_BUTTON_CLEAR_DEFAULT: if (CProfilesManager::Get().GetCurrentProfile().canWriteSources() && !g_passwordManager.IsProfileLockUnlocked()) return false; else if (!g_passwordManager.IsMasterLockUnlocked(true)) return false; // remove share default ClearDefault(type); return true; case CONTEXT_BUTTON_SET_THUMB: { if (CProfilesManager::Get().GetCurrentProfile().canWriteSources() && !g_passwordManager.IsProfileLockUnlocked()) return false; else if (!g_passwordManager.IsMasterLockUnlocked(true)) return false; // setup our thumb list CFileItemList items; // add the current thumb, if available if (!share->m_strThumbnailImage.empty()) { CFileItemPtr current(new CFileItem("thumb://Current", false)); current->SetArt("thumb", share->m_strThumbnailImage); current->SetLabel(g_localizeStrings.Get(20016)); items.Add(current); } else if (item->HasArt("thumb")) { // already have a thumb that the share doesn't know about - must be a local one, so we mayaswell reuse it. CFileItemPtr current(new CFileItem("thumb://Current", false)); current->SetArt("thumb", item->GetArt("thumb")); current->SetLabel(g_localizeStrings.Get(20016)); items.Add(current); } // see if there's a local thumb for this item std::string folderThumb = item->GetFolderThumb(); if (XFILE::CFile::Exists(folderThumb)) { CFileItemPtr local(new CFileItem("thumb://Local", false)); local->SetArt("thumb", folderThumb); local->SetLabel(g_localizeStrings.Get(20017)); items.Add(local); } // and add a "no thumb" entry as well CFileItemPtr nothumb(new CFileItem("thumb://None", false)); nothumb->SetIconImage(item->GetIconImage()); nothumb->SetLabel(g_localizeStrings.Get(20018)); items.Add(nothumb); std::string strThumb; VECSOURCES shares; g_mediaManager.GetLocalDrives(shares); if (!CGUIDialogFileBrowser::ShowAndGetImage(items, shares, g_localizeStrings.Get(1030), strThumb)) return false; if (strThumb == "thumb://Current") return true; if (strThumb == "thumb://Local") strThumb = folderThumb; if (strThumb == "thumb://None") strThumb = ""; if (!share->m_ignore) { CMediaSourceSettings::Get().UpdateSource(type,share->strName,"thumbnail",strThumb); CMediaSourceSettings::Get().Save(); } else if (!strThumb.empty()) { // this is some sort of an auto-share, so store in the texture database CTextureDatabase db; if (db.Open()) db.SetTextureForPath(item->GetPath(), "thumb", strThumb); } CGUIMessage msg(GUI_MSG_NOTIFY_ALL,0,0,GUI_MSG_UPDATE_SOURCES); g_windowManager.SendThreadMessage(msg); return true; } case CONTEXT_BUTTON_ADD_LOCK: { // prompt user for mastercode when changing lock settings) only for default user if (!g_passwordManager.IsMasterLockUnlocked(true)) return false; std::string strNewPassword = ""; if (!CGUIDialogLockSettings::ShowAndGetLock(share->m_iLockMode,strNewPassword)) return false; // password entry and re-entry succeeded, write out the lock data share->m_iHasLock = 2; CMediaSourceSettings::Get().UpdateSource(type, share->strName, "lockcode", strNewPassword); strNewPassword = StringUtils::Format("%i", share->m_iLockMode); CMediaSourceSettings::Get().UpdateSource(type, share->strName, "lockmode", strNewPassword); CMediaSourceSettings::Get().UpdateSource(type, share->strName, "badpwdcount", "0"); CMediaSourceSettings::Get().Save(); CGUIMessage msg(GUI_MSG_NOTIFY_ALL,0,0,GUI_MSG_UPDATE_SOURCES); g_windowManager.SendThreadMessage(msg); return true; } case CONTEXT_BUTTON_RESET_LOCK: { // prompt user for profile lock when changing lock settings if (!g_passwordManager.IsMasterLockUnlocked(true)) return false; CMediaSourceSettings::Get().UpdateSource(type, share->strName, "badpwdcount", "0"); CMediaSourceSettings::Get().Save(); CGUIMessage msg(GUI_MSG_NOTIFY_ALL,0,0,GUI_MSG_UPDATE_SOURCES); g_windowManager.SendThreadMessage(msg); return true; } case CONTEXT_BUTTON_REMOVE_LOCK: { if (!g_passwordManager.IsMasterLockUnlocked(true)) return false; if (!CGUIDialogYesNo::ShowAndGetInput(CVariant{12335}, CVariant{750})) return false; share->m_iHasLock = 0; CMediaSourceSettings::Get().UpdateSource(type, share->strName, "lockmode", "0"); CMediaSourceSettings::Get().UpdateSource(type, share->strName, "lockcode", "0"); CMediaSourceSettings::Get().UpdateSource(type, share->strName, "badpwdcount", "0"); CMediaSourceSettings::Get().Save(); CGUIMessage msg(GUI_MSG_NOTIFY_ALL,0,0,GUI_MSG_UPDATE_SOURCES); g_windowManager.SendThreadMessage(msg); return true; } case CONTEXT_BUTTON_REACTIVATE_LOCK: { bool maxRetryExceeded = false; if (CSettings::Get().GetInt("masterlock.maxretries") != 0) maxRetryExceeded = (share->m_iBadPwdCount >= CSettings::Get().GetInt("masterlock.maxretries")); if (!maxRetryExceeded) { // don't prompt user for mastercode when reactivating a lock g_passwordManager.LockSource(type, share->strName, true); return true; } return false; } case CONTEXT_BUTTON_CHANGE_LOCK: { if (!g_passwordManager.IsMasterLockUnlocked(true)) return false; std::string strNewPW; std::string strNewLockMode; if (CGUIDialogLockSettings::ShowAndGetLock(share->m_iLockMode,strNewPW)) strNewLockMode = StringUtils::Format("%i",share->m_iLockMode); else return false; // password ReSet and re-entry succeeded, write out the lock data CMediaSourceSettings::Get().UpdateSource(type, share->strName, "lockcode", strNewPW); CMediaSourceSettings::Get().UpdateSource(type, share->strName, "lockmode", strNewLockMode); CMediaSourceSettings::Get().UpdateSource(type, share->strName, "badpwdcount", "0"); CMediaSourceSettings::Get().Save(); CGUIMessage msg(GUI_MSG_NOTIFY_ALL,0,0,GUI_MSG_UPDATE_SOURCES); g_windowManager.SendThreadMessage(msg); return true; } default: break; } return false; }
bool CGUIDialogFileBrowser::OnMessage(CGUIMessage& message) { switch ( message.GetMessage() ) { case GUI_MSG_WINDOW_DEINIT: { if (m_thumbLoader.IsLoading()) m_thumbLoader.StopThread(); CGUIDialog::OnMessage(message); ClearFileItems(); m_addNetworkShareEnabled = false; return true; } break; case GUI_MSG_WINDOW_INIT: { m_bConfirmed = false; m_bFlip = false; bool bIsDir = false; // this code allows two different selection modes for directories // end the path with a slash to start inside the directory if (URIUtils::HasSlashAtEnd(m_selectedPath)) { bIsDir = true; bool bFool; int iSource = CUtil::GetMatchingSource(m_selectedPath,m_shares,bFool); bFool = true; if (iSource > -1 && iSource < (int)m_shares.size()) { if (m_shares[iSource].strPath.Equals(m_selectedPath)) bFool = false; } if (bFool && !CDirectory::Exists(m_selectedPath)) m_selectedPath.Empty(); } else { if (!CFile::Exists(m_selectedPath) && !CDirectory::Exists(m_selectedPath)) m_selectedPath.Empty(); } // find the parent folder if we are a file browser (don't do this for folders) m_Directory->SetPath(m_selectedPath); if (!m_browsingForFolders && !bIsDir) m_Directory->SetPath(URIUtils::GetParentPath(m_selectedPath)); Update(m_Directory->GetPath()); m_viewControl.SetSelectedItem(m_selectedPath); return CGUIDialog::OnMessage(message); } break; case GUI_MSG_CLICKED: { if (m_viewControl.HasControl(message.GetSenderId())) // list control { int iItem = m_viewControl.GetSelectedItem(); int iAction = message.GetParam1(); if (iItem < 0) break; if (iAction == ACTION_SELECT_ITEM || iAction == ACTION_MOUSE_LEFT_CLICK) { OnClick(iItem); return true; } else if (iAction == ACTION_HIGHLIGHT_ITEM && m_multipleSelection) { CFileItemPtr pItem = (*m_vecItems)[iItem]; if (!pItem->m_bIsShareOrDrive && !pItem->m_bIsFolder) { pItem->Select(!pItem->IsSelected()); CGUIMessage msg(GUI_MSG_ITEM_SELECT, GetID(), message.GetSenderId(), iItem + 1); OnMessage(msg); } } } else if (message.GetSenderId() == CONTROL_OK) { if (m_browsingForFolders == 2) { CStdString strTest; int iItem = m_viewControl.GetSelectedItem(); CStdString strPath; if (iItem == 0) strPath = m_selectedPath; else strPath = (*m_vecItems)[iItem]->GetPath(); URIUtils::AddFileToFolder(strPath,"1",strTest); CFile file; if (file.OpenForWrite(strTest,true)) { file.Close(); CFile::Delete(strTest); m_bConfirmed = true; Close(); } else CGUIDialogOK::ShowAndGetInput(257,20072,0,0); } else { if (m_multipleSelection) { for (int iItem = 0; iItem < m_vecItems->Size(); ++iItem) { CFileItemPtr pItem = (*m_vecItems)[iItem]; if (pItem->IsSelected()) m_markedPath.push_back(pItem->GetPath()); } } m_bConfirmed = true; Close(); } return true; } else if (message.GetSenderId() == CONTROL_CANCEL) { Close(); return true; } else if (message.GetSenderId() == CONTROL_NEWFOLDER) { CStdString strInput; if (CGUIDialogKeyboard::ShowAndGetInput(strInput,g_localizeStrings.Get(119),false)) { CStdString strPath; URIUtils::AddFileToFolder(m_vecItems->GetPath(),strInput,strPath); if (CDirectory::Create(strPath)) Update(m_vecItems->GetPath()); else CGUIDialogOK::ShowAndGetInput(20069,20072,20073,0); } } else if (message.GetSenderId() == CONTROL_FLIP) m_bFlip = !m_bFlip; } 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 only if this window is active if (message.GetParam1() == GUI_MSG_REMOVED_MEDIA) { if (m_Directory->IsVirtualDirectoryRoot() && IsActive()) { int iItem = m_viewControl.GetSelectedItem(); Update(m_Directory->GetPath()); m_viewControl.SetSelectedItem(iItem); } else if (m_Directory->IsRemovable()) { // check that we have this removable share still if (!m_rootDir.IsInSource(m_Directory->GetPath())) { // don't have this share any more if (IsActive()) Update(""); else { m_history.ClearPathHistory(); m_Directory->SetPath(""); } } } return true; } else if (message.GetParam1()==GUI_MSG_UPDATE_SOURCES) { // State of the sources changed, so update our view if (m_Directory->IsVirtualDirectoryRoot() && IsActive()) { int iItem = m_viewControl.GetSelectedItem(); Update(m_Directory->GetPath()); m_viewControl.SetSelectedItem(iItem); } return true; } else if (message.GetParam1()==GUI_MSG_UPDATE_PATH) { if (IsActive()) { if((message.GetStringParam() == m_Directory->GetPath()) || (m_Directory->IsMultiPath() && XFILE::CMultiPathDirectory::HasPath(m_Directory->GetPath(), message.GetStringParam()))) { int iItem = m_viewControl.GetSelectedItem(); Update(m_Directory->GetPath()); m_viewControl.SetSelectedItem(iItem); } } } } break; } return CGUIDialog::OnMessage(message); }
void CGUIWindowMusicBase::GetContextButtons(int itemNumber, CContextButtons &buttons) { CFileItemPtr item; if (itemNumber >= 0 && itemNumber < m_vecItems->Size()) item = m_vecItems->Get(itemNumber); if (item) { if (item && !item->IsParentFolder()) { if (item->CanQueue() && !item->IsAddonsPath() && !item->IsScript()) { buttons.Add(CONTEXT_BUTTON_QUEUE_ITEM, 13347); //queue // allow a folder to be ad-hoc queued and played by the default player if (item->m_bIsFolder || (item->IsPlayList() && !g_advancedSettings.m_playlistAsFolders)) { buttons.Add(CONTEXT_BUTTON_PLAY_ITEM, 208); // Play } else { // check what players we have, if we have multiple display play with option std::vector<std::string> players; CPlayerCoreFactory::GetInstance().GetPlayers(*item, players); if (players.size() >= 1) buttons.Add(CONTEXT_BUTTON_PLAY_WITH, 15213); // Play With... } if (item->IsSmartPlayList()) { buttons.Add(CONTEXT_BUTTON_PLAY_PARTYMODE, 15216); // Play in Partymode } if (item->IsSmartPlayList() || m_vecItems->IsSmartPlayList()) buttons.Add(CONTEXT_BUTTON_EDIT_SMART_PLAYLIST, 586); else if (item->IsPlayList() || m_vecItems->IsPlayList()) buttons.Add(CONTEXT_BUTTON_EDIT, 586); } if (!m_vecItems->IsMusicDb() && !m_vecItems->IsInternetStream() && !item->IsPath("add") && !item->IsParentFolder() && !item->IsPlugin() && !item->IsMusicDb() && !item->IsLibraryFolder() && !StringUtils::StartsWithNoCase(item->GetPath(), "addons://") && (CProfilesManager::GetInstance().GetCurrentProfile().canWriteDatabases() || g_passwordManager.bMasterUser)) { buttons.Add(CONTEXT_BUTTON_SCAN, 13352); } #ifdef HAS_DVD_DRIVE // enable Rip CD Audio or Track button if we have an audio disc if (g_mediaManager.IsDiscInDrive() && m_vecItems->IsCDDA()) { // those cds can also include Audio Tracks: CDExtra and MixedMode! MEDIA_DETECT::CCdInfo *pCdInfo = g_mediaManager.GetCdInfo(); if (pCdInfo->IsAudio(1) || pCdInfo->IsCDExtra(1) || pCdInfo->IsMixedMode(1)) buttons.Add(CONTEXT_BUTTON_RIP_TRACK, 610); } #endif } // enable CDDB lookup if the current dir is CDDA if (g_mediaManager.IsDiscInDrive() && m_vecItems->IsCDDA() && (CProfilesManager::GetInstance().GetCurrentProfile().canWriteDatabases() || g_passwordManager.bMasterUser)) { buttons.Add(CONTEXT_BUTTON_CDDB, 16002); } } CGUIMediaWindow::GetContextButtons(itemNumber, buttons); }
bool CGUIWindowMusicBase::OnContextButton(int itemNumber, CONTEXT_BUTTON button) { CFileItemPtr item; if (itemNumber >= 0 && itemNumber < m_vecItems->Size()) item = m_vecItems->Get(itemNumber); if (CGUIDialogContextMenu::OnContextButton("music", item, button)) { if (button == CONTEXT_BUTTON_REMOVE_SOURCE) OnRemoveSource(itemNumber); Update(m_vecItems->GetPath()); return true; } switch (button) { case CONTEXT_BUTTON_QUEUE_ITEM: OnQueueItem(itemNumber); return true; case CONTEXT_BUTTON_INFO: OnItemInfo(itemNumber); return true; case CONTEXT_BUTTON_EDIT: { std::string playlist = item->IsPlayList() ? item->GetPath() : m_vecItems->GetPath(); // save path as activatewindow will destroy our items g_windowManager.ActivateWindow(WINDOW_MUSIC_PLAYLIST_EDITOR, playlist); // need to update m_vecItems->RemoveDiscCache(GetID()); return true; } case CONTEXT_BUTTON_EDIT_SMART_PLAYLIST: { std::string playlist = item->IsSmartPlayList() ? item->GetPath() : m_vecItems->GetPath(); // save path as activatewindow will destroy our items if (CGUIDialogSmartPlaylistEditor::EditPlaylist(playlist, "music")) Refresh(true); // need to update return true; } case CONTEXT_BUTTON_PLAY_ITEM: PlayItem(itemNumber); return true; case CONTEXT_BUTTON_PLAY_WITH: { std::vector<std::string> players; CPlayerCoreFactory::GetInstance().GetPlayers(*item, players); std::string player = CPlayerCoreFactory::GetInstance().SelectPlayerDialog(players); if (!player.empty()) OnClick(itemNumber, player); return true; } case CONTEXT_BUTTON_PLAY_PARTYMODE: g_partyModeManager.Enable(PARTYMODECONTEXT_MUSIC, item->GetPath()); return true; case CONTEXT_BUTTON_ACTIVE_ADSP_SETTINGS: g_windowManager.ActivateWindow(WINDOW_DIALOG_AUDIO_DSP_OSD_SETTINGS); return true; case CONTEXT_BUTTON_RIP_CD: OnRipCD(); return true; #ifdef HAS_CDDA_RIPPER case CONTEXT_BUTTON_CANCEL_RIP_CD: CCDDARipper::GetInstance().CancelJobs(); return true; #endif case CONTEXT_BUTTON_RIP_TRACK: OnRipTrack(itemNumber); return true; case CONTEXT_BUTTON_SCAN: OnScan(itemNumber); return true; case CONTEXT_BUTTON_CDDB: if (m_musicdatabase.LookupCDDBInfo(true)) Refresh(); return true; default: break; } return CGUIMediaWindow::OnContextButton(itemNumber, button); }
void CGUIWindowVideoNav::GetContextButtons(int itemNumber, CContextButtons &buttons) { CFileItemPtr item; if (itemNumber >= 0 && itemNumber < m_vecItems->Size()) item = m_vecItems->Get(itemNumber); CGUIWindowVideoBase::GetContextButtons(itemNumber, buttons); if (item && item->GetProperty("pluginreplacecontextitems").asBoolean()) return; CVideoDatabaseDirectory dir; NODE_TYPE node = dir.GetDirectoryChildType(m_vecItems->GetPath()); if (!item) { // nothing to do here } else if (m_vecItems->GetPath().Equals("sources://video/")) { // get the usual shares CGUIDialogContextMenu::GetContextButtons("video", item, buttons); // add scan button somewhere here if (g_application.IsVideoScanning()) buttons.Add(CONTEXT_BUTTON_STOP_SCANNING, 13353); // Stop Scanning if (!item->IsDVD() && item->GetPath() != "add" && !item->IsParentFolder() && (CProfilesManager::Get().GetCurrentProfile().canWriteDatabases() || g_passwordManager.bMasterUser)) { CVideoDatabase database; database.Open(); ADDON::ScraperPtr info = database.GetScraperForPath(item->GetPath()); if (!g_application.IsVideoScanning()) { if (!item->IsLiveTV() && !item->IsPlugin() && !item->IsAddonsPath() && !URIUtils::IsUPnP(item->GetPath())) { if (info && info->Content() != CONTENT_NONE) buttons.Add(CONTEXT_BUTTON_SET_CONTENT, 20442); else buttons.Add(CONTEXT_BUTTON_SET_CONTENT, 20333); } } if (info && !g_application.IsVideoScanning()) buttons.Add(CONTEXT_BUTTON_SCAN, 13349); } } else { // are we in the playlists location? bool inPlaylists = m_vecItems->GetPath().Equals(CUtil::VideoPlaylistsLocation()) || m_vecItems->GetPath().Equals("special://videoplaylists/"); if (item->HasVideoInfoTag() && !item->GetVideoInfoTag()->m_artist.empty()) { CMusicDatabase database; database.Open(); if (database.GetArtistByName(StringUtils::Join(item->GetVideoInfoTag()->m_artist, g_advancedSettings.m_videoItemSeparator)) > -1) buttons.Add(CONTEXT_BUTTON_GO_TO_ARTIST, 20396); } if (item->HasVideoInfoTag() && item->GetVideoInfoTag()->m_strAlbum.size() > 0) { CMusicDatabase database; database.Open(); if (database.GetAlbumByName(item->GetVideoInfoTag()->m_strAlbum) > -1) buttons.Add(CONTEXT_BUTTON_GO_TO_ALBUM, 20397); } if (item->HasVideoInfoTag() && item->GetVideoInfoTag()->m_strAlbum.size() > 0 && item->GetVideoInfoTag()->m_artist.size() > 0 && item->GetVideoInfoTag()->m_strTitle.size() > 0) { CMusicDatabase database; database.Open(); if (database.GetSongByArtistAndAlbumAndTitle(StringUtils::Join(item->GetVideoInfoTag()->m_artist, g_advancedSettings.m_videoItemSeparator), item->GetVideoInfoTag()->m_strAlbum, item->GetVideoInfoTag()->m_strTitle) > -1) { buttons.Add(CONTEXT_BUTTON_PLAY_OTHER, 20398); } } if (!item->IsParentFolder()) { ADDON::ScraperPtr info; VIDEO::SScanSettings settings; GetScraperForItem(item.get(), info, settings); if (info && info->Content() == CONTENT_TVSHOWS) buttons.Add(CONTEXT_BUTTON_INFO, item->m_bIsFolder ? 20351 : 20352); else if (info && info->Content() == CONTENT_MUSICVIDEOS) buttons.Add(CONTEXT_BUTTON_INFO,20393); else if (info && info->Content() == CONTENT_MOVIES) buttons.Add(CONTEXT_BUTTON_INFO, 13346); // can we update the database? if (CProfilesManager::Get().GetCurrentProfile().canWriteDatabases() || g_passwordManager.bMasterUser) { if (!item->IsPlugin() && !item->IsScript() && !item->IsLiveTV() && !item->IsAddonsPath() && item->GetPath() != "sources://video/" && item->GetPath() != "special://videoplaylists/" && !StringUtils::StartsWith(item->GetPath(), "newsmartplaylist://") && !StringUtils::StartsWith(item->GetPath(), "newplaylist://") && !StringUtils::StartsWith(item->GetPath(), "newtag://")) { if (item->m_bIsFolder) { // Have both options for folders since we don't know whether all childs are watched/unwatched buttons.Add(CONTEXT_BUTTON_MARK_UNWATCHED, 16104); //Mark as UnWatched buttons.Add(CONTEXT_BUTTON_MARK_WATCHED, 16103); //Mark as Watched } else { if (item->GetOverlayImage().Equals("OverlayWatched.png")) buttons.Add(CONTEXT_BUTTON_MARK_UNWATCHED, 16104); //Mark as UnWatched else buttons.Add(CONTEXT_BUTTON_MARK_WATCHED, 16103); //Mark as Watched } } if (!g_application.IsVideoScanning() && item->IsVideoDb() && item->HasVideoInfoTag() && (item->GetVideoInfoTag()->m_type == "movie" || // movies item->GetVideoInfoTag()->m_type == "tvshow" || // tvshows item->GetVideoInfoTag()->m_type == "episode" || // episodes item->GetVideoInfoTag()->m_type == "musicvideo" || // musicvideos item->GetVideoInfoTag()->m_type == "tag" || // tags item->GetVideoInfoTag()->m_type == "set")) // sets { buttons.Add(CONTEXT_BUTTON_EDIT, 16106); } if (node == NODE_TYPE_TITLE_TVSHOWS) { if (g_application.IsVideoScanning()) buttons.Add(CONTEXT_BUTTON_STOP_SCANNING, 13353); else buttons.Add(CONTEXT_BUTTON_SCAN, 13349); } if (node == NODE_TYPE_SEASONS && item->m_bIsFolder) buttons.Add(CONTEXT_BUTTON_SET_SEASON_ART, 13511); if (node == NODE_TYPE_ACTOR && !dir.IsAllItem(item->GetPath()) && item->m_bIsFolder) { if (StringUtils::StartsWithNoCase(m_vecItems->GetPath(), "videodb://musicvideos")) // mvids buttons.Add(CONTEXT_BUTTON_SET_ARTIST_THUMB, 13359); else buttons.Add(CONTEXT_BUTTON_SET_ACTOR_THUMB, 20403); } } if (!m_vecItems->IsVideoDb() && !m_vecItems->IsVirtualDirectoryRoot()) { // non-video db items, file operations are allowed if ((CSettings::Get().GetBool("filelists.allowfiledeletion") && CUtil::SupportsWriteFileOperations(item->GetPath())) || (inPlaylists && !URIUtils::GetFileName(item->GetPath()).Equals("PartyMode-Video.xsp") && (item->IsPlayList() || item->IsSmartPlayList()))) { buttons.Add(CONTEXT_BUTTON_DELETE, 117); buttons.Add(CONTEXT_BUTTON_RENAME, 118); } // add "Set/Change content" to folders if (item->m_bIsFolder && !item->IsVideoDb() && !item->IsPlayList() && !item->IsSmartPlayList() && !item->IsLibraryFolder() && !item->IsLiveTV() && !item->IsPlugin() && !item->IsAddonsPath() && !URIUtils::IsUPnP(item->GetPath())) { if (!g_application.IsVideoScanning()) { if (info && info->Content() != CONTENT_NONE) { buttons.Add(CONTEXT_BUTTON_SET_CONTENT, 20442); buttons.Add(CONTEXT_BUTTON_SCAN, 13349); } else buttons.Add(CONTEXT_BUTTON_SET_CONTENT, 20333); } } } if (item->IsPlugin() || item->IsScript() || m_vecItems->IsPlugin()) buttons.Add(CONTEXT_BUTTON_PLUGIN_SETTINGS, 1045); } } }
bool CGUIWindowVideoNav::OnContextButton(int itemNumber, CONTEXT_BUTTON button) { CFileItemPtr item; if (itemNumber >= 0 && itemNumber < m_vecItems->Size()) item = m_vecItems->Get(itemNumber); if (CGUIDialogContextMenu::OnContextButton("video", item, button)) { //TODO should we search DB for entries from plugins? if (button == CONTEXT_BUTTON_REMOVE_SOURCE && !item->IsPlugin() && !item->IsLiveTV() &&!item->IsRSS() && !URIUtils::IsUPnP(item->GetPath())) { OnUnAssignContent(item->GetPath(),20375,20340,20341); } Refresh(); return true; } switch (button) { case CONTEXT_BUTTON_EDIT: { CONTEXT_BUTTON ret = (CONTEXT_BUTTON)CGUIDialogVideoInfo::ManageVideoItem(item); if (ret >= 0) { if (ret == CONTEXT_BUTTON_MARK_WATCHED) m_viewControl.SetSelectedItem(itemNumber + 1); Refresh(true); } return true; } case CONTEXT_BUTTON_SET_SEASON_ART: case CONTEXT_BUTTON_SET_ACTOR_THUMB: case CONTEXT_BUTTON_SET_ARTIST_THUMB: { std::string type = "season"; if (button == CONTEXT_BUTTON_SET_ACTOR_THUMB) type = "actor"; else if (button == CONTEXT_BUTTON_SET_ARTIST_THUMB) type = "artist"; bool result = CGUIDialogVideoInfo::ManageVideoItemArtwork(m_vecItems->Get(itemNumber), type); Refresh(); return result; } case CONTEXT_BUTTON_GO_TO_ARTIST: { CStdString strPath; CMusicDatabase database; database.Open(); strPath = StringUtils::Format("musicdb://artists/%ld/", database.GetArtistByName(StringUtils::Join(m_vecItems->Get(itemNumber)->GetVideoInfoTag()->m_artist, g_advancedSettings.m_videoItemSeparator))); g_windowManager.ActivateWindow(WINDOW_MUSIC_NAV,strPath); return true; } case CONTEXT_BUTTON_GO_TO_ALBUM: { CStdString strPath; CMusicDatabase database; database.Open(); strPath = StringUtils::Format("musicdb://albums/%ld/", database.GetAlbumByName(m_vecItems->Get(itemNumber)->GetVideoInfoTag()->m_strAlbum)); g_windowManager.ActivateWindow(WINDOW_MUSIC_NAV,strPath); return true; } case CONTEXT_BUTTON_PLAY_OTHER: { CMusicDatabase database; database.Open(); CSong song; if (database.GetSong(database.GetSongByArtistAndAlbumAndTitle(StringUtils::Join(m_vecItems->Get(itemNumber)->GetVideoInfoTag()->m_artist, g_advancedSettings.m_videoItemSeparator),m_vecItems->Get(itemNumber)->GetVideoInfoTag()->m_strAlbum, m_vecItems->Get(itemNumber)->GetVideoInfoTag()->m_strTitle), song)) { CApplicationMessenger::Get().PlayFile(song); } return true; } default: break; } return CGUIWindowVideoBase::OnContextButton(itemNumber, button); }
void CGUIWindowVideoNav::OnDeleteItem(CFileItemPtr pItem) { if (m_vecItems->IsParentFolder()) return; if (!m_vecItems->IsVideoDb() && !pItem->IsVideoDb()) { if (!pItem->GetPath().Equals("newsmartplaylist://video") && !pItem->GetPath().Equals("special://videoplaylists/") && !pItem->GetPath().Equals("sources://video/") && !StringUtils::StartsWithNoCase(pItem->GetPath(), "newtag://")) CGUIWindowVideoBase::OnDeleteItem(pItem); } else if (StringUtils::StartsWithNoCase(pItem->GetPath(), "videodb://movies/sets/") && pItem->GetPath().size() > 22 && pItem->m_bIsFolder) { CGUIDialogYesNo* pDialog = (CGUIDialogYesNo*)g_windowManager.GetWindow(WINDOW_DIALOG_YES_NO); pDialog->SetHeading(432); CStdString strLabel = StringUtils::Format(g_localizeStrings.Get(433),pItem->GetLabel().c_str()); pDialog->SetLine(1, strLabel); pDialog->SetLine(2, "");; pDialog->DoModal(); if (pDialog->IsConfirmed()) { CFileItemList items; CDirectory::GetDirectory(pItem->GetPath(),items,"",DIR_FLAG_NO_FILE_DIRS); for (int i=0; i<items.Size(); ++i) OnDeleteItem(items[i]); CVideoDatabaseDirectory dir; CQueryParams params; dir.GetQueryParams(pItem->GetPath(),params); m_database.DeleteSet(params.GetSetId()); } } else if (m_vecItems->GetContent() == "tags" && pItem->m_bIsFolder) { CGUIDialogYesNo* pDialog = (CGUIDialogYesNo*)g_windowManager.GetWindow(WINDOW_DIALOG_YES_NO); pDialog->SetHeading(432); CStdString strLabel = StringUtils::Format(g_localizeStrings.Get(433), pItem->GetLabel().c_str()); pDialog->SetLine(1, strLabel); pDialog->SetLine(2, ""); pDialog->DoModal(); if (pDialog->IsConfirmed()) { CVideoDatabaseDirectory dir; CQueryParams params; dir.GetQueryParams(pItem->GetPath(), params); m_database.DeleteTag(params.GetTagId(), (VIDEODB_CONTENT_TYPE)params.GetContentType()); } } else if (m_vecItems->GetPath().Equals(CUtil::VideoPlaylistsLocation()) || m_vecItems->GetPath().Equals("special://videoplaylists/")) { pItem->m_bIsFolder = false; CFileUtils::DeleteItem(pItem); } else { if (!CGUIDialogVideoInfo::DeleteVideoItem(pItem)) return; } CUtil::DeleteVideoDatabaseDirectoryCache(); }
void CGUIWindowVideoNav::LoadVideoInfo(CFileItemList &items, CVideoDatabase &database, bool allowReplaceLabels) { // TODO: this could possibly be threaded as per the music info loading, // we could also cache the info if (!items.GetContent().empty() && !items.IsPlugin()) return; // don't load for listings that have content set and weren't created from plugins CStdString content = items.GetContent(); // determine content only if it isn't set if (content.empty()) { content = database.GetContentForPath(items.GetPath()); items.SetContent(content.empty() ? "files" : content); } /* If we have a matching item in the library, so we can assign the metadata to it. In addition, we can choose * whether the item is stacked down (eg in the case of folders representing a single item) * whether or not we assign the library's labels to the item, or leave the item as is. As certain users (read: certain developers) don't want either of these to occur, we compromise by stacking items down only if stacking is available and enabled. Similarly, we assign the "clean" library labels to the item only if the "Replace filenames with library titles" setting is enabled. */ const bool stackItems = items.GetProperty("isstacked").asBoolean() || (StackingAvailable(items) && CSettings::Get().GetBool("myvideos.stackvideos")); const bool replaceLabels = allowReplaceLabels && CSettings::Get().GetBool("myvideos.replacelabels"); CFileItemList dbItems; /* NOTE: In the future when GetItemsForPath returns all items regardless of whether they're "in the library" we won't need the fetchedPlayCounts code, and can "simply" do this directly on absense of content. */ bool fetchedPlayCounts = false; if (!content.empty()) { database.GetItemsForPath(content, items.GetPath(), dbItems); dbItems.SetFastLookup(true); } for (int i = 0; i < items.Size(); i++) { CFileItemPtr pItem = items[i]; CFileItemPtr match; if (!content.empty()) /* optical media will be stacked down, so it's path won't match the base path */ match = dbItems.Get(pItem->IsOpticalMediaFile() ? pItem->GetLocalMetadataPath() : pItem->GetPath()); if (match) { pItem->UpdateInfo(*match, replaceLabels); if (stackItems) { if (match->m_bIsFolder) pItem->SetPath(match->GetVideoInfoTag()->m_strPath); else pItem->SetPath(match->GetVideoInfoTag()->m_strFileNameAndPath); // if we switch from a file to a folder item it means we really shouldn't be sorting files and // folders separately if (pItem->m_bIsFolder != match->m_bIsFolder) { items.SetSortIgnoreFolders(true); pItem->m_bIsFolder = match->m_bIsFolder; } } } else { /* NOTE: Currently we GetPlayCounts on our items regardless of whether content is set as if content is set, GetItemsForPaths doesn't return anything not in the content tables. This code can be removed once the content tables are always filled */ if (!pItem->m_bIsFolder && !fetchedPlayCounts) { database.GetPlayCounts(items.GetPath(), items); fetchedPlayCounts = true; } // preferably use some information from PVR info tag if available if (pItem->HasPVRRecordingInfoTag()) pItem->GetPVRRecordingInfoTag()->CopyClientInfo(pItem->GetVideoInfoTag()); // set the watched overlay if (pItem->IsVideo()) pItem->SetOverlayImage(CGUIListItem::ICON_OVERLAY_UNWATCHED, pItem->HasVideoInfoTag() && pItem->GetVideoInfoTag()->m_playCount > 0); } } }
bool CGUIWindowVideoNav::OnClick(int iItem) { CFileItemPtr item = m_vecItems->Get(iItem); if (!item->m_bIsFolder && item->IsVideoDb() && !item->Exists()) { CLog::Log(LOGDEBUG, "%s called on '%s' but file doesn't exist", __FUNCTION__, item->GetPath().c_str()); if (!CGUIDialogVideoInfo::DeleteVideoItemFromDatabase(item, true)) return true; // update list Refresh(true); m_viewControl.SetSelectedItem(iItem); return true; } else if (StringUtils::StartsWithNoCase(item->GetPath(), "newtag://")) { // dont allow update while scanning if (g_application.IsVideoScanning()) { CGUIDialogOK::ShowAndGetInput(257, 0, 14057, 0); return true; } //Get the new title CStdString strTag; if (!CGUIKeyboardFactory::ShowAndGetInput(strTag, g_localizeStrings.Get(20462), false)) return true; CVideoDatabase videodb; if (!videodb.Open()) return true; // get the media type and convert from plural to singular (by removing the trailing "s") CStdString mediaType = item->GetPath().substr(9); mediaType = mediaType.substr(0, mediaType.size() - 1); CStdString localizedType = CGUIDialogVideoInfo::GetLocalizedVideoType(mediaType); if (localizedType.empty()) return true; if (!videodb.GetSingleValue("tag", "tag.idTag", videodb.PrepareSQL("tag.strTag = '%s' AND tag.idTag IN (SELECT taglinks.idTag FROM taglinks WHERE taglinks.media_type = '%s')", strTag.c_str(), mediaType.c_str())).empty()) { CStdString strError = StringUtils::Format(g_localizeStrings.Get(20463), strTag.c_str()); CGUIDialogOK::ShowAndGetInput(20462, "", strError, ""); return true; } int idTag = videodb.AddTag(strTag); CFileItemList items; CStdString strLabel = StringUtils::Format(g_localizeStrings.Get(20464), localizedType.c_str()); if (CGUIDialogVideoInfo::GetItemsForTag(strLabel, mediaType, items, idTag)) { for (int index = 0; index < items.Size(); index++) { if (!items[index]->HasVideoInfoTag() || items[index]->GetVideoInfoTag()->m_iDbId <= 0) continue; videodb.AddTagToItem(items[index]->GetVideoInfoTag()->m_iDbId, idTag, mediaType); } } Refresh(true); return true; } return CGUIWindowVideoBase::OnClick(iItem); }
void CBackgroundInfoLoader::Run() { try { if (m_vecItems.size() > 0) { OnLoaderStart(); for (std::vector<CFileItemPtr>::const_iterator iter = m_vecItems.begin(); iter != m_vecItems.end(); ++iter) { CFileItemPtr pItem = *iter; // Ask the callback if we should abort if ((m_pProgressCallback && m_pProgressCallback->Abort()) || m_bStop) break; try { if (LoadItem(pItem.get()) && m_pObserver) m_pObserver->OnItemLoaded(pItem.get()); } catch (...) { CLog::Log(LOGERROR, "CBackgroundInfoLoader::LoadItem - Unhandled exception for item %s", CURL::GetRedacted(pItem->GetPath()).c_str()); } } } OnLoaderFinish(); m_bIsLoading = false; } catch (...) { m_bIsLoading = false; CLog::Log(LOGERROR, "%s - Unhandled exception", __FUNCTION__); } }
void CGUIWindowMusicBase::PlayItem(int iItem) { // restrictions should be placed in the appropiate window code // only call the base code if the item passes since this clears // the current playlist const CFileItemPtr pItem = m_vecItems->Get(iItem); #ifdef HAS_DVD_DRIVE if (pItem->IsDVD()) { MEDIA_DETECT::CAutorun::PlayDiscAskResume(pItem->GetPath()); return; } #endif // if its a folder, build a playlist if ((pItem->m_bIsFolder && !pItem->IsPlugin()) || (g_windowManager.GetActiveWindow() == WINDOW_MUSIC_NAV && pItem->IsPlayList())) { // make a copy so that we can alter the queue state CFileItemPtr item(new CFileItem(*m_vecItems->Get(iItem))); // Allow queuing of unqueueable items // when we try to queue them directly if (!item->CanQueue()) item->SetCanQueue(true); // skip ".." if (item->IsParentFolder()) return; CFileItemList queuedItems; AddItemToPlayList(item, queuedItems); if (g_partyModeManager.IsEnabled()) { g_partyModeManager.AddUserSongs(queuedItems, true); return; } /* std::string strPlayListDirectory = m_vecItems->GetPath(); URIUtils::RemoveSlashAtEnd(strPlayListDirectory); */ g_playlistPlayer.ClearPlaylist(PLAYLIST_MUSIC); g_playlistPlayer.Reset(); g_playlistPlayer.Add(PLAYLIST_MUSIC, queuedItems); g_playlistPlayer.SetCurrentPlaylist(PLAYLIST_MUSIC); // play! g_playlistPlayer.Play(); } else if (pItem->IsPlayList()) { // load the playlist the old way LoadPlayList(pItem->GetPath()); } else { // just a single item, play it //! @todo Add music-specific code for single playback of an item here (See OnClick in MediaWindow, and OnPlayMedia below) OnClick(iItem); } }
void CGUIDialogSmartPlaylistRule::OnBrowse() { CFileItemList items; CMusicDatabase database; database.Open(); CVideoDatabase videodatabase; videodatabase.Open(); std::string basePath; if (m_type.Equals("songs") || m_type.Equals("albums") || m_type.Equals("artists") || m_type.Equals("mixed")) basePath = "musicdb://"; else basePath = "videodb://"; VIDEODB_CONTENT_TYPE type = VIDEODB_CONTENT_MOVIES; if (m_type.Equals("movies")) basePath += "1/"; else if (m_type.Equals("tvshows")) { type = VIDEODB_CONTENT_TVSHOWS; basePath += "2/"; } else if (m_type.Equals("musicvideos")) { type = VIDEODB_CONTENT_MUSICVIDEOS; basePath += "3/"; } else if (m_type.Equals("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 += "2/"; } int iLabel = 0; if (m_rule.m_field == FieldGenre) { if (m_type.Equals("tvshows") || m_type.Equals("episodes") || m_type.Equals("movies")) videodatabase.GetGenresNav(basePath + "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(basePath, 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(basePath + "4/",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(basePath + "3/", items2, type); items.Append(items2); } iLabel = 562; } else if (m_rule.m_field == FieldDirector) { videodatabase.GetDirectorsNav(basePath + "5/", items, type); iLabel = 20339; } else if (m_rule.m_field == FieldStudio) { if (m_type.Equals("movies")) basePath += "6/"; else if (m_type.Equals("musicvideos") || m_type.Equals("mixed")) basePath += "7/"; else basePath += "5/"; videodatabase.GetStudiosNav(basePath, 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.Equals("tvshows") && m_rule.m_field == FieldTitle)) { videodatabase.GetTvShowsNav(basePath + "2/", items); iLabel = 20343; } else if (m_rule.m_field == FieldTitle) { if (m_type.Equals("songs")) { database.GetSongsNav("musicdb://4/", items, -1, -1, -1); iLabel = 134; } else if (m_type.Equals("movies")) { videodatabase.GetMoviesNav(basePath + "2/", items); iLabel = 20342; } else if (m_type.Equals("episodes")) { videodatabase.GetEpisodesNav(basePath + "2/-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; } else if (m_type.Equals("musicvideos")) { videodatabase.GetMusicVideosNav(basePath + "2/", items); iLabel = 20389; } else assert(false); } 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") || m_type.Equals("artists")) 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.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://1/7/", items, VIDEODB_CONTENT_MOVIES); iLabel = 20434; } else if (m_rule.m_field == FieldTag) { if (m_type == "movies") videodatabase.GetTagsNav(basePath + "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(); }
/** * 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; } bool bAllowVideo = true; // bool bAllowPictures = true; bool bAllowMusic = true; if (!g_passwordManager.IsMasterLockUnlocked(false)) { bAllowVideo = !g_settings.GetCurrentProfile().videoLocked(); // bAllowPictures = !g_settings.GetCurrentProfile().picturesLocked(); bAllowMusic = !g_settings.GetCurrentProfile().musicLocked(); } // is this a root folder we have to check the content to determine a disc type if( bRoot ) { // 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 || g_guiSettings.GetBool("dvds.autorun"))) { CStdString path = URIUtils::AddFileToFolder(pItem->GetPath(), "VIDEO_TS.IFO"); if(!CFile::Exists(path)) path = URIUtils::AddFileToFolder(pItem->GetPath(), "video_ts.ifo"); CFileItem item(path, false); item.SetLabel(g_mediaManager.GetDiskLabel(strDrive)); item.GetVideoInfoTag()->m_strFileNameAndPath = g_mediaManager.GetDiskUniqueId(strDrive); if (!startFromBeginning && !item.GetVideoInfoTag()->m_strFileNameAndPath.IsEmpty()) item.m_lStartOffset = STARTOFFSET_RESUME; g_application.PlayFile(item, false); bPlaying = true; 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 || g_guiSettings.GetBool("dvds.autorun"))) { CFileItem item(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.IsEmpty()) item.m_lStartOffset = STARTOFFSET_RESUME; g_application.PlayFile(item, false); bPlaying = true; 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.IsEmpty() && bAllowVideo && (bypassSettings || g_guiSettings.GetBool("dvds.autorun"))) { CFileItemList items; CDirectory::GetDirectory(pItem->GetPath(), items, strExt); if (items.Size()) { items.Sort(SORT_METHOD_LABEL, SORT_ORDER_ASC); g_playlistPlayer.ClearPlaylist(PLAYLIST_VIDEO); g_playlistPlayer.Add(PLAYLIST_VIDEO, items); g_playlistPlayer.SetCurrentPlaylist(PLAYLIST_VIDEO); g_playlistPlayer.Play(0); bPlaying = true; 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; strExec.Format("XBMC.RecursiveSlideShow(%s)", pItem->GetPath().c_str()); CBuiltins::Execute(strExec); return true; } */ } } } // check video first if (!nAddedToPlaylist && !bPlaying && (bypassSettings || g_guiSettings.GetBool("dvds.autorun"))) { // stack video files CFileItemList tempItems; tempItems.Append(vecItems); if (g_settings.m_videoStacking) 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 || g_guiSettings.GetBool("audiocds.autorun")) && 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; strExec.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 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(strPath, 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(strPath); 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); 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 (hints.flags & DIR_FLAG_BYPASS_CACHE) g_directoryCache.SetDirectory(strPath, 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) && !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 (!(hints.flags & DIR_FLAG_NO_FILE_DIRS) && !items.IsMusicDb() && !items.IsVideoDb() && !items.IsSmartPlayList()) FilterFileDirectories(items, hints.mask); 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; }
void CFileItemHandler::HandleFileItem(const char *ID, bool allowFile, const char *resultname, CFileItemPtr item, const CVariant ¶meterObject, const std::set<std::string> &validFields, CVariant &result, bool append /* = true */, CThumbLoader *thumbLoader /* = NULL */) { CVariant object; std::set<std::string> fields(validFields.begin(), validFields.end()); if (item.get()) { std::set<std::string>::const_iterator fileField = fields.find("file"); if (fileField != fields.end()) { if (allowFile) { if (item->HasVideoInfoTag() && !item->GetVideoInfoTag()->GetPath().empty()) object["file"] = item->GetVideoInfoTag()->GetPath().c_str(); if (item->HasMusicInfoTag() && !item->GetMusicInfoTag()->GetURL().empty()) object["file"] = item->GetMusicInfoTag()->GetURL().c_str(); if (!object.isMember("file")) object["file"] = item->GetPath().c_str(); } fields.erase(fileField); } if (ID) { if (item->HasPVRChannelInfoTag() && item->GetPVRChannelInfoTag()->ChannelID() > 0) object[ID] = item->GetPVRChannelInfoTag()->ChannelID(); else if (item->HasEPGInfoTag() && item->GetEPGInfoTag()->UniqueBroadcastID() > 0) object[ID] = item->GetEPGInfoTag()->UniqueBroadcastID(); else if (item->HasMusicInfoTag() && item->GetMusicInfoTag()->GetDatabaseId() > 0) object[ID] = (int)item->GetMusicInfoTag()->GetDatabaseId(); else if (item->HasVideoInfoTag() && item->GetVideoInfoTag()->m_iDbId > 0) object[ID] = item->GetVideoInfoTag()->m_iDbId; if (stricmp(ID, "id") == 0) { if (item->HasPVRChannelInfoTag()) object["type"] = "channel"; else if (item->HasMusicInfoTag()) { std::string type = item->GetMusicInfoTag()->GetType(); if (type == "album" || type == "song" || type == "artist") object["type"] = type; else object["type"] = "song"; } else if (item->HasVideoInfoTag() && !item->GetVideoInfoTag()->m_type.empty()) { std::string type = item->GetVideoInfoTag()->m_type; if (type == "movie" || type == "tvshow" || type == "episode" || type == "musicvideo") object["type"] = type; } else if (item->HasPictureInfoTag()) object["type"] = "picture"; if (!object.isMember("type")) object["type"] = "unknown"; if (fields.find("filetype") != fields.end()) { if (item->m_bIsFolder) object["filetype"] = "directory"; else object["filetype"] = "file"; } } } bool deleteThumbloader = false; if (thumbLoader == NULL) { if (item->HasVideoInfoTag()) thumbLoader = new CVideoThumbLoader(); else if (item->HasMusicInfoTag()) thumbLoader = new CMusicThumbLoader(); if (thumbLoader != NULL) { deleteThumbloader = true; thumbLoader->OnLoaderStart(); } } if (item->HasPVRChannelInfoTag()) FillDetails(item->GetPVRChannelInfoTag(), item, fields, object, thumbLoader); if (item->HasEPGInfoTag()) FillDetails(item->GetEPGInfoTag(), item, fields, object, thumbLoader); if (item->HasVideoInfoTag()) FillDetails(item->GetVideoInfoTag(), item, fields, object, thumbLoader); if (item->HasMusicInfoTag()) FillDetails(item->GetMusicInfoTag(), item, fields, object, thumbLoader); if (item->HasPictureInfoTag()) FillDetails(item->GetPictureInfoTag(), item, fields, object, thumbLoader); FillDetails(item.get(), item, fields, object, thumbLoader); if (deleteThumbloader) delete thumbLoader; object["label"] = item->GetLabel().c_str(); } else object = CVariant(CVariant::VariantTypeNull); if (resultname) { if (append) result[resultname].append(object); else result[resultname] = object; } }
void CGUIDialogFileBrowser::Update(const CStdString &strDirectory) { if (m_browsingForImages && m_thumbLoader.IsLoading()) m_thumbLoader.StopThread(); // get selected item int iItem = m_viewControl.GetSelectedItem(); CStdString strSelectedItem = ""; if (iItem >= 0 && iItem < m_vecItems->Size()) { CFileItemPtr pItem = (*m_vecItems)[iItem]; if (!pItem->IsParentFolder()) { strSelectedItem = pItem->GetPath(); URIUtils::RemoveSlashAtEnd(strSelectedItem); m_history.SetSelectedItem(strSelectedItem, m_Directory->GetPath().IsEmpty()?"empty":m_Directory->GetPath()); } } if (!m_singleList) { CFileItemList items; CStdString strParentPath; if (!m_rootDir.GetDirectory(strDirectory, items,m_useFileDirectories)) { CLog::Log(LOGERROR,"CGUIDialogFileBrowser::GetDirectory(%s) failed", strDirectory.c_str()); // We assume, we can get the parent // directory again CStdString strParentPath = m_history.GetParentPath(); m_history.RemoveParentPath(); Update(strParentPath); return; } // check if current directory is a root share if (!m_rootDir.IsSource(strDirectory)) { if (URIUtils::GetParentPath(strDirectory, strParentPath)) { CFileItemPtr pItem(new CFileItem("..")); pItem->SetPath(strParentPath); pItem->m_bIsFolder = true; pItem->m_bIsShareOrDrive = false; items.AddFront(pItem, 0); } } else { // yes, this is the root of a share // add parent path to the virtual directory CFileItemPtr pItem(new CFileItem("..")); pItem->SetPath(""); pItem->m_bIsShareOrDrive = false; pItem->m_bIsFolder = true; items.AddFront(pItem, 0); strParentPath = ""; } ClearFileItems(); m_vecItems->Copy(items); m_Directory->SetPath(strDirectory); m_strParentPath = strParentPath; } // if we're getting the root source listing // make sure the path history is clean if (strDirectory.IsEmpty()) m_history.ClearPathHistory(); // some evil stuff don't work with the '/' mask, e.g. shoutcast directory - make sure no files are in there if (m_browsingForFolders) { for (int i=0;i<m_vecItems->Size();++i) if (!(*m_vecItems)[i]->m_bIsFolder) { m_vecItems->Remove(i); i--; } } // No need to set thumbs m_vecItems->FillInDefaultIcons(); OnSort(); if (m_Directory->GetPath().IsEmpty() && m_addNetworkShareEnabled && (g_settings.GetMasterProfile().getLockMode() == LOCK_MODE_EVERYONE || g_settings.IsMasterUser() || g_passwordManager.bMasterUser)) { // we are in the virtual directory - add the "Add Network Location" item CFileItemPtr pItem(new CFileItem(g_localizeStrings.Get(1032))); pItem->SetPath("net://"); pItem->m_bIsFolder = true; m_vecItems->Add(pItem); } if (m_Directory->GetPath().IsEmpty() && !m_addSourceType.IsEmpty()) { CFileItemPtr pItem(new CFileItem(g_localizeStrings.Get(21359))); pItem->SetPath("source://"); pItem->m_bIsFolder = true; m_vecItems->Add(pItem); } m_viewControl.SetItems(*m_vecItems); m_viewControl.SetCurrentView((m_browsingForImages && CAutoSwitch::ByFileCount(*m_vecItems)) ? DEFAULT_VIEW_ICONS : DEFAULT_VIEW_LIST); CStdString strPath2 = m_Directory->GetPath(); URIUtils::RemoveSlashAtEnd(strPath2); strSelectedItem = m_history.GetSelectedItem(strPath2==""?"empty":strPath2); bool bSelectedFound = false; for (int i = 0; i < (int)m_vecItems->Size(); ++i) { CFileItemPtr pItem = (*m_vecItems)[i]; strPath2 = pItem->GetPath(); URIUtils::RemoveSlashAtEnd(strPath2); if (strPath2 == strSelectedItem) { m_viewControl.SetSelectedItem(i); bSelectedFound = true; break; } } // if we haven't found the selected item, select the first item if (!bSelectedFound) m_viewControl.SetSelectedItem(0); m_history.AddPath(m_Directory->GetPath()); if (m_browsingForImages) m_thumbLoader.Load(*m_vecItems); }
bool CFileItemHandler::GetField(const std::string &field, const CVariant &info, const CFileItemPtr &item, CVariant &result, bool &fetchedArt, CThumbLoader *thumbLoader /* = NULL */) { if (result.isMember(field) && !result[field].empty()) return true; // overwrite serialized values if (item) { if (field == "mimetype" && item->GetMimeType().empty()) { item->FillInMimeType(false); result[field] = item->GetMimeType(); return true; } } // check for serialized values if (info.isMember(field) && !info[field].isNull()) { result[field] = info[field]; return true; } // check if the field requires special handling if (item) { if (item->IsAlbum()) { if (field == "albumlabel") { result[field] = item->GetProperty("album_label"); return true; } if (item->HasProperty("album_" + field + "_array")) { result[field] = item->GetProperty("album_" + field + "_array"); return true; } if (item->HasProperty("album_" + field)) { result[field] = item->GetProperty("album_" + field); return true; } } if (item->HasProperty("artist_" + field + "_array")) { result[field] = item->GetProperty("artist_" + field + "_array"); return true; } if (item->HasProperty("artist_" + field)) { result[field] = item->GetProperty("artist_" + field); return true; } if (field == "art") { if (thumbLoader != NULL && item->GetArt().size() <= 0 && !fetchedArt && ((item->HasVideoInfoTag() && item->GetVideoInfoTag()->m_iDbId > -1) || (item->HasMusicInfoTag() && item->GetMusicInfoTag()->GetDatabaseId() > -1))) { thumbLoader->FillLibraryArt(*item); fetchedArt = true; } CGUIListItem::ArtMap artMap = item->GetArt(); CVariant artObj(CVariant::VariantTypeObject); for (CGUIListItem::ArtMap::const_iterator artIt = artMap.begin(); artIt != artMap.end(); ++artIt) { if (!artIt->second.empty()) artObj[artIt->first] = CTextureUtils::GetWrappedImageURL(artIt->second); } result["art"] = artObj; return true; } if (field == "thumbnail") { if (thumbLoader != NULL && !item->HasArt("thumb") && !fetchedArt && ((item->HasVideoInfoTag() && item->GetVideoInfoTag()->m_iDbId > -1) || (item->HasMusicInfoTag() && item->GetMusicInfoTag()->GetDatabaseId() > -1))) { thumbLoader->FillLibraryArt(*item); fetchedArt = true; } else if (item->HasPictureInfoTag() && !item->HasArt("thumb")) item->SetArt("thumb", CTextureUtils::GetWrappedThumbURL(item->GetPath())); if (item->HasArt("thumb")) result["thumbnail"] = CTextureUtils::GetWrappedImageURL(item->GetArt("thumb")); else result["thumbnail"] = ""; return true; } if (field == "fanart") { if (thumbLoader != NULL && !item->HasArt("fanart") && !fetchedArt && ((item->HasVideoInfoTag() && item->GetVideoInfoTag()->m_iDbId > -1) || (item->HasMusicInfoTag() && item->GetMusicInfoTag()->GetDatabaseId() > -1))) { thumbLoader->FillLibraryArt(*item); fetchedArt = true; } if (item->HasArt("fanart")) result["fanart"] = CTextureUtils::GetWrappedImageURL(item->GetArt("fanart")); else result["fanart"] = ""; return true; } if (item->HasVideoInfoTag() && item->GetVideoContentType() == VIDEODB_CONTENT_TVSHOWS) { if (item->GetVideoInfoTag()->m_iSeason < 0 && field == "season") { result[field] = (int)item->GetProperty("totalseasons").asInteger(); return true; } if (field == "watchedepisodes") { result[field] = (int)item->GetProperty("watchedepisodes").asInteger(); return true; } } if (field == "lastmodified" && item->m_dateTime.IsValid()) { result[field] = item->m_dateTime.GetAsLocalizedDateTime(); return true; } if (item->HasProperty(field)) { result[field] = item->GetProperty(field); return true; } } return false; }
void CGUIWindowMusicBase::PlayItem(int iItem) { // restrictions should be placed in the appropiate window code // only call the base code if the item passes since this clears // the current playlist const CFileItemPtr pItem = m_vecItems->Get(iItem); // special case for DAAP playlist folders bool bIsDAAPplaylist = false; #ifdef HAS_FILESYSTEM_DAAP if (pItem->IsDAAP() && pItem->m_bIsFolder) { CDAAPDirectory dirDAAP; if (dirDAAP.GetCurrLevel(pItem->GetPath()) == 0) bIsDAAPplaylist = true; } #endif // if its a folder, build a playlist if ((pItem->m_bIsFolder && !pItem->IsPlugin()) || (g_windowManager.GetActiveWindow() == WINDOW_MUSIC_NAV && pItem->IsPlayList())) { // make a copy so that we can alter the queue state CFileItemPtr item(new CFileItem(*m_vecItems->Get(iItem))); // Allow queuing of unqueueable items // when we try to queue them directly if (!item->CanQueue()) item->SetCanQueue(true); // skip ".." if (item->IsParentFolder()) return; CFileItemList queuedItems; AddItemToPlayList(item, queuedItems); if (g_partyModeManager.IsEnabled()) { g_partyModeManager.AddUserSongs(queuedItems, true); return; } /* CStdString strPlayListDirectory = m_vecItems->GetPath(); URIUtils::RemoveSlashAtEnd(strPlayListDirectory); */ g_playlistPlayer.ClearPlaylist(PLAYLIST_MUSIC); g_playlistPlayer.Reset(); g_playlistPlayer.Add(PLAYLIST_MUSIC, queuedItems); g_playlistPlayer.SetCurrentPlaylist(PLAYLIST_MUSIC); // activate the playlist window if its not activated yet if (bIsDAAPplaylist && GetID() == g_windowManager.GetActiveWindow()) g_windowManager.ActivateWindow(WINDOW_MUSIC_PLAYLIST); // play! g_playlistPlayer.Play(); } else if (pItem->IsPlayList()) { // load the playlist the old way LoadPlayList(pItem->GetPath()); } else { // just a single item, play it // TODO: Add music-specific code for single playback of an item here (See OnClick in MediaWindow, and OnPlayMedia below) OnClick(iItem); } }
bool CPlayListPlayer::Play(int iSong, bool bAutoPlay /* = false */, bool bPlayPrevious /* = false */) { if (m_iCurrentPlayList == PLAYLIST_NONE) return false; CPlayList& playlist = GetPlaylist(m_iCurrentPlayList); if (playlist.size() <= 0) return false; if (iSong < 0) iSong = 0; if (iSong >= playlist.size()) iSong = playlist.size() - 1; // check if the item itself is a playlist, and can be expanded // only allow a few levels, this could end up in a loop // if they refer to each other in a loop for(int i=0;i<5;i++) { if(!playlist.Expand(iSong)) break; } m_iCurrentSong = iSong; CFileItemPtr item = playlist[m_iCurrentSong]; playlist.SetPlayed(true); m_bPlaybackStarted = false; unsigned int playAttempt = XbmcThreads::SystemClockMillis(); if (!g_application.PlayFile(*item, bAutoPlay)) { CLog::Log(LOGERROR,"Playlist Player: skipping unplayable item: %i, path [%s]", m_iCurrentSong, item->GetPath().c_str()); playlist.SetUnPlayable(m_iCurrentSong); // abort on 100 failed CONSECTUTIVE songs if (!m_iFailedSongs) m_failedSongsStart = playAttempt; m_iFailedSongs++; if ((m_iFailedSongs >= g_advancedSettings.m_playlistRetries && g_advancedSettings.m_playlistRetries >= 0) || ((XbmcThreads::SystemClockMillis() - m_failedSongsStart >= (unsigned int)g_advancedSettings.m_playlistTimeout * 1000) && g_advancedSettings.m_playlistTimeout)) { CLog::Log(LOGDEBUG,"Playlist Player: one or more items failed to play... aborting playback"); // open error dialog CGUIDialogOK::ShowAndGetInput(16026, 16027, 16029, 0); CGUIMessage msg(GUI_MSG_PLAYLISTPLAYER_STOPPED, 0, 0, m_iCurrentPlayList, m_iCurrentSong); g_windowManager.SendThreadMessage(msg); Reset(); GetPlaylist(m_iCurrentPlayList).Clear(); m_iCurrentPlayList = PLAYLIST_NONE; m_iFailedSongs = 0; m_failedSongsStart = 0; return false; } // how many playable items are in the playlist? if (playlist.GetPlayable() > 0) { return bPlayPrevious ? PlayPrevious() : PlayNext(); } // none? then abort playback else { CLog::Log(LOGDEBUG,"Playlist Player: no more playable items... aborting playback"); CGUIMessage msg(GUI_MSG_PLAYLISTPLAYER_STOPPED, 0, 0, m_iCurrentPlayList, m_iCurrentSong); g_windowManager.SendThreadMessage(msg); Reset(); m_iCurrentPlayList = PLAYLIST_NONE; return false; } } // TODO - move the above failure logic and the below success logic // to callbacks instead so we don't rely on the return value // of PlayFile() // consecutive error counter so reset if the current item is playing m_iFailedSongs = 0; m_failedSongsStart = 0; m_bPlaybackStarted = true; m_bPlayedFirstFile = true; return true; }
bool CGUIWindowMusicBase::OnContextButton(int itemNumber, CONTEXT_BUTTON button) { CFileItemPtr item; if (itemNumber >= 0 && itemNumber < m_vecItems->Size()) item = m_vecItems->Get(itemNumber); switch (button) { case CONTEXT_BUTTON_QUEUE_ITEM: OnQueueItem(itemNumber); return true; case CONTEXT_BUTTON_INFO: OnInfo(itemNumber); return true; case CONTEXT_BUTTON_SONG_INFO: { ShowSongInfo(item.get()); return true; } case CONTEXT_BUTTON_EDIT: { CStdString playlist = item->IsPlayList() ? item->GetPath() : m_vecItems->GetPath(); // save path as activatewindow will destroy our items g_windowManager.ActivateWindow(WINDOW_MUSIC_PLAYLIST_EDITOR, playlist); // need to update m_vecItems->RemoveDiscCache(GetID()); return true; } case CONTEXT_BUTTON_EDIT_SMART_PLAYLIST: { CStdString playlist = item->IsSmartPlayList() ? item->GetPath() : m_vecItems->GetPath(); // save path as activatewindow will destroy our items if (CGUIDialogSmartPlaylistEditor::EditPlaylist(playlist, "music")) { // need to update m_vecItems->RemoveDiscCache(GetID()); Update(m_vecItems->GetPath()); } return true; } case CONTEXT_BUTTON_PLAY_ITEM: PlayItem(itemNumber); return true; case CONTEXT_BUTTON_PLAY_WITH: { VECPLAYERCORES vecCores; // base class? CPlayerCoreFactory::GetPlayers(*item, vecCores); g_application.m_eForcedNextPlayer = CPlayerCoreFactory::SelectPlayerDialog(vecCores); if( g_application.m_eForcedNextPlayer != EPC_NONE ) OnClick(itemNumber); return true; } case CONTEXT_BUTTON_PLAY_PARTYMODE: g_partyModeManager.Enable(PARTYMODECONTEXT_MUSIC, item->GetPath()); return true; case CONTEXT_BUTTON_STOP_SCANNING: { CGUIDialogMusicScan *scanner = (CGUIDialogMusicScan *)g_windowManager.GetWindow(WINDOW_DIALOG_MUSIC_SCAN); if (scanner) scanner->StopScanning(); return true; } case CONTEXT_BUTTON_NOW_PLAYING: g_windowManager.ActivateWindow(WINDOW_MUSIC_PLAYLIST); return true; case CONTEXT_BUTTON_GOTO_ROOT: Update(""); return true; case CONTEXT_BUTTON_SETTINGS: g_windowManager.ActivateWindow(WINDOW_SETTINGS_MYMUSIC); return true; case CONTEXT_BUTTON_LASTFM_UNBAN_ITEM: if (CLastFmManager::GetInstance()->Unban(*item->GetMusicInfoTag())) { g_directoryCache.ClearDirectory(m_vecItems->GetPath()); m_vecItems->RemoveDiscCache(GetID()); Update(m_vecItems->GetPath()); } return true; case CONTEXT_BUTTON_LASTFM_UNLOVE_ITEM: if (CLastFmManager::GetInstance()->Unlove(*item->GetMusicInfoTag())) { g_directoryCache.ClearDirectory(m_vecItems->GetPath()); m_vecItems->RemoveDiscCache(GetID()); Update(m_vecItems->GetPath()); } return true; default: break; } return CGUIMediaWindow::OnContextButton(itemNumber, button); }
void CAnnouncementManager::Announce(AnnouncementFlag flag, const char *sender, const char *message, CFileItemPtr item, CVariant &data) { if (!item.get()) { Announce(flag, sender, message, data); return; } // Extract db id of item CVariant object = data.isNull() || data.isObject() ? data : CVariant::VariantTypeObject; CStdString type; int id = 0; if(item->HasPVRChannelInfoTag()) { const PVR::CPVRChannel *channel = item->GetPVRChannelInfoTag(); id = channel->ChannelID(); type = "channel"; object["item"]["title"] = channel->ChannelName(); object["item"]["channeltype"] = channel->IsRadio() ? "radio" : "tv"; if (data.isMember("player") && data["player"].isMember("playerid")) object["player"]["playerid"] = channel->IsRadio() ? PLAYLIST_MUSIC : PLAYLIST_VIDEO; } else if (item->HasVideoInfoTag()) { id = item->GetVideoInfoTag()->m_iDbId; // TODO: Can be removed once this is properly handled when starting playback of a file if (id <= 0 && !item->GetPath().empty() && (!item->HasProperty(LOOKUP_PROPERTY) || item->GetProperty(LOOKUP_PROPERTY).asBoolean())) { CVideoDatabase videodatabase; if (videodatabase.Open()) { CStdString path = item->GetPath(); CStdString videoInfoTagPath(item->GetVideoInfoTag()->m_strFileNameAndPath); if (StringUtils::StartsWith(videoInfoTagPath, "removable://")) path = videoInfoTagPath; if (videodatabase.LoadVideoInfo(path, *item->GetVideoInfoTag())) id = item->GetVideoInfoTag()->m_iDbId; videodatabase.Close(); } } if (!item->GetVideoInfoTag()->m_type.empty()) type = item->GetVideoInfoTag()->m_type; else CVideoDatabase::VideoContentTypeToString((VIDEODB_CONTENT_TYPE)item->GetVideoContentType(), type); if (id <= 0) { // TODO: Can be removed once this is properly handled when starting playback of a file item->SetProperty(LOOKUP_PROPERTY, false); CStdString title = item->GetVideoInfoTag()->m_strTitle; if (title.empty()) title = item->GetLabel(); object["item"]["title"] = title; switch (item->GetVideoContentType()) { case VIDEODB_CONTENT_MOVIES: if (item->GetVideoInfoTag()->m_iYear > 0) object["item"]["year"] = item->GetVideoInfoTag()->m_iYear; break; case VIDEODB_CONTENT_EPISODES: if (item->GetVideoInfoTag()->m_iEpisode >= 0) object["item"]["episode"] = item->GetVideoInfoTag()->m_iEpisode; if (item->GetVideoInfoTag()->m_iSeason >= 0) object["item"]["season"] = item->GetVideoInfoTag()->m_iSeason; if (!item->GetVideoInfoTag()->m_strShowTitle.empty()) object["item"]["showtitle"] = item->GetVideoInfoTag()->m_strShowTitle; break; case VIDEODB_CONTENT_MUSICVIDEOS: if (!item->GetVideoInfoTag()->m_strAlbum.empty()) object["item"]["album"] = item->GetVideoInfoTag()->m_strAlbum; if (!item->GetVideoInfoTag()->m_artist.empty()) object["item"]["artist"] = StringUtils::Join(item->GetVideoInfoTag()->m_artist, " / "); break; } } } else if (item->HasMusicInfoTag()) { id = item->GetMusicInfoTag()->GetDatabaseId(); type = MediaTypeSong; // TODO: Can be removed once this is properly handled when starting playback of a file if (id <= 0 && !item->GetPath().empty() && (!item->HasProperty(LOOKUP_PROPERTY) || item->GetProperty(LOOKUP_PROPERTY).asBoolean())) { CMusicDatabase musicdatabase; if (musicdatabase.Open()) { CSong song; if (musicdatabase.GetSongByFileName(item->GetPath(), song, item->m_lStartOffset)) { item->GetMusicInfoTag()->SetSong(song); id = item->GetMusicInfoTag()->GetDatabaseId(); } musicdatabase.Close(); } } if (id <= 0) { // TODO: Can be removed once this is properly handled when starting playback of a file item->SetProperty(LOOKUP_PROPERTY, false); CStdString title = item->GetMusicInfoTag()->GetTitle(); if (title.empty()) title = item->GetLabel(); object["item"]["title"] = title; if (item->GetMusicInfoTag()->GetTrackNumber() > 0) object["item"]["track"] = item->GetMusicInfoTag()->GetTrackNumber(); if (!item->GetMusicInfoTag()->GetAlbum().empty()) object["item"]["album"] = item->GetMusicInfoTag()->GetAlbum(); if (!item->GetMusicInfoTag()->GetArtist().empty()) object["item"]["artist"] = item->GetMusicInfoTag()->GetArtist(); } } else if (item->IsVideo()) { // video item but has no video info tag. type = "movies"; object["item"]["title"] = item->GetLabel(); } else if (item->HasPictureInfoTag()) { type = "picture"; object["item"]["file"] = item->GetPath(); } else type = "unknown"; object["item"]["type"] = type; if (id > 0) object["item"]["id"] = id; Announce(flag, sender, message, object); }
/** * 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(SORT_METHOD_LABEL, 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"); CFileItem item(path, false); item.SetLabel(g_mediaManager.GetDiskLabel(strDrive)); item.GetVideoInfoTag()->m_strFileNameAndPath = g_mediaManager.GetDiskUniqueId(strDrive); if (!startFromBeginning && !item.GetVideoInfoTag()->m_strFileNameAndPath.IsEmpty()) item.m_lStartOffset = STARTOFFSET_RESUME; g_application.PlayFile(item, false); bPlaying = true; 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"))) { CFileItem item(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.IsEmpty()) item.m_lStartOffset = STARTOFFSET_RESUME; g_application.PlayFile(item, false); bPlaying = true; 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(SORT_METHOD_LABEL, 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(SORT_METHOD_LABEL, 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(SORT_METHOD_LABEL, 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(SORT_METHOD_SIZE, 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.IsEmpty()) 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); bPlaying = true; 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); bPlaying = true; 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.IsEmpty() && bAllowVideo && (bypassSettings || CSettings::Get().GetBool("dvds.autorun"))) { CFileItemList items; CDirectory::GetDirectory(pItem->GetPath(), items, strExt); if (items.Size()) { items.Sort(SORT_METHOD_LABEL, SortOrderAscending); g_playlistPlayer.ClearPlaylist(PLAYLIST_VIDEO); g_playlistPlayer.Add(PLAYLIST_VIDEO, items); g_playlistPlayer.SetCurrentPlaylist(PLAYLIST_VIDEO); g_playlistPlayer.Play(0); bPlaying = true; 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; strExec.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; strExec.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; }
void CFileItemHandler::HandleFileItem(const char *ID, bool allowFile, const char *resultname, CFileItemPtr item, const CVariant ¶meterObject, const CVariant &validFields, CVariant &result, bool append /* = true */) { CVariant object; bool hasFileField = false; bool hasThumbnailField = false; if (item.get()) { for (unsigned int i = 0; i < validFields.size(); i++) { CStdString field = validFields[i].asString(); if (field == "file") hasFileField = true; if (field == "thumbnail") hasThumbnailField = true; } if (allowFile && hasFileField) { if (item->HasVideoInfoTag() && !item->GetVideoInfoTag()->GetPath().IsEmpty()) object["file"] = item->GetVideoInfoTag()->GetPath().c_str(); if (item->HasMusicInfoTag() && !item->GetMusicInfoTag()->GetURL().IsEmpty()) object["file"] = item->GetMusicInfoTag()->GetURL().c_str(); if (!object.isMember("file")) object["file"] = item->GetPath().c_str(); } if (ID) { if (stricmp(ID, "genreid") == 0) { CStdString genre = item->GetPath(); genre.TrimRight('/'); object[ID] = atoi(genre.c_str()); } else if (item->HasMusicInfoTag() && item->GetMusicInfoTag()->GetDatabaseId() > 0) object[ID] = (int)item->GetMusicInfoTag()->GetDatabaseId(); else if (item->HasVideoInfoTag() && item->GetVideoInfoTag()->m_iDbId > 0) object[ID] = item->GetVideoInfoTag()->m_iDbId; if (stricmp(ID, "id") == 0) { if (item->HasMusicInfoTag()) { if (item->m_bIsFolder && item->IsAlbum()) object["type"] = "album"; else object["type"] = "song"; } else if (item->HasVideoInfoTag()) { switch (item->GetVideoContentType()) { case VIDEODB_CONTENT_EPISODES: object["type"] = "episode"; break; case VIDEODB_CONTENT_MUSICVIDEOS: object["type"] = "musicvideo"; break; case VIDEODB_CONTENT_MOVIES: object["type"] = "movie"; break; default: break; } } else if (item->HasPictureInfoTag()) object["type"] = "picture"; if (!object.isMember("type")) object["type"] = "unknown"; } } if (hasThumbnailField) { if (item->HasThumbnail()) object["thumbnail"] = item->GetThumbnailImage().c_str(); else if (item->HasVideoInfoTag()) { CStdString strPath, strFileName; URIUtils::Split(item->GetCachedVideoThumb(), strPath, strFileName); CStdString cachedThumb = strPath + "auto-" + strFileName; if (CFile::Exists(cachedThumb)) object["thumbnail"] = cachedThumb; } else if (item->HasPictureInfoTag()) { CStdString thumb = CTextureCache::Get().CheckAndCacheImage(CTextureCache::GetWrappedThumbURL(item->GetPath())); if (!thumb.empty()) object["thumbnail"] = thumb; } if (!object.isMember("thumbnail")) object["thumbnail"] = ""; } if (item->HasVideoInfoTag()) FillDetails(item->GetVideoInfoTag(), item, validFields, object); if (item->HasMusicInfoTag()) FillDetails(item->GetMusicInfoTag(), item, validFields, object); if (item->HasPictureInfoTag()) FillDetails(item->GetPictureInfoTag(), item, validFields, object); object["label"] = item->GetLabel().c_str(); } else object = CVariant(CVariant::VariantTypeNull); if (resultname) { if (append) result[resultname].append(object); else result[resultname] = object; } }
bool CGUIDialogVideoInfo::OnMessage(CGUIMessage& message) { switch ( message.GetMessage() ) { case GUI_MSG_WINDOW_DEINIT: { ClearCastList(); } break; case GUI_MSG_WINDOW_INIT: { m_dlgProgress = (CGUIDialogProgress*)g_windowManager.GetWindow(WINDOW_DIALOG_PROGRESS); m_bRefresh = false; m_bRefreshAll = true; m_hasUpdatedThumb = false; CGUIDialog::OnMessage(message); m_bViewReview = true; CVideoDatabase database; ADDON::ScraperPtr scraper; if(database.Open()) { scraper = database.GetScraperForPath(m_movieItem->GetVideoInfoTag()->GetPath()); database.Close(); } CONTROL_ENABLE_ON_CONDITION(CONTROL_BTN_REFRESH, (g_settings.GetCurrentProfile().canWriteDatabases() || g_passwordManager.bMasterUser) && !m_movieItem->GetVideoInfoTag()->m_strIMDBNumber.Left(2).Equals("xx") && scraper); CONTROL_ENABLE_ON_CONDITION(CONTROL_BTN_GET_THUMB, (g_settings.GetCurrentProfile().canWriteDatabases() || g_passwordManager.bMasterUser) && !m_movieItem->GetVideoInfoTag()->m_strIMDBNumber.Mid(2).Equals("plugin")); VIDEODB_CONTENT_TYPE type = (VIDEODB_CONTENT_TYPE)m_movieItem->GetVideoContentType(); if (type == VIDEODB_CONTENT_TVSHOWS || type == VIDEODB_CONTENT_MOVIES) CONTROL_ENABLE_ON_CONDITION(CONTROL_BTN_GET_FANART, (g_settings.GetCurrentProfile().canWriteDatabases() || g_passwordManager.bMasterUser) && !m_movieItem->GetVideoInfoTag()->m_strIMDBNumber.Mid(2).Equals("plugin")); else CONTROL_DISABLE(CONTROL_BTN_GET_FANART); Update(); return true; } break; case GUI_MSG_CLICKED: { int iControl = message.GetSenderId(); if (iControl == CONTROL_BTN_REFRESH) { if (m_movieItem->GetVideoInfoTag()->m_iSeason < 0 && !m_movieItem->GetVideoInfoTag()->m_strShowTitle.IsEmpty()) // tv show { bool bCanceled=false; if (CGUIDialogYesNo::ShowAndGetInput(20377,20378,-1,-1,bCanceled)) { m_bRefreshAll = true; CVideoDatabase db; if (db.Open()) { db.SetPathHash(m_movieItem->GetVideoInfoTag()->m_strPath,""); db.Close(); } } else m_bRefreshAll = false; if (bCanceled) return false; } m_bRefresh = true; Close(); return true; } else if (iControl == CONTROL_BTN_TRACKS) { m_bViewReview = !m_bViewReview; Update(); } else if (iControl == CONTROL_BTN_PLAY) { Play(); } else if (iControl == CONTROL_BTN_RESUME) { Play(true); } else if (iControl == CONTROL_BTN_GET_THUMB) { OnGetThumb(); } else if (iControl == CONTROL_BTN_PLAY_TRAILER) { PlayTrailer(); } else if (iControl == CONTROL_BTN_GET_FANART) { OnGetFanart(); } else if (iControl == CONTROL_BTN_DIRECTOR) { CStdString strDirector = StringUtils::Join(m_movieItem->GetVideoInfoTag()->m_director, g_advancedSettings.m_videoItemSeparator); OnSearch(strDirector); } else if (iControl == CONTROL_LIST) { int iAction = message.GetParam1(); if (ACTION_SELECT_ITEM == iAction || ACTION_MOUSE_LEFT_CLICK == iAction) { CGUIMessage msg(GUI_MSG_ITEM_SELECTED, GetID(), iControl); OnMessage(msg); int iItem = msg.GetParam1(); if (iItem < 0 || iItem >= m_castList->Size()) break; CStdString strItem = m_castList->Get(iItem)->GetLabel(); CStdString strFind; strFind.Format(" %s ",g_localizeStrings.Get(20347)); int iPos = strItem.Find(strFind); if (iPos == -1) iPos = strItem.size(); CStdString tmp = strItem.Left(iPos); OnSearch(tmp); } } } break; case GUI_MSG_NOTIFY_ALL: { if (IsActive() && message.GetParam1() == GUI_MSG_UPDATE_ITEM && message.GetItem()) { CFileItemPtr item = boost::static_pointer_cast<CFileItem>(message.GetItem()); if (item && m_movieItem->GetPath().Equals(item->GetPath())) { // Just copy over the stream details and the thumb if we don't already have one if (!m_movieItem->HasThumbnail()) m_movieItem->SetThumbnailImage(item->GetThumbnailImage()); m_movieItem->GetVideoInfoTag()->m_streamDetails = item->GetVideoInfoTag()->m_streamDetails; } return true; } } } return CGUIDialog::OnMessage(message); }
bool Addon_music_spotify::GetContextButtons(CFileItemPtr& item, CContextButtons &buttons) { if (isReady()) { CURL url(item->GetPath()); CStdString uri = url.GetFileNameWithoutPath(); //the path will look something like this "musicdb://2/spotify:artist:0LcJLqbBmaGUft1e9Mm8HV/-1/" //if we are trying to show all tracks for a spotify artist, we cant use the params becouse they are only integers. if (uri.Left(13).Equals("spotify:album")) { uri = uri.Left(uri.Find('#')); sp_link *spLink = sp_link_create_from_string(uri); sp_album *spAlbum = sp_link_as_album(spLink); SxAlbum* salbum = AlbumStore::getInstance()->getAlbum(spAlbum, true); if (salbum) { buttons.Add( CONTEXT_BUTTON_SPOTIFY_TOGGLE_STAR_ALBUM, salbum->isStarred() ? Settings::getInstance()->getUnstarAlbumString() : Settings::getInstance()->getStarAlbumString()); AlbumStore::getInstance()->removeAlbum(salbum); buttons.Add(CONTEXT_BUTTON_SPOTIFY_BROWSE_ARTIST, Settings::getInstance()->getBrowseArtistString()); } sp_link_release(spLink); sp_album_release(spAlbum); } else if (uri.Left(13).Equals("spotify:track")) { uri = uri.Left(uri.Find('.')); Logger::printOut(uri); sp_link *spLink = sp_link_create_from_string(uri); sp_track* spTrack = sp_link_as_track(spLink); buttons.Add( CONTEXT_BUTTON_SPOTIFY_TOGGLE_STAR_TRACK, sp_track_is_starred(Session::getInstance()->getSpSession(), spTrack) ? Settings::getInstance()->getUnstarTrackString() : Settings::getInstance()->getStarTrackString()); buttons.Add(CONTEXT_BUTTON_SPOTIFY_BROWSE_ALBUM, Settings::getInstance()->getBrowseAlbumString()); buttons.Add(CONTEXT_BUTTON_SPOTIFY_BROWSE_ARTIST, Settings::getInstance()->getBrowseArtistString()); //this is unstable as it is now... find a solution later SxAlbum* salbum = AlbumStore::getInstance()->getAlbum( sp_track_album(spTrack), true); if (salbum) { while (!Session::getInstance()->lock()) ; while (!salbum->isLoaded()) { Session::getInstance()->processEvents(); } Session::getInstance()->unlock(); buttons.Add( CONTEXT_BUTTON_SPOTIFY_TOGGLE_STAR_ALBUM, salbum->isStarred() ? Settings::getInstance()->getUnstarAlbumString() : Settings::getInstance()->getStarAlbumString()); AlbumStore::getInstance()->removeAlbum(salbum); } sp_track_release(spTrack); sp_link_release(spLink); } } return true; }