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
{
@@ -36,6 +36,12 @@ public class App : IDisposable
36
36
37
37
private Configuration _config ;
38
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
+
39
45
public App ( VBE vbe , IMessageBox messageBox ,
40
46
IRubberduckParser parser ,
41
47
IGeneralConfigService configService ,
@@ -60,9 +66,156 @@ public App(VBE vbe, IMessageBox messageBox,
60
66
_parser . State . StateChanged += Parser_StateChanged ;
61
67
_stateBar . Refresh += _stateBar_Refresh ;
62
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
+
63
81
UiDispatcher . Initialize ( ) ;
64
82
}
65
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
+
66
219
private Keys _firstStepHotKey ;
67
220
private bool _isAwaitingTwoStepKey ;
68
221
private bool _skipKeyUp ;
@@ -137,11 +290,12 @@ private async void hooks_MessageReceived(object sender, HookEventArgs e)
137
290
138
291
private void _stateBar_Refresh ( object sender , EventArgs e )
139
292
{
140
- _parser . State . OnParseRequested ( ) ;
293
+ _parser . State . OnParseRequested ( sender ) ;
141
294
}
142
295
143
- private void Parser_StateChanged ( object sender , ParserStateEventArgs e )
296
+ private void Parser_StateChanged ( object sender , EventArgs e )
144
297
{
298
+ Debug . WriteLine ( "App handles StateChanged ({0}), evaluating menu states..." , _parser . State . Status ) ;
145
299
_appMenus . EvaluateCanExecute ( _parser . State ) ;
146
300
}
147
301
@@ -152,13 +306,6 @@ public void Startup()
152
306
_appMenus . Initialize ( ) ;
153
307
_appMenus . Localize ( ) ;
154
308
155
- // delay to allow the VBE to properly load. HostApplication is null until then.
156
- Task . Delay ( 1000 ) . ContinueWith ( t =>
157
- {
158
- _parser . State . AddBuiltInDeclarations ( _vbe . HostApplication ( ) ) ;
159
- _parser . State . OnParseRequested ( ) ;
160
- } ) ;
161
-
162
309
//_hooks.AddHook(new LowLevelKeyboardHook(_vbe));
163
310
//_hooks.AddHook(new HotKey((IntPtr)_vbe.MainWindow.HWnd, "%^R", Keys.R));
164
311
//_hooks.AddHook(new HotKey((IntPtr)_vbe.MainWindow.HWnd, "%^I", Keys.I));
@@ -197,11 +344,17 @@ private void LoadConfig()
197
344
198
345
public void Dispose ( )
199
346
{
200
- //_hooks.MessageReceived -= hooks_MessageReceived;
201
347
_configService . LanguageChanged -= ConfigServiceLanguageChanged ;
202
348
_parser . State . StateChanged -= Parser_StateChanged ;
203
349
_autoSave . Dispose ( ) ;
204
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;
205
358
//_hooks.Dispose();
206
359
}
207
360
}
0 commit comments