Beispiel #1
0
        protected void AddCurrentViewToPlaylistInternal()
        {
            NavigationData navigationData = NavigationData;

            if (navigationData == null || !navigationData.IsEnabled)
            {
                ServiceRegistration.Get <ILogger>().Error("MediaNavigationModel: Cannot add current view to playlist - There is no enabled navigation data available");
            }
            string mode = Mode;

            switch (mode)
            {
            case MediaNavigationMode.Audio:
                PlayItemsModel.CheckQueryPlayAction(GetMediaItemsFromCurrentView, AVType.Audio);
                break;

            case MediaNavigationMode.Movies:
            case MediaNavigationMode.Series:
            case MediaNavigationMode.Videos:
            case MediaNavigationMode.Images:
                PlayItemsModel.CheckQueryPlayAction(GetMediaItemsFromCurrentView, AVType.Video);
                break;

            case MediaNavigationMode.BrowseLocalMedia:
            case MediaNavigationMode.BrowseMediaLibrary:
                PlayItemsModel.CheckQueryPlayAction(GetMediaItemsFromCurrentView);
                break;
            }
        }
 public void Play()
 {
     if (MediaItem != null)
     {
         PlayItemsModel.CheckQueryPlayAction(MediaItem);
     }
 }
        protected static async Task FillListAsync(IContentDirectory contentDirectory, Guid[] necessaryMIATypeIds, ItemsList list, MediaItemToListItemAction converterAction)
        {
            MediaItemQuery query = new MediaItemQuery(necessaryMIATypeIds, null)
            {
                Limit           = QUERY_LIMIT, // Last 5 imported items
                SortInformation = new List <ISortInformation> {
                    new AttributeSortInformation(ImporterAspect.ATTR_DATEADDED, SortDirection.Descending)
                }
            };

            Guid?           userProfile = null;
            IUserManagement userProfileDataManagement = ServiceRegistration.Get <IUserManagement>();

            if (userProfileDataManagement != null && userProfileDataManagement.IsValidUser)
            {
                userProfile = userProfileDataManagement.CurrentUser.ProfileId;
            }
            bool showVirtual = VirtualMediaHelper.ShowVirtualMedia(necessaryMIATypeIds);

            var items = await contentDirectory.SearchAsync(query, false, userProfile, showVirtual);

            list.Clear();
            foreach (MediaItem mediaItem in items)
            {
                PlayableMediaItem listItem = converterAction(mediaItem);
                listItem.Command = new MethodDelegateCommand(() => PlayItemsModel.CheckQueryPlayAction(listItem.MediaItem));
                list.Add(listItem);
            }
            list.FireChange();
        }
    protected static void FillList(IContentDirectory contentDirectory, Guid[] necessaryMIAs, ItemsList list, MediaItemToListItemAction converterAction)
    {
      MediaItemQuery query = new MediaItemQuery(necessaryMIAs, null)
      {
        Limit = QUERY_LIMIT, // Last 5 imported items
        SortInformation = new List<SortInformation> { new SortInformation(ImporterAspect.ATTR_DATEADDED, SortDirection.Descending) }
      };

      var items = contentDirectory.Search(query, false);
      list.Clear();
      foreach (MediaItem mediaItem in items)
      {
        PlayableMediaItem listItem = converterAction(mediaItem);
        listItem.Command = new MethodDelegateCommand(() => PlayItemsModel.CheckQueryPlayAction(listItem.MediaItem));
        list.Add(listItem);
      }
      list.FireChange();
    }
        public void LoadPlaylist()
        {
            IDialogManager dialogManager = ServiceRegistration.Get <IDialogManager>();

            if (_playlist == null)
            {
                dialogManager.ShowDialog(SkinBase.General.Consts.RES_SYSTEM_ERROR, Consts.RES_PLAYLIST_LOAD_NO_PLAYLIST, DialogType.OkDialog, false, null);
                return;
            }
            IContentDirectory cd     = ServiceRegistration.Get <IServerConnectionManager>().ContentDirectory;
            AVType?           avType = ConvertPlaylistTypeToAVType(_playlist.PlaylistType);

            if (cd == null || !avType.HasValue)
            {
                dialogManager.ShowDialog(SkinBase.General.Consts.RES_SYSTEM_ERROR, Consts.RES_PLAYLIST_LOAD_ERROR_LOADING, DialogType.OkDialog, false, null);
                return;
            }
            Guid[] necessaryMIATypes = new Guid[]
            {
                ProviderResourceAspect.ASPECT_ID,
                MediaAspect.ASPECT_ID,
            };
            Guid[] optionalMIATypes = new Guid[]
            {
                AudioAspect.ASPECT_ID,
                VideoAspect.ASPECT_ID,
                ImageAspect.ASPECT_ID,
            };
            // Big playlists cannot be loaded in one single step. We have several problems if we try to do so:
            // 1) Loading the playlist at once at the server results in one huge SQL IN statement which might break the SQL engine
            // 2) The time to load the playlist might lead the UPnP call to break because of the timeout when calling methods
            // 3) The resulting UPnP XML document might be too big to fit into memory

            // For that reason, we load the playlist in two steps:
            // 1) Load media item ids in the playlist
            // 2) Load media items in clusters - for each cluster, an own query will be executed at the content directory
            PlaylistRawData playlistData = cd.ExportPlaylist(_playlist.PlaylistId);

            PlayItemsModel.CheckQueryPlayAction(() => CollectionUtils.Cluster(playlistData.MediaItemIds, 1000).SelectMany(itemIds =>
                                                                                                                          cd.LoadCustomPlaylist(itemIds, necessaryMIATypes, optionalMIATypes)), avType.Value);
        }
        public void AddMediaItemstoPlaylist(GetMediaItemsDlgt getMediaItemsWithSelection)
        {
            string mode = Mode;

            switch (mode)
            {
            case MediaNavigationMode.Audio:
                PlayItemsModel.CheckQueryPlayAction(getMediaItemsWithSelection, AVType.Audio);
                break;

            case MediaNavigationMode.Movies:
            case MediaNavigationMode.Series:
            case MediaNavigationMode.Videos:
            case MediaNavigationMode.Images:
                PlayItemsModel.CheckQueryPlayAction(getMediaItemsWithSelection, AVType.Video);
                break;

            case MediaNavigationMode.BrowseLocalMedia:
            case MediaNavigationMode.BrowseMediaLibrary:
                PlayItemsModel.CheckQueryPlayAction(getMediaItemsWithSelection);
                break;
            }
        }
Beispiel #7
0
        /// <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;
            string         mode;

            if (_initializers.ContainsKey(workflowStateId))
            {
                // Use the IMediaNavigationInitializer that is associated with our root workflow state.
                IMediaNavigationInitializer initializer = _initializers[workflowStateId];
                initializer.InitMediaNavigation(out mode, out navigationData);
            }
            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);
        }
        /// <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);
        }