1
- using System ;
2
1
using System . Collections . Generic ;
2
+ using System . IO ;
3
3
using System . Linq ;
4
- using System . Runtime . InteropServices ;
5
- using System . Windows . Media . Imaging ;
6
4
using Rubberduck . Parsing . Symbols ;
7
- using Rubberduck . VBEditor ;
8
5
using Rubberduck . Parsing . Annotations ;
9
- using Rubberduck . VBEditor . ComManagement ;
10
6
using Rubberduck . VBEditor . SafeComWrappers ;
11
7
using Rubberduck . Resources . CodeExplorer ;
12
8
using Rubberduck . VBEditor . SafeComWrappers . Abstract ;
13
9
14
10
namespace Rubberduck . Navigation . CodeExplorer
15
11
{
16
- public class CodeExplorerComponentViewModel : CodeExplorerItemViewModel
12
+ public sealed class CodeExplorerComponentViewModel : CodeExplorerItemViewModel
17
13
{
18
- public override CodeExplorerItemViewModel Parent { get ; }
19
-
20
14
public static readonly DeclarationType [ ] MemberTypes =
21
15
{
22
16
DeclarationType . Constant ,
@@ -33,219 +27,98 @@ public class CodeExplorerComponentViewModel : CodeExplorerItemViewModel
33
27
DeclarationType . Variable
34
28
} ;
35
29
36
- public CodeExplorerComponentViewModel ( CodeExplorerItemViewModel parent , Declaration declaration , IEnumerable < Declaration > declarations , IProjectsProvider projectsProvider , IVBE vbe )
37
- : base ( declaration )
30
+ private readonly IVBE _vbe ;
31
+
32
+ public CodeExplorerComponentViewModel ( ICodeExplorerNode parent , Declaration declaration , IEnumerable < Declaration > declarations , IVBE vbe )
33
+ : base ( parent , declaration )
38
34
{
39
- Parent = parent ;
40
- SetIcon ( ) ;
41
-
42
- Items = declarations . GroupBy ( item => item . Scope ) . SelectMany ( grouping =>
43
- grouping . Where ( item => item . ParentDeclaration != null
44
- && item . ParentScope == declaration . Scope
45
- && MemberTypes . Contains ( item . DeclarationType ) )
46
- . OrderBy ( item => item . QualifiedSelection . Selection . StartLine )
47
- . Select ( item => new CodeExplorerMemberViewModel ( this , item , grouping ) ) )
48
- . ToList < CodeExplorerItemViewModel > ( ) ;
49
-
50
- _name = DeclarationType == DeclarationType . ResFile && string . IsNullOrEmpty ( Declaration . IdentifierName )
51
- ? CodeExplorerUI . CodeExplorer_ResourceFileText
52
- : Declaration . IdentifierName ;
53
-
54
- var qualifiedModuleName = declaration . QualifiedName . QualifiedModuleName ;
55
- try
56
- {
57
- switch ( qualifiedModuleName . ComponentType )
58
- {
59
- case ComponentType . Document :
60
- var parenthesizedName = string . Empty ;
61
- var state = DocumentState . Inaccessible ;
62
- using ( var app = vbe . HostApplication ( ) )
63
- {
64
- if ( app != null )
65
- {
66
- var document = app . GetDocument ( qualifiedModuleName ) ;
67
- parenthesizedName = document ? . DocumentName ?? string . Empty ;
68
- state = document ? . State ?? DocumentState . Inaccessible ;
69
- }
70
- }
71
-
72
- if ( state == DocumentState . DesignView && ContainsBuiltinDocumentPropertiesProperty ( projectsProvider ) )
73
- {
74
- CodeExplorerItemViewModel node = this ;
75
- while ( node . Parent != null )
76
- {
77
- node = node . Parent ;
78
- }
79
-
80
- if ( node is CodeExplorerProjectViewModel projectNode )
81
- {
82
- projectNode . SetParenthesizedName ( parenthesizedName ) ;
83
- }
84
- }
85
- else
86
- {
87
- if ( ! string . IsNullOrWhiteSpace ( parenthesizedName ) )
88
- {
89
- _name += " (" + parenthesizedName + ")" ;
90
- }
91
- }
92
- break ;
35
+ _vbe = vbe ;
36
+ SetName ( ) ;
37
+ AddNewChildren ( declarations . ToList ( ) ) ;
38
+ }
93
39
94
- case ComponentType . ResFile :
95
- var fileName = Declaration . IdentifierName . Split ( '\\ ' ) . Last ( ) ;
96
- _name = $ "{ CodeExplorerUI . CodeExplorer_ResourceFileText } ({ fileName } )";
97
- break ;
40
+ private string _name ;
41
+ public override string Name => _name ;
98
42
99
- case ComponentType . RelatedDocument :
100
- _name = $ "({ Declaration . IdentifierName . Split ( '\\ ' ) . Last ( ) } )";
101
- break ;
43
+ public override string NameWithSignature => $ "{ Name } { ( IsPredeclared ? " (Predeclared)" : string . Empty ) } ";
102
44
103
- default :
104
- _name = Declaration . IdentifierName ;
105
- break ;
106
- }
107
- }
108
- catch
109
- {
110
- // gotcha! (this means that the property either doesn't exist or we weren't able to get it for some reason)
111
- }
112
- }
45
+ public override Comparer < ICodeExplorerNode > SortComparer => CodeExplorerItemComparer . ComponentType ;
113
46
114
- private bool ContainsBuiltinDocumentPropertiesProperty ( IProjectsProvider projectsProvider )
115
- {
116
- var component = projectsProvider . Component ( Declaration . QualifiedName . QualifiedModuleName ) ;
117
- using ( var properties = component . Properties )
118
- {
119
- foreach ( var property in properties )
120
- using ( property )
121
- {
122
- if ( property . Name == "BuiltinDocumentProperties" )
123
- {
124
- return true ;
125
- }
126
- }
47
+ public bool IsPredeclared => Declaration != null &&
48
+ Declaration . IsUserDefined &&
49
+ Declaration . DeclarationType == DeclarationType . ClassModule &&
50
+ Declaration . QualifiedName . QualifiedModuleName . ComponentType != ComponentType . Document &&
51
+ Declaration . Attributes . HasPredeclaredIdAttribute ( out _ ) ;
127
52
128
- return false ;
129
- }
130
- }
53
+ public bool IsTestModule => Declaration . DeclarationType == DeclarationType . ProceduralModule
54
+ && Declaration . Annotations . Any ( annotation => annotation . AnnotationType == AnnotationType . TestModule ) ;
131
55
132
- private bool _isErrorState ;
133
- public bool IsErrorState
56
+ public override void Synchronize ( List < Declaration > updated )
134
57
{
135
- get => _isErrorState ;
136
- set
58
+ base . Synchronize ( updated ) ;
59
+ if ( Declaration is null )
137
60
{
138
- _isErrorState = value ;
139
- _icon = GetImageSource ( CodeExplorerUI . cross_circle ) ;
140
-
141
-
142
- foreach ( var item in Items )
143
- {
144
- ( ( CodeExplorerMemberViewModel ) item ) . ParentComponentHasError ( ) ;
145
- }
146
-
147
- OnPropertyChanged ( ) ;
148
- // ReSharper disable ExplicitCallerInfoArgument
149
- OnPropertyChanged ( "CollapsedIcon" ) ;
150
- OnPropertyChanged ( "ExpandedIcon" ) ;
151
- // ReSharper restore ExplicitCallerInfoArgument
61
+ return ;
152
62
}
63
+
64
+ // Document modules might have had the underlying COM object renamed since the last reparse. Let's check...
65
+ SetName ( ) ;
153
66
}
154
67
155
- public bool IsTestModule
68
+ protected override void AddNewChildren ( List < Declaration > updated )
156
69
{
157
- get
70
+ if ( updated is null )
158
71
{
159
- return Declaration . DeclarationType == DeclarationType . ProceduralModule
160
- && Declaration . Annotations . Any ( annotation => annotation . AnnotationType == AnnotationType . TestModule ) ;
72
+ return ;
161
73
}
162
- }
163
-
164
- private readonly string _name ;
165
- public override string Name => _name ;
166
-
167
- public override string NameWithSignature =>
168
- $ "{ _name } { ( IsPredeclared ? " (Predeclared)" : string . Empty ) } ";
169
74
170
- private bool IsPredeclared => Declaration != null &&
171
- DeclarationType == DeclarationType . ClassModule &&
172
- Declaration . Attributes . HasPredeclaredIdAttribute ( out _ ) ;
173
-
174
- public override QualifiedSelection ? QualifiedSelection => Declaration . QualifiedSelection ;
175
-
176
- private ComponentType ComponentType => Declaration . QualifiedName . QualifiedModuleName . ComponentType ;
75
+ AddChildren ( updated . GroupBy ( item => item . Scope ) . SelectMany ( grouping =>
76
+ grouping . Where ( item =>
77
+ item . ParentDeclaration != null && item . ParentScope == Declaration . Scope &&
78
+ MemberTypes . Contains ( item . DeclarationType ) )
79
+ . Select ( item => new CodeExplorerMemberViewModel ( this , item , grouping ) ) ) ) ;
80
+ }
177
81
178
- private static readonly IDictionary < ComponentType , DeclarationType > DeclarationTypes = new Dictionary < ComponentType , DeclarationType >
82
+ private void SetName ( )
179
83
{
180
- { ComponentType . ClassModule , DeclarationType . ClassModule } ,
181
- { ComponentType . StandardModule , DeclarationType . ProceduralModule } ,
182
- { ComponentType . Document , DeclarationType . Document } ,
183
- { ComponentType . UserForm , DeclarationType . UserForm } ,
184
- { ComponentType . VBForm , DeclarationType . VbForm } ,
185
- { ComponentType . MDIForm , DeclarationType . MdiForm } ,
186
- { ComponentType . UserControl , DeclarationType . UserControl } ,
187
- { ComponentType . DocObject , DeclarationType . DocObject } ,
188
- { ComponentType . ResFile , DeclarationType . ResFile } ,
189
- { ComponentType . RelatedDocument , DeclarationType . RelatedDocument } ,
190
- { ComponentType . PropPage , DeclarationType . PropPage } ,
191
- { ComponentType . ActiveXDesigner , DeclarationType . ActiveXDesigner }
192
- } ;
84
+ _name = Declaration ? . IdentifierName ?? string . Empty ;
193
85
194
- private DeclarationType DeclarationType
195
- {
196
- get
86
+ if ( Declaration is null )
197
87
{
198
- var result = DeclarationType . ClassModule ;
199
- try
200
- {
201
- DeclarationTypes . TryGetValue ( ComponentType , out result ) ;
202
- }
203
- catch ( COMException exception )
204
- {
205
- Console . WriteLine ( exception ) ;
206
- }
207
- return result ;
88
+ return ;
208
89
}
209
- }
210
90
211
- private static readonly BitmapImage PredeclaredIcon = GetImageSource ( CodeExplorerUI . ObjectClassPredeclared ) ;
212
- private static readonly BitmapImage OopsIcon = GetImageSource ( CodeExplorerUI . status_offline ) ;
91
+ var qualifiedModuleName = Declaration . QualifiedName . QualifiedModuleName ;
213
92
214
- private static readonly IDictionary < DeclarationType , BitmapImage > Icons = new Dictionary < DeclarationType , BitmapImage >
215
- {
216
- { DeclarationType . ClassModule , GetImageSource ( CodeExplorerUI . ObjectClass ) } ,
217
- { DeclarationType . ProceduralModule , GetImageSource ( CodeExplorerUI . ObjectModule ) } ,
218
- { DeclarationType . UserForm , GetImageSource ( CodeExplorerUI . ProjectForm ) } ,
219
- { DeclarationType . Document , GetImageSource ( CodeExplorerUI . document_office ) } ,
220
- { DeclarationType . VbForm , GetImageSource ( CodeExplorerUI . ProjectForm ) } ,
221
- { DeclarationType . MdiForm , GetImageSource ( CodeExplorerUI . MdiForm ) } ,
222
- { DeclarationType . UserControl , GetImageSource ( CodeExplorerUI . ui_scroll_pane_form ) } ,
223
- { DeclarationType . DocObject , GetImageSource ( CodeExplorerUI . document_globe ) } ,
224
- { DeclarationType . PropPage , GetImageSource ( CodeExplorerUI . ui_tab_content ) } ,
225
- { DeclarationType . ActiveXDesigner , GetImageSource ( CodeExplorerUI . pencil_ruler ) } ,
226
- { DeclarationType . ResFile , GetImageSource ( CodeExplorerUI . document_block ) } ,
227
- { DeclarationType . RelatedDocument , GetImageSource ( CodeExplorerUI . document_import ) }
228
- } ;
229
-
230
- private void SetIcon ( )
231
- {
232
- if ( IsPredeclared )
93
+ try
233
94
{
234
- _icon = PredeclaredIcon ;
235
- return ;
236
- }
95
+ switch ( qualifiedModuleName . ComponentType )
96
+ {
97
+ case ComponentType . Document :
237
98
238
- if ( Icons . ContainsKey ( DeclarationType ) )
99
+ using ( var app = _vbe . HostApplication ( ) )
100
+ {
101
+ var parenthesized = app ? . GetDocument ( qualifiedModuleName ) ? . DocumentName ?? string . Empty ;
102
+ _name = string . IsNullOrEmpty ( parenthesized ) ? _name : $ "{ _name } ({ parenthesized } )";
103
+ }
104
+
105
+ break ;
106
+ case ComponentType . ResFile :
107
+ _name = string . IsNullOrEmpty ( _name )
108
+ ? CodeExplorerUI . CodeExplorer_ResourceFileText
109
+ : $ "{ CodeExplorerUI . CodeExplorer_ResourceFileText } ({ Path . GetFileName ( _name ) } )";
110
+ break ;
111
+ case ComponentType . RelatedDocument :
112
+ _name = string . IsNullOrEmpty ( _name ) ? string . Empty : Path . GetFileName ( _name ) ;
113
+ break ;
114
+ }
115
+ }
116
+ catch
239
117
{
240
- _icon = Icons [ DeclarationType ] ;
241
- return ;
118
+ //Ignored;
242
119
}
243
120
244
- _icon = OopsIcon ;
121
+ OnNameChanged ( ) ;
245
122
}
246
-
247
- private BitmapImage _icon ;
248
- public override BitmapImage CollapsedIcon => _icon ;
249
- public override BitmapImage ExpandedIcon => _icon ;
250
123
}
251
124
}
0 commit comments