convert library explorer to win forms
This commit is contained in:
parent
8b71ab2e7d
commit
60213b2d3c
|
@ -1,178 +0,0 @@
|
|||
<Window x:Class="MediaBrowser.ServerApplication.LibraryExplorer"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:local="clr-namespace:MediaBrowser.ServerApplication"
|
||||
Title="Library Explorer"
|
||||
Height="733.75"
|
||||
Width="893">
|
||||
<Grid Margin="0,0,0,10">
|
||||
<TreeView x:Name="tvwLibrary"
|
||||
HorizontalAlignment="Left"
|
||||
Margin="10,54,0,0"
|
||||
Width="399"
|
||||
SelectedItemChanged="tvwLibrary_SelectedItemChanged"
|
||||
Height="417"
|
||||
VerticalAlignment="Top">
|
||||
<TreeView.Resources>
|
||||
<Style TargetType="{x:Type TreeViewItem}">
|
||||
<Setter Property="HeaderTemplate">
|
||||
<Setter.Value>
|
||||
<DataTemplate>
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<Image Name="img"
|
||||
Width="20"
|
||||
Height="20"
|
||||
Stretch="Fill"
|
||||
Source="{Binding RelativeSource={RelativeSource Mode=FindAncestor,
|
||||
AncestorType={x:Type TreeViewItem}},
|
||||
Path=Tag,
|
||||
Converter={x:Static local:ItemToImageConverter.Instance}}" />
|
||||
<TextBlock Text="{Binding}"
|
||||
Margin="5,0" />
|
||||
</StackPanel>
|
||||
</DataTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</Style>
|
||||
</TreeView.Resources>
|
||||
</TreeView>
|
||||
|
||||
<Button x:Name="btnLoad"
|
||||
Content="Load"
|
||||
HorizontalAlignment="Left"
|
||||
Margin="218,25,0,0"
|
||||
VerticalAlignment="Top"
|
||||
Width="75"
|
||||
RenderTransformOrigin="0.373,0.045"
|
||||
Click="btnLoad_Click"
|
||||
Visibility="Hidden" />
|
||||
<TextBox x:Name="txtData"
|
||||
Margin="427,54,0,0"
|
||||
HorizontalAlignment="Left"
|
||||
TextWrapping="Wrap"
|
||||
VerticalAlignment="Top"
|
||||
Height="417"
|
||||
Width="444"
|
||||
VerticalScrollBarVisibility="Auto" />
|
||||
|
||||
<Label Content="Contents
"
|
||||
HorizontalAlignment="Left"
|
||||
Margin="440,23,0,0"
|
||||
VerticalAlignment="Top"
|
||||
Height="26"
|
||||
Width="74"
|
||||
FontWeight="Bold" />
|
||||
<ListView x:Name="lstPreviews"
|
||||
HorizontalAlignment="Left"
|
||||
Margin="10,476,0,10"
|
||||
Width="861">
|
||||
<ListView.ItemsPanel>
|
||||
<ItemsPanelTemplate>
|
||||
<WrapPanel Orientation="Horizontal"
|
||||
MinWidth="100" />
|
||||
</ItemsPanelTemplate>
|
||||
</ListView.ItemsPanel>
|
||||
<ListView.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="150" />
|
||||
<RowDefinition Height="25" />
|
||||
</Grid.RowDefinitions>
|
||||
<Image Source="{Binding Preview}"
|
||||
Height="140"
|
||||
MaxWidth="300"
|
||||
Grid.Row="0" />
|
||||
<TextBlock Text="{Binding Name}"
|
||||
Grid.Row="1"
|
||||
FontFamily="Segoe Media Center"
|
||||
FontSize="14"
|
||||
FontWeight="Bold"
|
||||
HorizontalAlignment="Center" />
|
||||
</Grid>
|
||||
</DataTemplate>
|
||||
</ListView.ItemTemplate>
|
||||
</ListView>
|
||||
<ComboBox x:Name="ddlProfile"
|
||||
HorizontalAlignment="Left"
|
||||
Margin="10,25,0,0"
|
||||
VerticalAlignment="Top"
|
||||
Width="191"
|
||||
SelectionChanged="ddlProfile_SelectionChanged" />
|
||||
<Label Content="View;"
|
||||
HorizontalAlignment="Left"
|
||||
Margin="10,1,0,0"
|
||||
VerticalAlignment="Top"
|
||||
Height="24"
|
||||
Width="119"
|
||||
FontWeight="Bold" />
|
||||
<Label x:Name="lblLoading"
|
||||
Content="Loading..."
|
||||
HorizontalAlignment="Left"
|
||||
Margin="140,150,0,0"
|
||||
VerticalAlignment="Top"
|
||||
FontSize="18"
|
||||
Foreground="LightGray"
|
||||
Visibility="Hidden"
|
||||
FontStyle="Italic"
|
||||
FontWeight="Bold"
|
||||
RenderTransformOrigin="0.258,0.5" />
|
||||
<Label x:Name="lblObjType"
|
||||
Content="Type:
"
|
||||
HorizontalAlignment="Left"
|
||||
Margin="534,23,0,0"
|
||||
VerticalAlignment="Top"
|
||||
Height="26"
|
||||
Width="158"
|
||||
FontWeight="Bold" />
|
||||
<Button x:Name="btnRefresh"
|
||||
Content="Refresh"
|
||||
HorizontalAlignment="Left"
|
||||
Margin="712,25,0,0"
|
||||
VerticalAlignment="Top"
|
||||
Width="82"
|
||||
Click="btnRefresh_Click" />
|
||||
<CheckBox x:Name="cbxForce"
|
||||
Content="Force"
|
||||
HorizontalAlignment="Left"
|
||||
Margin="816,28,0,0"
|
||||
VerticalAlignment="Top"
|
||||
RenderTransformOrigin="-0.14,-0.562"
|
||||
Width="51" />
|
||||
<ComboBox x:Name="ddlIndexBy"
|
||||
HorizontalAlignment="Left"
|
||||
Margin="218,25,0,0"
|
||||
VerticalAlignment="Top"
|
||||
Width="92"
|
||||
SelectionChanged="ddlIndexBy_SelectionChanged" />
|
||||
<Label x:Name="lblIndexBy"
|
||||
Content="Index By"
|
||||
HorizontalAlignment="Left"
|
||||
Margin="218,0,0,0"
|
||||
VerticalAlignment="Top"
|
||||
Height="34"
|
||||
Width="75"
|
||||
FontWeight="Bold" />
|
||||
<ComboBox x:Name="ddlSortBy"
|
||||
HorizontalAlignment="Left"
|
||||
Margin="315,25,0,0"
|
||||
VerticalAlignment="Top"
|
||||
Width="94"
|
||||
SelectionChanged="ddlSortBy_SelectionChanged" />
|
||||
<Label x:Name="lblSortBy"
|
||||
Content="Sort By"
|
||||
HorizontalAlignment="Left"
|
||||
Margin="314,0,0,0"
|
||||
VerticalAlignment="Top"
|
||||
Height="34"
|
||||
Width="75"
|
||||
FontWeight="Bold" />
|
||||
<Label x:Name="lblVersion"
|
||||
Content="Version: "
|
||||
HorizontalAlignment="Left"
|
||||
Margin="729,-6,0,0"
|
||||
VerticalAlignment="Top"
|
||||
Width="138" />
|
||||
|
||||
</Grid>
|
||||
</Window>
|
|
@ -1,656 +0,0 @@
|
|||
using MediaBrowser.Common;
|
||||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Controller.Entities.Movies;
|
||||
using MediaBrowser.Controller.Entities.TV;
|
||||
using MediaBrowser.Controller.Library;
|
||||
using MediaBrowser.Controller.Localization;
|
||||
using MediaBrowser.Controller.Persistence;
|
||||
using MediaBrowser.Controller.Providers;
|
||||
using MediaBrowser.Model.Entities;
|
||||
using MediaBrowser.Model.Logging;
|
||||
using MediaBrowser.Model.Querying;
|
||||
using MediaBrowser.Model.Serialization;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Data;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Media.Imaging;
|
||||
|
||||
namespace MediaBrowser.ServerApplication
|
||||
{
|
||||
/// <summary>
|
||||
/// Interaction logic for LibraryExplorer.xaml
|
||||
/// </summary>
|
||||
public partial class LibraryExplorer : Window
|
||||
{
|
||||
private readonly ILogger _logger;
|
||||
|
||||
private readonly IJsonSerializer _jsonSerializer;
|
||||
private readonly ILibraryManager _libraryManager;
|
||||
private readonly IDisplayPreferencesRepository _displayPreferencesManager;
|
||||
|
||||
private readonly IItemRepository _itemRepository;
|
||||
|
||||
/// <summary>
|
||||
/// The current user
|
||||
/// </summary>
|
||||
private User CurrentUser;
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="LibraryExplorer" /> class.
|
||||
/// </summary>
|
||||
/// <param name="jsonSerializer">The json serializer.</param>
|
||||
/// <param name="logger">The logger.</param>
|
||||
/// <param name="appHost">The app host.</param>
|
||||
/// <param name="userManager">The user manager.</param>
|
||||
/// <param name="libraryManager">The library manager.</param>
|
||||
/// <param name="displayPreferencesManager">The display preferences manager.</param>
|
||||
public LibraryExplorer(IJsonSerializer jsonSerializer, ILogger logger, IApplicationHost appHost, IUserManager userManager, ILibraryManager libraryManager, IDisplayPreferencesRepository displayPreferencesManager, IItemRepository itemRepo)
|
||||
{
|
||||
_logger = logger;
|
||||
_jsonSerializer = jsonSerializer;
|
||||
_libraryManager = libraryManager;
|
||||
_displayPreferencesManager = displayPreferencesManager;
|
||||
|
||||
InitializeComponent();
|
||||
lblVersion.Content = "Version: " + appHost.ApplicationVersion;
|
||||
foreach (var user in userManager.Users)
|
||||
ddlProfile.Items.Add(user);
|
||||
ddlProfile.Items.Insert(0, new User { Name = "Physical" });
|
||||
ddlProfile.SelectedIndex = 0;
|
||||
ddlIndexBy.Visibility = ddlSortBy.Visibility = lblIndexBy.Visibility = lblSortBy.Visibility = Visibility.Hidden;
|
||||
_itemRepository = itemRepo;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handles the Click event of the btnLoad control.
|
||||
/// </summary>
|
||||
/// <param name="sender">The source of the event.</param>
|
||||
/// <param name="e">The <see cref="RoutedEventArgs" /> instance containing the event data.</param>
|
||||
private void btnLoad_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Loads the tree.
|
||||
/// </summary>
|
||||
/// <returns>Task.</returns>
|
||||
private async Task LoadTree()
|
||||
{
|
||||
tvwLibrary.Items.Clear();
|
||||
lblLoading.Visibility = Visibility.Visible;
|
||||
//grab UI context so we can update within the below task
|
||||
var ui = TaskScheduler.FromCurrentSynchronizationContext();
|
||||
//this whole async thing doesn't really work in this instance since all my work pretty much needs to be on the UI thread...
|
||||
Cursor = Cursors.Wait;
|
||||
await Task.Run(() =>
|
||||
{
|
||||
IEnumerable<BaseItem> children = CurrentUser.Name == "Physical" ? new[] { _libraryManager.RootFolder } : _libraryManager.RootFolder.GetChildren(CurrentUser, true);
|
||||
children = OrderByName(children, CurrentUser);
|
||||
|
||||
foreach (Folder folder in children)
|
||||
{
|
||||
|
||||
var currentFolder = folder;
|
||||
Task.Factory.StartNew(() =>
|
||||
{
|
||||
var prefs = ddlProfile.SelectedItem != null ? _displayPreferencesManager.GetDisplayPreferences(currentFolder.DisplayPreferencesId, (ddlProfile.SelectedItem as User).Id, "LibraryExplorer") ?? new DisplayPreferences { SortBy = ItemSortBy.SortName } : new DisplayPreferences { SortBy = ItemSortBy.SortName };
|
||||
var node = new TreeViewItem { Tag = currentFolder };
|
||||
|
||||
var subChildren = currentFolder.GetChildren(CurrentUser, true);
|
||||
subChildren = OrderByName(subChildren, CurrentUser);
|
||||
AddChildren(node, subChildren, CurrentUser);
|
||||
node.Header = currentFolder.Name + " (" +
|
||||
node.Items.Count + ")";
|
||||
tvwLibrary.Items.Add(node);
|
||||
}, CancellationToken.None, TaskCreationOptions.None, ui);
|
||||
}
|
||||
});
|
||||
lblLoading.Visibility = Visibility.Hidden;
|
||||
Cursor = Cursors.Arrow;
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Orders the name of the by.
|
||||
/// </summary>
|
||||
/// <param name="items">The items.</param>
|
||||
/// <param name="user">The user.</param>
|
||||
/// <returns>IEnumerable{BaseItem}.</returns>
|
||||
private IEnumerable<BaseItem> OrderByName(IEnumerable<BaseItem> items, User user)
|
||||
{
|
||||
return OrderBy(items, user, ItemSortBy.SortName);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Orders the name of the by.
|
||||
/// </summary>
|
||||
/// <param name="items">The items.</param>
|
||||
/// <param name="user">The user.</param>
|
||||
/// <returns>IEnumerable{BaseItem}.</returns>
|
||||
private IEnumerable<BaseItem> OrderBy(IEnumerable<BaseItem> items, User user, string order)
|
||||
{
|
||||
return _libraryManager.Sort(items, user, new[] { order }, SortOrder.Ascending);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds the children.
|
||||
/// </summary>
|
||||
/// <param name="parent">The parent.</param>
|
||||
/// <param name="children">The children.</param>
|
||||
/// <param name="user">The user.</param>
|
||||
private void AddChildren(TreeViewItem parent, IEnumerable<BaseItem> children, User user)
|
||||
{
|
||||
foreach (var item in children)
|
||||
{
|
||||
var node = new TreeViewItem { Tag = item };
|
||||
var subFolder = item as Folder;
|
||||
if (subFolder != null)
|
||||
{
|
||||
var prefs = _displayPreferencesManager.GetDisplayPreferences(subFolder.DisplayPreferencesId, user.Id, "LibraryExplorer");
|
||||
|
||||
AddChildren(node, OrderBy(subFolder.GetChildren(user, true), user, prefs.SortBy), user);
|
||||
node.Header = item.Name + " (" + node.Items.Count + ")";
|
||||
}
|
||||
else
|
||||
{
|
||||
node.Header = item.Name;
|
||||
}
|
||||
parent.Items.Add(node);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// TVWs the library_ selected item changed.
|
||||
/// </summary>
|
||||
/// <param name="sender">The sender.</param>
|
||||
/// <param name="e">The e.</param>
|
||||
private async void tvwLibrary_SelectedItemChanged(object sender, RoutedPropertyChangedEventArgs<object> e)
|
||||
{
|
||||
if (tvwLibrary.SelectedItem != null)
|
||||
{
|
||||
var item = (BaseItem)(tvwLibrary.SelectedItem as TreeViewItem).Tag;
|
||||
lblObjType.Content = "Type: " + item.GetType().Name;
|
||||
|
||||
var movie = item as Movie;
|
||||
|
||||
var folder = item as Folder;
|
||||
if (folder != null)
|
||||
{
|
||||
lblIndexBy.Visibility = ddlIndexBy.Visibility = ddlSortBy.Visibility = lblSortBy.Visibility = Visibility.Visible;
|
||||
ddlIndexBy.ItemsSource = folder.IndexByOptionStrings;
|
||||
|
||||
ddlSortBy.ItemsSource = new[]
|
||||
{
|
||||
ItemSortBy.SortName,
|
||||
ItemSortBy.Album,
|
||||
ItemSortBy.AlbumArtist,
|
||||
ItemSortBy.Artist,
|
||||
ItemSortBy.CommunityRating,
|
||||
ItemSortBy.DateCreated,
|
||||
ItemSortBy.DatePlayed,
|
||||
ItemSortBy.PremiereDate,
|
||||
ItemSortBy.ProductionYear,
|
||||
ItemSortBy.Random,
|
||||
ItemSortBy.Runtime
|
||||
};
|
||||
|
||||
var prefs = _displayPreferencesManager.GetDisplayPreferences(folder.DisplayPreferencesId, (ddlProfile.SelectedItem as User).Id, "LibraryExplorer");
|
||||
|
||||
ddlIndexBy.SelectedItem = prefs != null
|
||||
? prefs.IndexBy ?? LocalizedStrings.Instance.GetString("NoneDispPref")
|
||||
: LocalizedStrings.Instance.GetString("NoneDispPref");
|
||||
ddlSortBy.SelectedItem = prefs != null
|
||||
? prefs.SortBy ?? ItemSortBy.SortName
|
||||
: ItemSortBy.SortName;
|
||||
}
|
||||
else
|
||||
{
|
||||
lblIndexBy.Visibility = ddlIndexBy.Visibility = ddlSortBy.Visibility = lblSortBy.Visibility = Visibility.Hidden;
|
||||
|
||||
}
|
||||
|
||||
var json = FormatJson(_jsonSerializer.SerializeToString(item));
|
||||
|
||||
if (item is IHasMediaStreams)
|
||||
{
|
||||
var mediaStreams = _itemRepository.GetMediaStreams(new MediaStreamQuery
|
||||
{
|
||||
ItemId = item.Id
|
||||
|
||||
}).ToList();
|
||||
|
||||
if (mediaStreams.Count > 0)
|
||||
{
|
||||
json += "\n\nMedia Streams:\n\n" + FormatJson(_jsonSerializer.SerializeToString(mediaStreams));
|
||||
}
|
||||
}
|
||||
|
||||
txtData.Text = json;
|
||||
|
||||
var previews = new List<PreviewItem>();
|
||||
await Task.Run(() =>
|
||||
{
|
||||
if (!string.IsNullOrEmpty(item.PrimaryImagePath))
|
||||
{
|
||||
previews.Add(new PreviewItem(item.PrimaryImagePath, "Primary"));
|
||||
}
|
||||
if (item.HasImage(ImageType.Banner))
|
||||
{
|
||||
previews.Add(new PreviewItem(item.GetImagePath(ImageType.Banner), "Banner"));
|
||||
}
|
||||
if (item.HasImage(ImageType.Logo))
|
||||
{
|
||||
previews.Add(new PreviewItem(item.GetImagePath(ImageType.Logo), "Logo"));
|
||||
}
|
||||
if (item.HasImage(ImageType.Art))
|
||||
{
|
||||
previews.Add(new PreviewItem(item.GetImagePath(ImageType.Art), "Art"));
|
||||
}
|
||||
if (item.HasImage(ImageType.Thumb))
|
||||
{
|
||||
previews.Add(new PreviewItem(item.GetImagePath(ImageType.Thumb), "Thumb"));
|
||||
}
|
||||
previews.AddRange(
|
||||
item.GetImages(ImageType.Backdrop).Select(
|
||||
image => new PreviewItem(image.Path, "Backdrop")));
|
||||
});
|
||||
lstPreviews.ItemsSource = previews;
|
||||
lstPreviews.Items.Refresh();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The INDEN t_ STRING
|
||||
/// </summary>
|
||||
private const string INDENT_STRING = " ";
|
||||
/// <summary>
|
||||
/// Formats the json.
|
||||
/// </summary>
|
||||
/// <param name="str">The STR.</param>
|
||||
/// <returns>System.String.</returns>
|
||||
private static string FormatJson(string str)
|
||||
{
|
||||
var indent = 0;
|
||||
var quoted = false;
|
||||
var sb = new StringBuilder();
|
||||
for (var i = 0; i < str.Length; i++)
|
||||
{
|
||||
var ch = str[i];
|
||||
switch (ch)
|
||||
{
|
||||
case '{':
|
||||
case '[':
|
||||
sb.Append(ch);
|
||||
if (!quoted)
|
||||
{
|
||||
sb.AppendLine();
|
||||
Enumerable.Range(0, ++indent).ForEach(item => sb.Append(INDENT_STRING));
|
||||
}
|
||||
break;
|
||||
case '}':
|
||||
case ']':
|
||||
if (!quoted)
|
||||
{
|
||||
sb.AppendLine();
|
||||
Enumerable.Range(0, --indent).ForEach(item => sb.Append(INDENT_STRING));
|
||||
}
|
||||
sb.Append(ch);
|
||||
break;
|
||||
case '"':
|
||||
sb.Append(ch);
|
||||
bool escaped = false;
|
||||
var index = i;
|
||||
while (index > 0 && str[--index] == '\\')
|
||||
escaped = !escaped;
|
||||
if (!escaped)
|
||||
quoted = !quoted;
|
||||
break;
|
||||
case ',':
|
||||
sb.Append(ch);
|
||||
if (!quoted)
|
||||
{
|
||||
sb.AppendLine();
|
||||
Enumerable.Range(0, indent).ForEach(item => sb.Append(INDENT_STRING));
|
||||
}
|
||||
break;
|
||||
case ':':
|
||||
sb.Append(ch);
|
||||
if (!quoted)
|
||||
sb.Append(" ");
|
||||
break;
|
||||
default:
|
||||
sb.Append(ch);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handles the SelectionChanged event of the ddlProfile control.
|
||||
/// </summary>
|
||||
/// <param name="sender">The source of the event.</param>
|
||||
/// <param name="e">The <see cref="SelectionChangedEventArgs" /> instance containing the event data.</param>
|
||||
private void ddlProfile_SelectionChanged(object sender, SelectionChangedEventArgs e)
|
||||
{
|
||||
CurrentUser = ddlProfile.SelectedItem as User;
|
||||
if (CurrentUser != null)
|
||||
LoadTree().ConfigureAwait(false);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handles the Click event of the btnRefresh control.
|
||||
/// </summary>
|
||||
/// <param name="sender">The source of the event.</param>
|
||||
/// <param name="e">The <see cref="RoutedEventArgs" /> instance containing the event data.</param>
|
||||
private void btnRefresh_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (tvwLibrary.SelectedItem != null)
|
||||
{
|
||||
var item = ((TreeViewItem)tvwLibrary.SelectedItem).Tag as BaseItem;
|
||||
if (item != null)
|
||||
{
|
||||
item.RefreshMetadata(new MetadataRefreshOptions { ReplaceAllMetadata = cbxForce.IsChecked.Value }, CancellationToken.None);
|
||||
tvwLibrary_SelectedItemChanged(this, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handles the SelectionChanged event of the ddlIndexBy control.
|
||||
/// </summary>
|
||||
/// <param name="sender">The source of the event.</param>
|
||||
/// <param name="e">The <see cref="SelectionChangedEventArgs" /> instance containing the event data.</param>
|
||||
private async void ddlIndexBy_SelectionChanged(object sender, SelectionChangedEventArgs e)
|
||||
{
|
||||
if (ddlIndexBy.SelectedItem != null)
|
||||
{
|
||||
var treeItem = tvwLibrary.SelectedItem as TreeViewItem;
|
||||
var folder = treeItem != null
|
||||
? treeItem.Tag as Folder
|
||||
: null;
|
||||
var prefs = folder != null ? _displayPreferencesManager.GetDisplayPreferences(folder.DisplayPreferencesId, CurrentUser.Id, "LibraryExplorer") : new DisplayPreferences { SortBy = ItemSortBy.SortName };
|
||||
if (folder != null && prefs.IndexBy != ddlIndexBy.SelectedItem as string)
|
||||
{
|
||||
//grab UI context so we can update within the below task
|
||||
var ui = TaskScheduler.FromCurrentSynchronizationContext();
|
||||
Cursor = Cursors.Wait;
|
||||
await Task.Factory.StartNew(() =>
|
||||
{
|
||||
using (
|
||||
new Profiler("Explorer full index expansion for " +
|
||||
folder.Name, _logger))
|
||||
{
|
||||
//re-build the current item's children as an index
|
||||
prefs.IndexBy = ddlIndexBy.SelectedItem as string;
|
||||
treeItem.Items.Clear();
|
||||
AddChildren(treeItem, OrderBy(folder.GetChildren(CurrentUser, true), CurrentUser, prefs.SortBy), CurrentUser);
|
||||
treeItem.Header = folder.Name + "(" +
|
||||
treeItem.Items.Count + ")";
|
||||
Cursor = Cursors.Arrow;
|
||||
|
||||
}
|
||||
}, CancellationToken.None, TaskCreationOptions.None,
|
||||
ui);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handles the SelectionChanged event of the ddlSortBy control.
|
||||
/// </summary>
|
||||
/// <param name="sender">The source of the event.</param>
|
||||
/// <param name="e">The <see cref="SelectionChangedEventArgs" /> instance containing the event data.</param>
|
||||
private async void ddlSortBy_SelectionChanged(object sender, SelectionChangedEventArgs e)
|
||||
{
|
||||
if (ddlSortBy.SelectedItem != null)
|
||||
{
|
||||
var treeItem = tvwLibrary.SelectedItem as TreeViewItem;
|
||||
var folder = treeItem != null
|
||||
? treeItem.Tag as Folder
|
||||
: null;
|
||||
var prefs = folder != null ? _displayPreferencesManager.GetDisplayPreferences(folder.DisplayPreferencesId, CurrentUser.Id, "LibraryExplorer") : new DisplayPreferences();
|
||||
if (folder != null && prefs.SortBy != ddlSortBy.SelectedItem as string)
|
||||
{
|
||||
//grab UI context so we can update within the below task
|
||||
var ui = TaskScheduler.FromCurrentSynchronizationContext();
|
||||
Cursor = Cursors.Wait;
|
||||
await Task.Factory.StartNew(() =>
|
||||
{
|
||||
using (
|
||||
new Profiler("Explorer sorting by " + ddlSortBy.SelectedItem + " for " +
|
||||
folder.Name, _logger))
|
||||
{
|
||||
//re-sort
|
||||
prefs.SortBy = ddlSortBy.SelectedItem as string;
|
||||
treeItem.Items.Clear();
|
||||
AddChildren(treeItem, OrderBy(folder.GetChildren(CurrentUser, true), CurrentUser, prefs.SortBy ?? ItemSortBy.SortName), CurrentUser);
|
||||
treeItem.Header = folder.Name + "(" +
|
||||
treeItem.Items.Count + ")";
|
||||
Cursor = Cursors.Arrow;
|
||||
|
||||
}
|
||||
}, CancellationToken.None, TaskCreationOptions.None,
|
||||
ui);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Class PreviewItem
|
||||
/// </summary>
|
||||
public class PreviewItem
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// The preview
|
||||
/// </summary>
|
||||
private readonly string preview;
|
||||
/// <summary>
|
||||
/// The name
|
||||
/// </summary>
|
||||
private readonly string name;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the preview.
|
||||
/// </summary>
|
||||
/// <value>The preview.</value>
|
||||
public string Preview
|
||||
{
|
||||
get { return preview; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the name.
|
||||
/// </summary>
|
||||
/// <value>The name.</value>
|
||||
public string Name
|
||||
{
|
||||
get { return name; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="PreviewItem" /> class.
|
||||
/// </summary>
|
||||
/// <param name="p">The p.</param>
|
||||
/// <param name="n">The n.</param>
|
||||
public PreviewItem(string p, string n)
|
||||
{
|
||||
preview = p;
|
||||
name = n;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Class Extensions
|
||||
/// </summary>
|
||||
static class Extensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Fors the each.
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="ie">The ie.</param>
|
||||
/// <param name="action">The action.</param>
|
||||
public static void ForEach<T>(this IEnumerable<T> ie, Action<T> action)
|
||||
{
|
||||
foreach (var i in ie)
|
||||
{
|
||||
action(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
#region ItemToImageConverter
|
||||
|
||||
/// <summary>
|
||||
/// Class ItemToImageConverter
|
||||
/// </summary>
|
||||
[ValueConversion(typeof(string), typeof(bool))]
|
||||
public class ItemToImageConverter : IValueConverter
|
||||
{
|
||||
/// <summary>
|
||||
/// The instance
|
||||
/// </summary>
|
||||
public static ItemToImageConverter Instance =
|
||||
new ItemToImageConverter();
|
||||
|
||||
/// <summary>
|
||||
/// Converts a value.
|
||||
/// </summary>
|
||||
/// <param name="value">The value produced by the binding source.</param>
|
||||
/// <param name="targetType">The type of the binding target property.</param>
|
||||
/// <param name="parameter">The converter parameter to use.</param>
|
||||
/// <param name="culture">The culture to use in the converter.</param>
|
||||
/// <returns>A converted value. If the method returns null, the valid null value is used.</returns>
|
||||
public object Convert(object value, Type targetType,
|
||||
object parameter, CultureInfo culture)
|
||||
{
|
||||
var item = value as BaseItem ?? new Folder();
|
||||
switch (item.DisplayMediaType)
|
||||
{
|
||||
case "DVD":
|
||||
case "HD DVD":
|
||||
case "Blu-ray":
|
||||
case "Blu-Ray":
|
||||
case "Movie":
|
||||
{
|
||||
var uri = new Uri
|
||||
("pack://application:,,,/Resources/Images/movie.png");
|
||||
var source = new BitmapImage(uri);
|
||||
return source;
|
||||
}
|
||||
case "Series":
|
||||
{
|
||||
var uri = new Uri
|
||||
("pack://application:,,,/Resources/Images/series.png");
|
||||
var source = new BitmapImage(uri);
|
||||
return source;
|
||||
}
|
||||
case "Season":
|
||||
{
|
||||
var uri = new Uri
|
||||
("pack://application:,,,/Resources/Images/season.png");
|
||||
var source = new BitmapImage(uri);
|
||||
return source;
|
||||
}
|
||||
case "Episode":
|
||||
{
|
||||
var uri = new Uri
|
||||
("pack://application:,,,/Resources/Images/episode.png");
|
||||
var source = new BitmapImage(uri);
|
||||
return source;
|
||||
}
|
||||
case "BoxSet":
|
||||
{
|
||||
var uri = new Uri
|
||||
("pack://application:,,,/Resources/Images/boxset.png");
|
||||
var source = new BitmapImage(uri);
|
||||
return source;
|
||||
}
|
||||
case "Audio":
|
||||
{
|
||||
var uri = new Uri
|
||||
("pack://application:,,,/Resources/Images/audio.png");
|
||||
var source = new BitmapImage(uri);
|
||||
return source;
|
||||
}
|
||||
case "Person":
|
||||
{
|
||||
var uri = new Uri
|
||||
("pack://application:,,,/Resources/Images/persons.png");
|
||||
var source = new BitmapImage(uri);
|
||||
return source;
|
||||
}
|
||||
case "MusicArtist":
|
||||
{
|
||||
var uri = new Uri
|
||||
("pack://application:,,,/Resources/Images/artist.png");
|
||||
var source = new BitmapImage(uri);
|
||||
return source;
|
||||
}
|
||||
case "MusicAlbum":
|
||||
{
|
||||
var uri = new Uri
|
||||
("pack://application:,,,/Resources/Images/album.png");
|
||||
var source = new BitmapImage(uri);
|
||||
return source;
|
||||
}
|
||||
case "Trailer":
|
||||
{
|
||||
var uri = new Uri
|
||||
("pack://application:,,,/Resources/Images/trailer.png");
|
||||
var source = new BitmapImage(uri);
|
||||
return source;
|
||||
}
|
||||
case "None":
|
||||
{
|
||||
Uri uri;
|
||||
if (item is Movie)
|
||||
uri = new Uri("pack://application:,,,/Resources/Images/movie.png");
|
||||
else if (item is Series)
|
||||
uri = new Uri("pack://application:,,,/Resources/Images/series.png");
|
||||
else if (item is BoxSet)
|
||||
uri = new Uri("pack://application:,,,/Resources/Images/boxset.png");
|
||||
else
|
||||
uri = new Uri("pack://application:,,,/Resources/Images/folder.png");
|
||||
|
||||
return new BitmapImage(uri);
|
||||
}
|
||||
default:
|
||||
{
|
||||
var uri = new Uri("pack://application:,,,/Resources/Images/folder.png");
|
||||
var source = new BitmapImage(uri);
|
||||
return source;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts a value.
|
||||
/// </summary>
|
||||
/// <param name="value">The value that is produced by the binding target.</param>
|
||||
/// <param name="targetType">The type to convert to.</param>
|
||||
/// <param name="parameter">The converter parameter to use.</param>
|
||||
/// <param name="culture">The culture to use in the converter.</param>
|
||||
/// <returns>A converted value. If the method returns null, the valid null value is used.</returns>
|
||||
/// <exception cref="System.NotSupportedException">Cannot convert back</exception>
|
||||
public object ConvertBack(object value, Type targetType,
|
||||
object parameter, CultureInfo culture)
|
||||
{
|
||||
throw new NotSupportedException("Cannot convert back");
|
||||
}
|
||||
}
|
||||
|
||||
#endregion // ItemToImageConverter
|
||||
}
|
127
MediaBrowser.ServerApplication/LibraryViewer.Designer.cs
generated
Normal file
127
MediaBrowser.ServerApplication/LibraryViewer.Designer.cs
generated
Normal file
|
@ -0,0 +1,127 @@
|
|||
namespace MediaBrowser.ServerApplication
|
||||
{
|
||||
partial class LibraryViewer
|
||||
{
|
||||
/// <summary>
|
||||
/// Required designer variable.
|
||||
/// </summary>
|
||||
private System.ComponentModel.IContainer components = null;
|
||||
|
||||
/// <summary>
|
||||
/// Clean up any resources being used.
|
||||
/// </summary>
|
||||
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing && (components != null))
|
||||
{
|
||||
components.Dispose();
|
||||
}
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
#region Windows Form Designer generated code
|
||||
|
||||
/// <summary>
|
||||
/// Required method for Designer support - do not modify
|
||||
/// the contents of this method with the code editor.
|
||||
/// </summary>
|
||||
private void InitializeComponent()
|
||||
{
|
||||
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(LibraryViewer));
|
||||
this.treeView1 = new System.Windows.Forms.TreeView();
|
||||
this.txtJson = new System.Windows.Forms.TextBox();
|
||||
this.panel1 = new System.Windows.Forms.Panel();
|
||||
this.selectUser = new System.Windows.Forms.ComboBox();
|
||||
this.lblType = new System.Windows.Forms.Label();
|
||||
this.panel2 = new System.Windows.Forms.Panel();
|
||||
this.panel1.SuspendLayout();
|
||||
this.panel2.SuspendLayout();
|
||||
this.SuspendLayout();
|
||||
//
|
||||
// treeView1
|
||||
//
|
||||
this.treeView1.Dock = System.Windows.Forms.DockStyle.Left;
|
||||
this.treeView1.Font = new System.Drawing.Font("Segoe UI", 10F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
|
||||
this.treeView1.Location = new System.Drawing.Point(0, 0);
|
||||
this.treeView1.Name = "treeView1";
|
||||
this.treeView1.Size = new System.Drawing.Size(260, 517);
|
||||
this.treeView1.TabIndex = 0;
|
||||
//
|
||||
// txtJson
|
||||
//
|
||||
this.txtJson.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.txtJson.Font = new System.Drawing.Font("Consolas", 10F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
|
||||
this.txtJson.Location = new System.Drawing.Point(260, 0);
|
||||
this.txtJson.Multiline = true;
|
||||
this.txtJson.Name = "txtJson";
|
||||
this.txtJson.ScrollBars = System.Windows.Forms.ScrollBars.Both;
|
||||
this.txtJson.Size = new System.Drawing.Size(524, 517);
|
||||
this.txtJson.TabIndex = 1;
|
||||
//
|
||||
// panel1
|
||||
//
|
||||
this.panel1.Controls.Add(this.selectUser);
|
||||
this.panel1.Controls.Add(this.lblType);
|
||||
this.panel1.Dock = System.Windows.Forms.DockStyle.Top;
|
||||
this.panel1.Location = new System.Drawing.Point(0, 0);
|
||||
this.panel1.Name = "panel1";
|
||||
this.panel1.Size = new System.Drawing.Size(784, 44);
|
||||
this.panel1.TabIndex = 2;
|
||||
//
|
||||
// selectUser
|
||||
//
|
||||
this.selectUser.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
|
||||
this.selectUser.FormattingEnabled = true;
|
||||
this.selectUser.Location = new System.Drawing.Point(12, 12);
|
||||
this.selectUser.Name = "selectUser";
|
||||
this.selectUser.Size = new System.Drawing.Size(121, 21);
|
||||
this.selectUser.TabIndex = 2;
|
||||
//
|
||||
// lblType
|
||||
//
|
||||
this.lblType.AutoSize = true;
|
||||
this.lblType.Location = new System.Drawing.Point(260, 15);
|
||||
this.lblType.Name = "lblType";
|
||||
this.lblType.Size = new System.Drawing.Size(0, 13);
|
||||
this.lblType.TabIndex = 1;
|
||||
//
|
||||
// panel2
|
||||
//
|
||||
this.panel2.Controls.Add(this.txtJson);
|
||||
this.panel2.Controls.Add(this.treeView1);
|
||||
this.panel2.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.panel2.Location = new System.Drawing.Point(0, 44);
|
||||
this.panel2.Name = "panel2";
|
||||
this.panel2.Size = new System.Drawing.Size(784, 517);
|
||||
this.panel2.TabIndex = 3;
|
||||
//
|
||||
// LibraryViewer
|
||||
//
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
this.ClientSize = new System.Drawing.Size(784, 561);
|
||||
this.Controls.Add(this.panel2);
|
||||
this.Controls.Add(this.panel1);
|
||||
this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
|
||||
this.Name = "LibraryViewer";
|
||||
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
|
||||
this.Text = "Library Explorer";
|
||||
this.panel1.ResumeLayout(false);
|
||||
this.panel1.PerformLayout();
|
||||
this.panel2.ResumeLayout(false);
|
||||
this.panel2.PerformLayout();
|
||||
this.ResumeLayout(false);
|
||||
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private System.Windows.Forms.TreeView treeView1;
|
||||
private System.Windows.Forms.TextBox txtJson;
|
||||
private System.Windows.Forms.Panel panel1;
|
||||
private System.Windows.Forms.ComboBox selectUser;
|
||||
private System.Windows.Forms.Label lblType;
|
||||
private System.Windows.Forms.Panel panel2;
|
||||
}
|
||||
}
|
243
MediaBrowser.ServerApplication/LibraryViewer.cs
Normal file
243
MediaBrowser.ServerApplication/LibraryViewer.cs
Normal file
|
@ -0,0 +1,243 @@
|
|||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Controller.Library;
|
||||
using MediaBrowser.Controller.Persistence;
|
||||
using MediaBrowser.Model.Querying;
|
||||
using MediaBrowser.Model.Serialization;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Windows.Forms;
|
||||
using SortOrder = MediaBrowser.Model.Entities.SortOrder;
|
||||
|
||||
namespace MediaBrowser.ServerApplication
|
||||
{
|
||||
public partial class LibraryViewer : Form
|
||||
{
|
||||
private readonly IJsonSerializer _jsonSerializer;
|
||||
private readonly ILibraryManager _libraryManager;
|
||||
private readonly IDisplayPreferencesRepository _displayPreferencesManager;
|
||||
private readonly IItemRepository _itemRepository;
|
||||
|
||||
private User _currentUser;
|
||||
|
||||
public LibraryViewer(IJsonSerializer jsonSerializer, IUserManager userManager, ILibraryManager libraryManager, IDisplayPreferencesRepository displayPreferencesManager, IItemRepository itemRepo)
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
_jsonSerializer = jsonSerializer;
|
||||
_libraryManager = libraryManager;
|
||||
_displayPreferencesManager = displayPreferencesManager;
|
||||
_itemRepository = itemRepo;
|
||||
|
||||
foreach (var user in userManager.Users)
|
||||
selectUser.Items.Add(user);
|
||||
selectUser.Items.Insert(0, new User { Name = "Physical" });
|
||||
selectUser.SelectedIndex = 0;
|
||||
|
||||
selectUser.SelectedIndexChanged += selectUser_SelectedIndexChanged;
|
||||
treeView1.AfterSelect += treeView1_AfterSelect;
|
||||
}
|
||||
|
||||
void treeView1_AfterSelect(object sender, TreeViewEventArgs e)
|
||||
{
|
||||
if (e.Node != null)
|
||||
{
|
||||
var item = (BaseItem)e.Node.Tag;
|
||||
lblType.Text = "Type: " + item.GetType().Name;
|
||||
|
||||
var json = FormatJson(_jsonSerializer.SerializeToString(item));
|
||||
|
||||
if (item is IHasMediaStreams)
|
||||
{
|
||||
var mediaStreams = _itemRepository.GetMediaStreams(new MediaStreamQuery
|
||||
{
|
||||
ItemId = item.Id
|
||||
|
||||
}).ToList();
|
||||
|
||||
if (mediaStreams.Count > 0)
|
||||
{
|
||||
json += "\n\nMedia Streams:\n\n" + FormatJson(_jsonSerializer.SerializeToString(mediaStreams));
|
||||
}
|
||||
}
|
||||
|
||||
txtJson.Text = json;
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnLoad(EventArgs e)
|
||||
{
|
||||
base.OnLoad(e);
|
||||
|
||||
selectUser_SelectedIndexChanged(null, null);
|
||||
}
|
||||
|
||||
void selectUser_SelectedIndexChanged(object sender, EventArgs e)
|
||||
{
|
||||
_currentUser = selectUser.SelectedItem as User;
|
||||
if (_currentUser != null)
|
||||
LoadTree();
|
||||
}
|
||||
|
||||
private void LoadTree()
|
||||
{
|
||||
treeView1.Nodes.Clear();
|
||||
|
||||
IEnumerable<BaseItem> children = _currentUser.Name == "Physical" ? new[] { _libraryManager.RootFolder } : _libraryManager.RootFolder.GetChildren(_currentUser, true);
|
||||
children = OrderByName(children, _currentUser);
|
||||
|
||||
foreach (Folder folder in children)
|
||||
{
|
||||
|
||||
var currentFolder = folder;
|
||||
|
||||
var node = new TreeNode { Tag = currentFolder };
|
||||
|
||||
var subChildren = currentFolder.GetChildren(_currentUser, true);
|
||||
subChildren = OrderByName(subChildren, _currentUser);
|
||||
AddChildren(node, subChildren, _currentUser);
|
||||
node.Text = currentFolder.Name + " (" +
|
||||
node.Nodes.Count + ")";
|
||||
|
||||
treeView1.Nodes.Add(node);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds the children.
|
||||
/// </summary>
|
||||
/// <param name="parent">The parent.</param>
|
||||
/// <param name="children">The children.</param>
|
||||
/// <param name="user">The user.</param>
|
||||
private void AddChildren(TreeNode parent, IEnumerable<BaseItem> children, User user)
|
||||
{
|
||||
foreach (var item in children)
|
||||
{
|
||||
var node = new TreeNode { Tag = item };
|
||||
var subFolder = item as Folder;
|
||||
if (subFolder != null)
|
||||
{
|
||||
var prefs = _displayPreferencesManager.GetDisplayPreferences(subFolder.DisplayPreferencesId, user.Id, "LibraryExplorer");
|
||||
|
||||
AddChildren(node, OrderBy(subFolder.GetChildren(user, true), user, prefs.SortBy), user);
|
||||
node.Text = item.Name + " (" + node.Nodes.Count + ")";
|
||||
}
|
||||
else
|
||||
{
|
||||
node.Text = item.Name;
|
||||
}
|
||||
parent.Nodes.Add(node);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Orders the name of the by.
|
||||
/// </summary>
|
||||
/// <param name="items">The items.</param>
|
||||
/// <param name="user">The user.</param>
|
||||
/// <returns>IEnumerable{BaseItem}.</returns>
|
||||
private IEnumerable<BaseItem> OrderByName(IEnumerable<BaseItem> items, User user)
|
||||
{
|
||||
return OrderBy(items, user, ItemSortBy.SortName);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Orders the name of the by.
|
||||
/// </summary>
|
||||
/// <param name="items">The items.</param>
|
||||
/// <param name="user">The user.</param>
|
||||
/// <returns>IEnumerable{BaseItem}.</returns>
|
||||
private IEnumerable<BaseItem> OrderBy(IEnumerable<BaseItem> items, User user, string order)
|
||||
{
|
||||
return _libraryManager.Sort(items, user, new[] { order }, SortOrder.Ascending);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The INDEN t_ STRING
|
||||
/// </summary>
|
||||
private const string INDENT_STRING = " ";
|
||||
/// <summary>
|
||||
/// Formats the json.
|
||||
/// </summary>
|
||||
/// <param name="str">The STR.</param>
|
||||
/// <returns>System.String.</returns>
|
||||
private static string FormatJson(string str)
|
||||
{
|
||||
var indent = 0;
|
||||
var quoted = false;
|
||||
var sb = new StringBuilder();
|
||||
for (var i = 0; i < str.Length; i++)
|
||||
{
|
||||
var ch = str[i];
|
||||
switch (ch)
|
||||
{
|
||||
case '{':
|
||||
case '[':
|
||||
sb.Append(ch);
|
||||
if (!quoted)
|
||||
{
|
||||
sb.AppendLine();
|
||||
Enumerable.Range(0, ++indent).ForEach(item => sb.Append(INDENT_STRING));
|
||||
}
|
||||
break;
|
||||
case '}':
|
||||
case ']':
|
||||
if (!quoted)
|
||||
{
|
||||
sb.AppendLine();
|
||||
Enumerable.Range(0, --indent).ForEach(item => sb.Append(INDENT_STRING));
|
||||
}
|
||||
sb.Append(ch);
|
||||
break;
|
||||
case '"':
|
||||
sb.Append(ch);
|
||||
bool escaped = false;
|
||||
var index = i;
|
||||
while (index > 0 && str[--index] == '\\')
|
||||
escaped = !escaped;
|
||||
if (!escaped)
|
||||
quoted = !quoted;
|
||||
break;
|
||||
case ',':
|
||||
sb.Append(ch);
|
||||
if (!quoted)
|
||||
{
|
||||
sb.AppendLine();
|
||||
Enumerable.Range(0, indent).ForEach(item => sb.Append(INDENT_STRING));
|
||||
}
|
||||
break;
|
||||
case ':':
|
||||
sb.Append(ch);
|
||||
if (!quoted)
|
||||
sb.Append(" ");
|
||||
break;
|
||||
default:
|
||||
sb.Append(ch);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return sb.ToString();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Class Extensions
|
||||
/// </summary>
|
||||
static class Extensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Fors the each.
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="ie">The ie.</param>
|
||||
/// <param name="action">The action.</param>
|
||||
public static void ForEach<T>(this IEnumerable<T> ie, Action<T> action)
|
||||
{
|
||||
foreach (var i in ie)
|
||||
{
|
||||
action(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
2473
MediaBrowser.ServerApplication/LibraryViewer.resx
Normal file
2473
MediaBrowser.ServerApplication/LibraryViewer.resx
Normal file
File diff suppressed because it is too large
Load Diff
|
@ -231,7 +231,7 @@ namespace MediaBrowser.ServerApplication
|
|||
/// <param name="e">The <see cref="RoutedEventArgs" /> instance containing the event data.</param>
|
||||
private void cmOpenExplorer_click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
new LibraryExplorer(_jsonSerializer, _logger, _appHost, _userManager, _libraryManager, _displayPreferencesManager, _itemRepository).Show();
|
||||
new LibraryViewer(_jsonSerializer, _userManager, _libraryManager, _displayPreferencesManager, _itemRepository).Show();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
|
@ -170,6 +170,12 @@
|
|||
<Compile Include="FFMpeg\FFMpegDownloadInfo.cs" />
|
||||
<Compile Include="FFMpeg\FFMpegInfo.cs" />
|
||||
<Compile Include="IO\FileSystemFactory.cs" />
|
||||
<Compile Include="LibraryViewer.cs">
|
||||
<SubType>Form</SubType>
|
||||
</Compile>
|
||||
<Compile Include="LibraryViewer.Designer.cs">
|
||||
<DependentUpon>LibraryViewer.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Logging\LogForm.cs">
|
||||
<SubType>Form</SubType>
|
||||
</Compile>
|
||||
|
@ -197,10 +203,6 @@
|
|||
<Generator>MSBuild:Compile</Generator>
|
||||
<SubType>Designer</SubType>
|
||||
</Page>
|
||||
<Page Include="LibraryExplorer.xaml">
|
||||
<SubType>Designer</SubType>
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
<Page Include="MainWindow.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
<SubType>Designer</SubType>
|
||||
|
@ -213,9 +215,6 @@
|
|||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
<Compile Include="ApplicationHost.cs" />
|
||||
<Compile Include="LibraryExplorer.xaml.cs">
|
||||
<DependentUpon>LibraryExplorer.xaml</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Logging\WindowTraceListener.cs" />
|
||||
<Compile Include="MainWindow.xaml.cs">
|
||||
<DependentUpon>MainWindow.xaml</DependentUpon>
|
||||
|
@ -240,6 +239,9 @@
|
|||
<DependentUpon>Settings.settings</DependentUpon>
|
||||
<DesignTimeSharedInput>True</DesignTimeSharedInput>
|
||||
</Compile>
|
||||
<EmbeddedResource Include="LibraryViewer.resx">
|
||||
<DependentUpon>LibraryViewer.cs</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="Logging\LogForm.resx">
|
||||
<DependentUpon>LogForm.cs</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
|
|
Loading…
Reference in New Issue
Block a user