Browse Source

Fixed snippet options.

pull/6/merge
Daniel Grunwald 14 years ago
parent
commit
2fc9ff16e3
  1. 1
      src/AddIns/DisplayBindings/AvalonEdit.AddIn/AvalonEdit.AddIn.csproj
  2. 37
      src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/Snippets/CodeSnippet.cs
  3. 30
      src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/Snippets/CodeSnippetComparer.cs
  4. 24
      src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/Snippets/CodeSnippetGroup.cs
  5. 17
      src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/Snippets/SnippetManager.cs

1
src/AddIns/DisplayBindings/AvalonEdit.AddIn/AvalonEdit.AddIn.csproj

@ -73,6 +73,7 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Compile Include="Src\DocumentSequence.cs" /> <Compile Include="Src\DocumentSequence.cs" />
<Compile Include="Src\Snippets\CodeSnippetComparer.cs" />
<Compile Include="Src\Utils.cs" /> <Compile Include="Src\Utils.cs" />
<None Include="AvalonEdit.AddIn.addin"> <None Include="AvalonEdit.AddIn.addin">
<CopyToOutputDirectory>Always</CopyToOutputDirectory> <CopyToOutputDirectory>Always</CopyToOutputDirectory>

37
src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/Snippets/CodeSnippet.cs

