Skip to content

Commit df92cef

Browse files
authored
Themed colours (#202)
* remove duplicate ico * themed colours
1 parent 78ccff1 commit df92cef

15 files changed

+754
-118
lines changed

FineCodeCoverage/FineCodeCoverage.csproj

+10
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,10 @@
7373
<Link>Resources\LICENSE</Link>
7474
<IncludeInVSIX>true</IncludeInVSIX>
7575
</Content>
76+
<Content Include="..\Shared Files\Resources\reportparts.xml">
77+
<Link>Resources\reportparts.xml</Link>
78+
<IncludeInVSIX>true</IncludeInVSIX>
79+
</Content>
7680
<Content Include="ZippedTools\coverlet.collector.3.0.3.zip">
7781
<IncludeInVSIX>true</IncludeInVSIX>
7882
</Content>
@@ -113,6 +117,9 @@
113117
<PackageReference Include="CliWrap">
114118
<Version>3.2.2</Version>
115119
</PackageReference>
120+
<PackageReference Include="ExCSS">
121+
<Version>4.1.1</Version>
122+
</PackageReference>
116123
<PackageReference Include="Microsoft.Build.Locator">
117124
<Version>1.4.1</Version>
118125
</PackageReference>
@@ -135,6 +142,9 @@
135142
<PackageReference Include="RSA.Fizzler.Systems.HtmlAgilityPack">
136143
<Version>1.0.0</Version>
137144
</PackageReference>
145+
<PackageReference Include="Svg">
146+
<Version>3.3.0</Version>
147+
</PackageReference>
138148
<PackageReference Include="System.Composition">
139149
<Version>5.0.1</Version>
140150
</PackageReference>

FineCodeCoverage2022/FineCodeCoverage2022.csproj

+10
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,10 @@
6565
<Link>OutputToolWindowPackage.vsct</Link>
6666
<ResourceName>Menus.ctmenu</ResourceName>
6767
</VSCTCompile>
68+
<Content Include="..\Shared Files\Resources\reportparts.xml">
69+
<Link>Resources\reportparts.xml</Link>
70+
<IncludeInVSIX>true</IncludeInVSIX>
71+
</Content>
6872
<Content Include="..\Shared Files\ZippedTools\coverlet.collector.3.0.3.zip">
6973
<Link>ZippedTools\coverlet.collector.3.0.3.zip</Link>
7074
<IncludeInVSIX>true</IncludeInVSIX>
@@ -111,6 +115,9 @@
111115
<PackageReference Include="CliWrap">
112116
<Version>3.2.2</Version>
113117
</PackageReference>
118+
<PackageReference Include="ExCSS">
119+
<Version>4.1.1</Version>
120+
</PackageReference>
114121
<PackageReference Include="Microsoft.Build.Locator">
115122
<Version>1.4.1</Version>
116123
</PackageReference>
@@ -133,6 +140,9 @@
133140
<PackageReference Include="RSA.Fizzler.Systems.HtmlAgilityPack">
134141
<Version>1.0.0</Version>
135142
</PackageReference>
143+
<PackageReference Include="Svg">
144+
<Version>3.3.0</Version>
145+
</PackageReference>
136146
<PackageReference Include="System.Composition">
137147
<Version>5.0.1</Version>
138148
</PackageReference>

FineCodeCoverageTests/FCCEngine_Tests.cs

+5-12
Original file line numberDiff line numberDiff line change
@@ -262,7 +262,7 @@ await ReloadSuitableCoverageProject(mockCoverageProject => {
262262
Assert.AreEqual(coverageProjectAfterCoverageOutputManager.CoverageOutputFolder, "Set by ICoverageToolOutputManager");
263263
}
264264

265-
[Test] // Not testing dark mode as ui will change
265+
[Test]
266266
public async Task Should_Run_Report_Generator_With_Output_Files_From_Coverage_For_Coverage_Projects_That_Have_Not_Failed()
267267
{
268268
var failedProject = CreateSuitableProject();
@@ -277,7 +277,6 @@ public async Task Should_Run_Report_Generator_With_Output_Files_From_Coverage_Fo
277277
It.Is<string[]>(
278278
coverOutputFiles => coverOutputFiles.Count() == 1 && coverOutputFiles.First() == passedProjectCoverageOutputFile),
279279
It.IsAny<string>(),
280-
It.IsAny<bool>(),
281280
true).Result).Returns(new ReportGeneratorResult { Success = true });
282281

283282
await ReloadInitializedCoverage(failedProject.Object, passedProject.Object);
@@ -290,7 +289,7 @@ public async Task Should_Run_Report_Generator_With_Output_Files_From_Coverage_Fo
290289
public async Task Should_Not_Run_ReportGenerator_If_No_Successful_Projects()
291290
{
292291
await ReloadInitializedCoverage();
293-
mocker.Verify<IReportGeneratorUtil>(rg => rg.GenerateAsync(It.IsAny<IEnumerable<string>>(),It.IsAny<string>(), It.IsAny<bool>(), It.IsAny<bool>()), Times.Never());
292+
mocker.Verify<IReportGeneratorUtil>(rg => rg.GenerateAsync(It.IsAny<IEnumerable<string>>(), It.IsAny<string>(), It.IsAny<bool>()), Times.Never());
294293
}
295294

296295
[Test]
@@ -303,7 +302,6 @@ public async Task Should_Process_ReportGenerator_Output_If_Success()
303302
rg.GenerateAsync(
304303
It.IsAny<IEnumerable<string>>(),
305304
It.IsAny<string>(),
306-
It.IsAny<bool>(),
307305
true).Result)
308306
.Returns(
309307
new ReportGeneratorResult
@@ -314,7 +312,7 @@ public async Task Should_Process_ReportGenerator_Output_If_Success()
314312
}
315313
);
316314

