From 767cdc1f6f6a63ce997fc9476911e2c361f9d402 Mon Sep 17 00:00:00 2001 From: LukePulverenti Date: Wed, 20 Feb 2013 20:33:05 -0500 Subject: Pushing missing changes --- .../Sorting/BaseItemComparer.cs | 231 +++++++++++++++++++++ MediaBrowser.Controller/Sorting/SortOrder.cs | 33 +++ 2 files changed, 264 insertions(+) create mode 100644 MediaBrowser.Controller/Sorting/BaseItemComparer.cs create mode 100644 MediaBrowser.Controller/Sorting/SortOrder.cs (limited to 'MediaBrowser.Controller/Sorting') diff --git a/MediaBrowser.Controller/Sorting/BaseItemComparer.cs b/MediaBrowser.Controller/Sorting/BaseItemComparer.cs new file mode 100644 index 0000000000..6e49f396f7 --- /dev/null +++ b/MediaBrowser.Controller/Sorting/BaseItemComparer.cs @@ -0,0 +1,231 @@ +using MediaBrowser.Common.Logging; +using MediaBrowser.Controller.Entities; +using System; +using System.Collections.Generic; + +namespace MediaBrowser.Controller.Sorting { + /// + /// Class BaseItemComparer + /// + public class BaseItemComparer : IComparer { + /// + /// The _order + /// + private readonly SortOrder _order; + /// + /// The _property name + /// + private readonly string _propertyName; + /// + /// The _compare culture + /// + private readonly StringComparison _compareCulture = StringComparison.CurrentCultureIgnoreCase; + + /// + /// Initializes a new instance of the class. + /// + /// The order. + public BaseItemComparer(SortOrder order) { + _order = order; + } + + /// + /// Initializes a new instance of the class. + /// + /// The order. + /// The compare. + public BaseItemComparer(SortOrder order, StringComparison compare) { + _order = order; + _compareCulture = compare; + } + + /// + /// Initializes a new instance of the class. + /// + /// The property. + public BaseItemComparer(string property) { + _order = SortOrder.Custom; + _propertyName = property; + } + + /// + /// Initializes a new instance of the class. + /// + /// The property. + /// The compare. + public BaseItemComparer(string property, StringComparison compare) { + _order = SortOrder.Custom; + _propertyName = property; + _compareCulture = compare; + } + + #region IComparer Members + + /// + /// Compares the specified x. + /// + /// The x. + /// The y. + /// System.Int32. + public int Compare(BaseItem x, BaseItem y) { + int compare = 0; + + switch (_order) { + + case SortOrder.Date: + compare = -x.DateCreated.CompareTo(y.DateCreated); + break; + + case SortOrder.Year: + + var xProductionYear = x.ProductionYear ?? 0; + var yProductionYear = y.ProductionYear ?? 0; + + + compare = yProductionYear.CompareTo(xProductionYear); + break; + + case SortOrder.Rating: + + var xRating = x.CommunityRating ?? 0; + var yRating = y.CommunityRating ?? 0; + + compare = yRating.CompareTo(xRating); + break; + + case SortOrder.Runtime: + var xRuntime = x.RunTimeTicks ?? 0; + var yRuntime = y.RunTimeTicks ?? 0; + + compare = xRuntime.CompareTo(yRuntime); + break; + + case SortOrder.Custom: + + Logger.LogDebugInfo("Sorting on custom field " + _propertyName); + var yProp = y.GetType().GetProperty(_propertyName); + var xProp = x.GetType().GetProperty(_propertyName); + if (yProp == null || xProp == null) break; + var yVal = yProp.GetValue(y, null); + var xVal = xProp.GetValue(x,null); + if (yVal == null && xVal == null) break; + if (yVal == null) return 1; + if (xVal == null) return -1; + compare = String.Compare(xVal.ToString(), yVal.ToString(),_compareCulture); + break; + + default: + compare = 0; + break; + } + + if (compare == 0) { + + var name1 = x.SortName ?? x.Name ?? ""; + var name2 = y.SortName ?? y.Name ?? ""; + + //if (Config.Instance.EnableAlphanumericSorting) + compare = AlphaNumericCompare(name1, name2,_compareCulture); + //else + // compare = String.Compare(name1,name2,_compareCulture); + } + + return compare; + } + + + #endregion + + /// + /// Alphas the numeric compare. + /// + /// The s1. + /// The s2. + /// The compare culture. + /// System.Int32. + public static int AlphaNumericCompare(string s1, string s2, StringComparison compareCulture) { + // http://dotnetperls.com/Content/Alphanumeric-Sorting.aspx + + int len1 = s1.Length; + int len2 = s2.Length; + int marker1 = 0; + int marker2 = 0; + + // Walk through two the strings with two markers. + while (marker1 < len1 && marker2 < len2) { + char ch1 = s1[marker1]; + char ch2 = s2[marker2]; + + // Some buffers we can build up characters in for each chunk. + var space1 = new char[len1]; + var loc1 = 0; + var space2 = new char[len2]; + var loc2 = 0; + + // Walk through all following characters that are digits or + // characters in BOTH strings starting at the appropriate marker. + // Collect char arrays. + do { + space1[loc1++] = ch1; + marker1++; + + if (marker1 < len1) { + ch1 = s1[marker1]; + } else { + break; + } + } while (char.IsDigit(ch1) == char.IsDigit(space1[0])); + + do { + space2[loc2++] = ch2; + marker2++; + + if (marker2 < len2) { + ch2 = s2[marker2]; + } else { + break; + } + } while (char.IsDigit(ch2) == char.IsDigit(space2[0])); + + // If we have collected numbers, compare them numerically. + // Otherwise, if we have strings, compare them alphabetically. + var str1 = new string(space1); + var str2 = new string(space2); + + var result = 0; + + //biggest int - 2147483647 + if (char.IsDigit(space1[0]) && char.IsDigit(space2[0]) /*&& str1.Length < 10 && str2.Length < 10*/) //this assumed the entire string was a number... + { + int thisNumericChunk; + var isValid = false; + + if (int.TryParse(str1.Substring(0, str1.Length > 9 ? 10 : str1.Length), out thisNumericChunk)) + { + int thatNumericChunk; + + if (int.TryParse(str2.Substring(0, str2.Length > 9 ? 10 : str2.Length), out thatNumericChunk)) + { + isValid = true; + result = thisNumericChunk.CompareTo(thatNumericChunk); + } + } + + if (!isValid) + { + Logger.LogError("Error comparing numeric strings: " + str1 + "/" + str2); + result = String.Compare(str1, str2, compareCulture); + } + + } else { + result = String.Compare(str1,str2,compareCulture); + } + + if (result != 0) { + return result; + } + } + return len1 - len2; + } + } +} diff --git a/MediaBrowser.Controller/Sorting/SortOrder.cs b/MediaBrowser.Controller/Sorting/SortOrder.cs new file mode 100644 index 0000000000..3152ac67e4 --- /dev/null +++ b/MediaBrowser.Controller/Sorting/SortOrder.cs @@ -0,0 +1,33 @@ + +namespace MediaBrowser.Controller.Sorting { + /// + /// Enum SortOrder + /// + public enum SortOrder { + + /// + /// Sort by name + /// + Name, + /// + /// Sort by date added to the library + /// + Date, + /// + /// Sort by community rating + /// + Rating, + /// + /// Sort by runtime + /// + Runtime, + /// + /// Sort by year + /// + Year, + /// + /// Custom sort order added by plugins + /// + Custom + } +} -- cgit v1.2.3