31 changed files with 288 additions and 214 deletions
@ -0,0 +1,104 @@
@@ -0,0 +1,104 @@
|
||||
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
|
||||
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
|
||||
|
||||
using System; |
||||
using System.Collections; |
||||
using System.Collections.Generic; |
||||
using System.Collections.Specialized; |
||||
using System.Linq; |
||||
|
||||
namespace ICSharpCode.SharpDevelop.Dom |
||||
{ |
||||
/// <summary>
|
||||
/// A model collection that filters an input collection.
|
||||
/// </summary>
|
||||
public sealed class FilterModelCollection<T> : IModelCollection<T> |
||||
{ |
||||
readonly IModelCollection<T> input; |
||||
readonly Func<T, bool> predicate; |
||||
bool isAttached; |
||||
NotifyCollectionChangedEventHandler collectionChanged; |
||||
|
||||
public FilterModelCollection(IModelCollection<T> input, Func<T, bool> predicate) |
||||
{ |
||||
if (input == null) |
||||
throw new ArgumentNullException("input"); |
||||
if (predicate == null) |
||||
throw new ArgumentNullException("predicate"); |
||||
this.input = input; |
||||
this.predicate = predicate; |
||||
} |
||||
|
||||
public event NotifyCollectionChangedEventHandler CollectionChanged { |
||||
add { |
||||
collectionChanged += value; |
||||
if (collectionChanged != null && !isAttached) { |
||||
input.CollectionChanged += input_CollectionChanged; |
||||
isAttached = true; |
||||
} |
||||
} |
||||
remove { |
||||
collectionChanged -= value; |
||||
if (collectionChanged == null && isAttached) { |
||||
input.CollectionChanged -= input_CollectionChanged; |
||||
isAttached = false; |
||||
} |
||||
} |
||||
} |
||||
|
||||
void input_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e) |
||||
{ |
||||
switch (e.Action) { |
||||
case NotifyCollectionChangedAction.Add: |
||||
collectionChanged(this, new NotifyCollectionChangedEventArgs( |
||||
NotifyCollectionChangedAction.Add, ApplyFilter(e.NewItems))); |
||||
break; |
||||
case NotifyCollectionChangedAction.Remove: |
||||
collectionChanged(this, new NotifyCollectionChangedEventArgs( |
||||
NotifyCollectionChangedAction.Remove, ApplyFilter(e.OldItems))); |
||||
break; |
||||
case NotifyCollectionChangedAction.Replace: |
||||
collectionChanged(this, new NotifyCollectionChangedEventArgs( |
||||
NotifyCollectionChangedAction.Replace, ApplyFilter(e.OldItems), ApplyFilter(e.NewItems))); |
||||
break; |
||||
case NotifyCollectionChangedAction.Move: |
||||
// this collection is unordered
|
||||
break; |
||||
case NotifyCollectionChangedAction.Reset: |
||||
collectionChanged(this, new NotifyCollectionChangedEventArgs( |
||||
NotifyCollectionChangedAction.Reset)); |
||||
break; |
||||
default: |
||||
throw new NotSupportedException(); |
||||
} |
||||
} |
||||
|
||||
IList ApplyFilter(IList inputItems) |
||||
{ |
||||
if (inputItems == null) |
||||
return null; |
||||
List<T> outputItems = new List<T>(); |
||||
foreach (T item in inputItems) { |
||||
if (predicate(item)) |
||||
outputItems.Add(item); |
||||
} |
||||
return outputItems; |
||||
} |
||||
|
||||
public int Count { |
||||
get { |
||||
return input.Count(predicate); |
||||
} |
||||
} |
||||
|
||||
public IEnumerator<T> GetEnumerator() |
||||
{ |
||||
return input.Where(predicate).GetEnumerator(); |
||||
} |
||||
|
||||
IEnumerator IEnumerable.GetEnumerator() |
||||
{ |
||||
return GetEnumerator(); |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,15 @@
@@ -0,0 +1,15 @@
|
||||
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
|
||||
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
|
||||
|
||||
using System; |
||||
using System.Collections.ObjectModel; |
||||
|
||||
namespace ICSharpCode.SharpDevelop.Dom |
||||
{ |
||||
/// <summary>
|
||||
/// A model collection implementation that is based on a ObservableCollection.
|
||||
/// </summary>
|
||||
public class SimpleModelCollection<T> : ObservableCollection<T>, IModelCollection<T> |
||||
{ |
||||
} |
||||
} |
@ -0,0 +1,28 @@
@@ -0,0 +1,28 @@
|
||||
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
|
||||
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
|
||||
|
||||
using System; |
||||
using System.Collections.Generic; |
||||
using ICSharpCode.SharpDevelop.Editor; |
||||
|
||||
namespace ICSharpCode.SharpDevelop.Editor.Bookmarks |
||||
{ |
||||
/// <summary>
|
||||
/// The bookmark margin.
|
||||
/// </summary>
|
||||
[DocumentService] |
||||
public interface IBookmarkMargin |
||||
{ |
||||
/// <summary>
|
||||
/// Gets the list of bookmarks.
|
||||
/// </summary>
|
||||
IList<IBookmark> Bookmarks { get; } |
||||
|
||||
/// <summary>
|
||||
/// Redraws the bookmark margin. Bookmarks need to call this method when the Image changes.
|
||||
/// </summary>
|
||||
void Redraw(); |
||||
|
||||
event EventHandler RedrawRequested; |
||||
} |
||||
} |
@ -1,123 +0,0 @@
@@ -1,123 +0,0 @@
|
||||
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
|
||||
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
|
||||
|
||||
using System; |
||||
using System.ComponentModel; |
||||
using System.Globalization; |
||||
using System.Text; |
||||
using System.Windows; |
||||
using ICSharpCode.Core; |
||||
using ICSharpCode.NRefactory; |
||||
|
||||
namespace ICSharpCode.SharpDevelop.Bookmarks |
||||
{ |
||||
public sealed class BookmarkConverter : TypeConverter |
||||
{ |
||||
public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType) |
||||
{ |
||||
if (sourceType == typeof(string)) { |
||||
return true; |
||||
} else { |
||||
return base.CanConvertFrom(context, sourceType); |
||||
} |
||||
} |
||||
|
||||
public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value) |
||||
{ |
||||
if (value is string) { |
||||
string[] v = ((string)value).Split('|'); |
||||
|
||||
FileName fileName = FileName.Create(v[1]); |
||||
int lineNumber = int.Parse(v[2], culture); |
||||
int columnNumber = int.Parse(v[3], culture); |
||||
if (lineNumber < 0) |
||||
return null; |
||||
if (columnNumber < 0) |
||||
return null; |
||||
SDBookmark bookmark; |
||||
switch (v[0]) { |
||||
case "Breakpoint": |
||||
Debugging.BreakpointAction action = Debugging.BreakpointAction.Break; |
||||
string scriptLanguage = ""; |
||||
string script = ""; |
||||
action = (Debugging.BreakpointAction)Enum.Parse(typeof(Debugging.BreakpointAction), v[5]); |
||||
scriptLanguage = v[6]; |
||||
script = v[7]; |
||||
|
||||
var bbm = new Debugging.BreakpointBookmark(fileName, new TextLocation(lineNumber, columnNumber), action, scriptLanguage, script); |
||||
bbm.IsEnabled = bool.Parse(v[4]); |
||||
bbm.Action = action; |
||||
bbm.ScriptLanguage = scriptLanguage; |
||||
bbm.Condition = script; |
||||
bookmark = bbm; |
||||
break; |
||||
case "DecompiledBreakpointBookmark": |
||||
action = (Debugging.BreakpointAction)Enum.Parse(typeof(Debugging.BreakpointAction), v[5]); |
||||
scriptLanguage = v[6]; |
||||
script = v[7]; |
||||
|
||||
bbm = new DecompiledBreakpointBookmark(fileName, new TextLocation(columnNumber, lineNumber), action, scriptLanguage, script); |
||||
bbm.IsEnabled = bool.Parse(v[4]); |
||||
bbm.Action = action; |
||||
bbm.ScriptLanguage = scriptLanguage; |
||||
bbm.Condition = script; |
||||
bookmark = bbm; |
||||
break; |
||||
default: |
||||
bookmark = new Bookmark(fileName, new TextLocation(lineNumber, columnNumber)); |
||||
break; |
||||
} |
||||
return bookmark; |
||||
} else { |
||||
return base.ConvertFrom(context, culture, value); |
||||
} |
||||
} |
||||
|
||||
public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType) |
||||
{ |
||||
SDBookmark bookmark = value as SDBookmark; |
||||
if (destinationType == typeof(string) && bookmark != null) { |
||||
StringBuilder b = new StringBuilder(); |
||||
if (bookmark is DecompiledBreakpointBookmark) { |
||||
b.Append("DecompiledBreakpointBookmark"); |
||||
} else if (bookmark is Debugging.BreakpointBookmark) { |
||||
b.Append("Breakpoint"); |
||||
} else { |
||||
b.Append("Bookmark"); |
||||
} |
||||
b.Append('|'); |
||||
b.Append(bookmark.FileName); |
||||
b.Append('|'); |
||||
b.Append(bookmark.LineNumber); |
||||
b.Append('|'); |
||||
b.Append(bookmark.ColumnNumber); |
||||
|
||||
if (bookmark is DecompiledBreakpointBookmark) { |
||||
var bbm = (DecompiledBreakpointBookmark)bookmark; |
||||
b.Append('|'); |
||||
b.Append(bbm.IsEnabled.ToString()); |
||||
b.Append('|'); |
||||
b.Append(bbm.Action.ToString()); |
||||
b.Append('|'); |
||||
b.Append(bbm.ScriptLanguage); |
||||
b.Append('|'); |
||||
b.Append(bbm.Condition); |
||||
} else if (bookmark is Debugging.BreakpointBookmark) { |
||||
var bbm = (Debugging.BreakpointBookmark)bookmark; |
||||
b.Append('|'); |
||||
b.Append(bbm.IsEnabled.ToString()); |
||||
b.Append('|'); |
||||
b.Append(bbm.Action.ToString()); |
||||
b.Append('|'); |
||||
b.Append(bbm.ScriptLanguage); |
||||
b.Append('|'); |
||||
b.Append(bbm.Condition); |
||||
} |
||||
|
||||
return b.ToString(); |
||||
} else { |
||||
return base.ConvertTo(context, culture, value, destinationType); |
||||
} |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,68 @@
@@ -0,0 +1,68 @@
|
||||
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
|
||||
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
|
||||
|
||||
using System; |
||||
using System.Collections.Generic; |
||||
using System.Collections.Specialized; |
||||
using System.Linq; |
||||
using ICSharpCode.SharpDevelop.Dom; |
||||
using NUnit.Framework; |
||||
|
||||
namespace ICSharpCode.SharpDevelop.Utils |
||||
{ |
||||
/// <summary>
|
||||
/// Checks the change events of a model collection for consistency
|
||||
/// with the collection data.
|
||||
/// </summary>
|
||||
public class ModelCollectionEventCheck<T> |
||||
{ |
||||
readonly IModelCollection<T> modelCollection; |
||||
List<T> list; |
||||
|
||||
public ModelCollectionEventCheck(IModelCollection<T> modelCollection) |
||||
{ |
||||
if (modelCollection == null) |
||||
throw new ArgumentNullException("modelCollection"); |
||||
this.modelCollection = modelCollection; |
||||
this.list = new List<T>(modelCollection); |
||||
modelCollection.CollectionChanged += OnCollectionChanged; |
||||
} |
||||
|
||||
void OnCollectionChanged(object sender, NotifyCollectionChangedEventArgs e) |
||||
{ |
||||
switch (e.Action) { |
||||
case NotifyCollectionChangedAction.Add: |
||||
list.InsertRange(e.NewStartingIndex, e.NewItems.Cast<T>()); |
||||
break; |
||||
case NotifyCollectionChangedAction.Remove: |
||||
Assert.AreEqual(list.GetRange(e.OldStartingIndex, e.OldItems.Count), e.OldItems); |
||||
list.RemoveRange(e.OldStartingIndex, e.OldItems.Count); |
||||
break; |
||||
case NotifyCollectionChangedAction.Replace: |
||||
Assert.AreEqual(e.OldStartingIndex, e.NewStartingIndex, "Old and new starting index must be identical for replace action"); |
||||
Assert.AreEqual(list.GetRange(e.OldStartingIndex, e.OldItems.Count), e.OldItems); |
||||
list.RemoveRange(e.OldStartingIndex, e.OldItems.Count); |
||||
list.InsertRange(e.NewStartingIndex, e.NewItems.Cast<T>()); |
||||
break; |
||||
case NotifyCollectionChangedAction.Move: |
||||
Assert.AreEqual(e.OldItems, e.NewItems); |
||||
Assert.AreEqual(list.GetRange(e.OldStartingIndex, e.OldItems.Count), e.OldItems); |
||||
list.RemoveRange(e.OldStartingIndex, e.OldItems.Count); |
||||
list.InsertRange(e.NewStartingIndex, e.NewItems.Cast<T>()); |
||||
break; |
||||
case NotifyCollectionChangedAction.Reset: |
||||
list.Clear(); |
||||
list.AddRange(modelCollection); |
||||
break; |
||||
default: |
||||
throw new Exception("Invalid value for NotifyCollectionChangedAction"); |
||||
} |
||||
Verify(); |
||||
} |
||||
|
||||
public void Verify() |
||||
{ |
||||
Assert.AreEqual(list, modelCollection.ToList()); |
||||
} |
||||
} |
||||
} |
Loading…
Reference in new issue