317-
mockReportGenerator.Setup(rg => rg.ProcessUnifiedHtml("Unified html",It.IsAny<string>(), It.IsAny<bool>()));
315+
mockReportGenerator.Setup(rg => rg.ProcessUnifiedHtml("Unified html", It.IsAny<string>()));
318316

319317
await ReloadInitializedCoverage(passedProject.Object);
320318
mocker.Verify<ICoberturaUtil>(coberturaUtil => coberturaUtil.ProcessCoberturaXml("Unified xml file"));
@@ -331,7 +329,6 @@ public async Task Should_Not_Process_ReportGenerator_Output_If_Failure()
331329
rg.GenerateAsync(
332330
It.IsAny<IEnumerable<string>>(),
333331
It.IsAny<string>(),
334-
It.IsAny<bool>(),
335332
true).Result)
336333
.Returns(
337334
new ReportGeneratorResult
@@ -480,7 +477,6 @@ private void VerifyClearUIEvents(int eventNumber)
480477
rg.GenerateAsync(
481478
It.Is<IEnumerable<string>>(coverOutputFiles => coverOutputFiles.Count() == 1 && coverOutputFiles.First() == coverageProject.CoverageOutputFile),
482479
It.IsAny<string>(),
483-
It.IsAny<bool>(),
484480
true).Result)
485481
.Returns(
486482
new ReportGeneratorResult
@@ -491,8 +487,7 @@ private void VerifyClearUIEvents(int eventNumber)
491487
);
492488

493489
var reportGeneratedHtmlContent = "<somehtml/>";
494-
mockReportGenerator.Setup(rg => rg.ProcessUnifiedHtml("Unified", It.IsAny<string>(), It.IsAny<bool>())).Returns(reportGeneratedHtmlContent);
495-
490+
mockReportGenerator.Setup(rg => rg.ProcessUnifiedHtml("Unified", It.IsAny<string>())).Returns(reportGeneratedHtmlContent);
496491
List<CoverageLine> coverageLines = new List<CoverageLine>() { new CoverageLine() };
497492
mocker.GetMock<ICoberturaUtil>().Setup(coberturaUtil => coberturaUtil.CoverageLines).Returns(coverageLines);
498493
if (noCoverageProjects)
@@ -517,7 +512,6 @@ private async Task ThrowReadingReportHtml()
517512
rg.GenerateAsync(
518513
It.IsAny<IEnumerable<string>>(),
519514
It.IsAny<string>(),
520-
It.IsAny<bool>(),
521515
true).Result)
522516
.Returns(
523517
new ReportGeneratorResult
@@ -527,7 +521,6 @@ private async Task ThrowReadingReportHtml()
527521
);
528522

529523
var badPath = "^&$!";
530-
//mockReportGenerator.Setup(rg => rg.ProcessUnifiedHtml(It.IsAny<string>(), It.IsAny<bool>(), out badPath));
531524