@ -19,7 +19,7 @@ namespace ICSharpCode.AvalonEdit.AddIn.Snippets
/// <summary> /// <summary>
/// A code snippet. /// A code snippet.
/// </summary> /// </summary>
public class CodeSnippet : INotifyPropertyChanged, IEquatable<CodeSnippet> public class CodeSnippet : AbstractFreezable, INotifyPropertyChanged
{ {
string name = string.Empty, description = string.Empty, text = string.Empty, keyword = string.Empty; string name = string.Empty, description = string.Empty, text = string.Empty, keyword = string.Empty;
@ -38,6 +38,7 @@ namespace ICSharpCode.AvalonEdit.AddIn.Snippets
public string Name { public string Name {
get { return name; } get { return name; }
set { set {
CheckBeforeMutation();
if (name != value) { if (name != value) {
name = value ?? string.Empty; name = value ?? string.Empty;
OnPropertyChanged("Name"); OnPropertyChanged("Name");
@ -48,6 +49,7 @@ namespace ICSharpCode.AvalonEdit.AddIn.Snippets
public string Text { public string Text {
get { return text; } get { return text; }
set { set {
CheckBeforeMutation();
if (text != value) { if (text != value) {
text = value ?? string.Empty; text = value ?? string.Empty;
OnPropertyChanged("Text"); OnPropertyChanged("Text");
@ -58,6 +60,7 @@ namespace ICSharpCode.AvalonEdit.AddIn.Snippets
public string Description { public string Description {
get { return description; } get { return description; }
set { set {
CheckBeforeMutation();
if (description != value) { if (description != value) {
description = value ?? string.Empty; description = value ?? string.Empty;
OnPropertyChanged("Description"); OnPropertyChanged("Description");
@ -76,6 +79,7 @@ namespace ICSharpCode.AvalonEdit.AddIn.Snippets
public string Keyword { public string Keyword {
get { return keyword; } get { return keyword; }
set { set {
CheckBeforeMutation();
if (keyword != value) { if (keyword != value) {
keyword = value ?? string.Empty; keyword = value ?? string.Empty;
OnPropertyChanged("Keyword"); OnPropertyChanged("Keyword");
@ -226,41 +230,12 @@ namespace ICSharpCode.AvalonEdit.AddIn.Snippets
} }
} }
public override int GetHashCode()
{
int hashCode = 0;
unchecked {
if (name != null)
hashCode += 1000000007 * name.GetHashCode();
if (description != null)
hashCode += 1000000009 * description.GetHashCode();
if (text != null)
hashCode += 1000000021 * text.GetHashCode();
if (keyword != null)
hashCode += 1000000033 * keyword.GetHashCode();
}
return hashCode;
}
public override bool Equals(object obj)
{
CodeSnippet other = obj as CodeSnippet;
return Equals(other);
}
public bool Equals(CodeSnippet other)
{
if (other == null)
return false;
return this.name == other.name && this.description == other.description && this.text == other.text && this.keyword == other.keyword;
}
/// <summary> /// <summary>
/// Reports the snippet usage to UDC /// Reports the snippet usage to UDC
/// </summary> /// </summary>
internal void TrackUsage(string activationMethod) internal void TrackUsage(string activationMethod)
{ {
bool isUserModified = !SnippetManager.defaultSnippets.Any(g => g.Snippets.Contains(this)); bool isUserModified = !SnippetManager.Instance.defaultSnippets.Any(g => g.Snippets.Contains(this, CodeSnippetComparer.Instance));
Core.AnalyticsMonitorService.TrackFeature(typeof(CodeSnippet), isUserModified ? "usersnippet" : Name, activationMethod); Core.AnalyticsMonitorService.TrackFeature(typeof(CodeSnippet), isUserModified ? "usersnippet" : Name, activationMethod);
} }
} }

30
src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/Snippets/CodeSnippetComparer.cs

@ -0,0 +1,30 @@
// 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;
namespace ICSharpCode.AvalonEdit.AddIn.Snippets
{
/// <summary>
/// Compares code snippets.
/// </summary>
public class CodeSnippetComparer : IEqualityComparer<CodeSnippet>
{
public static readonly CodeSnippetComparer Instance = new CodeSnippetComparer();
public bool Equals(CodeSnippet x, CodeSnippet y)
{
if (x == y)
return true;
if (x == null || y == null)
return false;
return x.Name == y.Name && x.Description == y.Description && x.Text == y.Text && x.Keyword == y.Keyword;
}
public int GetHashCode(CodeSnippet obj)
{
return obj != null ? obj.Name.GetHashCode() : 0;
}
}
}

24
src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/Snippets/CodeSnippetGroup.cs

@ -4,14 +4,27 @@
using System; using System;
using System.Collections.ObjectModel; using System.Collections.ObjectModel;
using System.ComponentModel; using System.ComponentModel;
using System.Linq;
using ICSharpCode.SharpDevelop;
using ICSharpCode.SharpDevelop.Dom;
namespace ICSharpCode.AvalonEdit.AddIn.Snippets namespace ICSharpCode.AvalonEdit.AddIn.Snippets
{ {
/// <summary> /// <summary>
/// A group of snippets (for a specific file extension). /// A group of snippets (for a specific file extension).
/// </summary> /// </summary>
public class CodeSnippetGroup : INotifyPropertyChanged public class CodeSnippetGroup : AbstractFreezable, INotifyPropertyChanged
{ {
public CodeSnippetGroup()
{
}
public CodeSnippetGroup(CodeSnippetGroup g)
{
this.Extensions = g.Extensions;
this.Snippets.AddRange(g.Snippets.Select(s => new CodeSnippet(s)));
}
string extensions = ""; string extensions = "";
ObservableCollection<CodeSnippet> snippets = new ObservableCollection<CodeSnippet>(); ObservableCollection<CodeSnippet> snippets = new ObservableCollection<CodeSnippet>();
@ -19,11 +32,20 @@ namespace ICSharpCode.AvalonEdit.AddIn.Snippets
get { return snippets; } get { return snippets; }
} }
protected override void FreezeInternal()
{
base.FreezeInternal();
foreach (var snippet in this.snippets)
snippet.Freeze();
this.snippets.CollectionChanged += delegate { throw new NotSupportedException(); };
}
public string Extensions { public string Extensions {
get { return extensions; } get { return extensions; }
set { set {
if (value == null) if (value == null)
throw new ArgumentNullException(); throw new ArgumentNullException();
CheckBeforeMutation();
if (extensions != value) { if (extensions != value) {
extensions = value; extensions = value;
OnPropertyChanged("Extensions"); OnPropertyChanged("Extensions");

17
src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/Snippets/SnippetManager.cs

@ -18,7 +18,7 @@ namespace ICSharpCode.AvalonEdit.AddIn.Snippets
public sealed class SnippetManager public sealed class SnippetManager
{ {
readonly object lockObj = new object(); readonly object lockObj = new object();
internal static readonly List<CodeSnippetGroup> defaultSnippets = new List<CodeSnippetGroup> { internal readonly List<CodeSnippetGroup> defaultSnippets = new List<CodeSnippetGroup> {
new CodeSnippetGroup { new CodeSnippetGroup {
Extensions = ".cs", Extensions = ".cs",
Snippets = { Snippets = {
@ -304,6 +304,8 @@ End Property${Caret}",
private SnippetManager() private SnippetManager()
{ {
foreach (var g in defaultSnippets)
g.Freeze();
snippetElementProviders = AddInTree.BuildItems<ISnippetElementProvider>("/SharpDevelop/ViewContent/AvalonEdit/SnippetElementProviders", null, false); snippetElementProviders = AddInTree.BuildItems<ISnippetElementProvider>("/SharpDevelop/ViewContent/AvalonEdit/SnippetElementProviders", null, false);
} }
@ -314,6 +316,10 @@ End Property${Caret}",
{ {
var savedSnippets = PropertyService.Get("CodeSnippets", new List<CodeSnippetGroup>()); var savedSnippets = PropertyService.Get("CodeSnippets", new List<CodeSnippetGroup>());
// HACK: clone all groups to ensure we use instances independent from the PropertyService
// this can be removed in SD5 where PropertyService.Get deserializes a new instance on every call.
savedSnippets = savedSnippets.Select(g => new CodeSnippetGroup(g)).ToList();
foreach (var group in savedSnippets) { foreach (var group in savedSnippets) {
var defaultGroup = defaultSnippets.FirstOrDefault(i => i.Extensions == group.Extensions); var defaultGroup = defaultSnippets.FirstOrDefault(i => i.Extensions == group.Extensions);
if (defaultGroup != null) { if (defaultGroup != null) {
@ -329,7 +335,7 @@ End Property${Caret}",
} }
foreach (var group in defaultSnippets.Except(savedSnippets, new ByMemberComparer<CodeSnippetGroup, string>(g => g.Extensions))) { foreach (var group in defaultSnippets.Except(savedSnippets, new ByMemberComparer<CodeSnippetGroup, string>(g => g.Extensions))) {
savedSnippets.Add(group); savedSnippets.Add(new CodeSnippetGroup(group));
} }
return savedSnippets; return savedSnippets;
@ -371,7 +377,7 @@ End Property${Caret}",
IEnumerable<CodeSnippet> saveSnippets = group.Snippets; IEnumerable<CodeSnippet> saveSnippets = group.Snippets;
if (defaultGroup != null) { if (defaultGroup != null) {
saveSnippets = group.Snippets.Except(defaultGroup.Snippets); saveSnippets = group.Snippets.Except(defaultGroup.Snippets, CodeSnippetComparer.Instance);
} }
// save all groups, even if they're empty // save all groups, even if they're empty
@ -391,8 +397,11 @@ End Property${Caret}",
public ReadOnlyCollection<CodeSnippetGroup> ActiveGroups { public ReadOnlyCollection<CodeSnippetGroup> ActiveGroups {
get { get {
lock (lockObj) { lock (lockObj) {
if (activeGroups == null) if (activeGroups == null) {
activeGroups = LoadGroups().AsReadOnly(); activeGroups = LoadGroups().AsReadOnly();
foreach (var g in activeGroups)
g.Freeze();
}
return activeGroups; return activeGroups;
} }
} }

Loading…
Cancel
Save