Browse Source
git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/trunk@4586 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61shortcuts
4 changed files with 292 additions and 150 deletions
@ -0,0 +1,211 @@
@@ -0,0 +1,211 @@
|
||||
// <file>
|
||||
// <copyright see="prj:///doc/copyright.txt"/>
|
||||
// <license see="prj:///doc/license.txt"/>
|
||||
// <owner name="David Srbecký" email="dsrbecky@gmail.com"/>
|
||||
// <version>$Revision$</version>
|
||||
// </file>
|
||||
|
||||
using System; |
||||
using System.Collections; |
||||
using System.Collections.Generic; |
||||
using System.Collections.ObjectModel; |
||||
using System.Collections.Specialized; |
||||
using System.Linq; |
||||
|
||||
// Missing XML comment
|
||||
#pragma warning disable 1591
|
||||
|
||||
namespace ICSharpCode.AvalonEdit.XmlParser |
||||
{ |
||||
/// <summary>
|
||||
/// Collection that is publicly read-only and has support
|
||||
/// for adding/removing multiple items at a time.
|
||||
/// </summary>
|
||||
public class ChildrenCollection<T>: Collection<T>, INotifyCollectionChanged |
||||
{ |
||||
public event NotifyCollectionChangedEventHandler CollectionChanged; |
||||
|
||||
protected virtual void OnCollectionChanged(NotifyCollectionChangedEventArgs e) |
||||
{ |
||||
if (CollectionChanged != null) { |
||||
CollectionChanged(this, e); |
||||
} |
||||
} |
||||
|
||||
protected override void ClearItems() |
||||
{ |
||||
throw new NotSupportedException(); |
||||
} |
||||
|
||||
protected override void InsertItem(int index, T item) |
||||
{ |
||||
throw new NotSupportedException(); |
||||
} |
||||
|
||||
protected override void RemoveItem(int index) |
||||
{ |
||||
throw new NotSupportedException(); |
||||
} |
||||
|
||||
protected override void SetItem(int index, T item) |
||||
{ |
||||
throw new NotSupportedException(); |
||||
} |
||||
|
||||
internal void InsertItems(int index, IList<T> items) |
||||
{ |
||||
for(int i = 0; i < items.Count; i++) { |
||||
base.InsertItem(index + i, items[i]); |
||||
} |
||||
OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, (IList)items, index)); |
||||
} |
||||
|
||||
internal void RemoveItems(int index, int count) |
||||
{ |
||||
List<T> removed = new List<T>(); |
||||
for(int i = 0; i < count; i++) { |
||||
removed.Add(this[index]); |
||||
base.RemoveItem(index); |
||||
} |
||||
OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Remove, (IList)removed, index)); |
||||
} |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Collection that presents only some items from the wrapped collection
|
||||
/// </summary>
|
||||
public class FilteredCollection<C, T>: ObservableCollection<T> where C: INotifyCollectionChanged, IList<T> |
||||
{ |
||||
C source; |
||||
Predicate<T> condition; |
||||
List<int> srcPtrs = new List<int>(); // Index to the original collection
|
||||
|
||||
public FilteredCollection(C source, Predicate<T> condition) |
||||
{ |
||||
this.source = source; |
||||
this.condition = condition; |
||||
|
||||
this.source.CollectionChanged += SourceCollectionChanged; |
||||
|
||||
Reset(); |
||||
} |
||||
|
||||
void Reset() |
||||
{ |
||||
this.Clear(); |
||||
srcPtrs.Clear(); |
||||
for(int i = 0; i < source.Count; i++) { |
||||
if (condition(source[i])) { |
||||
this.Add(source[i]); |
||||
srcPtrs.Add(i); |
||||
} |
||||
} |
||||
} |
||||
|
||||
void SourceCollectionChanged(object sender, NotifyCollectionChangedEventArgs e) |
||||
{ |
||||
switch(e.Action) { |
||||
case NotifyCollectionChangedAction.Add: |
||||
// Update pointers
|
||||
for(int i = 0; i < srcPtrs.Count; i++) { |
||||
if (srcPtrs[i] >= e.NewStartingIndex) { |
||||
srcPtrs[i] += e.NewItems.Count; |
||||
} |
||||
} |
||||
// Find where to add items
|
||||
int addIndex = srcPtrs.FindIndex(srcPtr => srcPtr >= e.NewStartingIndex); |
||||
if (addIndex == -1) addIndex = this.Count; |
||||
// Add items to collection
|
||||
for(int i = 0; i < e.NewItems.Count; i++) { |
||||
if (condition((T)e.NewItems[i])) { |
||||
this.InsertItem(addIndex, (T)e.NewItems[i]); |
||||
srcPtrs.Insert(addIndex, e.NewStartingIndex + i); |
||||
addIndex++; |
||||
} |
||||
} |
||||
break; |
||||
case NotifyCollectionChangedAction.Remove: |
||||
// Remove the item from our collection
|
||||
for(int i = 0; i < e.OldItems.Count; i++) { |
||||
// Anyone points to the removed item?
|
||||
int removeIndex = srcPtrs.IndexOf(e.OldStartingIndex + i); |
||||
// Remove
|
||||
if (removeIndex != -1) { |
||||
this.RemoveAt(removeIndex); |
||||
srcPtrs.RemoveAt(removeIndex); |
||||
} |
||||
} |
||||
// Update pointers
|
||||
for(int i = 0; i < srcPtrs.Count; i++) { |
||||
if (srcPtrs[i] >= e.OldStartingIndex) { |
||||
srcPtrs[i] -= e.OldItems.Count; |
||||
} |
||||
} |
||||
break; |
||||
case NotifyCollectionChangedAction.Reset: |
||||
Reset(); |
||||
break; |
||||
default: |
||||
throw new NotSupportedException(e.Action.ToString()); |
||||
} |
||||
} |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Two collections in sequence
|
||||
/// </summary>
|
||||
public class MergedCollection<C, T>: ObservableCollection<T> where C: INotifyCollectionChanged, IList<T> |
||||
{ |
||||
C a; |
||||
C b; |
||||
|
||||
public MergedCollection(C a, C b) |
||||
{ |
||||
this.a = a; |
||||
this.b = b; |
||||
|
||||
this.a.CollectionChanged += SourceCollectionAChanged; |
||||
this.b.CollectionChanged += SourceCollectionBChanged; |
||||
|
||||
Reset(); |
||||
} |
||||
|
||||
void Reset() |
||||
{ |
||||
this.Clear(); |
||||
foreach(T item in a) this.Add(item); |
||||
foreach(T item in b) this.Add(item); |
||||
} |
||||
|
||||
void SourceCollectionAChanged(object sender, NotifyCollectionChangedEventArgs e) |
||||
{ |
||||
SourceCollectionChanged(0, e); |
||||
} |
||||
|
||||
void SourceCollectionBChanged(object sender, NotifyCollectionChangedEventArgs e) |
||||
{ |
||||
SourceCollectionChanged(a.Count, e); |
||||
} |
||||
|
||||
void SourceCollectionChanged(int collectionStart, NotifyCollectionChangedEventArgs e) |
||||
{ |
||||
switch(e.Action) { |
||||
case NotifyCollectionChangedAction.Add: |
||||
for (int i = 0; i < e.NewItems.Count; i++) { |
||||
this.InsertItem(collectionStart + e.NewStartingIndex + i, (T)e.NewItems[i]); |
||||
} |
||||
break; |
||||
case NotifyCollectionChangedAction.Remove: |
||||
for (int i = 0; i < e.OldItems.Count; i++) { |
||||
this.RemoveAt(collectionStart + e.OldStartingIndex); |
||||
} |
||||
break; |
||||
case NotifyCollectionChangedAction.Reset: |
||||
Reset(); |
||||
break; |
||||
default: |
||||
throw new NotSupportedException(e.Action.ToString()); |
||||
} |
||||
} |
||||
} |
||||
} |
||||
@ -1,112 +0,0 @@
@@ -1,112 +0,0 @@
|
||||
// <file>
|
||||
// <copyright see="prj:///doc/copyright.txt"/>
|
||||
// <license see="prj:///doc/license.txt"/>
|
||||
// <owner name="David Srbecký" email="dsrbecky@gmail.com"/>
|
||||
// <version>$Revision$</version>
|
||||
// </file>
|
||||
|
||||
using System; |
||||
using System.Collections.Generic; |
||||
using System.Collections.ObjectModel; |
||||
using System.Collections.Specialized; |
||||
using System.Linq; |
||||
|
||||
// Missing XML comment
|
||||
#pragma warning disable 1591
|
||||
|
||||
namespace ICSharpCode.AvalonEdit.XmlParser |
||||
{ |
||||
public class FilteredObservableCollection<T>: ObservableCollection<T> |
||||
{ |
||||
ObservableCollection<T> source; |
||||
Predicate<T> condition; |
||||
List<int> srcPtrs = new List<int>(); |
||||
|
||||
public FilteredObservableCollection(ObservableCollection<T> source, Predicate<T> condition) |
||||
{ |
||||
this.source = source; |
||||
this.condition = condition; |
||||
|
||||
for(int i = 0; i < source.Count; i++) { |
||||
if (condition(source[i])) { |
||||
int index = srcPtrs.Count; |
||||
this.InsertItem(index, source[i]); |
||||
srcPtrs.Insert(index, i); |
||||
} |
||||
} |
||||
|
||||
this.source.CollectionChanged += new NotifyCollectionChangedEventHandler(FilteredObservableCollection_CollectionChanged); |
||||
} |
||||
|
||||
void FilteredObservableCollection_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e) |
||||
{ |
||||
if (e.Action == NotifyCollectionChangedAction.Remove) { |
||||
// Remove the item from our collection
|
||||
if (condition((T)e.OldItems[0])) { |
||||
int index = srcPtrs.IndexOf(e.OldStartingIndex); |
||||
this.RemoveAt(index); |
||||
srcPtrs.RemoveAt(index); |
||||
} |
||||
// Update pointers
|
||||
for(int i = 0; i < srcPtrs.Count; i++) { |
||||
if (srcPtrs[i] > e.OldStartingIndex) { |
||||
srcPtrs[i]--; |
||||
} |
||||
} |
||||
} |
||||
if (e.Action == NotifyCollectionChangedAction.Add) { |
||||
// Update pointers
|
||||
for(int i = 0; i < srcPtrs.Count; i++) { |
||||
if (srcPtrs[i] >= e.NewStartingIndex) { |
||||
srcPtrs[i]++; |
||||
} |
||||
} |
||||
// Add item to collection
|
||||
if (condition((T)e.NewItems[0])) { |
||||
int index = srcPtrs.FindIndex(srcPtr => srcPtr >= e.NewStartingIndex); |
||||
if (index == -1) index = srcPtrs.Count; |
||||
this.InsertItem(index, (T)e.NewItems[0]); |
||||
srcPtrs.Insert(index, e.NewStartingIndex); |
||||
} |
||||
} |
||||
} |
||||
} |
||||
|
||||
public class MergedObservableCollection<T>: ObservableCollection<T> |
||||
{ |
||||
ObservableCollection<T> a; |
||||
ObservableCollection<T> b; |
||||
|
||||
public MergedObservableCollection(ObservableCollection<T> a, ObservableCollection<T> b) |
||||
{ |
||||
this.a = a; |
||||
this.b = b; |
||||
|
||||
foreach(T item in a) this.Add(item); |
||||
foreach(T item in b) this.Add(item); |
||||
|
||||
this.a.CollectionChanged += new NotifyCollectionChangedEventHandler(MergedObservableCollection_CollectionAChanged); |
||||
this.b.CollectionChanged += new NotifyCollectionChangedEventHandler(MergedObservableCollection_CollectionBChanged); |
||||
} |
||||
|
||||
void MergedObservableCollection_CollectionAChanged(object sender, NotifyCollectionChangedEventArgs e) |
||||
{ |
||||
if (e.Action == NotifyCollectionChangedAction.Remove) { |
||||
this.RemoveAt(e.OldStartingIndex); |
||||
} |
||||
if (e.Action == NotifyCollectionChangedAction.Add) { |
||||
this.InsertItem(e.NewStartingIndex, (T)e.NewItems[0]); |
||||
} |
||||
} |
||||
|
||||
void MergedObservableCollection_CollectionBChanged(object sender, NotifyCollectionChangedEventArgs e) |
||||
{ |
||||
if (e.Action == NotifyCollectionChangedAction.Remove) { |
||||
this.RemoveAt(e.OldStartingIndex + a.Count); |
||||
} |
||||
if (e.Action == NotifyCollectionChangedAction.Add) { |
||||
this.InsertItem(e.NewStartingIndex + a.Count, (T)e.NewItems[0]); |
||||
} |
||||
} |
||||
} |
||||
} |
||||
Loading…
Reference in new issue