protected internal override void ReLoadItemsAndSubViewSpecifications(out IList <MediaItem> mediaItems, out IList <ViewSpecification> subViewSpecifications) { mediaItems = null; subViewSpecifications = null; IContentDirectory cd = ServiceRegistration.Get <IServerConnectionManager>().ContentDirectory; if (cd == null) { return; } bool showVirtual = ShowVirtualSetting.ShowVirtualMedia(_query.NecessaryRequestedMIATypeIDs); Guid? userProfile = null; IUserManagement userProfileDataManagement = ServiceRegistration.Get <IUserManagement>(); if (userProfileDataManagement != null && userProfileDataManagement.IsValidUser) { userProfile = userProfileDataManagement.CurrentUser.ProfileId; } try { if (MaxNumItems.HasValue) { // First request value groups. That is a performance consideration: // If we have many items, we need groups. If we have few items, we don't need the groups but simply do a search. // We request the groups first to make it faster for the many items case. In the case of few items, both groups and items // are requested which doesn't take so long because there are only few items. IList <MLQueryResultGroup> groups = cd.GroupValueGroups(MediaAspect.ATTR_TITLE, null, ProjectionFunction.None, _query.NecessaryRequestedMIATypeIDs, _query.Filter, _onlyOnline, GroupingFunction.FirstCharacter, showVirtual); long numItems = groups.Aggregate <MLQueryResultGroup, long>(0, (current, group) => current + group.NumItemsInGroup); if (numItems > MaxNumItems.Value) { // Group items mediaItems = new List <MediaItem>(0); subViewSpecifications = new List <ViewSpecification>(groups.Count); foreach (MLQueryResultGroup group in groups) { MediaLibraryQueryViewSpecification subViewSpecification = CreateSubViewSpecification(string.Format("{0}", group.GroupKey), _filterPath, group.AdditionalFilter, null); subViewSpecification.MaxNumItems = null; subViewSpecification._absNumItems = group.NumItemsInGroup; subViewSpecifications.Add(subViewSpecification); } return; } // Else: No grouping } // Else: No grouping mediaItems = cd.Search(_query, _onlyOnline, userProfile, showVirtual); subViewSpecifications = new List <ViewSpecification>(0); } catch (UPnPRemoteException e) { ServiceRegistration.Get <ILogger>().Error("SimpleTextSearchViewSpecification.ReLoadItemsAndSubViewSpecifications: Error requesting server", e); mediaItems = null; subViewSpecifications = null; } }
public void InitMediaNavigation(out string mediaNavigationMode, out NavigationData navigationData) { IEnumerable<Guid> skinDependentOptionalMIATypeIDs = MediaNavigationModel.GetMediaSkinOptionalMIATypes(MediaNavigationMode); AbstractItemsScreenData.PlayableItemCreatorDelegate picd = mi => new VideoItem(mi) { Command = new MethodDelegateCommand(() => PlayItemsModel.CheckQueryPlayAction(mi)) }; ViewSpecification rootViewSpecification = new MediaLibraryQueryViewSpecification(SlimTvConsts.RES_RECORDINGS_VIEW_NAME, null, SlimTvConsts.NECESSARY_RECORDING_MIAS, skinDependentOptionalMIATypeIDs, true) { MaxNumItems = Consts.MAX_NUM_ITEMS_VISIBLE }; AbstractScreenData defaultScreen = new RecordingFilterByNameScreenData(); ICollection<AbstractScreenData> availableScreens = new List<AbstractScreenData> { // C# doesn't like it to have an assignment inside a collection initializer defaultScreen, new VideosShowItemsScreenData(picd), new RecordingsFilterByChannelScreenData(), new VideosFilterByActorScreenData(), new VideosFilterByDirectorScreenData(), new VideosFilterByWriterScreenData(), new VideosFilterByGenreScreenData(), new VideosFilterByYearScreenData(), new VideosFilterBySystemScreenData(), new VideosSimpleSearchScreenData(picd), }; Sorting defaultSorting = new SortByRecordingDateDesc(); ICollection<Sorting> availableSortings = new List<Sorting> { defaultSorting, new SortByTitle(), new VideoSortByFirstGenre(), new VideoSortByDuration(), new VideoSortByFirstActor(), new VideoSortByFirstDirector(), new VideoSortByFirstWriter(), new VideoSortBySize(), new VideoSortByAspectRatio(), new SortBySystem(), }; navigationData = new NavigationData(null, Consts.RES_MOVIES_VIEW_NAME, MediaNavigationRootState, MediaNavigationRootState, rootViewSpecification, defaultScreen, availableScreens, defaultSorting) { AvailableSortings = availableSortings }; mediaNavigationMode = MediaNavigationMode; }
public void InitMediaNavigation(out string mediaNavigationMode, out NavigationData navigationData) { IEnumerable<Guid> skinDependentOptionalMIATypeIDs = MediaNavigationModel.GetMediaSkinOptionalMIATypes(MediaNavigationMode); AbstractItemsScreenData.PlayableItemCreatorDelegate picd = mi => new VideoItem(mi) { Command = new MethodDelegateCommand(() => PlayItemsModel.CheckQueryPlayAction(mi)) }; ViewSpecification rootViewSpecification = new MediaLibraryQueryViewSpecification(Consts.RES_VIDEOS_VIEW_NAME, null, Consts.NECESSARY_VIDEO_MIAS, skinDependentOptionalMIATypeIDs, true) { MaxNumItems = Consts.MAX_NUM_ITEMS_VISIBLE }; AbstractScreenData filterByGenre = new VideosFilterByGenreScreenData(); ICollection<AbstractScreenData> availableScreens = new List<AbstractScreenData> { new VideosShowItemsScreenData(picd), new VideosFilterByLanguageScreenData(), new VideosFilterByActorScreenData(), filterByGenre, // C# doesn't like it to have an assignment inside a collection initializer new VideosFilterByYearScreenData(), new VideosFilterBySystemScreenData(), new VideosSimpleSearchScreenData(picd), }; Sorting.Sorting sortByTitle = new SortByTitle(); ICollection<Sorting.Sorting> availableSortings = new List<Sorting.Sorting> { sortByTitle, new SortByYear(), new VideoSortByFirstGenre(), new VideoSortByDuration(), new VideoSortByDirector(), new VideoSortByFirstActor(), new VideoSortBySize(), new VideoSortByAspectRatio(), new SortBySystem(), }; navigationData = new NavigationData(null, Consts.RES_VIDEOS_VIEW_NAME, MediaNavigationRootState, MediaNavigationRootState, rootViewSpecification, filterByGenre, availableScreens, sortByTitle) { AvailableSortings = availableSortings }; mediaNavigationMode = MediaNavigationMode; }
protected void InitializeSearch(ViewSpecification baseViewSpecification) { _baseViewSpecification = baseViewSpecification as MediaLibraryQueryViewSpecification; if (_baseViewSpecification == null) return; if (_simpleSearchTextProperty == null) { _simpleSearchTextProperty = new WProperty(typeof(string), string.Empty); _simpleSearchTextProperty.Attach(OnSimpleSearchTextChanged); } SimpleSearchText = string.Empty; // Initialize data manually which would have been initialized by AbstractItemsScreenData.UpdateMediaItems else IsItemsValid = true; IsItemsEmpty = false; TooManyItems = false; NumItemsStr = "-"; NumItems = 0; lock (_syncObj) _view = null; _items = new ItemsList(); }
/// <summary> /// Returns context variables to be set for the given workflow state id. /// </summary> /// <param name="workflowStateId">Workflow state which determines the root media navigation state.</param> /// <returns>Mapping of context variable keys to values.</returns> protected static IDictionary<string, object> PrepareRootState(Guid workflowStateId) { IDictionary<string, object> result = new Dictionary<string, object>(); // The initial state ID determines the media model "part" to initialize: Browse local media, browse media library, audio, videos or images. // The media model part determines the media navigation mode and the view contents to be set. NavigationData navigationData; MediaNavigationMode mode; if (workflowStateId == Consts.WF_STATE_ID_AUDIO_NAVIGATION_ROOT) { mode = MediaNavigationMode.Audio; IEnumerable<Guid> skinDependentOptionalMIATypeIDs = GetMediaSkinOptionalMIATypes(mode); AbstractItemsScreenData.PlayableItemCreatorDelegate picd = mi => new AudioItem(mi) { Command = new MethodDelegateCommand(() => PlayItemsModel.CheckQueryPlayAction(mi)) }; ViewSpecification rootViewSpecification = new MediaLibraryQueryViewSpecification(Consts.RES_AUDIO_VIEW_NAME, null, Consts.NECESSARY_AUDIO_MIAS, skinDependentOptionalMIATypeIDs, true) { MaxNumItems = Consts.MAX_NUM_ITEMS_VISIBLE }; AbstractScreenData filterByAlbum = new AudioFilterByAlbumScreenData(); ICollection<AbstractScreenData> availableScreens = new List<AbstractScreenData> { new AudioShowItemsScreenData(picd), new AudioFilterByArtistScreenData(), filterByAlbum, // C# doesn't like it to have an assignment inside a collection initializer new AudioFilterByGenreScreenData(), new AudioFilterByDecadeScreenData(), new AudioFilterBySystemScreenData(), new AudioSimpleSearchScreenData(picd), }; Sorting.Sorting sortByAlbumTrack = new AudioSortByAlbumTrack(); ICollection<Sorting.Sorting> availableSortings = new List<Sorting.Sorting> { sortByAlbumTrack, new SortByTitle(), new AudioSortByFirstGenre(), new AudioSortByFirstArtist(), new AudioSortByAlbum(), new AudioSortByTrack(), new SortByYear(), new SortBySystem(), }; navigationData = new NavigationData(null, Consts.RES_AUDIO_VIEW_NAME, workflowStateId, workflowStateId, rootViewSpecification, filterByAlbum, availableScreens, sortByAlbumTrack) { AvailableSortings = availableSortings }; } else if (workflowStateId == Consts.WF_STATE_ID_VIDEOS_NAVIGATION_ROOT) { mode = MediaNavigationMode.Videos; IEnumerable<Guid> skinDependentOptionalMIATypeIDs = GetMediaSkinOptionalMIATypes(mode); AbstractItemsScreenData.PlayableItemCreatorDelegate picd = mi => new VideoItem(mi) { Command = new MethodDelegateCommand(() => PlayItemsModel.CheckQueryPlayAction(mi)) }; ViewSpecification rootViewSpecification = new MediaLibraryQueryViewSpecification(Consts.RES_VIDEOS_VIEW_NAME, null, Consts.NECESSARY_VIDEO_MIAS, skinDependentOptionalMIATypeIDs, true) { MaxNumItems = Consts.MAX_NUM_ITEMS_VISIBLE }; AbstractScreenData filterByGenre = new VideosFilterByGenreScreenData(); ICollection<AbstractScreenData> availableScreens = new List<AbstractScreenData> { new VideosShowItemsScreenData(picd), new VideosFilterByLanguageScreenData(), new VideosFilterByActorScreenData(), filterByGenre, // C# doesn't like it to have an assignment inside a collection initializer new VideosFilterByYearScreenData(), new VideosFilterBySystemScreenData(), new VideosSimpleSearchScreenData(picd), }; Sorting.Sorting sortByTitle = new SortByTitle(); ICollection<Sorting.Sorting> availableSortings = new List<Sorting.Sorting> { sortByTitle, new SortByYear(), new VideoSortByFirstGenre(), new VideoSortByDuration(), new VideoSortByDirector(), new VideoSortByFirstActor(), new VideoSortBySize(), new VideoSortByAspectRatio(), new SortBySystem(), }; navigationData = new NavigationData(null, Consts.RES_VIDEOS_VIEW_NAME, workflowStateId, workflowStateId, rootViewSpecification, filterByGenre, availableScreens, sortByTitle) { AvailableSortings = availableSortings }; } else if (workflowStateId == Consts.WF_STATE_ID_SERIES_NAVIGATION_ROOT) { mode = MediaNavigationMode.Videos; IEnumerable<Guid> skinDependentOptionalMIATypeIDs = GetMediaSkinOptionalMIATypes(mode); AbstractItemsScreenData.PlayableItemCreatorDelegate picd = mi => new SeriesItem(mi) { Command = new MethodDelegateCommand(() => PlayItemsModel.CheckQueryPlayAction(mi)) }; ViewSpecification rootViewSpecification = new MediaLibraryQueryViewSpecification(Consts.RES_SERIES_VIEW_NAME, null, Consts.NECESSARY_SERIES_MIAS, skinDependentOptionalMIATypeIDs, true) { MaxNumItems = Consts.MAX_NUM_ITEMS_VISIBLE }; AbstractScreenData filterBySeries = new SeriesFilterByNameScreenData(); ICollection<AbstractScreenData> availableScreens = new List<AbstractScreenData> { new SeriesShowItemsScreenData(picd), filterBySeries, // C# doesn't like it to have an assignment inside a collection initializer new VideosFilterByLanguageScreenData(), new SeriesFilterBySeasonScreenData(), new VideosFilterByGenreScreenData(), new VideosSimpleSearchScreenData(picd), }; Sorting.Sorting sortByEpisode = new SeriesSortByEpisode(); ICollection<Sorting.Sorting> availableSortings = new List<Sorting.Sorting> { sortByEpisode, new SortByTitle(), new SortByDate(), new SortBySystem(), }; navigationData = new NavigationData(null, Consts.RES_SERIES_VIEW_NAME, workflowStateId, workflowStateId, rootViewSpecification, filterBySeries, availableScreens, sortByEpisode) { AvailableSortings = availableSortings }; } else if (workflowStateId == Consts.WF_STATE_ID_MOVIES_NAVIGATION_ROOT) { mode = MediaNavigationMode.Movies; IEnumerable<Guid> skinDependentOptionalMIATypeIDs = GetMediaSkinOptionalMIATypes(mode); AbstractItemsScreenData.PlayableItemCreatorDelegate picd = mi => new MovieItem(mi) { Command = new MethodDelegateCommand(() => PlayItemsModel.CheckQueryPlayAction(mi)) }; ViewSpecification rootViewSpecification = new MediaLibraryQueryViewSpecification(Consts.RES_MOVIES_VIEW_NAME, null, Consts.NECESSARY_MOVIES_MIAS, skinDependentOptionalMIATypeIDs, true) { MaxNumItems = Consts.MAX_NUM_ITEMS_VISIBLE }; AbstractScreenData filterByGenre = new VideosFilterByGenreScreenData(); ICollection<AbstractScreenData> availableScreens = new List<AbstractScreenData> { new MoviesShowItemsScreenData(picd), new VideosFilterByActorScreenData(), filterByGenre, // C# doesn't like it to have an assignment inside a collection initializer new VideosFilterByYearScreenData(), new VideosFilterBySystemScreenData(), new VideosSimpleSearchScreenData(picd), }; Sorting.Sorting sortByTitle = new SortByTitle(); ICollection<Sorting.Sorting> availableSortings = new List<Sorting.Sorting> { sortByTitle, new SortByYear(), new VideoSortByFirstGenre(), new VideoSortByDuration(), new VideoSortByDirector(), new VideoSortByFirstActor(), new VideoSortBySize(), new VideoSortByAspectRatio(), new SortBySystem(), }; navigationData = new NavigationData(null, Consts.RES_MOVIES_VIEW_NAME, workflowStateId, workflowStateId, rootViewSpecification, filterByGenre, availableScreens, sortByTitle) { AvailableSortings = availableSortings }; } else if (workflowStateId == Consts.WF_STATE_ID_IMAGES_NAVIGATION_ROOT) { mode = MediaNavigationMode.Images; IEnumerable<Guid> skinDependentOptionalMIATypeIDs = GetMediaSkinOptionalMIATypes(mode); AbstractItemsScreenData.PlayableItemCreatorDelegate picd = mi => new ImageItem(mi) { Command = new MethodDelegateCommand(() => PlayItemsModel.CheckQueryPlayAction(mi)) }; ViewSpecification rootViewSpecification = new MediaLibraryQueryViewSpecification(Consts.RES_IMAGES_VIEW_NAME, null, Consts.NECESSARY_IMAGE_MIAS, skinDependentOptionalMIATypeIDs, true) { MaxNumItems = Consts.MAX_NUM_ITEMS_VISIBLE }; AbstractScreenData filterByYear = new ImagesFilterByYearScreenData(); ICollection<AbstractScreenData> availableScreens = new List<AbstractScreenData> { new ImagesShowItemsScreenData(picd), filterByYear, // C# doesn't like it to have an assignment inside a collection initializer new ImagesFilterBySizeScreenData(), new ImagesFilterBySystemScreenData(), new ImagesSimpleSearchScreenData(picd), }; Sorting.Sorting sortByYear = new SortByYear(); ICollection<Sorting.Sorting> availableSortings = new List<Sorting.Sorting> { new SortByYear(), new SortByTitle(), new ImageSortBySize(), new SortBySystem(), }; navigationData = new NavigationData(null, Consts.RES_IMAGES_VIEW_NAME, workflowStateId, workflowStateId, rootViewSpecification, filterByYear, availableScreens, sortByYear) { AvailableSortings = availableSortings }; } else { // If we were called with a supported root state, we should be either in state WF_STATE_ID_LOCAL_MEDIA_NAVIGATION_ROOT // or WF_STATE_ID_MEDIA_BROWSE_NAVIGATION_ROOT here if (workflowStateId != Consts.WF_STATE_ID_LOCAL_MEDIA_NAVIGATION_ROOT && workflowStateId != Consts.WF_STATE_ID_BROWSE_MEDIA_NAVIGATION_ROOT) { // Error case: We cannot handle the given state ServiceRegistration.Get<ILogger>().Warn("MediaNavigationModel: Unknown root workflow state with ID '{0}', initializing local media navigation", workflowStateId); // We simply use the local media mode as fallback for this case, so we go on workflowStateId = Consts.WF_STATE_ID_LOCAL_MEDIA_NAVIGATION_ROOT; } mode = workflowStateId == Consts.WF_STATE_ID_LOCAL_MEDIA_NAVIGATION_ROOT ? MediaNavigationMode.BrowseLocalMedia : MediaNavigationMode.BrowseMediaLibrary; IEnumerable<Guid> skinDependentOptionalMIATypeIDs = GetMediaSkinOptionalMIATypes(mode); AbstractItemsScreenData.PlayableItemCreatorDelegate picd = mi => { if (mi.Aspects.ContainsKey(AudioAspect.ASPECT_ID)) return new AudioItem(mi) { Command = new MethodDelegateCommand(() => PlayItemsModel.CheckQueryPlayAction(mi)) }; if (mi.Aspects.ContainsKey(VideoAspect.ASPECT_ID)) return new VideoItem(mi) { Command = new MethodDelegateCommand(() => PlayItemsModel.CheckQueryPlayAction(mi)) }; if (mi.Aspects.ContainsKey(ImageAspect.ASPECT_ID)) return new ImageItem(mi) { Command = new MethodDelegateCommand(() => PlayItemsModel.CheckQueryPlayAction(mi)) }; return null; }; IEnumerable<Guid> necessaryMIATypeIDs = new Guid[] { ProviderResourceAspect.ASPECT_ID, MediaAspect.ASPECT_ID, }; IEnumerable<Guid> optionalMIATypeIDs = new Guid[] { AudioAspect.ASPECT_ID, VideoAspect.ASPECT_ID, ImageAspect.ASPECT_ID, }.Union(skinDependentOptionalMIATypeIDs); string viewName = workflowStateId == Consts.WF_STATE_ID_LOCAL_MEDIA_NAVIGATION_ROOT ? Consts.RES_LOCAL_MEDIA_ROOT_VIEW_NAME : Consts.RES_BROWSE_MEDIA_ROOT_VIEW_NAME; ViewSpecification rootViewSpecification = workflowStateId == Consts.WF_STATE_ID_LOCAL_MEDIA_NAVIGATION_ROOT ? new AddedRemovableMediaViewSpecificationFacade(new LocalMediaRootProxyViewSpecification(viewName, necessaryMIATypeIDs, optionalMIATypeIDs)) : new AddedRemovableMediaViewSpecificationFacade(new BrowseMediaRootProxyViewSpecification(viewName, necessaryMIATypeIDs, optionalMIATypeIDs)); // Dynamic screens remain null - browse media states don't provide dynamic filters AbstractScreenData screenData = workflowStateId == Consts.WF_STATE_ID_LOCAL_MEDIA_NAVIGATION_ROOT ? (AbstractScreenData) new LocalMediaNavigationScreenData(picd) : new BrowseMediaNavigationScreenData(picd); Sorting.Sorting browseDefaultSorting = new BrowseDefaultSorting(); ICollection<Sorting.Sorting> availableSortings = new List<Sorting.Sorting> { browseDefaultSorting, new SortByTitle(), new SortByDate(), // We could offer sortings here which are specific for one media item type but which will cope with all three item types (and sort items of the three types in a defined order) }; navigationData = new NavigationData(null, viewName, workflowStateId, workflowStateId, rootViewSpecification, screenData, null, browseDefaultSorting) { AvailableSortings = availableSortings }; } result.Add(Consts.KEY_NAVIGATION_MODE, mode); result.Add(Consts.KEY_NAVIGATION_DATA, navigationData); return result; }