17
17
using Rubberduck . UI . Command . MenuItems ;
18
18
using Infralution . Localization . Wpf ;
19
19
using Rubberduck . Common . Dispatch ;
20
+ using Rubberduck . VBEditor . Extensions ;
20
21
21
22
namespace Rubberduck
22
23
{
@@ -39,10 +40,10 @@ public class App : IDisposable
39
40
private readonly IConnectionPoint _projectsEventsConnectionPoint ;
40
41
private readonly int _projectsEventsCookie ;
41
42
42
- private readonly IDictionary < VBProjectsEventsSink , Tuple < IConnectionPoint , int > > _componentsEventsConnectionPoints =
43
- new Dictionary < VBProjectsEventsSink , Tuple < IConnectionPoint , int > > ( ) ;
44
- private readonly IDictionary < VBProjectsEventsSink , Tuple < IConnectionPoint , int > > _referencesEventsConnectionPoints =
45
- new Dictionary < VBProjectsEventsSink , Tuple < IConnectionPoint , int > > ( ) ;
43
+ private readonly IDictionary < string , Tuple < IConnectionPoint , int > > _componentsEventsConnectionPoints =
44
+ new Dictionary < string , Tuple < IConnectionPoint , int > > ( ) ;
45
+ private readonly IDictionary < string , Tuple < IConnectionPoint , int > > _referencesEventsConnectionPoints =
46
+ new Dictionary < string , Tuple < IConnectionPoint , int > > ( ) ;
46
47
47
48
public App ( VBE vbe , IMessageBox messageBox ,
48
49
IRubberduckParser parser ,
@@ -127,11 +128,6 @@ public void Startup()
127
128
{
128
129
CleanReloadConfig ( ) ;
129
130
130
- foreach ( var project in _vbe . VBProjects . Cast < VBProject > ( ) )
131
- {
132
- _parser . State . AddProject ( project ) ;
133
- }
134
-
135
131
_appMenus . Initialize ( ) ;
136
132
_appMenus . Localize ( ) ;
137
133
@@ -150,40 +146,51 @@ public void Startup()
150
146
#region sink handlers. todo: move to another class
151
147
async void sink_ProjectRemoved ( object sender , DispatcherEventArgs < VBProject > e )
152
148
{
153
- var sink = ( VBProjectsEventsSink ) sender ;
154
- _componentsEventSinks . Remove ( sink ) ;
155
- _referencesEventsSinks . Remove ( sink ) ;
149
+ if ( e . Item . Protection == vbext_ProjectProtection . vbext_pp_locked )
150
+ {
151
+ Debug . WriteLine ( string . Format ( "Locked project '{0}' was removed." , e . Item . Name ) ) ;
152
+ return ;
153
+ }
154
+
155
+ var projectId = e . Item . HelpFile ;
156
+ _componentsEventsSinks . Remove ( projectId ) ;
157
+ _referencesEventsSinks . Remove ( projectId ) ;
156
158
_parser . State . RemoveProject ( e . Item ) ;
157
159
158
160
Debug . WriteLine ( string . Format ( "Project '{0}' was removed." , e . Item . Name ) ) ;
159
161
Tuple < IConnectionPoint , int > componentsTuple ;
160
- if ( _componentsEventsConnectionPoints . TryGetValue ( sink , out componentsTuple ) )
162
+ if ( _componentsEventsConnectionPoints . TryGetValue ( projectId , out componentsTuple ) )
161
163
{
162
164
componentsTuple . Item1 . Unadvise ( componentsTuple . Item2 ) ;
163
- _componentsEventsConnectionPoints . Remove ( sink ) ;
165
+ _componentsEventsConnectionPoints . Remove ( projectId ) ;
164
166
}
165
167
166
168
Tuple < IConnectionPoint , int > referencesTuple ;
167
- if ( _referencesEventsConnectionPoints . TryGetValue ( sink , out referencesTuple ) )
169
+ if ( _referencesEventsConnectionPoints . TryGetValue ( projectId , out referencesTuple ) )
168
170
{
169
171
referencesTuple . Item1 . Unadvise ( referencesTuple . Item2 ) ;
170
- _referencesEventsConnectionPoints . Remove ( sink ) ;
172
+ _referencesEventsConnectionPoints . Remove ( projectId ) ;
171
173
}
172
-
173
- _parser . State . ClearDeclarations ( e . Item ) ;
174
174
}
175
175
176
- private readonly IDictionary < VBProjectsEventsSink , VBComponentsEventsSink > _componentsEventSinks =
177
- new Dictionary < VBProjectsEventsSink , VBComponentsEventsSink > ( ) ;
176
+ private readonly IDictionary < string , VBComponentsEventsSink > _componentsEventsSinks =
177
+ new Dictionary < string , VBComponentsEventsSink > ( ) ;
178
178
179
- private readonly IDictionary < VBProjectsEventsSink , ReferencesEventsSink > _referencesEventsSinks =
180
- new Dictionary < VBProjectsEventsSink , ReferencesEventsSink > ( ) ;
179
+ private readonly IDictionary < string , ReferencesEventsSink > _referencesEventsSinks =
180
+ new Dictionary < string , ReferencesEventsSink > ( ) ;
181
181
182
182
async void sink_ProjectAdded ( object sender , DispatcherEventArgs < VBProject > e )
183
183
{
184
- var sink = ( VBProjectsEventsSink ) sender ;
185
- RegisterComponentsEventSink ( e , sink ) ;
186
- _parser . State . AddProject ( e . Item ) ;
184
+ Debug . WriteLine ( string . Format ( "Project '{0}' was added." , e . Item . Name ) ) ;
185
+ if ( e . Item . Protection == vbext_ProjectProtection . vbext_pp_locked )
186
+ {
187
+ Debug . WriteLine ( "Project is protected and will not be added to parser state." ) ;
188
+ return ;
189
+ }
190
+
191
+ _parser . State . AddProject ( e . Item ) ; // note side-effect: assigns ProjectId/HelpFile
192
+ var projectId = e . Item . HelpFile ;
193
+ RegisterComponentsEventSink ( e . Item . VBComponents , projectId ) ;
187
194
188
195
if ( ! _parser . State . AllDeclarations . Any ( ) )
189
196
{
@@ -193,13 +200,19 @@ async void sink_ProjectAdded(object sender, DispatcherEventArgs<VBProject> e)
193
200
return ;
194
201
}
195
202
196
- Debug . WriteLine ( string . Format ( "Project '{0}' was added." , e . Item . Name ) ) ;
197
203
_parser . State . OnParseRequested ( sender ) ;
198
204
}
199
205
200
- private void RegisterComponentsEventSink ( DispatcherEventArgs < VBProject > e , VBProjectsEventsSink sink )
206
+ private void RegisterComponentsEventSink ( VBComponents components , string projectId )
201
207
{
202
- var connectionPointContainer = ( IConnectionPointContainer ) e . Item . VBComponents ;
208
+ if ( _componentsEventsSinks . ContainsKey ( projectId ) )
209
+ {
210
+ // already registered - this is caused by the initial load+rename of a project in the VBE
211
+ Debug . WriteLine ( "Components sink already registered." ) ;
212
+ return ;
213
+ }
214
+
215
+ var connectionPointContainer = ( IConnectionPointContainer ) components ;
203
216
var interfaceId = typeof ( _dispVBComponentsEvents ) . GUID ;
204
217
205
218
IConnectionPoint connectionPoint ;
@@ -212,12 +225,13 @@ private void RegisterComponentsEventSink(DispatcherEventArgs<VBProject> e, VBPro
212
225
componentsSink . ComponentRemoved += sink_ComponentRemoved ;
213
226
componentsSink . ComponentRenamed += sink_ComponentRenamed ;
214
227
componentsSink . ComponentSelected += sink_ComponentSelected ;
215
- //_componentsEventSinks .Add(sink , componentsSink);
228
+ _componentsEventsSinks . Add ( projectId , componentsSink ) ;
216
229
217
- // int cookie;
218
- // connectionPoint.Advise(componentsSink, out cookie);
230
+ int cookie ;
231
+ connectionPoint . Advise ( componentsSink , out cookie ) ;
219
232
220
- //_componentsEventsConnectionPoints.Add(sink, Tuple.Create(connectionPoint, cookie));
233
+ _componentsEventsConnectionPoints . Add ( projectId , Tuple . Create ( connectionPoint , cookie ) ) ;
234
+ Debug . WriteLine ( "Components sink registered and advising." ) ;
221
235
}
222
236
223
237
async void sink_ComponentSelected ( object sender , DispatcherEventArgs < VBComponent > e )
@@ -251,7 +265,7 @@ async void sink_ComponentRemoved(object sender, DispatcherEventArgs<VBComponent>
251
265
}
252
266
253
267
Debug . WriteLine ( string . Format ( "Component '{0}' was removed." , e . Item . Name ) ) ;
254
- _parser . State . ClearDeclarations ( e . Item ) ;
268
+ _parser . State . ClearStateCache ( e . Item ) ;
255
269
}
256
270
257
271
async void sink_ComponentReloaded ( object sender , DispatcherEventArgs < VBComponent > e )
@@ -364,7 +378,10 @@ public void Dispose()
364
378
{
365
379
item . Value . Item1 . Unadvise ( item . Value . Item2 ) ;
366
380
}
367
-
381
+ foreach ( var item in _referencesEventsConnectionPoints )
382
+ {
383
+ item . Value . Item1 . Unadvise ( item . Value . Item2 ) ;
384
+ }
368
385
_hooks . Dispose ( ) ;
369
386
}
370
387
}
0 commit comments