Skip to content

Commit

Permalink
Merge pull request #51 from rubberduck-vba/next
Browse files Browse the repository at this point in the history
sync with merged PR's in main repo
  • Loading branch information
retailcoder committed Feb 28, 2016
2 parents 1009854 + 5f6abf6 commit ba6c9b4
Show file tree
Hide file tree
Showing 8 changed files with 207 additions and 68 deletions.
25 changes: 24 additions & 1 deletion RetailCoder.VBE/Common/ClipboardWriter.cs
Expand Up @@ -10,13 +10,36 @@ namespace Rubberduck.Common
public interface IClipboardWriter
{
void Write(string text);
void AppendData(string format, object data);
void Flush();
}

public class ClipboardWriter : IClipboardWriter
{
private DataObject _data;

public void Write(string text)
{
Clipboard.SetText(text);
this.AppendData(DataFormats.UnicodeText, text);
this.Flush();
}

public void AppendData(string format, object data)
{
if (_data == null)
{
_data = new DataObject();
}
_data.SetData(format, data);
}

public void Flush()
{
if (_data != null)
{
Clipboard.SetDataObject(_data, true);
_data = null;
}
}
}
}
139 changes: 139 additions & 0 deletions RetailCoder.VBE/Common/ExportFormatter.cs
@@ -0,0 +1,139 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;

namespace Rubberduck.Common
{
public static class ExportFormatter
{
public static string Csv(object[][] data, string Title)
{
string s = "";
string[] rows = new string[data.Length];
for (var r = 0; r < data.Length; r++)
{
string[] row = new string[data[r].Length];
for (var c = 0; c < data[r].Length; c++)
{
row[c] = CsvEncode(data[r][c]);
}
rows[r] = string.Join(",", row);
}
return CsvEncode(Title) + Environment.NewLine + string.Join(Environment.NewLine, rows);
}

private static string CsvEncode(object value)
{
string s = "";
if (value is string)
{
s = value.ToString();

//Escape commas
if (s.IndexOf(",") >= 0 || s.IndexOf("\"") >= 0)
{
//replace CrLf with Lf
s = s.Replace("\r\n", "\n");

//escape double-quotes
s = "\"" + s.Replace("\"", "\"\"") + "\"";
}
}
else
{
if (value != null)
{
s = value.ToString();
}
}
return s;
}

public static string HtmlClipboardFragment(object[][] data, string Title)
{
const string OffsetFormat = "0000000000";
const string CFHeaderTemplate =
"Version:1.0\r\n" +
"StartHTML:{0}\r\n" +
"EndHTML:{1}\r\n" +
"StartFragment:{2}\r\n" +
"EndFragment:{3}\r\n";

const string HtmlHeader =
"<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\r\n" +
"<html xmlns=\"http://www.w3.org/1999/xhtml\">\r\n" +
"<body>\r\n" +
"<!--StartFragment-->\r\n";

const string HtmlFooter =
"<!--EndFragment-->\r\n" +
"</body>\r\n" +
"</html>";

string html = ExportFormatter.HtmlTable(data,Title);

int CFHeaderLength = string.Format(CFHeaderTemplate, OffsetFormat, OffsetFormat, OffsetFormat, OffsetFormat).Length;
int startFragment = CFHeaderLength + HtmlHeader.Length;
int endFragment = startFragment + html.Length;
int endHTML = endFragment + HtmlFooter.Length;

string CfHtml = string.Format(CFHeaderTemplate, CFHeaderLength.ToString(OffsetFormat), endHTML.ToString(OffsetFormat), startFragment.ToString(OffsetFormat), endFragment.ToString(OffsetFormat));

return CfHtml + HtmlHeader + html + HtmlFooter;
}

public static string HtmlTable(object[][] data, string Title)
{
string[] rows = new string[data.Length];
for (var r = 0; r < data.Length; r++)
{
string[] row = new string[data[r].Length];
for (var c = 0; c < data[r].Length; c++)
{
row[c] = HtmlCell(data[r][c], r == data.Length - 1, c == 0 ? 5: 10);
}
rows[r] = " <tr>\r\n" + string.Join(Environment.NewLine, row) + "\r\n</tr>";
}
return "<table cellspacing=\"0\">\r\n" + string.Join(Environment.NewLine, rows) + "\r\n</table>\r\n";
}

private static string HtmlCell(object value, bool BottomBorder = false, int LeftPadding = 10)
{
const string td = " <td style=\"{0}\"><div style=\"{1}\">{2}</div></td>";
const string nbsp = "&#160;";

string CellContent = nbsp;
bool AlignLeft = true;
string Border = BottomBorder ? "0.5pt" : "";
if (value != null)
{
CellContent = value.ToString().HtmlEncode();
AlignLeft = value is string;
}
return string.Format(td, TdStyle(AlignLeft, Border), TdDivStyle(LeftPadding), CellContent);
}

private static string TdStyle(bool AlignLeft = true, string BorderBottom = "")
{
const string tdstyle = "vertical-align: bottom; ";

string sAlign = AlignLeft ? "text-align: left; " : "text-align: right; ";
string sBorder = BorderBottom.Length > 0 ? "border-bottom: " + BorderBottom + " solid #000000; " : "";

return tdstyle + sAlign + sBorder;
}

private static string TdDivStyle(int LeftPadding)
{
return "vertical-align: bottom; padding-left: " + LeftPadding + "px; ";
}

private static string HtmlEncode(this string value)
{
return WebUtility.HtmlEncode(value.ToString());
}
}
}
1 change: 1 addition & 0 deletions RetailCoder.VBE/Inspections/ICodeInspectionResult.cs
Expand Up @@ -14,5 +14,6 @@ public interface ICodeInspectionResult : IComparable<ICodeInspectionResult>, ICo
QualifiedSelection QualifiedSelection { get; }
IInspection Inspection { get; }
string ToCsvString();
object[] ToArray();
}
}
8 changes: 7 additions & 1 deletion RetailCoder.VBE/Inspections/InspectionResultBase.cs
Expand Up @@ -106,11 +106,17 @@ public int CompareTo(object obj)
return CompareTo(obj as ICodeInspectionResult);
}

