1
+ using System ;
2
+ using System . ComponentModel . Composition ;
3
+ using FineCodeCoverage . Options ;
4
+ using Microsoft ;
5
+ using Microsoft . VisualStudio ;
6
+ using Microsoft . VisualStudio . Shell ;
7
+ using Microsoft . VisualStudio . Shell . Interop ;
8
+
9
+ namespace FineCodeCoverage . Impl
10
+ {
11
+ [ Export ( typeof ( ICoverageColoursProvider ) ) ]
12
+ [ Export ( typeof ( ICoverageColours ) ) ]
13
+ internal class CoverageColorProvider : ICoverageColoursProvider , ICoverageColours
14
+ {
15
+ private readonly IVsFontAndColorStorage fontAndColorStorage ;
16
+ private Guid categoryWithCoverage = Guid . Parse ( "ff349800-ea43-46c1-8c98-878e78f46501" ) ;
17
+ private uint storeFlags = ( uint ) ( __FCSTORAGEFLAGS . FCSF_READONLY | __FCSTORAGEFLAGS . FCSF_LOADDEFAULTS | __FCSTORAGEFLAGS . FCSF_NOAUTOCOLORS | __FCSTORAGEFLAGS . FCSF_PROPAGATECHANGES ) ;
18
+ private System . Windows . Media . Color defaultCoverageTouchedArea = System . Windows . Media . Colors . Green ;
19
+ private System . Windows . Media . Color defaultCoverageNotTouchedArea = System . Windows . Media . Colors . Red ;
20
+ private System . Windows . Media . Color defaultCoveragePartiallyTouchedArea = System . Windows . Media . Color . FromRgb ( 255 , 165 , 0 ) ;
21
+ private System . Windows . Media . Color coverageTouchedArea ;
22
+ private System . Windows . Media . Color coverageNotTouchedArea ;
23
+ private System . Windows . Media . Color coveragePartiallyTouchedArea ;
24
+ public System . Windows . Media . Color CoverageTouchedArea {
25
+ get {
26
+ UpdateFromFontsAndColorsIfNecessary ( ) ;
27
+ return coverageTouchedArea ;
28
+ }
29
+ private set
30
+ {
31
+ coverageTouchedArea = value ;
32
+ }
33
+ }
34
+
35
+ public System . Windows . Media . Color CoverageNotTouchedArea {
36
+ get
37
+ {
38
+ UpdateFromFontsAndColorsIfNecessary ( ) ;
39
+ return coverageNotTouchedArea ;
40
+ }
41
+ private set
42
+ {
43
+ coverageNotTouchedArea = value ;
44
+ }
45
+ }
46
+
47
+ public System . Windows . Media . Color CoveragePartiallyTouchedArea {
48
+ get
49
+ {
50
+ UpdateFromFontsAndColorsIfNecessary ( ) ;
51
+ return coveragePartiallyTouchedArea ;
52
+ }
53
+ private set
54
+ {
55
+ coveragePartiallyTouchedArea = value ;
56
+ }
57
+
58
+ }
59
+
60
+ private bool coverageColoursFromFontsAndColours ;
61
+ private bool requiresFromFontsAndColours ;
62
+
63
+ [ ImportingConstructor ]
64
+ public CoverageColorProvider ( [ Import ( typeof ( SVsServiceProvider ) ) ] IServiceProvider serviceProvider , IAppOptionsProvider appOptionsProvider )
65
+ {
66
+ ThreadHelper . ThrowIfNotOnUIThread ( ) ;
67
+ fontAndColorStorage = ( IVsFontAndColorStorage ) serviceProvider . GetService ( typeof ( IVsFontAndColorStorage ) ) ;
68
+ Assumes . Present ( fontAndColorStorage ) ;
69
+ coverageColoursFromFontsAndColours = appOptionsProvider . Get ( ) . CoverageColoursFromFontsAndColours ;
70
+ UseDefaultColoursIfNotFontsAndColours ( ) ;
71
+ appOptionsProvider . OptionsChanged += AppOptionsProvider_OptionsChanged ;
72
+ }
73
+
74
+ private void AppOptionsProvider_OptionsChanged ( IAppOptions appOptions )
75
+ {
76
+ coverageColoursFromFontsAndColours = appOptions . CoverageColoursFromFontsAndColours ;
77
+ UseDefaultColoursIfNotFontsAndColours ( ) ;
78
+ }
79
+
80
+ private void UseDefaultColoursIfNotFontsAndColours ( )
81
+ {
82
+ if ( ! coverageColoursFromFontsAndColours )
83
+ {
84
+ CoverageTouchedArea = defaultCoverageTouchedArea ;
85
+ CoverageNotTouchedArea = defaultCoverageNotTouchedArea ;
86
+ CoveragePartiallyTouchedArea = defaultCoveragePartiallyTouchedArea ;
87
+ }
88
+ }
89
+
90
+ public void UpdateRequired ( )
91
+ {
92
+ requiresFromFontsAndColours = true ;
93
+ }
94
+
95
+ private void UpdateFromFontsAndColorsIfNecessary ( )
96
+ {
97
+ if ( coverageColoursFromFontsAndColours && requiresFromFontsAndColours )
98
+ {
99
+ UpdateColoursFromFontsAndColors ( ) ;
100
+ }
101
+ }
102
+
103
+ private void UpdateColoursFromFontsAndColors ( )
104
+ {
105
+ ThreadHelper . ThrowIfNotOnUIThread ( ) ;
106
+ var success = fontAndColorStorage . OpenCategory ( ref categoryWithCoverage , storeFlags ) ;
107
+ if ( success == VSConstants . S_OK )
108
+ {
109
+ CoverageTouchedArea = GetColor ( "Coverage Touched Area" ) ;
110
+ CoverageNotTouchedArea = GetColor ( "Coverage Not Touched Area" ) ;
111
+ CoveragePartiallyTouchedArea = GetColor ( "Coverage Partially Touched Area" ) ;
112
+ }
113
+ fontAndColorStorage . CloseCategory ( ) ;
114
+ //throw ?
115
+ requiresFromFontsAndColours = false ;
116
+ }
117
+
118
+ private System . Windows . Media . Color GetColor ( string displayName )
119
+ {
120
+ ThreadHelper . ThrowIfNotOnUIThread ( ) ;
121
+ var touchAreaInfo = new ColorableItemInfo [ 1 ] ;
122
+ var getItemSuccess = fontAndColorStorage . GetItem ( displayName , touchAreaInfo ) ;
123
+ if ( getItemSuccess == VSConstants . S_OK )
124
+ {
125
+ return ParseColor ( touchAreaInfo [ 0 ] . crBackground ) ;
126
+ }
127
+ throw new Exception ( "Failed to get color" ) ;
128
+ }
129
+
130
+ private System . Windows . Media . Color ParseColor ( uint color )
131
+ {
132
+ var dcolor = System . Drawing . ColorTranslator . FromOle ( Convert . ToInt32 ( color ) ) ;
133
+ return System . Windows . Media . Color . FromArgb ( dcolor . A , dcolor . R , dcolor . G , dcolor . B ) ;
134
+ }
135
+
136
+
137
+ }
138
+
139
+ }
0 commit comments