532525
List<CoverageLine> coverageLines = new List<CoverageLine>() { new CoverageLine() };
533526
mocker.GetMock<ICoberturaUtil>().Setup(coberturaUtil => coberturaUtil.CoverageLines).Returns(coverageLines);
@@ -572,8 +565,8 @@ private void SetUpSuccessfulRunReportGenerator()
572565
.Setup(rg => rg.GenerateAsync(
573566
It.IsAny<IEnumerable<string>>(),
574567
It.IsAny<string>(),
575-
It.IsAny<bool>(),
576568
It.IsAny<bool>()
569+
//It.IsAny<bool>()
577570
).Result)
578571
.Returns(new ReportGeneratorResult { Success = true });
579572
}
Binary file not shown.
+26
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<ReportParts>
3+
<ReportPart Name="ScrollBarArrowColour" SelectedThemeColourName="EnvironmentColors.ScrollBarArrowBackgroundColorKey" />
4+
<ReportPart Name="ScrollBarTrackColour" SelectedThemeColourName="EnvironmentColors.ScrollBarBackgroundColorKey" />
5+
<ReportPart Name="ScrollBarThumbColour" SelectedThemeColourName="EnvironmentColors.ScrollBarThumbBackgroundColorKey" />
6+
<ReportPart Name="ComboBoxColour" SelectedThemeColourName="CommonControlsColors.ComboBoxBackgroundColorKey" />
7+
<ReportPart Name="ComboBoxBorderColour" SelectedThemeColourName="CommonControlsColors.ComboBoxBorderColorKey" />
8+
<ReportPart Name="ComboBoxTextColour" SelectedThemeColourName="CommonControlsColors.ComboBoxTextColorKey" />
9+
<ReportPart Name="GrayCoverage" SelectedThemeColourName="EnvironmentColors.SystemGrayTextColorKey" />
10+
<ReportPart Name="BackgroundColour" SelectedThemeColourName="EnvironmentColors.ToolWindowBackgroundColorKey" />
11+
<ReportPart Name="FontColour" SelectedThemeColourName="EnvironmentColors.ToolWindowTextColorKey" />
12+
<ReportPart Name="TableBorderColour" SelectedThemeColourName="EnvironmentColors.GridLineColorKey" />
13+
<ReportPart Name="LinkColour" SelectedThemeColourName="EnvironmentColors.ControlLinkTextColorKey" />
14+
<ReportPart Name="CoverageTableHeaderFontColour" SelectedThemeColourName="EnvironmentColors.ToolWindowTextColorKey" />
15+
<ReportPart Name="CoverageTableActiveSortColour" SelectedThemeColourName="EnvironmentColors.SystemHighlightColorKey" />
16+
<ReportPart Name="CoverageTableInactiveSortColour" SelectedThemeColourName="EnvironmentColors.ToolWindowTextColorKey" />
17+
<ReportPart Name="CoverageTableExpandCollapseIconColour" SelectedThemeColourName="EnvironmentColors.ToolWindowTextColorKey" />
18+
<ReportPart Name="CoverageTableRowHoverBackgroundColour" SelectedThemeColourName="EnvironmentColors.ToolWindowBackgroundColorKey" />
19+
<ReportPart Name="TabBackgroundColour" SelectedThemeColourName="EnvironmentColors.FileTabBackgroundColorKey" />
20+
<ReportPart Name="DivHeaderBackgroundColour" SelectedThemeColourName="EnvironmentColors.ToolWindowBackgroundColorKey" />
21+
<ReportPart Name="HeaderFontColour" SelectedThemeColourName="EnvironmentColors.FileTabTextColorKey" />
22+
<ReportPart Name="HeaderBorderColour" SelectedThemeColourName="EnvironmentColors.CommandBarBorderColorKey" />
23+
<ReportPart Name="TextBoxColour" SelectedThemeColourName="CommonControlsColors.TextBoxBackgroundColorKey" />
24+
<ReportPart Name="TextBoxTextColour" SelectedThemeColourName="CommonControlsColors.TextBoxTextColorKey" />
25+
<ReportPart Name="TextBoxBorderColour" SelectedThemeColourName="CommonControlsColors.TextBoxBorderColorKey" />
26+
</ReportParts>

SharedProject/Core/FCCEngine.cs

