1
1
using System ;
2
+ using System . Collections . Generic ;
3
+ using System . Diagnostics ;
2
4
using System . Globalization ;
3
5
using System . Linq ;
6
+ using System . Runtime . InteropServices . ComTypes ;
4
7
using System . Threading . Tasks ;
5
8
using System . Windows . Forms ;
6
9
using Microsoft . Vbe . Interop ;
7
10
using NLog ;
8
- using Rubberduck . AutoSave ;
9
11
using Rubberduck . Common ;
10
- using Rubberduck . Inspections ;
11
12
using Rubberduck . Parsing ;
12
13
using Rubberduck . Parsing . VBA ;
13
14
using Rubberduck . Settings ;
14
15
using Rubberduck . SmartIndenter ;
15
16
using Rubberduck . UI ;
16
17
using Rubberduck . UI . Command . MenuItems ;
17
- using Rubberduck . UI . ParserErrors ;
18
- using Rubberduck . VBEditor . Extensions ;
19
18
using Infralution . Localization . Wpf ;
19
+ using Rubberduck . Common . Dispatch ;
20
20
21
21
namespace Rubberduck
22
22
{
23
23
public class App : IDisposable
24
24
{
25
25
private readonly VBE _vbe ;
26
26
private readonly IMessageBox _messageBox ;
27
- private readonly IParserErrorsPresenterFactory _parserErrorsPresenterFactory ;
28
27
private readonly IRubberduckParser _parser ;
29
- private readonly IInspectorFactory _inspectorFactory ;
30
28
private readonly AutoSave . AutoSave _autoSave ;
31
29
private readonly IGeneralConfigService _configService ;
32
30
private readonly IAppMenu _appMenus ;
@@ -38,10 +36,14 @@ public class App : IDisposable
38
36
39
37
private Configuration _config ;
40
38
39
+ private readonly IConnectionPoint _projectsEventsConnectionPoint ;
40
+ private readonly int _projectsEventsCookie ;
41
+
42
+ private readonly IDictionary < VBComponents , Tuple < IConnectionPoint , int > > _componentsEventsConnectionPoints =
43
+ new Dictionary < VBComponents , Tuple < IConnectionPoint , int > > ( ) ;
44
+
41
45
public App ( VBE vbe , IMessageBox messageBox ,
42
- IParserErrorsPresenterFactory parserErrorsPresenterFactory ,
43
46
IRubberduckParser parser ,
44
- IInspectorFactory inspectorFactory ,
45
47
IGeneralConfigService configService ,
46
48
IAppMenu appMenus ,
47
49
RubberduckCommandBar stateBar ,
@@ -50,25 +52,170 @@ public App(VBE vbe, IMessageBox messageBox,
50
52
{
51
53
_vbe = vbe ;
52
54
_messageBox = messageBox ;
53
- _parserErrorsPresenterFactory = parserErrorsPresenterFactory ;
54
55
_parser = parser ;
55
- _inspectorFactory = inspectorFactory ;
56
- _autoSave = new AutoSave . AutoSave ( _vbe , new AutoSaveSettings ( ) ) ;
57
56
_configService = configService ;
57
+ _autoSave = new AutoSave . AutoSave ( _vbe , _configService ) ;
58
58
_appMenus = appMenus ;
59
59
_stateBar = stateBar ;
60
60
_indenter = indenter ;
61
61
//_hooks = hooks;
62
62
_logger = LogManager . GetCurrentClassLogger ( ) ;
63
63
64
64
//_hooks.MessageReceived += hooks_MessageReceived;
65
- _configService . SettingsChanged += _configService_SettingsChanged ;
65
+ _configService . LanguageChanged += ConfigServiceLanguageChanged ;
66
66
_parser . State . StateChanged += Parser_StateChanged ;
67
67
_stateBar . Refresh += _stateBar_Refresh ;
68
68
69
+ var sink = new VBProjectsEventsSink ( ) ;
70
+ var connectionPointContainer = ( IConnectionPointContainer ) _vbe . VBProjects ;
71
+ var interfaceId = typeof ( _dispVBProjectsEvents ) . GUID ;
72
+ connectionPointContainer . FindConnectionPoint ( ref interfaceId , out _projectsEventsConnectionPoint ) ;
73
+
74
+ sink . ProjectAdded += sink_ProjectAdded ;
75
+ sink . ProjectRemoved += sink_ProjectRemoved ;
76
+ sink . ProjectActivated += sink_ProjectActivated ;
77
+ sink . ProjectRenamed += sink_ProjectRenamed ;
78
+
79
+ _projectsEventsConnectionPoint . Advise ( sink , out _projectsEventsCookie ) ;
80
+
69
81
UiDispatcher . Initialize ( ) ;
70
82
}
71
83
84
+ async void sink_ProjectRemoved ( object sender , DispatcherEventArgs < VBProject > e )
85
+ {
86
+ Debug . WriteLine ( string . Format ( "Project '{0}' was removed." , e . Item . Name ) ) ;
87
+ Tuple < IConnectionPoint , int > value ;
88
+ if ( _componentsEventsConnectionPoints . TryGetValue ( e . Item . VBComponents , out value ) )
89
+ {
90
+ value . Item1 . Unadvise ( value . Item2 ) ;
91
+ _componentsEventsConnectionPoints . Remove ( e . Item . VBComponents ) ;
92
+
93
+ _parser . State . ClearDeclarations ( e . Item ) ;
94
+ }
95
+ }
96
+
97
+ async void sink_ProjectAdded ( object sender , DispatcherEventArgs < VBProject > e )
98
+ {
99
+ if ( ! _parser . State . AllDeclarations . Any ( ) )
100
+ {
101
+ // forces menus to evaluate their CanExecute state:
102
+ Parser_StateChanged ( this , new ParserStateEventArgs ( ParserState . Pending ) ) ;
103
+ _stateBar . SetStatusText ( ) ;
104
+ return ;
105
+ }
106
+
107
+ Debug . WriteLine ( string . Format ( "Project '{0}' was added." , e . Item . Name ) ) ;
108
+ var connectionPointContainer = ( IConnectionPointContainer ) e . Item . VBComponents ;
109
+ var interfaceId = typeof ( _dispVBComponentsEvents ) . GUID ;
110
+
111
+ IConnectionPoint connectionPoint ;
112
+ connectionPointContainer . FindConnectionPoint ( ref interfaceId , out connectionPoint ) ;
113
+
114
+ var sink = new VBComponentsEventsSink ( ) ;
115
+ sink . ComponentActivated += sink_ComponentActivated ;
116
+ sink . ComponentAdded += sink_ComponentAdded ;
117
+ sink . ComponentReloaded += sink_ComponentReloaded ;
118
+ sink . ComponentRemoved += sink_ComponentRemoved ;
119
+ sink . ComponentRenamed += sink_ComponentRenamed ;
120
+ sink . ComponentSelected += sink_ComponentSelected ;
121
+
122
+ int cookie ;
123
+ connectionPoint . Advise ( sink , out cookie ) ;
124
+
125
+ _componentsEventsConnectionPoints . Add ( e . Item . VBComponents , Tuple . Create ( connectionPoint , cookie ) ) ;
126
+ _parser . State . OnParseRequested ( sender ) ;
127
+ }
128
+
129
+ async void sink_ComponentSelected ( object sender , DispatcherEventArgs < VBComponent > e )
130
+ {
131
+ if ( ! _parser . State . AllDeclarations . Any ( ) )
132
+ {
133
+ return ;
134
+ }
135
+
136
+ Debug . WriteLine ( string . Format ( "Component '{0}' was selected." , e . Item . Name ) ) ;
137
+ // do something?
138
+ }
139
+
140
+ async void sink_ComponentRenamed ( object sender , DispatcherRenamedEventArgs < VBComponent > e )
141
+ {
142
+ if ( ! _parser . State . AllDeclarations . Any ( ) )
143
+ {
144
+ return ;
145
+ }
146
+
147
+ Debug . WriteLine ( string . Format ( "Component '{0}' was renamed." , e . Item . Name ) ) ;
148
+
149
+ _parser . State . OnParseRequested ( sender , e . Item ) ;
150
+ }
151
+
152
+ async void sink_ComponentRemoved ( object sender , DispatcherEventArgs < VBComponent > e )
153
+ {
154
+ if ( ! _parser . State . AllDeclarations . Any ( ) )
155
+ {
156
+ return ;
157
+ }
158
+
159
+ Debug . WriteLine ( string . Format ( "Component '{0}' was removed." , e . Item . Name ) ) ;
160
+ _parser . State . ClearDeclarations ( e . Item ) ;
161
+ }
162
+
163
+ async void sink_ComponentReloaded ( object sender , DispatcherEventArgs < VBComponent > e )
164
+ {
165
+ if ( ! _parser . State . AllDeclarations . Any ( ) )
166
+ {
167
+ return ;
168
+ }
169
+
170
+ Debug . WriteLine ( string . Format ( "Component '{0}' was reloaded." , e . Item . Name ) ) ;
171
+ _parser . State . OnParseRequested ( sender , e . Item ) ;
172
+ }
173
+
174
+ async void sink_ComponentAdded ( object sender , DispatcherEventArgs < VBComponent > e )
175
+ {
176
+ if ( ! _parser . State . AllDeclarations . Any ( ) )
177
+ {
178
+ return ;
179
+ }
180
+
181
+ Debug . WriteLine ( string . Format ( "Component '{0}' was added." , e . Item . Name ) ) ;
182
+ _parser . State . OnParseRequested ( sender , e . Item ) ;
183
+ }
184
+
185
+ async void sink_ComponentActivated ( object sender , DispatcherEventArgs < VBComponent > e )
186
+ {
187
+ if ( ! _parser . State . AllDeclarations . Any ( ) )
188
+ {
189
+ return ;
190
+ }
191
+
192
+ Debug . WriteLine ( string . Format ( "Component '{0}' was activated." , e . Item . Name ) ) ;
193
+ // do something?
194
+ }
195
+
196
+ async void sink_ProjectRenamed ( object sender , DispatcherRenamedEventArgs < VBProject > e )
197
+ {
198
+ if ( ! _parser . State . AllDeclarations . Any ( ) )
199
+ {
200
+ return ;
201
+ }
202
+
203
+ Debug . WriteLine ( string . Format ( "Project '{0}' was renamed." , e . Item . Name ) ) ;
204
+ _parser . State . ClearDeclarations ( e . Item ) ;
205
+ _parser . State . OnParseRequested ( sender ) ;
206
+ }
207
+
208
+ async void sink_ProjectActivated ( object sender , DispatcherEventArgs < VBProject > e )
209
+ {
210
+ if ( ! _parser . State . AllDeclarations . Any ( ) )
211
+ {
212
+ return ;
213
+ }
214
+
215
+ Debug . WriteLine ( string . Format ( "Project '{0}' was activated." , e . Item . Name ) ) ;
216
+ // do something?
217
+ }
218
+
72
219
private Keys _firstStepHotKey ;
73
220
private bool _isAwaitingTwoStepKey ;
74
221
private bool _skipKeyUp ;
@@ -143,11 +290,12 @@ private async void hooks_MessageReceived(object sender, HookEventArgs e)
143
290
144
291
private void _stateBar_Refresh ( object sender , EventArgs e )
145
292
{
146
- _parser . State . OnParseRequested ( ) ;
293
+ _parser . State . OnParseRequested ( sender ) ;
147
294
}
148
295
149
- private void Parser_StateChanged ( object sender , ParserStateEventArgs e )
296
+ private void Parser_StateChanged ( object sender , EventArgs e )
150
297
{
298
+ Debug . WriteLine ( "App handles StateChanged ({0}), evaluating menu states..." , _parser . State . Status ) ;
151
299
_appMenus . EvaluateCanExecute ( _parser . State ) ;
152
300
}
153
301
@@ -158,13 +306,6 @@ public void Startup()
158
306
_appMenus . Initialize ( ) ;
159
307
_appMenus . Localize ( ) ;
160
308
161
- // delay to allow the VBE to properly load. HostApplication is null until then.
162
- Task . Delay ( 1000 ) . ContinueWith ( t =>
163
- {
164
- _parser . State . AddBuiltInDeclarations ( _vbe . HostApplication ( ) ) ;
165
- _parser . State . OnParseRequested ( ) ;
166
- } ) ;
167
-
168
309
//_hooks.AddHook(new LowLevelKeyboardHook(_vbe));
169
310
//_hooks.AddHook(new HotKey((IntPtr)_vbe.MainWindow.HWnd, "%^R", Keys.R));
170
311
//_hooks.AddHook(new HotKey((IntPtr)_vbe.MainWindow.HWnd, "%^I", Keys.I));
@@ -174,10 +315,9 @@ public void Startup()
174
315
private void CleanReloadConfig ( )
175
316
{
176
317
LoadConfig ( ) ;
177
- Setup ( ) ;
178
318
}
179
319
180
- private void _configService_SettingsChanged ( object sender , EventArgs e )
320
+ private void ConfigServiceLanguageChanged ( object sender , EventArgs e )
181
321
{
182
322
CleanReloadConfig ( ) ;
183
323
}
@@ -202,19 +342,19 @@ private void LoadConfig()
202
342
}
203
343
}
204
344
205
- private void Setup ( )
206
- {
207
- _inspectorFactory . Create ( ) ;
208
- _parserErrorsPresenterFactory . Create ( ) ;
209
- }
210
-
211
345
public void Dispose ( )
212
346
{
213
- //_hooks.MessageReceived -= hooks_MessageReceived;
214
- _configService . SettingsChanged -= _configService_SettingsChanged ;
347
+ _configService . LanguageChanged -= ConfigServiceLanguageChanged ;
215
348
_parser . State . StateChanged -= Parser_StateChanged ;
216
349
_autoSave . Dispose ( ) ;
217
350
351
+ _projectsEventsConnectionPoint . Unadvise ( _projectsEventsCookie ) ;
352
+ foreach ( var item in _componentsEventsConnectionPoints )
353
+ {
354
+ item . Value . Item1 . Unadvise ( item . Value . Item2 ) ;
355
+ }
356
+
357
+ //_hooks.MessageReceived -= hooks_MessageReceived;
218
358
//_hooks.Dispose();
219
359
}
220
360
}
0 commit comments