public object[] ToArray()
{
var module = QualifiedSelection.QualifiedName;
return new object[] {Inspection.Severity.ToString(), Description, module.ProjectName, module.ComponentName, QualifiedSelection.Selection.StartLine };
}

public string ToCsvString()
{
var module = QualifiedSelection.QualifiedName;
return string.Format(
"{0}, {1}, {2}, {3}, {4}",
"\"{0}\",\"{1}\",\"{2}\",\"{3}\",{4}",
Inspection.Severity,
Description,
module.ProjectName,
Expand Down
2 changes: 1 addition & 1 deletion RetailCoder.VBE/Rubberduck.csproj
Expand Up @@ -277,6 +277,7 @@
<ItemGroup>
<Compile Include="AppMenu.cs" />
<Compile Include="AutoSave\AutoSave.cs" />
<Compile Include="Common\ExportFormatter.cs" />
<Compile Include="Common\ClipboardWriter.cs" />
<Compile Include="Common\DeclarationExtensions.cs" />
<Compile Include="Common\Dispatch\DispatcherEventArgs.cs" />
Expand Down Expand Up @@ -554,7 +555,6 @@
<DependentUpon>SearchView.xaml</DependentUpon>
</Compile>
<Compile Include="UI\FolderBrowser.cs" />
<Compile Include="UI\GeneralConverters\EqualWidthConverter.cs" />
<Compile Include="UI\IMessageBox.cs" />
<Compile Include="UI\ParserErrors\ParseErrorListItem.cs" />
<Compile Include="UI\Refactorings\EncapsulateFieldDialog.cs">
Expand Down
18 changes: 15 additions & 3 deletions RetailCoder.VBE/UI/CodeInspections/InspectionResultsViewModel.cs
Expand Up @@ -2,9 +2,11 @@
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.Globalization;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Data;
using System.Windows.Input;
using System.Windows.Threading;
Expand Down Expand Up @@ -283,14 +285,24 @@ private void ExecuteCopyResultsCommand(object parameter)
{
return;
}
var aResults = _results.Select(result => result.ToArray()).ToArray();

var results = string.Join("\n", _results.Select(result => result.ToString() + Environment.NewLine).ToArray());
var resource = _results.Count == 1
? RubberduckUI.CodeInspections_NumberOfIssuesFound_Singular
: RubberduckUI.CodeInspections_NumberOfIssuesFound_Plural;
var text = string.Format(resource, DateTime.Now, _results.Count) + Environment.NewLine + results;

_clipboard.Write(text);
var title = string.Format(resource, DateTime.Now.ToString(CultureInfo.InstalledUICulture), _results.Count);

var textResults = title + Environment.NewLine + string.Join("", _results.Select(result => result.ToString() + Environment.NewLine).ToArray());
var csvResults = ExportFormatter.Csv(aResults, title);
var htmlResults = ExportFormatter.HtmlClipboardFragment(aResults, title);

//Add the formats from richest formatting to least formatting
_clipboard.AppendData(DataFormats.Html, htmlResults);
_clipboard.AppendData(DataFormats.CommaSeparatedValue, csvResults);
_clipboard.AppendData(DataFormats.UnicodeText, textResults);

_clipboard.Flush();
}

private bool CanExecuteCopyResultsCommand(object parameter)
Expand Down
20 changes: 0 additions & 20 deletions RetailCoder.VBE/UI/GeneralConverters/EqualWidthConverter.cs

This file was deleted.

62 changes: 20 additions & 42 deletions RetailCoder.VBE/UI/Settings/SettingsControl.xaml
Expand Up @@ -5,13 +5,10 @@
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:settings="clr-namespace:Rubberduck.UI.Settings"
xmlns:converters="clr-namespace:Rubberduck.UI.Settings.Converters"
xmlns:generalConverters="clr-namespace:Rubberduck.UI.GeneralConverters"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="600"
d:DataContext="{d:DesignInstance {x:Type settings:SettingsControlViewModel}, IsDesignTimeCreatable=False}">
<UserControl.Resources>
<generalConverters:EqualWidthConverter x:Key="EqualWidthConverter" />

<LinearGradientBrush x:Key="{x:Static SystemColors.HighlightBrushKey}" EndPoint="0,1" StartPoint="0,0">
<GradientStop Color="#FFD9F4FF" Offset="0"/>
<GradientStop Color="#FF9BDDFB" Offset="1"/>
Expand Down Expand Up @@ -95,52 +92,33 @@
BorderThickness="0, 1, 0, 0">
<DockPanel VerticalAlignment="Center"
Height="40"
Background="{x:Static SystemColors.ControlDarkBrush}">
<StackPanel Orientation="Horizontal"
HorizontalAlignment="Right">
<Button Name="ResetButton"
Content="{Resx ResxName=Rubberduck.UI.RubberduckUI, Key=Settings_ResetSettings}"
Background="{x:Static SystemColors.ControlDarkBrush}"
Grid.IsSharedSizeScope="True">
<Grid HorizontalAlignment="Right"
Margin="5,0">
<Grid.ColumnDefinitions>
<ColumnDefinition SharedSizeGroup="SettingsButtons" />
<ColumnDefinition SharedSizeGroup="SettingsButtons" />
<ColumnDefinition SharedSizeGroup="SettingsButtons" />
</Grid.ColumnDefinitions>
<Button Content="{Resx ResxName=Rubberduck.UI.RubberduckUI, Key=Settings_ResetSettings}"
Height="20"
HorizontalAlignment="Right"
Margin="20,0"
Padding="10,0"
Command="{Binding ResetButtonCommand}">
<Button.MinWidth>
<MultiBinding Converter="{StaticResource EqualWidthConverter}">
<Binding ElementName="OkButton" Path="ActualWidth" />
<Binding ElementName="CancelButton" Path="ActualWidth" />
</MultiBinding>
</Button.MinWidth>
</Button>
<Button Name="OkButton"
Content="{Resx ResxName=Rubberduck.UI.RubberduckUI, Key=OK}"
Margin="10,0"
Padding="5,0"
Command="{Binding ResetButtonCommand}" />
<Button Content="{Resx ResxName=Rubberduck.UI.RubberduckUI, Key=OK}"
Grid.Column="1"
Height="20"
HorizontalAlignment="Left"
Margin="5,0"
Padding="10,0"
Command="{Binding OKButtonCommand}">
<Button.MinWidth>
<MultiBinding Converter="{StaticResource EqualWidthConverter}">
<Binding ElementName="CancelButton" Path="ActualWidth" />
<Binding ElementName="ResetButton" Path="ActualWidth" />
</MultiBinding>
</Button.MinWidth>
</Button>
<Button Name="CancelButton"
Content="{Resx ResxName=Rubberduck.UI.RubberduckUI, Key=CancelButtonText}"
Command="{Binding OKButtonCommand}" />
<Button Content="{Resx ResxName=Rubberduck.UI.RubberduckUI, Key=CancelButtonText}"
Grid.Column="2"
Height="20"
HorizontalAlignment="Right"
Margin="5,0"
Padding="10,0"
Command="{Binding CancelButtonCommand}">
<Button.MinWidth>
<MultiBinding Converter="{StaticResource EqualWidthConverter}">
<Binding ElementName="OkButton" Path="ActualWidth" />
<Binding ElementName="ResetButton" Path="ActualWidth" />
</MultiBinding>
</Button.MinWidth>
</Button>
</StackPanel>
Command="{Binding CancelButtonCommand}" />
</Grid>
</DockPanel>
</Border>
</Grid>
Expand Down

0 comments on commit ba6c9b4

Please sign in to comment.