Skip to content

Commit 9fefd4a

Browse files
committed
implemented AutoCompleteSettings
1 parent 3a8d2f7 commit 9fefd4a

File tree

9 files changed

+424
-93
lines changed

9 files changed

+424
-93
lines changed
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
using System.Collections.Generic;
2+
using System.Linq;
3+
using Rubberduck.Settings;
4+
5+
namespace Rubberduck.AutoComplete
6+
{
7+
public interface IAutoCompleteProvider
8+
{
9+
IEnumerable<IAutoComplete> AutoCompletes { get; }
10+
}
11+
12+
public class AutoCompleteProvider : IAutoCompleteProvider
13+
{
14+
public AutoCompleteProvider(IEnumerable<IAutoComplete> autoCompletes)
15+
{
16+
var defaults = new DefaultSettings<AutoCompleteSettings>().Default;
17+
var defaultKeys = defaults.Settings.Select(x => x.Key);
18+
var defaultAutoCompletes = autoCompletes.Where(autoComplete => defaultKeys.Contains(autoComplete.GetType().Name));
19+
20+
foreach (var autoComplete in defaultAutoCompletes)
21+
{
22+
autoComplete.IsEnabled = defaults.Settings.First(setting => setting.Key == autoComplete.GetType().Name).IsEnabled;
23+
}
24+
25+
AutoCompletes = autoCompletes;
26+
}
27+
28+
public IEnumerable<IAutoComplete> AutoCompletes { get; }
29+
}
30+
}

Rubberduck.Core/AutoComplete/IAutoComplete.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,6 @@ public interface IAutoComplete
77
string InputToken { get; }
88
string OutputToken { get; }
99
bool Execute(AutoCompleteEventArgs e);
10-
bool IsEnabled { get; }
10+
bool IsEnabled { get; set; }
1111
}
1212
}

Rubberduck.Core/Properties/Settings.Designer.cs

Lines changed: 12 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Rubberduck.Core/Properties/Settings.settings

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -257,5 +257,11 @@
257257
&lt;RunInspectionsOnSuccessfulParse&gt;true&lt;/RunInspectionsOnSuccessfulParse&gt;
258258
&lt;/CodeInspectionSettings&gt;</Value>
259259
</Setting>
260+
<Setting Name="AutoCompleteSettings" Type="Rubberduck.Settings.AutoCompleteSettings" Scope="Application">
261+
<Value Profile="(Default)">&lt;?xml version="1.0" encoding="utf-16"?&gt;
262+
&lt;AutoCompleteSettings xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"&gt;
263+
&lt;Settings /&gt;
264+
&lt;/AutoCompleteSettings&gt;</Value>
265+
</Setting>
260266
</Settings>
261267
</SettingsFile>

