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