Selective Sync now shows both server AND local folders
[pithos-ms-client] / trunk / Pithos.Client.WPF / Utils / EnumerableExtensions.cs
1 using System;
2 using System.Collections;
3 using System.Collections.Generic;
4 using System.IO;
5 using System.Linq;
6 using System.Linq.Expressions;
7 using System.Text;
8 using System.Text.RegularExpressions;
9 using Pithos.Client.WPF.SelectiveSynch;
10 using Pithos.Core;
11 using Pithos.Interfaces;
12
13 namespace Pithos.Client.WPF.Utils
14 {
15     public static class EnumerableExtensions
16     {
17         public static IEnumerable<T> Slice<T>(this IEnumerable<T> collection, int start, int end)
18         {
19             int index = 0;
20             int count = 0;
21
22             if (collection == null)
23                 throw new ArgumentNullException("collection");
24
25             // Optimise item count for ICollection interfaces.
26             if (collection is ICollection<T>)
27                 count = ((ICollection<T>)collection).Count;
28             else if (collection is ICollection)
29                 count = ((ICollection)collection).Count;
30             else
31             {
32                 count = collection.Count();
33             }
34
35             // Get start/end indexes, negative numbers start at the end of the collection.
36             if (start < 0)
37                 start += count;
38
39             if (end < 0)
40                 end += count;
41
42             foreach (var item in collection)
43             {
44                 if (index >= end)
45                     yield break;
46
47                 if (index >= start)
48                     yield return item;
49
50                 ++index;
51             }
52         }
53
54         public static IEnumerable<Node<T>> ToTree<TSource,T>(this IEnumerable<TSource> enumerable,Func<TSource,string> pathFunc,Func<TSource,T> valueFunc,string delimiter="/")
55         {
56             var orderedItems=enumerable.OrderBy(pathFunc);
57             var lookups = new Dictionary<string,Node<T>>();
58             var nodes = new List<Node<T>>();
59             foreach (var item in orderedItems)
60             {
61                 var path = pathFunc(item);
62                 var value = valueFunc(item);
63                 var newNode = new Node<T> { Path = path,Data=value };
64                 lookups[path] = newNode;
65
66                 var lastIndex = path.LastIndexOf(delimiter, StringComparison.Ordinal);
67                 var upTo = lastIndex < 0 ? path.Length - 1 : lastIndex;
68                 var parentPath = path.Substring(0, upTo);              
69   
70                 Node<T> parent;
71                 if (lookups.TryGetValue(parentPath, out parent))
72                 {
73                     parent.Children.Add(newNode);   
74                     parent.Children.Sort((x,y)=>String.CompareOrdinal(x.Path, y.Path));
75                 }
76                 else
77                     nodes.Add(newNode);
78
79             }
80             return nodes;
81         }
82
83
84
85
86         static readonly Regex PascalCaseRegex = new Regex("[a-z][A-Z]", RegexOptions.Compiled);        
87         public static string Name(this  Enum value)
88         {
89             var name = Enum.GetName(value.GetType(), value);            
90             return PascalCaseRegex.Replace(name, m => m.Value[0] + " " + char.ToLower(m.Value[1]));            
91         }
92     }
93 }