Rubberduck.Core/Rubberduck.Core.csproj

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -332,6 +332,7 @@
332332
<Compile Include="Common\WinAPI\WindowLongFlags.cs" />
333333
<Compile Include="Common\WindowsOperatingSystem.cs" />
334334
<Compile Include="Common\UndocumentedAttribute.cs" />
335+
<Compile Include="AutoComplete\AutoCompleteProvider.cs" />
335336
<Compile Include="Inspections\IInspectionProvider.cs" />
336337
<Compile Include="Inspections\InspectionProvider.cs" />
337338
<Compile Include="Navigation\CodeExplorer\ICodeExplorerDeclarationViewModel.cs" />
@@ -363,6 +364,9 @@
363364
<Compile Include="Refactorings\ExtractMethod\IExtractMethodProc.cs" />
364365
<Compile Include="Refactorings\ExtractMethod\IExtractMethodRule.cs" />
365366
<Compile Include="Refactorings\ExtractMethod\IExtractMethodSelectionValidation.cs" />
367+
<Compile Include="Settings\AutoCompleteConfigProvider.cs" />
368+
<Compile Include="Settings\AutoCompleteSetting.cs" />
369+
<Compile Include="Settings\AutoCompleteSettings.cs" />
366370
<Compile Include="Settings\CodeInspectionConfigProvider.cs" />
367371
<Compile Include="Settings\ExperimentalFeatures.cs" />
368372
<Compile Include="Settings\DefaultSettings.cs" />
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
using System.Collections.Generic;
2+
using System.Linq;
3+
using Rubberduck.AutoComplete;
4+
using Rubberduck.Parsing.VBA;
5+
using Rubberduck.SettingsProvider;
6+
7+
namespace Rubberduck.Settings
8+
{
9+
public class AutoCompleteConfigProvider : IConfigProvider<AutoCompleteSettings>
10+
{
11+
private readonly IPersistanceService<AutoCompleteSettings> _persister;
12+
private readonly AutoCompleteSettings _defaultSettings;
13+
private readonly HashSet<string> _foundAutoCompleteKeys;
14+
15+
public AutoCompleteConfigProvider(IPersistanceService<AutoCompleteSettings> persister, IAutoCompleteProvider provider)
16+
{
17+
_persister = persister;
18+
_foundAutoCompleteKeys = provider.AutoCompletes.Select(e => e.GetType().Name).ToHashSet();
19+
_defaultSettings = new DefaultSettings<AutoCompleteSettings>().Default;
20+
_defaultSettings.Settings = _defaultSettings.Settings.Where(setting => _foundAutoCompleteKeys.Contains(setting.Key)).ToHashSet();
21+
22+
}
23+
24+
public AutoCompleteSettings Create()
25+
{
26+
var prototype = new AutoCompleteSettings(_defaultSettings.Settings);
27+
28+
// Loaded settings don't contain defaults, so we need to use the `Settings` property to combine user settings with defaults.
29+
var loaded = _persister.Load(prototype);
30+
if (loaded != null)
31+
{
32+
prototype.Settings = loaded.Settings;
33+
}
34+
35+
return prototype;
36+
}
37+
38+
public AutoCompleteSettings CreateDefaults()
39+
{
40+
return new AutoCompleteSettings(_defaultSettings.Settings);
41+
}
42+
43+
public void Save(AutoCompleteSettings settings)
44+
{
45+
_persister.Save(settings);
46+
}
47+
}
48+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
using System.Xml.Serialization;
2+
using System.Configuration;
3+
using Rubberduck.AutoComplete;
4+
5+
namespace Rubberduck.Settings
6+
{
7+
[SettingsSerializeAs(SettingsSerializeAs.Xml)]
8+
public class AutoCompleteSetting
9+
{
10+
public AutoCompleteSetting() { /* default ctor required for XML serialization */ }
11+
12+
public AutoCompleteSetting(IAutoComplete autoComplete)
13+
{
14+
Key = autoComplete.GetType().Name;
15+
IsEnabled = autoComplete.IsEnabled;
16+
}
17+
18+
public string Key { get; set; }
19+
public bool IsEnabled { get; set; }
20+
21+
[XmlIgnore]
22+
public string Description => Resources.Settings.SettingsUI.ResourceManager.GetString(Key + "Description");
23+
}
24+
}
Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
using Rubberduck.AutoComplete;
2+
using Rubberduck.Parsing.VBA;
3+
using System;
4+
using System.Collections.Generic;
5+
using System.Configuration;
6+
using System.Linq;
7+
using System.Xml.Serialization;
8+
9+
namespace Rubberduck.Settings
10+
{
11+
public interface IAutoCompleteSettings
12+
{
13+
HashSet<AutoCompleteSetting> Settings { get; set; }
14+
}
15+
16+
[SettingsSerializeAs(SettingsSerializeAs.Xml)]
17+
[XmlType(AnonymousType = true)]
18+
public class AutoCompleteSettings : IAutoCompleteSettings
19+
{
20+
private readonly IEnumerable<AutoCompleteSetting> _defaultSettings;
21+
private HashSet<AutoCompleteSetting> _settings = new HashSet<AutoCompleteSetting>();
22+
23+
public AutoCompleteSettings() { /* default constructor required for XML serialization */ }
24+
25+
public AutoCompleteSettings(IEnumerable<AutoCompleteSetting> defaultSettings)
26+
{
27+
_defaultSettings = defaultSettings;
28+
_settings = defaultSettings.ToHashSet();
29+
}
30+
31+
[XmlArrayItem("AutoComplete", IsNullable = false)]
32+
public HashSet<AutoCompleteSetting> Settings
33+
{
34+
get => _settings;
35+
set
36+
{
37+
// Enable loading user settings during deserialization
38+
if (_defaultSettings == null)
39+
{
40+
if (value != null)
41+
{
42+
AddUnique(value);
43+
}
44+
45+
return;
46+
}
47+
48+
var defaults = _defaultSettings.ToArray();
49+
50+
if (value == null || value.Count == 0)
51+
{
52+
_settings = new HashSet<AutoCompleteSetting>(defaults);
53+
return;
54+
}
55+
56+
_settings = new HashSet<AutoCompleteSetting>();
57+
58+
var incoming = value;
59+
AddUnique(incoming);
60+
61+
//Merge any hotkeys that weren't found in the input.
62+
foreach (var setting in defaults.Where(setting => _settings.FirstOrDefault(s => s.Key.Equals(setting.Key)) == null))
63+
{
64+
setting.IsEnabled &= !IsDuplicate(setting);
65+
_settings.Add(setting);
66+
}
67+
}
68+
69+
}
70+
71+
private void AddUnique(IEnumerable<AutoCompleteSetting> settings)
72+
{
73+
//Only take the first setting if multiple definitions are found.
74+
foreach (var setting in settings.GroupBy(s => s.Key).Select(autocomplete => autocomplete.First()))
75+
{
76+
//Only allow one hotkey to be enabled with the same key combination.
77+
setting.IsEnabled &= !IsDuplicate(setting);
78+
_settings.Add(setting);
79+
}
80+
}
81+
82+
private bool IsDuplicate(AutoCompleteSetting setting)
83+
{
84+
return _settings.FirstOrDefault(s => s.Key == setting.Key) != null;
85+
}
86+
87+
public AutoCompleteSetting GetSetting<TAutoComplete>() where TAutoComplete : IAutoComplete
88+
{
89+
return Settings.FirstOrDefault(s => typeof(TAutoComplete).Name.Equals(s.Key))
90+
?? GetSetting(typeof(TAutoComplete));
91+
}
92+
93+
public AutoCompleteSetting GetSetting(Type autoCompleteType)
94+
{
95+
try
96+
{
97+
var existing = Settings.FirstOrDefault(s => autoCompleteType.Name.Equals(s.Key));
98+
if (existing != null)
99+
{
100+
return existing;
101+
}
102+
var proto = Convert.ChangeType(Activator.CreateInstance(autoCompleteType, new object[] { null }), autoCompleteType);
103+
var setting = new AutoCompleteSetting(proto as IAutoComplete);
104+
Settings.Add(setting);
105+
return setting;
106+
}
107+
catch (Exception)
108+
{
109+
return null;
110+
}
111+
}
112+
}
113+
}

0 commit comments

Comments
 (0)