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 CPVRRecordings::GetSubDirectories(const CStdString &strBase, CFileItemList *results, bool bAutoSkip /* = true */) { CStdString strUseBase = TrimSlashes(strBase); std::set<CStdString> unwatchedFolders; for (unsigned int iRecordingPtr = 0; iRecordingPtr < m_recordings.size(); iRecordingPtr++) { CPVRRecording *current = m_recordings.at(iRecordingPtr); const CStdString strCurrent = GetDirectoryFromPath(current->m_strDirectory, strUseBase); if (strCurrent.IsEmpty()) continue; CStdString strFilePath; if(strUseBase.empty()) strFilePath.Format("pvr://recordings/%s/", strCurrent.c_str()); else strFilePath.Format("pvr://recordings/%s/%s/", strUseBase.c_str(), strCurrent.c_str()); if (!results->Contains(strFilePath)) { current->UpdateMetadata(); CFileItemPtr pFileItem; pFileItem.reset(new CFileItem(strCurrent, true)); pFileItem->SetPath(strFilePath); pFileItem->SetLabel(strCurrent); pFileItem->SetLabelPreformated(true); pFileItem->m_dateTime = current->RecordingTimeAsLocalTime(); // Initialize folder overlay from play count (either directly from client or from video database) if (current->m_playCount > 0) pFileItem->SetOverlayImage(CGUIListItem::ICON_OVERLAY_WATCHED, false); else unwatchedFolders.insert(strFilePath); results->Add(pFileItem); } else { CFileItemPtr pFileItem; pFileItem=results->Get(strFilePath); if (pFileItem->m_dateTime<current->RecordingTimeAsLocalTime()) pFileItem->m_dateTime = current->RecordingTimeAsLocalTime(); // Unset folder overlay if recording is unwatched if (unwatchedFolders.find(strFilePath) == unwatchedFolders.end()) { if (current->m_playCount == 0) { pFileItem->SetOverlayImage(CGUIListItem::ICON_OVERLAY_UNWATCHED, false); unwatchedFolders.insert(strFilePath); } } } } int subDirectories = results->Size(); CFileItemList files; GetContents(strBase, &files); if (bAutoSkip && results->Size() == 1 && files.Size() == 0) { CStdString strGetPath; strGetPath.Format("%s/%s/", strUseBase.c_str(), results->Get(0)->GetLabel()); results->Clear(); CLog::Log(LOGDEBUG, "CPVRRecordings - %s - '%s' only has 1 subdirectory, selecting that directory ('%s')", __FUNCTION__, strUseBase.c_str(), strGetPath.c_str()); GetSubDirectories(strGetPath, results, true); return; } results->Append(files); // Add 'All Recordings' item (if we have at least one subdirectory in the list) if (subDirectories > 0) { CStdString strLabel(g_localizeStrings.Get(19270)); // "* All recordings" CFileItemPtr pItem(new CFileItem(strLabel)); CStdString strAllPath; if(strUseBase.empty()) strAllPath = "pvr://recordings"; else strAllPath.Format("pvr://recordings/%s", strUseBase.c_str()); pItem->SetPath(AddAllRecordingsPathExtension(strAllPath)); pItem->SetSpecialSort(SortSpecialOnTop); pItem->SetLabelPreformated(true); pItem->m_bIsFolder = true; pItem->m_bIsShareOrDrive = false; for(int i=0; i<results->Size(); ++i) { if(pItem->m_dateTime < results->Get(i)->m_dateTime) pItem->m_dateTime = results->Get(i)->m_dateTime; } results->AddFront(pItem, 0); } }
bool CGUIWindowPrograms::OnContextButton(int itemNumber, CONTEXT_BUTTON button) { CFileItemPtr item = (itemNumber >= 0 && itemNumber < m_vecItems->Size()) ? m_vecItems->Get(itemNumber) : CFileItemPtr(); if (item && m_vecItems->IsVirtualDirectoryRoot()) { CMediaSource *share = CGUIDialogContextMenu::GetShare("programs", item.get()); if (CGUIDialogContextMenu::OnContextButton("programs", share, button)) { Update(""); return true; } } switch (button) { case CONTEXT_BUTTON_RENAME: { CStdString strDescription; CShortcut cut; if (item->IsShortCut()) { cut.Create(item->m_strPath); strDescription = cut.m_strLabel; } else strDescription = item->GetLabel(); if (CGUIDialogKeyboard::ShowAndGetInput(strDescription, g_localizeStrings.Get(16008), false)) { if (item->IsShortCut()) { cut.m_strLabel = strDescription; cut.Save(item->m_strPath); } else { // SetXBEDescription will truncate to 40 characters. //CUtil::SetXBEDescription(item->m_strPath,strDescription); //m_database.SetDescription(item->m_strPath,strDescription); } Update(m_vecItems->m_strPath); } return true; } case CONTEXT_BUTTON_SETTINGS: m_gWindowManager.ActivateWindow(WINDOW_SETTINGS_MYPROGRAMS); return true; case CONTEXT_BUTTON_GOTO_ROOT: Update(""); return true; case CONTEXT_BUTTON_LAUNCH: OnClick(itemNumber); return true; default: break; } return CGUIMediaWindow::OnContextButton(itemNumber, button); }
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 (URIUtils::PathEquals(m_shares[iSource].strPath, m_selectedPath)) bFool = false; } if (bFool && !CDirectory::Exists(m_selectedPath)) m_selectedPath.clear(); } else { if (!CFile::Exists(m_selectedPath) && !CDirectory::Exists(m_selectedPath)) m_selectedPath.clear(); } // 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) { int iItem = m_viewControl.GetSelectedItem(); std::string strPath; if (iItem == 0) strPath = m_selectedPath; else strPath = (*m_vecItems)[iItem]->GetPath(); std::string strTest = URIUtils::AddFileToFolder(strPath, "1"); CFile file; if (file.OpenForWrite(strTest,true)) { file.Close(); CFile::Delete(strTest); m_bConfirmed = true; Close(); } else CGUIDialogOK::ShowAndGetInput(CVariant{257}, CVariant{20072}); } 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) { std::string strInput; if (CGUIKeyboardFactory::ShowAndGetInput(strInput, CVariant{g_localizeStrings.Get(119)}, false)) { std::string strPath = URIUtils::AddFileToFolder(m_vecItems->GetPath(), strInput); if (CDirectory::Create(strPath)) Update(m_vecItems->GetPath()); else CGUIDialogOK::ShowAndGetInput(CVariant{20069}, CVariant{20072}); } } 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); }
bool CGUIDialogFileBrowser::OnPopupMenu(int iItem) { CContextButtons choices; choices.Add(1, m_addSourceType.empty() ? 20133 : 21364); choices.Add(2, m_addSourceType.empty() ? 20134 : 21365); int btnid = CGUIDialogContextMenu::ShowAndGetChoice(choices); if (btnid == 1) { if (m_addNetworkShareEnabled) { std::string strOldPath=m_selectedPath,newPath=m_selectedPath; VECSOURCES shares=m_shares; if (CGUIDialogNetworkSetup::ShowAndGetNetworkAddress(newPath)) { g_mediaManager.SetLocationPath(strOldPath,newPath); for (unsigned int i=0;i<shares.size();++i) { if (URIUtils::CompareWithoutSlashAtEnd(shares[i].strPath, strOldPath))//getPath().Equals(strOldPath)) { shares[i].strName = newPath; shares[i].strPath = newPath;//setPath(newPath); URIUtils::RemoveSlashAtEnd(shares[i].strName); break; } } // re-open our dialog SetSources(shares); m_rootDir.SetMask("/"); m_browsingForFolders = 1; m_addNetworkShareEnabled = true; m_selectedPath = newPath; DoModal(); } } else { CFileItemPtr item = m_vecItems->Get(iItem); OnEditMediaSource(item.get()); } } if (btnid == 2) { if (m_addNetworkShareEnabled) { g_mediaManager.RemoveLocation(m_selectedPath); for (unsigned int i=0;i<m_shares.size();++i) { if (URIUtils::CompareWithoutSlashAtEnd(m_shares[i].strPath, m_selectedPath) && !m_shares[i].m_ignore) // getPath().Equals(m_selectedPath)) { m_shares.erase(m_shares.begin()+i); break; } } m_rootDir.SetSources(m_shares); m_rootDir.SetMask("/"); m_browsingForFolders = 1; m_addNetworkShareEnabled = true; m_selectedPath = ""; Update(m_Directory->GetPath()); } else { CMediaSourceSettings::Get().DeleteSource(m_addSourceType,(*m_vecItems)[iItem]->GetLabel(),(*m_vecItems)[iItem]->GetPath()); SetSources(*CMediaSourceSettings::Get().GetSources(m_addSourceType)); Update(""); } } return true; }
/// \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->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) CMusicDbUrl musicUrl; if (musicUrl.FromString(pItem->GetPath())) { musicUrl.AppendPath("-1/"); CFileItemPtr item(new CFileItem(musicUrl.ToString(), 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); for (int i = 0; i < items.Size(); ++i) AddItemToPlayList(items[i], queuedItems); } else { if (pItem->IsPlayList()) { unique_ptr<CPlayList> pPlayList (CPlayListFactory::Create(*pItem)); if (pPlayList.get()) { // load it if (!pPlayList->Load(pItem->GetPath())) { CGUIDialogOK::ShowAndGetInput(CVariant{6}, CVariant{477}); 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->IsNFO() && (pItem->IsAudio() || pItem->IsVideo())) { 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 CMusicInfoLoader::LoadItemLookup(CFileItem* pItem) { if (m_pProgressCallback && !pItem->m_bIsFolder) m_pProgressCallback->SetProgressAdvance(); if (pItem->m_bIsFolder || pItem->IsPlayList() || pItem->IsNFO() || pItem->IsInternetStream()) return false; if (!pItem->HasMusicInfoTag() || !pItem->GetMusicInfoTag()->Loaded()) { // first check the cached item CFileItemPtr mapItem = (*m_mapFileItems)[pItem->GetPath()]; if (mapItem && mapItem->m_dateTime==pItem->m_dateTime && mapItem->HasMusicInfoTag() && mapItem->GetMusicInfoTag()->Loaded()) { // Query map if we previously cached the file on HD *pItem->GetMusicInfoTag() = *mapItem->GetMusicInfoTag(); if (mapItem->HasArt("thumb")) pItem->SetArt("thumb", mapItem->GetArt("thumb")); } else { std::string strPath = URIUtils::GetDirectory(pItem->GetPath()); URIUtils::AddSlashAtEnd(strPath); if (strPath!=m_strPrevPath) { // The item is from another directory as the last one, // query the database for the new directory... m_musicDatabase.GetSongsByPath(strPath, m_songsMap); m_databaseHits++; } MAPSONGS::iterator it = m_songsMap.find(pItem->GetPath()); if (it != m_songsMap.end()) { // Have we loaded this item from database before pItem->GetMusicInfoTag()->SetSong(it->second); pItem->GetMusicInfoTag()->SetCueSheet(m_musicDatabase.LoadCuesheet(it->second.strFileName)); if (!it->second.strThumb.empty()) pItem->SetArt("thumb", it->second.strThumb); } else if (pItem->IsMusicDb()) { // a music db item that doesn't have tag loaded - grab details from the database XFILE::MUSICDATABASEDIRECTORY::CQueryParams param; XFILE::MUSICDATABASEDIRECTORY::CDirectoryNode::GetDatabaseInfo(pItem->GetPath(),param); CSong song; if (m_musicDatabase.GetSong(param.GetSongId(), song)) { pItem->GetMusicInfoTag()->SetSong(song); if (!song.strThumb.empty()) pItem->SetArt("thumb", song.strThumb); } } else if (CSettings::GetInstance().GetBool(CSettings::SETTING_MUSICFILES_USETAGS) || pItem->IsCDDA()) { // Nothing found, load tag from file, // always try to load cddb info // get correct tag parser unique_ptr<IMusicInfoTagLoader> pLoader (CMusicInfoTagLoaderFactory::CreateLoader(*pItem)); if (NULL != pLoader.get()) // get tag pLoader->Load(pItem->GetPath(), *pItem->GetMusicInfoTag()); m_tagReads++; } m_strPrevPath = strPath; } } return true; }
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; }
bool GroupUtils::Group(GroupBy groupBy, const std::string &baseDir, const CFileItemList &items, CFileItemList &groupedItems, GroupAttribute groupAttributes /* = GroupAttributeNone */) { if (items.Size() <= 0 || groupBy == GroupByNone) return false; SetMap setMap; for (int index = 0; index < items.Size(); index++) { bool add = true; const CFileItemPtr item = items.Get(index); // group by sets if ((groupBy & GroupBySet) && item->HasVideoInfoTag() && item->GetVideoInfoTag()->m_iSetId > 0) { add = false; setMap[item->GetVideoInfoTag()->m_iSetId].insert(item); } if (add) groupedItems.Add(item); } if ((groupBy & GroupBySet) && setMap.size() > 0) { CVideoDbUrl itemsUrl; if (!itemsUrl.FromString(baseDir)) return false; for (SetMap::const_iterator set = setMap.begin(); set != setMap.end(); set++) { // only one item in the set, so just re-add it if (set->second.size() == 1 && (groupAttributes & GroupAttributeIgnoreSingleItems)) { groupedItems.Add(*set->second.begin()); continue; } CFileItemPtr pItem(new CFileItem((*set->second.begin())->GetVideoInfoTag()->m_strSet)); pItem->GetVideoInfoTag()->m_iDbId = set->first; pItem->GetVideoInfoTag()->m_type = "set"; std::string basePath = StringUtils::Format("videodb://1/7/%ld/", set->first); CVideoDbUrl videoUrl; if (!videoUrl.FromString(basePath)) pItem->SetPath(basePath); else { videoUrl.AddOptions(itemsUrl.GetOptionsString()); pItem->SetPath(videoUrl.ToString()); } pItem->m_bIsFolder = true; CVideoInfoTag* setInfo = pItem->GetVideoInfoTag(); setInfo->m_strPath = pItem->GetPath(); setInfo->m_strTitle = pItem->GetLabel(); int ratings = 0; int iWatched = 0; // have all the movies been played at least once? std::set<CStdString> pathSet; for (std::set<CFileItemPtr>::const_iterator movie = set->second.begin(); movie != set->second.end(); movie++) { CVideoInfoTag* movieInfo = (*movie)->GetVideoInfoTag(); // handle rating if (movieInfo->m_fRating > 0.0f) { ratings++; setInfo->m_fRating += movieInfo->m_fRating; } // handle year if (movieInfo->m_iYear > setInfo->m_iYear) setInfo->m_iYear = movieInfo->m_iYear; // handle lastplayed if (movieInfo->m_lastPlayed.IsValid() && movieInfo->m_lastPlayed > setInfo->m_lastPlayed) setInfo->m_lastPlayed = movieInfo->m_lastPlayed; // handle dateadded if (movieInfo->m_dateAdded.IsValid() && movieInfo->m_dateAdded > setInfo->m_dateAdded) setInfo->m_dateAdded = movieInfo->m_dateAdded; // handle playcount/watched setInfo->m_playCount += movieInfo->m_playCount; if (movieInfo->m_playCount > 0) iWatched++; //accumulate the path for a multipath construction CFileItem video(movieInfo->m_basePath, false); if (video.IsVideo()) pathSet.insert(URIUtils::GetParentPath(movieInfo->m_basePath)); else pathSet.insert(movieInfo->m_basePath); } setInfo->m_basePath = XFILE::CMultiPathDirectory::ConstructMultiPath(pathSet); if (ratings > 1) pItem->GetVideoInfoTag()->m_fRating /= ratings; setInfo->m_playCount = iWatched >= (int)set->second.size() ? (setInfo->m_playCount / set->second.size()) : 0; pItem->SetProperty("total", (int)set->second.size()); pItem->SetProperty("watched", iWatched); pItem->SetProperty("unwatched", (int)set->second.size() - iWatched); pItem->SetOverlayImage(CGUIListItem::ICON_OVERLAY_UNWATCHED, setInfo->m_playCount > 0); groupedItems.Add(pItem); } } return true; }
/** * This method tries to determine what type of disc is located in the given drive and starts to play the content appropriately. */ bool CAutorun::RunDisc(IDirectory* pDir, const std::string& strDrive, int& nAddedToPlaylist, bool bRoot, bool bypassSettings /* = false */, bool startFromBeginning /* = false */) { bool bPlaying(false); CFileItemList vecItems; const CURL pathToUrl(strDrive); if ( !pDir->GetDirectory( pathToUrl, vecItems ) ) { return false; } // Sorting necessary for easier HDDVD handling vecItems.Sort(SortByLabel, SortOrderAscending); bool bAllowVideo = true; // bool bAllowPictures = true; bool bAllowMusic = true; if (!g_passwordManager.IsMasterLockUnlocked(false)) { bAllowVideo = !CProfilesManager::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 ) { std::string hddvdname = ""; CFileItemPtr phddvdItem; // check root folders next, for normal structured dvd's for (int i = 0; i < vecItems.Size(); i++) { CFileItemPtr pItem = vecItems[i]; // is the current item a (non system) folder? if (pItem->m_bIsFolder && pItem->GetPath() != "." && pItem->GetPath() != "..") { std::string name = pItem->GetPath(); URIUtils::RemoveSlashAtEnd(name); name = URIUtils::GetFileName(name); // Check if the current foldername indicates a DVD structure (name is "VIDEO_TS") if (StringUtils::EqualsNoCase(name, "VIDEO_TS") && bAllowVideo && (bypassSettings || CSettings::Get().GetBool("dvds.autorun"))) { std::string path = URIUtils::AddFileToFolder(pItem->GetPath(), "VIDEO_TS.IFO"); if(!CFile::Exists(path)) path = URIUtils::AddFileToFolder(pItem->GetPath(), "video_ts.ifo"); CFileItemPtr item(new CFileItem(path, false)); item->SetLabel(g_mediaManager.GetDiskLabel(strDrive)); item->GetVideoInfoTag()->m_strFileNameAndPath = g_mediaManager.GetDiskUniqueId(strDrive); if (!startFromBeginning && !item->GetVideoInfoTag()->m_strFileNameAndPath.empty()) item->m_lStartOffset = STARTOFFSET_RESUME; g_playlistPlayer.ClearPlaylist(PLAYLIST_VIDEO); g_playlistPlayer.SetShuffle (PLAYLIST_VIDEO, false); g_playlistPlayer.Add(PLAYLIST_VIDEO, item); g_playlistPlayer.SetCurrentPlaylist(PLAYLIST_VIDEO); g_playlistPlayer.Play(0); return true; } // Check if the current foldername indicates a Blu-Ray structure (default is "BDMV"). // A BR should also include an "AACS" folder for encryption, Sony-BRs can also include update folders for PS3 (PS3_UPDATE / PS3_VPRM). // ToDo: for the time beeing, the DVD autorun settings are used to determine if the BR should be started automatically. if (StringUtils::EqualsNoCase(name, "BDMV") && bAllowVideo && (bypassSettings || CSettings::Get().GetBool("dvds.autorun"))) { CFileItemPtr item(new CFileItem(URIUtils::AddFileToFolder(pItem->GetPath(), "index.bdmv"), false)); item->SetLabel(g_mediaManager.GetDiskLabel(strDrive)); item->GetVideoInfoTag()->m_strFileNameAndPath = g_mediaManager.GetDiskUniqueId(strDrive); if (!startFromBeginning && !item->GetVideoInfoTag()->m_strFileNameAndPath.empty()) item->m_lStartOffset = STARTOFFSET_RESUME; g_playlistPlayer.ClearPlaylist(PLAYLIST_VIDEO); g_playlistPlayer.SetShuffle (PLAYLIST_VIDEO, false); if (!CGUIWindowVideoBase::ShowPlaySelection(item)) return false; g_playlistPlayer.Add(PLAYLIST_VIDEO, item); g_playlistPlayer.SetCurrentPlaylist(PLAYLIST_VIDEO); g_playlistPlayer.Play(0); return true; } // Check if the current foldername indicates a HD DVD structure (default is "HVDVD_TS"). // Most HD DVD will also include an "ADV_OBJ" folder for advanced content. This folder should be handled first. // ToDo: for the time beeing, the DVD autorun settings are used to determine if the HD DVD should be started automatically. CFileItemList items, sitems; // Advanced Content HD DVD (most discs?) if (StringUtils::EqualsNoCase(name, "ADV_OBJ")) { CLog::Log(LOGINFO,"HD DVD: Checking for playlist."); // find playlist file CDirectory::GetDirectory(pItem->GetPath(), items, "*.xpl"); if (items.Size()) { // HD DVD Standard says the highest numbered playlist has to be handled first. CLog::Log(LOGINFO,"HD DVD: Playlist found. Set filetypes to *.xpl for external player."); items.Sort(SortByLabel, SortOrderDescending); phddvdItem = pItem; hddvdname = URIUtils::GetFileName(items[0]->GetPath()); CLog::Log(LOGINFO,"HD DVD: %s", items[0]->GetPath().c_str()); } } // Standard Content HD DVD (few discs?) if (StringUtils::EqualsNoCase(name, "HVDVD_TS") && bAllowVideo && (bypassSettings || CSettings::Get().GetBool("dvds.autorun"))) { if (hddvdname == "") { CLog::Log(LOGINFO,"HD DVD: Checking for ifo."); // find Video Manager or Title Set Information CDirectory::GetDirectory(pItem->GetPath(), items, "HV*.ifo"); if (items.Size()) { // HD DVD Standard says the lowest numbered ifo has to be handled first. CLog::Log(LOGINFO,"HD DVD: IFO found. Set filename to HV* and filetypes to *.ifo for external player."); items.Sort(SortByLabel, SortOrderAscending); phddvdItem = pItem; hddvdname = URIUtils::GetFileName(items[0]->GetPath()); CLog::Log(LOGINFO,"HD DVD: %s",items[0]->GetPath().c_str()); } } // Find and sort *.evo files for internal playback. // While this algorithm works for all of my HD DVDs, it may fail on other discs. If there are very large extras which are // alphabetically before the main movie they will be sorted to the top of the playlist and get played first. CDirectory::GetDirectory(pItem->GetPath(), items, "*.evo"); if (items.Size()) { // Sort *.evo files in alphabetical order. items.Sort(SortByLabel, SortOrderAscending); int64_t asize = 0; int ecount = 0; // calculate average size of elements above 1gb for (int j = 0; j < items.Size(); j++) if (items[j]->m_dwSize > 1000000000) { ecount++; asize = asize + items[j]->m_dwSize; } asize = asize / ecount; // Put largest files in alphabetical order to top of new list. for (int j = 0; j < items.Size(); j++) if (items[j]->m_dwSize >= asize) sitems.Add (items[j]); // Sort *.evo files by size. items.Sort(SortBySize, SortOrderDescending); // Add other files with descending size to bottom of new list. for (int j = 0; j < items.Size(); j++) if (items[j]->m_dwSize < asize) sitems.Add (items[j]); // Replace list with optimized list. items.Clear(); items.Copy (sitems); sitems.Clear(); } if (hddvdname != "") { CFileItem item(URIUtils::AddFileToFolder(phddvdItem->GetPath(), hddvdname), false); item.SetLabel(g_mediaManager.GetDiskLabel(strDrive)); item.GetVideoInfoTag()->m_strFileNameAndPath = g_mediaManager.GetDiskUniqueId(strDrive); if (!startFromBeginning && !item.GetVideoInfoTag()->m_strFileNameAndPath.empty()) item.m_lStartOffset = STARTOFFSET_RESUME; // get playername std::string hddvdplayer = CPlayerCoreFactory::Get().GetPlayerName(CPlayerCoreFactory::Get().GetDefaultPlayer(item)); // Single *.xpl or *.ifo files require an external player to handle playback. // If no matching rule was found, DVDPlayer will be default player. if (hddvdplayer != "DVDPlayer") { CLog::Log(LOGINFO,"HD DVD: External singlefile playback initiated: %s",hddvdname.c_str()); g_application.PlayFile(item, false); return true; } else CLog::Log(LOGINFO,"HD DVD: No external player found. Fallback to internal one."); } // internal *.evo playback. CLog::Log(LOGINFO,"HD DVD: Internal multifile playback initiated."); g_playlistPlayer.ClearPlaylist(PLAYLIST_VIDEO); g_playlistPlayer.SetShuffle (PLAYLIST_VIDEO, false); g_playlistPlayer.Add(PLAYLIST_VIDEO, items); g_playlistPlayer.SetCurrentPlaylist(PLAYLIST_VIDEO); g_playlistPlayer.Play(0); return true; } // Video CDs can have multiple file formats. First we need to determine which one is used on the CD std::string strExt; if (StringUtils::EqualsNoCase(name, "MPEGAV")) strExt = ".dat"; if (StringUtils::EqualsNoCase(name, "MPEG2")) strExt = ".mpg"; // If a file format was extracted we are sure this is a VCD. Autoplay if settings indicate we should. if (!strExt.empty() && bAllowVideo && (bypassSettings || CSettings::Get().GetBool("dvds.autorun"))) { CFileItemList items; CDirectory::GetDirectory(pItem->GetPath(), items, strExt); if (items.Size()) { items.Sort(SortByLabel, SortOrderAscending); g_playlistPlayer.ClearPlaylist(PLAYLIST_VIDEO); g_playlistPlayer.Add(PLAYLIST_VIDEO, items); g_playlistPlayer.SetCurrentPlaylist(PLAYLIST_VIDEO); g_playlistPlayer.Play(0); return true; } } /* Probably want this if/when we add some automedia action dialog... else if (pItem->GetPath().Find("PICTURES") != -1 && bAllowPictures && (bypassSettings)) { bPlaying = true; std::string strExec = StringUtils::Format("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->GetURL(), 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; std::string strExec = StringUtils::Format("RecursiveSlideShow(%s)", strDrive.c_str()); CBuiltins::Execute(strExec); break; } } } */ // check subdirs if we are not playing yet if (!bPlaying) { for (int i = 0; i < vecItems.Size(); i++) { CFileItemPtr pItem = vecItems[i]; if (pItem->m_bIsFolder) { if (pItem->GetPath() != "." && pItem->GetPath() != ".." ) { if (RunDisc(pDir, pItem->GetPath(), nAddedToPlaylist, false, bypassSettings, startFromBeginning)) { bPlaying = true; break; } } } // if (non system) folder } // for all items in directory } // if root folder return bPlaying; }
void 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; } }
// NB: The rar manager expects paths in rars to be terminated with a "\". bool CRarManager::GetFilesInRar(CFileItemList& vecpItems, const std::string& strRarPath, bool bMask, const std::string& strPathInRar) { #ifdef HAS_FILESYSTEM_RAR CSingleLock lock(m_CritSection); ArchiveList_struct* pFileList = NULL; map<std::string,pair<ArchiveList_struct*,vector<CFileInfo> > >::iterator it = m_ExFiles.find(strRarPath); if (it == m_ExFiles.end()) { if( urarlib_list((char*) strRarPath.c_str(), &pFileList, NULL) ) m_ExFiles.insert(make_pair(strRarPath,make_pair(pFileList,vector<CFileInfo>()))); else { if( pFileList ) urarlib_freelist(pFileList); return false; } } else pFileList = it->second.first; CFileItemPtr pFileItem; vector<std::string> vec; set<std::string> dirSet; StringUtils::Tokenize(strPathInRar,vec,"/"); unsigned int iDepth = vec.size(); ArchiveList_struct* pIterator; std::string strCompare = strPathInRar; if (!URIUtils::HasSlashAtEnd(strCompare) && !strCompare.empty()) strCompare += '/'; for( pIterator = pFileList; pIterator ; pIterator ? pIterator = pIterator->next : NULL) { std::string strName; /* convert to utf8 */ if( pIterator->item.NameW && wcslen(pIterator->item.NameW) > 0) g_charsetConverter.wToUTF8(pIterator->item.NameW, strName); else g_charsetConverter.unknownToUTF8(pIterator->item.Name, strName); /* replace back slashes into forward slashes */ /* this could get us into troubles, file could two different files, one with / and one with \ */ StringUtils::Replace(strName, '\\', '/'); if (bMask) { if (!strstr(strName.c_str(),strCompare.c_str())) continue; vec.clear(); StringUtils::Tokenize(strName,vec,"/"); if (vec.size() < iDepth) continue; } unsigned int iMask = (pIterator->item.HostOS==3 ? 0x0040000:16); // win32 or unix attribs? if (((pIterator->item.FileAttr & iMask) == iMask) || (vec.size() > iDepth+1 && bMask)) // we have a directory { if (!bMask) continue; if (vec.size() == iDepth) continue; // remove root of listing if (dirSet.find(vec[iDepth]) == dirSet.end()) { dirSet.insert(vec[iDepth]); pFileItem.reset(new CFileItem(vec[iDepth])); pFileItem->SetPath(vec[iDepth] + '/'); pFileItem->m_bIsFolder = true; pFileItem->m_idepth = pIterator->item.Method; pFileItem->m_iDriveType = pIterator->item.HostOS; //pFileItem->m_lEndOffset = long(pIterator->item.iOffset); } } else { if (vec.size() == iDepth+1 || !bMask) { if (vec.size() == 0) pFileItem.reset(new CFileItem(strName)); else pFileItem.reset(new CFileItem(vec[iDepth])); pFileItem->SetPath(strName.c_str()+strPathInRar.size()); pFileItem->m_dwSize = pIterator->item.UnpSize; pFileItem->m_idepth = pIterator->item.Method; pFileItem->m_iDriveType = pIterator->item.HostOS; //pFileItem->m_lEndOffset = long(pIterator->item.iOffset); } } if (pFileItem) vecpItems.Add(pFileItem); pFileItem.reset(); } return vecpItems.Size() > 0; #else return false; #endif }
// Add an "* All ..." folder to the CFileItemList // depending on the child node void CDirectoryNode::AddQueuingFolder(CFileItemList& items) const { CFileItemPtr pItem; // always hide "all" items if (g_advancedSettings.m_bVideoLibraryHideAllItems) return; // no need for "all" item when only one item if (items.GetObjectCount() <= 1) return; // hack - as the season node might return episodes auto_ptr<CDirectoryNode> pNode(ParseURL(items.GetPath())); switch (pNode->GetChildType()) { case NODE_TYPE_SEASONS: { CStdString strLabel = g_localizeStrings.Get(20366); pItem.reset(new CFileItem(strLabel)); // "All Seasons" pItem->SetPath(BuildPath() + "-1/"); // set the number of watched and unwatched items accordingly int watched = 0; int unwatched = 0; for (int i = 0; i < items.Size(); i++) { CFileItemPtr item = items[i]; watched += (int)item->GetProperty("watchedepisodes").asInteger(); unwatched += (int)item->GetProperty("unwatchedepisodes").asInteger(); } pItem->SetProperty("totalepisodes", watched + unwatched); pItem->SetProperty("numepisodes", watched + unwatched); // will be changed later to reflect watchmode setting pItem->SetProperty("watchedepisodes", watched); pItem->SetProperty("unwatchedepisodes", unwatched); if (items.Size() && items[0]->GetVideoInfoTag()) { *pItem->GetVideoInfoTag() = *items[0]->GetVideoInfoTag(); pItem->GetVideoInfoTag()->m_iSeason = -1; } pItem->GetVideoInfoTag()->m_strTitle = strLabel; pItem->GetVideoInfoTag()->m_iEpisode = watched + unwatched; pItem->GetVideoInfoTag()->m_playCount = (unwatched == 0) ? 1 : 0; CVideoDatabase db; if (db.Open()) { pItem->GetVideoInfoTag()->m_iDbId = db.GetSeasonId(pItem->GetVideoInfoTag()->m_iIdShow, -1); db.Close(); } pItem->GetVideoInfoTag()->m_type = "season"; } break; default: break; } if (pItem) { pItem->m_bIsFolder = true; pItem->SetSpecialSort(g_advancedSettings.m_bVideoLibraryAllItemsOnBottom ? SortSpecialOnBottom : SortSpecialOnTop); pItem->SetCanQueue(false); items.Add(pItem); } }
/** * 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; }
void CFileItemHandler::FillDetails(ISerializable* info, CFileItemPtr item, const CVariant& fields, CVariant &result) { if (info == NULL || fields.size() == 0) return; CVariant serialization; info->Serialize(serialization); for (unsigned int i = 0; i < fields.size(); i++) { CStdString field = fields[i].asString(); if (item) { if (item->IsAlbum() && field.Equals("albumlabel")) field = "label"; if (item->IsAlbum() && item->HasProperty("album_" + field)) { if (field == "label") result["albumlabel"] = item->GetProperty("album_label"); else result[field] = item->GetProperty("album_" + field); continue; } if (item->HasProperty("artist_" + field)) { result[field] = item->GetProperty("artist_" + field); continue; } if (field == "fanart" && !item->HasPictureInfoTag()) { CStdString fanart; if (item->HasProperty("fanart_image")) fanart = item->GetProperty("fanart_image").asString(); if (fanart.empty()) fanart = item->GetCachedFanart(); if (!fanart.empty()) result["fanart"] = fanart.c_str(); continue; } } if (serialization.isMember(field) && !result.isMember(field)) result[field] = serialization[field]; } }
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; }
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) { videodatabase.GetTvShowsNav("videodb://2/2/",items); iLabel = 20343; } else if (m_rule.m_field == FieldPlaylist) { // use filebrowser to grab another smart playlist // Note: This can cause infinite loops (playlist that refers to the same playlist) but I don't // think there's any decent way to deal with this, as the infinite loop may be an arbitrary // number of playlists deep, eg playlist1 -> playlist2 -> playlist3 ... -> playlistn -> playlist1 CStdString path = "special://videoplaylists/"; if (m_type.Equals("songs") || m_type.Equals("albums")) path = "special://musicplaylists/"; XFILE::CDirectory::GetDirectory(path, items, ".xsp", XFILE::DIR_FLAG_NO_FILE_DIRS); for (int i = 0; i < items.Size(); i++) { CFileItemPtr item = items[i]; CSmartPlaylist playlist; if (playlist.OpenAndReadName(item->GetPath())) item->SetLabel(playlist.GetName()); } iLabel = 559; } else if (m_rule.m_field == FieldPath) { VECSOURCES sources; if (m_type == "songs" || m_type == "mixed") sources = *g_settings.GetSourcesFromType("music"); if (m_type != "songs") { VECSOURCES sources2 = *g_settings.GetSourcesFromType("video"); sources.insert(sources.end(),sources2.begin(),sources2.end()); } g_mediaManager.GetLocalDrives(sources); CStdString path = m_rule.GetLocalizedParameter(m_type); CGUIDialogFileBrowser::ShowAndGetDirectory(sources, g_localizeStrings.Get(657), path, false); if (m_rule.m_parameter.size() > 0) m_rule.m_parameter.clear(); if (!path.empty()) m_rule.m_parameter.push_back(path); UpdateButtons(); return; } else if (m_rule.m_field == FieldSet) { videodatabase.GetSetsNav("videodb://1/7/", items, VIDEODB_CONTENT_MOVIES); iLabel = 20434; } else if (m_rule.m_field == FieldTag) { if (m_type == "movies") videodatabase.GetTagsNav(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(); }
bool CPVRGUIActions::PlayRecording(const CFileItemPtr &item, bool bPlayMinimized, bool bCheckResume) const { const CPVRRecordingPtr recording(CPVRItem(item).GetRecording()); if (!recording) return false; std::string stream = recording->m_strStreamURL; if (stream.empty()) { if (!bCheckResume || CheckResumeRecording(item)) { CFileItem *itemToPlay = new CFileItem(recording); itemToPlay->m_lStartOffset = item->m_lStartOffset; CApplicationMessenger::GetInstance().PostMsg(TMSG_MEDIA_PLAY, 0, 0, static_cast<void*>(itemToPlay)); } return true; } /* Isolate the folder from the filename */ size_t found = stream.find_last_of("/"); if (found == std::string::npos) found = stream.find_last_of("\\"); if (found != std::string::npos) { /* Check here for asterisk at the begin of the filename */ if (stream[found+1] == '*') { /* Create a "stack://" url with all files matching the extension */ std::string ext = URIUtils::GetExtension(stream); std::string dir = stream.substr(0, found); CFileItemList items; XFILE::CDirectory::GetDirectory(dir, items); items.Sort(SortByFile, SortOrderAscending); std::vector<int> stack; for (int i = 0; i < items.Size(); ++i) { if (URIUtils::HasExtension(items[i]->GetPath(), ext)) stack.push_back(i); } if (stack.empty()) { /* If we have a stack change the path of the item to it */ XFILE::CStackDirectory dir; std::string stackPath = dir.ConstructStackPath(items, stack); item->SetPath(stackPath); } } else { /* If no asterisk is present play only the given stream URL */ item->SetPath(stream); } } else { CLog::Log(LOGERROR, "CPVRGUIActions - %s - can't open recording: no valid filename", __FUNCTION__); CGUIDialogOK::ShowAndGetInput(CVariant{19033}, CVariant{19036}); return false; } if (!bCheckResume || CheckResumeRecording(item)) CApplicationMessenger::GetInstance().PostMsg(TMSG_MEDIA_PLAY, 0, 0, static_cast<void*>(new CFileItem(*item))); return true; }
bool 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: { 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: { VECPLAYERCORES vecCores; // base class? CPlayerCoreFactory::GetInstance().GetPlayers(*item, vecCores); g_application.m_eForcedNextPlayer = CPlayerCoreFactory::GetInstance().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: { g_application.StopMusicScan(); return true; } case CONTEXT_BUTTON_GOTO_ROOT: Update(""); return true; case CONTEXT_BUTTON_SETTINGS: g_windowManager.ActivateWindow(WINDOW_SETTINGS_MYMUSIC); 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); }
bool CGUIControlListSetting::OnClick() { if (m_pButton == NULL) return false; CGUIDialogSelect *dialog = (CGUIDialogSelect*)g_windowManager.GetWindow(WINDOW_DIALOG_SELECT); if (dialog == NULL) return false; CFileItemList options; if (!GetItems(m_pSetting, options) || options.Size() <= 1) return false; const CSettingControlList *control = static_cast<const CSettingControlList*>(m_pSetting->GetControl()); dialog->Reset(); dialog->SetHeading(CVariant{g_localizeStrings.Get(m_pSetting->GetLabel())}); dialog->SetItems(&options); dialog->SetMultiSelection(control->CanMultiSelect()); dialog->Open(); if (!dialog->IsConfirmed()) return false; std::vector<CVariant> values; for (int i : dialog->GetSelectedItems()) { const CFileItemPtr item = options.Get(i); if (item == NULL || !item->HasProperty("value")) return false; values.push_back(item->GetProperty("value")); } bool ret = false; switch (m_pSetting->GetType()) { case SettingTypeInteger: if (values.size() > 1) return false; ret = ((CSettingInt *)m_pSetting)->SetValue((int)values.at(0).asInteger()); break; case SettingTypeString: if (values.size() > 1) return false; ret = ((CSettingString *)m_pSetting)->SetValue(values.at(0).asString()); break; case SettingTypeList: ret = CSettingUtils::SetList(static_cast<CSettingList*>(m_pSetting), values); break; default: return false; } if (ret) Update(); else SetValid(false); return IsValid(); }
void CAddonDatabase::SetPropertiesFromAddon(const AddonPtr& addon, CFileItemPtr& pItem) { pItem->SetProperty("Addon.ID", addon->ID()); pItem->SetProperty("Addon.Type", TranslateType(addon->Type(),true)); pItem->SetProperty("Addon.intType", TranslateType(addon->Type())); pItem->SetProperty("Addon.Name", addon->Name()); pItem->SetProperty("Addon.Version", addon->Version().asString()); pItem->SetProperty("Addon.Summary", addon->Summary()); pItem->SetProperty("Addon.Description", addon->Description()); pItem->SetProperty("Addon.Creator", addon->Author()); pItem->SetProperty("Addon.Disclaimer", addon->Disclaimer()); pItem->SetProperty("Addon.Rating", addon->Stars()); std::string starrating = StringUtils::Format("rating%d.png", addon->Stars()); pItem->SetProperty("Addon.StarRating",starrating); pItem->SetProperty("Addon.Path", addon->Path()); if (addon->Props().broken == "DEPSNOTMET") pItem->SetProperty("Addon.Broken", g_localizeStrings.Get(24044)); else pItem->SetProperty("Addon.Broken", addon->Props().broken); std::map<std::string,std::string>::iterator it = addon->Props().extrainfo.find("language"); if (it != addon->Props().extrainfo.end()) pItem->SetProperty("Addon.Language", it->second); }
void CGUIDialogFileBrowser::Update(const std::string &strDirectory) { const CURL pathToUrl(strDirectory); if (m_browsingForImages && m_thumbLoader.IsLoading()) m_thumbLoader.StopThread(); // get selected item int iItem = m_viewControl.GetSelectedItem(); std::string 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().empty()?"empty":m_Directory->GetPath()); } } if (!m_singleList) { CFileItemList items; std::string strParentPath; if (!m_rootDir.GetDirectory(pathToUrl, items, m_useFileDirectories)) { CLog::Log(LOGERROR,"CGUIDialogFileBrowser::GetDirectory(%s) failed", pathToUrl.GetRedacted().c_str()); // We assume, we can get the parent // directory again std::string 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.empty()) 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().empty() && m_addNetworkShareEnabled && (CProfilesManager::Get().GetMasterProfile().getLockMode() == LOCK_MODE_EVERYONE || CProfilesManager::Get().IsMasterProfile() || 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().empty() && !m_addSourceType.empty()) { 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)) ? CONTROL_THUMBS : CONTROL_LIST); std::string 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 CGUIWindowFullScreen::OnAction(const CAction &action) { if (m_timeCodePosition > 0 && action.GetButtonCode()) { // check whether we have a mapping in our virtual videotimeseek "window" and have a select action CKey key(action.GetButtonCode()); CAction timeSeek = CButtonTranslator::GetInstance().GetAction(WINDOW_VIDEO_TIME_SEEK, key, false); if (timeSeek.GetID() == ACTION_SELECT_ITEM) { SeekToTimeCodeStamp(SEEK_ABSOLUTE); return true; } } switch (action.GetID()) { case ACTION_SHOW_OSD: ToggleOSD(); return true; case ACTION_SHOW_GUI: { // switch back to the menu OutputDebugString("Switching to GUI\n"); g_windowManager.PreviousWindow(); OutputDebugString("Now in GUI\n"); return true; } break; case ACTION_PLAYER_PLAY: case ACTION_PAUSE: if (m_timeCodePosition > 0) { SeekToTimeCodeStamp(SEEK_ABSOLUTE); return true; } break; case ACTION_STEP_BACK: if (m_timeCodePosition > 0) SeekToTimeCodeStamp(SEEK_RELATIVE, SEEK_BACKWARD); else g_application.m_pPlayer->Seek(false, false); return true; case ACTION_STEP_FORWARD: if (m_timeCodePosition > 0) SeekToTimeCodeStamp(SEEK_RELATIVE, SEEK_FORWARD); else g_application.m_pPlayer->Seek(true, false); return true; case ACTION_BIG_STEP_BACK: case ACTION_CHAPTER_OR_BIG_STEP_BACK: if (m_timeCodePosition > 0) SeekToTimeCodeStamp(SEEK_RELATIVE, SEEK_BACKWARD); else g_application.m_pPlayer->Seek(false, true, action.GetID() == ACTION_CHAPTER_OR_BIG_STEP_BACK); return true; case ACTION_BIG_STEP_FORWARD: case ACTION_CHAPTER_OR_BIG_STEP_FORWARD: if (m_timeCodePosition > 0) SeekToTimeCodeStamp(SEEK_RELATIVE, SEEK_FORWARD); else g_application.m_pPlayer->Seek(true, true, action.GetID() == ACTION_CHAPTER_OR_BIG_STEP_FORWARD); return true; case ACTION_NEXT_SCENE: if (g_application.m_pPlayer->SeekScene(true)) g_infoManager.SetDisplayAfterSeek(); return true; break; case ACTION_PREV_SCENE: if (g_application.m_pPlayer->SeekScene(false)) g_infoManager.SetDisplayAfterSeek(); return true; break; case ACTION_SHOW_OSD_TIME: m_bShowCurrentTime = !m_bShowCurrentTime; if(!m_bShowCurrentTime) g_infoManager.SetDisplayAfterSeek(0); //Force display off g_infoManager.SetShowTime(m_bShowCurrentTime); return true; break; case ACTION_SHOW_INFO: { CGUIDialogFullScreenInfo* pDialog = (CGUIDialogFullScreenInfo*)g_windowManager.GetWindow(WINDOW_DIALOG_FULLSCREEN_INFO); if (pDialog) { CFileItem item(g_application.CurrentFileItem()); pDialog->DoModal(); return true; } break; } case REMOTE_0: case REMOTE_1: case REMOTE_2: case REMOTE_3: case REMOTE_4: case REMOTE_5: case REMOTE_6: case REMOTE_7: case REMOTE_8: case REMOTE_9: { if (g_application.CurrentFileItem().IsLiveTV()) { CPVRChannelPtr playingChannel; g_PVRManager.GetCurrentChannel(playingChannel); if (action.GetID() == REMOTE_0) { CPVRChannelGroupPtr group = g_PVRChannelGroups->GetPreviousPlayedGroup(); if (group) { g_PVRManager.SetPlayingGroup(group); CFileItemPtr fileItem = group->GetLastPlayedChannel(playingChannel->ChannelID()); if (fileItem && fileItem->HasPVRChannelInfoTag()) { CLog::Log(LOGDEBUG, "%s - switch to channel number %d", __FUNCTION__, fileItem->GetPVRChannelInfoTag()->ChannelNumber()); g_application.OnAction(CAction(ACTION_CHANNEL_SWITCH, (float) fileItem->GetPVRChannelInfoTag()->ChannelNumber())); } } } else { int autoCloseTime = CSettings::Get().GetBool("pvrplayback.confirmchannelswitch") ? 0 : g_advancedSettings.m_iPVRNumericChannelSwitchTimeout; CStdString strChannel = StringUtils::Format("%i", action.GetID() - REMOTE_0); if (CGUIDialogNumeric::ShowAndGetNumber(strChannel, g_localizeStrings.Get(19000), autoCloseTime) || autoCloseTime) { int iChannelNumber = atoi(strChannel.c_str()); if (iChannelNumber > 0 && iChannelNumber != playingChannel->ChannelNumber()) { CPVRChannelGroupPtr selectedGroup = g_PVRManager.GetPlayingGroup(playingChannel->IsRadio()); CFileItemPtr channel = selectedGroup->GetByChannelNumber(iChannelNumber); if (!channel || !channel->HasPVRChannelInfoTag()) return false; g_application.OnAction(CAction(ACTION_CHANNEL_SWITCH, (float)iChannelNumber)); } } } } else { ChangetheTimeCode(action.GetID()); } return true; } break; case ACTION_ASPECT_RATIO: { // toggle the aspect ratio mode (only if the info is onscreen) if (m_bShowViewModeInfo) { #ifdef HAS_VIDEO_PLAYBACK g_renderManager.SetViewMode(++CMediaSettings::Get().GetCurrentVideoSettings().m_ViewMode); #endif } m_bShowViewModeInfo = true; m_dwShowViewModeTimeout = XbmcThreads::SystemClockMillis(); } return true; break; case ACTION_SMALL_STEP_BACK: if (m_timeCodePosition > 0) SeekToTimeCodeStamp(SEEK_RELATIVE, SEEK_BACKWARD); else { int orgpos = (int)g_application.GetTime(); int jumpsize = g_advancedSettings.m_videoSmallStepBackSeconds; // secs int setpos = (orgpos > jumpsize) ? orgpos - jumpsize : 0; g_application.SeekTime((double)setpos); } return true; break; case ACTION_SHOW_PLAYLIST: { CFileItem item(g_application.CurrentFileItem()); if (item.HasPVRChannelInfoTag()) g_windowManager.ActivateWindow(WINDOW_DIALOG_PVR_OSD_CHANNELS); else if (item.HasVideoInfoTag()) g_windowManager.ActivateWindow(WINDOW_VIDEO_PLAYLIST); else if (item.HasMusicInfoTag()) g_windowManager.ActivateWindow(WINDOW_MUSIC_PLAYLIST); } return true; break; case ACTION_PREVIOUS_CHANNELGROUP: { if (g_application.CurrentFileItem().HasPVRChannelInfoTag()) ChangetheTVGroup(false); return true; } case ACTION_NEXT_CHANNELGROUP: { if (g_application.CurrentFileItem().HasPVRChannelInfoTag()) ChangetheTVGroup(true); return true; } default: break; } return CGUIWindow::OnAction(action); }
void CGUIDialogPVRTimerSettings::CreateSettings() { CPVRTimerInfoTag* tag = m_timerItem->GetPVRTimerInfoTag(); // clear out any old settings m_settings.clear(); // create our settings controls AddBool(CONTROL_TMR_ACTIVE, 19074, &tag->m_bIsActive); AddButton(CONTROL_TMR_NAME, 19075, &tag->m_strTitle, true); AddBool(CONTROL_TMR_RADIO, 19077, &tag->m_bIsRadio); /// Channel names { // For TV CFileItemList channelslist_tv; SETTINGSTRINGS channelstrings_tv; CPVRManager::GetChannelGroups()->GetGroupAll(false)->GetMembers(&channelslist_tv); channelstrings_tv.push_back("0 dummy"); for (int i = 0; i < channelslist_tv.Size(); i++) { CStdString string; CFileItemPtr item = channelslist_tv[i]; string.Format("%i %s", item->GetPVRChannelInfoTag()->ChannelNumber(), item->GetPVRChannelInfoTag()->ChannelName().c_str()); channelstrings_tv.push_back(string); } AddSpin(CONTROL_TMR_CHNAME_TV, 19078, &tag->m_iChannelNumber, channelstrings_tv.size(), channelstrings_tv); EnableSettings(CONTROL_TMR_CHNAME_TV, !tag->m_bIsRadio); // For Radio CFileItemList channelslist_radio; SETTINGSTRINGS channelstrings_radio; CPVRManager::GetChannelGroups()->GetGroupAll(true)->GetMembers(&channelslist_radio); channelstrings_radio.push_back("0 dummy"); for (int i = 0; i < channelslist_radio.Size(); i++) { CStdString string; CFileItemPtr item = channelslist_radio[i]; string.Format("%i %s", item->GetPVRChannelInfoTag()->ChannelNumber(), item->GetPVRChannelInfoTag()->ChannelName().c_str()); channelstrings_radio.push_back(string); } AddSpin(CONTROL_TMR_CHNAME_RADIO, 19078, &tag->m_iChannelNumber, channelstrings_radio.size(), channelstrings_radio); EnableSettings(CONTROL_TMR_CHNAME_RADIO, tag->m_bIsRadio); } /// Day { SETTINGSTRINGS daystrings; tm time_cur; tm time_tmr; daystrings.push_back(g_localizeStrings.Get(19086)); daystrings.push_back(g_localizeStrings.Get(19087)); daystrings.push_back(g_localizeStrings.Get(19088)); daystrings.push_back(g_localizeStrings.Get(19089)); daystrings.push_back(g_localizeStrings.Get(19090)); daystrings.push_back(g_localizeStrings.Get(19091)); daystrings.push_back(g_localizeStrings.Get(19092)); daystrings.push_back(g_localizeStrings.Get(19093)); daystrings.push_back(g_localizeStrings.Get(19094)); daystrings.push_back(g_localizeStrings.Get(19095)); daystrings.push_back(g_localizeStrings.Get(19096)); CDateTime time = CDateTime::GetCurrentDateTime(); CDateTime timestart = tag->StartAsLocalTime(); /* get diffence of timer in days between today and timer start date */ time.GetAsTm(time_cur); timestart.GetAsTm(time_tmr); if (time_tmr.tm_yday - time_cur.tm_yday >= 0) m_tmp_day += time_tmr.tm_yday - time_cur.tm_yday; else m_tmp_day += time_tmr.tm_yday - time_cur.tm_yday + 365; for (int i = 1; i < 365; ++i) { CStdString string = time.GetAsLocalizedDate(); daystrings.push_back(string); time += CDateTimeSpan(1, 0, 0, 0); } if (tag->m_bIsRepeating) { if (tag->m_iWeekdays == 0x01) m_tmp_day = 0; else if (tag->m_iWeekdays == 0x02) m_tmp_day = 1; else if (tag->m_iWeekdays == 0x04) m_tmp_day = 2; else if (tag->m_iWeekdays == 0x08) m_tmp_day = 3; else if (tag->m_iWeekdays == 0x10) m_tmp_day = 4; else if (tag->m_iWeekdays == 0x20) m_tmp_day = 5; else if (tag->m_iWeekdays == 0x40) m_tmp_day = 6; else if (tag->m_iWeekdays == 0x1F) m_tmp_day = 7; else if (tag->m_iWeekdays == 0x3F) m_tmp_day = 8; else if (tag->m_iWeekdays == 0x7F) m_tmp_day = 9; else if (tag->m_iWeekdays == 0x60) m_tmp_day = 10; } AddSpin(CONTROL_TMR_DAY, 19079, &m_tmp_day, daystrings.size(), daystrings); } AddButton(CONTROL_TMR_BEGIN, 19080, &timerStartTimeStr, true); AddButton(CONTROL_TMR_END, 19081, &timerEndTimeStr, true); AddSpin(CONTROL_TMR_PRIORITY, 19082, &tag->m_iPriority, 0, 99); AddSpin(CONTROL_TMR_LIFETIME, 19083, &tag->m_iLifetime, 0, 365); /// First day { SETTINGSTRINGS daystrings; tm time_cur; tm time_tmr; CDateTime time = CDateTime::GetCurrentDateTime(); CDateTime timestart = tag->FirstDayAsLocalTime(); /* get diffence of timer in days between today and timer start date */ if (time < timestart) { time.GetAsTm(time_cur); timestart.GetAsTm(time_tmr); if (time_tmr.tm_yday - time_cur.tm_yday >= 0) { m_tmp_iFirstDay += time_tmr.tm_yday - time_cur.tm_yday + 1; } else { m_tmp_iFirstDay += time_tmr.tm_yday - time_cur.tm_yday + 365 + 1; } } daystrings.push_back(g_localizeStrings.Get(19030)); for (int i = 1; i < 365; ++i) { CStdString string = time.GetAsLocalizedDate(); daystrings.push_back(string); time += CDateTimeSpan(1, 0, 0, 0); } AddSpin(CONTROL_TMR_FIRST_DAY, 19084, &m_tmp_iFirstDay, daystrings.size(), daystrings); if (tag->m_bIsRepeating) EnableSettings(CONTROL_TMR_FIRST_DAY, true); else EnableSettings(CONTROL_TMR_FIRST_DAY, false); } }
bool CGUIWindowFullScreen::OnMessage(CGUIMessage& message) { switch (message.GetMessage()) { case GUI_MSG_WINDOW_INIT: { // check whether we've come back here from a window during which time we've actually // stopped playing videos if (message.GetParam1() == WINDOW_INVALID && !g_application.m_pPlayer->IsPlayingVideo()) { // why are we here if nothing is playing??? g_windowManager.PreviousWindow(); return true; } g_infoManager.SetShowInfo(false); g_infoManager.SetShowCodec(false); m_bShowCurrentTime = false; m_bGroupSelectShow = false; g_infoManager.SetDisplayAfterSeek(0); // Make sure display after seek is off. // switch resolution g_graphicsContext.SetFullScreenVideo(true); #ifdef HAS_VIDEO_PLAYBACK // make sure renderer is uptospeed g_renderManager.Update(); #endif // now call the base class to load our windows CGUIWindow::OnMessage(message); m_bShowViewModeInfo = false; return true; } case GUI_MSG_WINDOW_DEINIT: { CGUIDialog *pDialog = (CGUIDialog *)g_windowManager.GetWindow(WINDOW_DIALOG_OSD_TELETEXT); if (pDialog) pDialog->Close(true); pDialog = (CGUIDialog *)g_windowManager.GetWindow(WINDOW_DIALOG_SLIDER); if (pDialog) pDialog->Close(true); pDialog = (CGUIDialog *)g_windowManager.GetWindow(WINDOW_DIALOG_VIDEO_OSD); if (pDialog) pDialog->Close(true); pDialog = (CGUIDialog *)g_windowManager.GetWindow(WINDOW_DIALOG_FULLSCREEN_INFO); if (pDialog) pDialog->Close(true); pDialog = (CGUIDialog *)g_windowManager.GetWindow(WINDOW_DIALOG_PVR_OSD_CHANNELS); if (pDialog) pDialog->Close(true); pDialog = (CGUIDialog *)g_windowManager.GetWindow(WINDOW_DIALOG_PVR_OSD_GUIDE); if (pDialog) pDialog->Close(true); pDialog = (CGUIDialog *)g_windowManager.GetWindow(WINDOW_DIALOG_PVR_OSD_DIRECTOR); if (pDialog) pDialog->Close(true); pDialog = (CGUIDialog *)g_windowManager.GetWindow(WINDOW_DIALOG_PVR_OSD_CUTTER); if (pDialog) pDialog->Close(true); CGUIWindow::OnMessage(message); CSettings::Get().Save(); CSingleLock lock (g_graphicsContext); g_graphicsContext.SetFullScreenVideo(false); lock.Leave(); #ifdef HAS_VIDEO_PLAYBACK // make sure renderer is uptospeed g_renderManager.Update(); #endif return true; } case GUI_MSG_CLICKED: { unsigned int iControl = message.GetSenderId(); if (iControl == CONTROL_GROUP_CHOOSER && g_PVRManager.IsStarted()) { // Get the currently selected label of the Select button CGUIMessage msg(GUI_MSG_ITEM_SELECTED, GetID(), iControl); OnMessage(msg); CStdString strLabel = msg.GetLabel(); CPVRChannelPtr playingChannel; if (g_PVRManager.GetCurrentChannel(playingChannel)) { CPVRChannelGroupPtr selectedGroup = g_PVRChannelGroups->Get(playingChannel->IsRadio())->GetByName(strLabel); if (selectedGroup) { g_PVRManager.SetPlayingGroup(selectedGroup); CLog::Log(LOGDEBUG, "%s - switched to group '%s'", __FUNCTION__, selectedGroup->GroupName().c_str()); if (!selectedGroup->IsGroupMember(*playingChannel)) { CLog::Log(LOGDEBUG, "%s - channel '%s' is not a member of '%s', switching to channel 1 of the new group", __FUNCTION__, playingChannel->ChannelName().c_str(), selectedGroup->GroupName().c_str()); CFileItemPtr switchChannel = selectedGroup->GetByChannelNumber(1); if (switchChannel && switchChannel->HasPVRChannelInfoTag()) g_application.OnAction(CAction(ACTION_CHANNEL_SWITCH, (float) switchChannel->GetPVRChannelInfoTag()->ChannelNumber())); else { CLog::Log(LOGERROR, "%s - cannot find channel '1' in group %s", __FUNCTION__, selectedGroup->GroupName().c_str()); CApplicationMessenger::Get().MediaStop(false); } } } else { CLog::Log(LOGERROR, "%s - could not switch to group '%s'", __FUNCTION__, selectedGroup->GroupName().c_str()); CApplicationMessenger::Get().MediaStop(false); } } else { CLog::Log(LOGERROR, "%s - cannot find the current channel", __FUNCTION__); CApplicationMessenger::Get().MediaStop(false); } // hide the control and reset focus m_bGroupSelectShow = false; SET_CONTROL_HIDDEN(CONTROL_GROUP_CHOOSER); // SET_CONTROL_FOCUS(0, 0); return true; } break; } case GUI_MSG_SETFOCUS: case GUI_MSG_LOSTFOCUS: if (message.GetSenderId() != WINDOW_FULLSCREEN_VIDEO) return true; break; } return CGUIWindow::OnMessage(message); }
bool CGUIWindowPVRBase::OnContextButton(int itemNumber, CONTEXT_BUTTON button) { bool bReturn = false; switch(button) { case CONTEXT_BUTTON_MENU_HOOKS: if (itemNumber >= 0 && itemNumber < m_vecItems->Size()) { CFileItemPtr item = m_vecItems->Get(itemNumber); if (item->IsEPG() && item->GetEPGInfoTag()->HasPVRChannel()) g_PVRClients->ProcessMenuHooks(item->GetEPGInfoTag()->ChannelTag()->ClientID(), PVR_MENUHOOK_EPG, item.get()); else if (item->IsPVRChannel()) g_PVRClients->ProcessMenuHooks(item->GetPVRChannelInfoTag()->ClientID(), PVR_MENUHOOK_CHANNEL, item.get()); else if (item->IsDeletedPVRRecording()) g_PVRClients->ProcessMenuHooks(item->GetPVRRecordingInfoTag()->m_iClientId, PVR_MENUHOOK_DELETED_RECORDING, item.get()); else if (item->IsUsablePVRRecording()) g_PVRClients->ProcessMenuHooks(item->GetPVRRecordingInfoTag()->m_iClientId, PVR_MENUHOOK_RECORDING, item.get()); else if (item->IsPVRTimer()) g_PVRClients->ProcessMenuHooks(item->GetPVRTimerInfoTag()->m_iClientId, PVR_MENUHOOK_TIMER, item.get()); bReturn = true; } break; case CONTEXT_BUTTON_FIND: { int windowSearchId = m_bRadio ? WINDOW_RADIO_SEARCH : WINDOW_TV_SEARCH; CGUIWindowPVRBase *windowSearch = (CGUIWindowPVRBase*) g_windowManager.GetWindow(windowSearchId); if (windowSearch && itemNumber >= 0 && itemNumber < m_vecItems->Size()) { CFileItemPtr item = m_vecItems->Get(itemNumber); g_windowManager.ActivateWindow(windowSearchId); bReturn = windowSearch->OnContextButton(*item.get(), button); } break; } default: bReturn = false; } return bReturn || CGUIMediaWindow::OnContextButton(itemNumber, button); }
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 CGUIWindowPrograms::GetDirectory(const CStdString &strDirectory, CFileItemList &items) { #ifdef __APPLE__ // Launch Mac OS X apps if (Cocoa_IsAppBundle(strDirectory.c_str())) { if (strDirectory.Find("/Front Row.app/") > 0) { PlexRemoteHelper::Get().Stop(); Cocoa_LaunchFrontRow(); return true; } else { // Special cases for app compatibility if ((strDirectory.Find("/DVD Player.app/") > 0) || (strDirectory.Find("/iTunes.app/") > 0) || (strDirectory.Find("/EyeTV.app/") > 0)) PlexRemoteHelper::Get().Stop(); Cocoa_LaunchApp(strDirectory.c_str()); return true; } } // Launch Automator workflows if (Cocoa_IsWflowBundle(strDirectory.c_str())) { PlexRemoteHelper::Get().Stop(); Cocoa_LaunchAutomatorWorkflow(strDirectory.c_str()); return true; } #endif bool bFlattened=false; if (CUtil::IsDVD(strDirectory)) { CStdString strPath; CUtil::AddFileToFolder(strDirectory,"default.xbe",strPath); if (CFile::Exists(strPath)) // flatten dvd { CFileItemPtr item(new CFileItem("default.xbe")); item->m_strPath = strPath; items.Add(item); items.m_strPath=strDirectory; bFlattened = true; } } if (!bFlattened) if (!CGUIMediaWindow::GetDirectory(strDirectory, items)) return false; if (items.IsVirtualDirectoryRoot()) { // Set thumbnail images for OS X apps & workflows added as sources for (int i = 0; i < items.Size(); i++) { CFileItemPtr item = items[i]; if (item->m_strPath.Find(".app/") > 0) { //Get the app's icon CStdString appIcon = Cocoa_GetAppIcon(item->m_strPath.c_str()); if (appIcon != NULL) item->SetThumbnailImage(appIcon); } if (item->m_strPath.Find(".workflow/") > 0) item->SetThumbnailImage(Cocoa_GetIconFromBundle("/Applications/Automator.app", "AutomatorDocument")); } return true; } // flatten any folders m_database.BeginTransaction(); DWORD dwTick=timeGetTime(); bool bProgressVisible = false; for (int i = 0; i < items.Size(); i++) { CStdString shortcutPath; CFileItemPtr item = items[i]; if (!bProgressVisible && timeGetTime()-dwTick>1500 && m_dlgProgress) { // tag loading takes more then 1.5 secs, show a progress dialog m_dlgProgress->SetHeading(189); m_dlgProgress->SetLine(0, 20120); m_dlgProgress->SetLine(1,""); m_dlgProgress->SetLine(2, item->GetLabel()); m_dlgProgress->StartModal(); bProgressVisible = true; } if (bProgressVisible) { m_dlgProgress->SetLine(2,item->GetLabel()); m_dlgProgress->Progress(); } if (item->m_bIsFolder && !item->IsParentFolder()) { // folder item - let's check for a default.xbe file, and flatten if we have one CStdString defaultXBE; CUtil::AddFileToFolder(item->m_strPath, "default.xbe", defaultXBE); if (CFile::Exists(defaultXBE)) { // yes, format the item up item->m_strPath = defaultXBE; item->m_bIsFolder = false; } } else if (item->IsShortCut()) { // resolve the shortcut to set it's description etc. // and save the old shortcut path (so we can reassign it later) CShortcut cut; if (cut.Create(item->m_strPath)) { shortcutPath = item->m_strPath; item->m_strPath = cut.m_strPath; item->SetThumbnailImage(cut.m_strThumb); LABEL_MASKS labelMasks; m_guiState->GetSortMethodLabelMasks(labelMasks); CLabelFormatter formatter("", labelMasks.m_strLabel2File); if (!cut.m_strLabel.IsEmpty()) { item->SetLabel(cut.m_strLabel); struct __stat64 stat; if (CFile::Stat(item->m_strPath,&stat) == 0) item->m_dwSize = stat.st_size; formatter.FormatLabel2(item.get()); item->SetLabelPreformated(true); } } } if (!shortcutPath.IsEmpty()) item->m_strPath = shortcutPath; // Special case for OS X application bundles if (item->GetLabel().Find(".app") > 0) { //Remove .app from the end of the label CStdString itemLabel = item->GetLabel(); CUtil::RemoveExtension(itemLabel); item->SetLabel(itemLabel); //Get the app's icon CStdString appIcon = Cocoa_GetAppIcon(item->m_strPath.c_str()); if (appIcon != NULL) item->SetThumbnailImage(appIcon); } // Special case for Automator workflows if (item->GetLabel().Find(".workflow") > 0) { CStdString itemLabel = item->GetLabel(); CUtil::RemoveExtension(itemLabel); item->SetLabel(itemLabel); item->SetThumbnailImage(Cocoa_GetIconFromBundle("/Applications/Automator.app", "AutomatorDocument")); } } m_database.CommitTransaction(); // set the cached thumbs items.SetThumbnailImage(""); items.SetCachedProgramThumbs(); items.SetCachedProgramThumb(); if (!items.HasThumbnail()) items.SetUserProgramThumb(); if (bProgressVisible) m_dlgProgress->Close(); return true; }
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); }