+2-6
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,6 @@ internal class FCCEngine : IFCCEngine
2222
internal int InitializeWait { get; set; } = 5000;
2323
internal const string initializationFailedMessagePrefix = "Initialization failed. Please check the following error which may be resolved by reopening visual studio which will start the initialization process again.";
2424
private readonly object colorThemeService;
25-
private string CurrentTheme => $"{((dynamic)colorThemeService)?.CurrentTheme?.Name}".Trim();
26-
2725
private CancellationTokenSource cancellationTokenSource;
2826

2927
public event UpdateMarginTagsDelegate UpdateMarginTags;
@@ -162,9 +160,7 @@ private void UpdateUI(List<CoverageLine> coverageLines, string reportHtml)
162160
List<CoverageLine> coverageLines = null;
163161
string processedReport = null;
164162

165-
var darkMode = CurrentTheme.Equals("Dark", StringComparison.OrdinalIgnoreCase);
166-
167-
var result = await reportGeneratorUtil.GenerateAsync(coverOutputFiles,reportOutputFolder, darkMode, true);
163+
var result = await reportGeneratorUtil.GenerateAsync(coverOutputFiles,reportOutputFolder, true);
168164

169165
if (result.Success)
170166
{
@@ -173,7 +169,7 @@ private void UpdateUI(List<CoverageLine> coverageLines, string reportHtml)
173169
coverageLines = coberturaUtil.CoverageLines;
174170

175171
logger.Log("Processing report");
176-
processedReport = reportGeneratorUtil.ProcessUnifiedHtml(result.UnifiedHtml,reportOutputFolder, darkMode);
172+
processedReport = reportGeneratorUtil.ProcessUnifiedHtml(result.UnifiedHtml,reportOutputFolder);
177173
}
178174
return (coverageLines, processedReport);
179175
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.IO;
4+
using System.Linq;
5+
using System.Text;
6+
using ExCSS;
7+
using Svg;
8+
9+
namespace FineCodeCoverage.Engine.ReportGenerator
10+
{
11+
public class Base64ReportImage
12+
{
13+
private readonly string originalBase64;
14+
15+
public Base64ReportImage(string selector, string originalBase64)
16+
{
17+
this.Selector = selector;
18+
this.originalBase64 = originalBase64;
19+
}
20+
21+
public string Selector { get; }
22+
23+
public string Base64FromColour(string fillColor)
24+
{
25+
System.Drawing.Color fillColorColor;
26+
if (fillColor.StartsWith("#"))
27+
{
28+
fillColorColor = System.Drawing.ColorTranslator.FromHtml(fillColor);
29+
}
30+
else
31+
{
32+
fillColor = fillColor.Substring(5);
33+
fillColor = fillColor.Replace(")", string.Empty);
34+
var parts = fillColor.Split(new string[] { "," }, StringSplitOptions.None);
35+
fillColorColor = System.Drawing.Color.FromArgb(int.Parse(parts[3]), int.Parse(parts[0]), int.Parse(parts[1]), int.Parse(parts[2]));
36+
}
37+
38+
return Base64Full(GetBase64WithColor(fillColorColor));
39+
}
40+
41+
public void FillSvg(IEnumerable<IStyleRule> styleRules, string fillColor)
42+
{
43+
var rule = styleRules.First(r => r.SelectorText == Selector);
44+
rule.Style.BackgroundImage = Base64FromColour(fillColor);
45+
}
46+
47+
private string EncodeTo64(string toEncode)
48+
{
49+
byte[] toEncodeAsBytes
50+
51+
= System.Text.ASCIIEncoding.ASCII.GetBytes(toEncode);
52+
53+
string returnValue
54+
55+
= System.Convert.ToBase64String(toEncodeAsBytes);
56+
57+
return returnValue;
58+
}
59+
60+
private string GetBase64WithColor(System.Drawing.Color color)
61+
{
62+
string encoded = null;
63+
var bytes = Convert.FromBase64String(originalBase64);
64+
using (MemoryStream ms = new MemoryStream(bytes))
65+
{
66+
var svgDoc = SvgDocument.Open<SvgDocument>(ms);
67+
var child = svgDoc.Children[0];
68+
child.Fill = new SvgColourServer(color);
69+
var svgDocString = svgDoc.GetXML();
70+
encoded = EncodeTo64(svgDocString);
71+
}
72+
73+
return encoded;
74+
}
75+
76+
private string Base64Full(string base64)
77+
{
78+
return $"url(data:image/svg+xml;base64,{base64})";
79+
}
80+
}
81+
82+
}

0 commit comments

Comments
 (0)