Period Checkin

This commit is contained in:
Jordan Wages 2019-02-21 17:03:40 -06:00
parent f81e4f13da
commit be05120bdb
28 changed files with 1542 additions and 43 deletions

View File

@ -0,0 +1,38 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace mdfinder.hashprovider
{
public interface IHashProvider
{
/// <summary> Gets the name of the hash provider. </summary>
/// <value> The name of the hash provider. </value>
string Name { get; }
/// <summary> Gets the description of the hash provider. </summary>
/// <value> The description. </value>
string Description { get; }
/// <summary> Gets a value indicating if this hash provider is valid to use. </summary>
/// <value> The value indicating if the hash provider is valid. </value>
/// <remarks> This value can be used by hash providers to limit use of the provider. This can be used to create paid hash providers. </remarks>
bool IsValid { get; }
/// <summary> Gets or sets the priority this provider has when multiple providers support the same extension. </summary>
/// <value> The priority of the hash provider. </value>
int Priority { get; set; }
/// <summary> Gets the file extensions that this hash provider can work with. </summary>
/// <value> The file extensions the hash provider works with. </value>
IEnumerable<string> FileExtensions { get; }
/// <summary> Gets a hash from a file. </summary>
/// <param name="file"> The file to hash. </param>
/// <returns> The hash. </returns>
string GetHash(FileInfo file);
}
}

View File

@ -0,0 +1,36 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("mdfinder.hashprovider")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("mdfinder.hashprovider")]
[assembly: AssemblyCopyright("Copyright © 2019")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("f383e2d1-f62e-44cf-9e58-63542dcbd06e")]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]

View File

@ -0,0 +1,48 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{F383E2D1-F62E-44CF-9E58-63542DCBD06E}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>mdfinder.hashprovider</RootNamespace>
<AssemblyName>mdfinder.hashprovider</AssemblyName>
<TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<Deterministic>true</Deterministic>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="IHashProvider.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>

View File

@ -5,6 +5,8 @@ VisualStudioVersion = 15.0.28307.168
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "mdfinder", "mdfinder\mdfinder.csproj", "{E0F831FA-FCE1-471E-8767-D3FD7EDC7CCF}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "mdfinder.hashprovider", "mdfinder.hashprovider\mdfinder.hashprovider.csproj", "{F383E2D1-F62E-44CF-9E58-63542DCBD06E}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@ -15,6 +17,10 @@ Global
{E0F831FA-FCE1-471E-8767-D3FD7EDC7CCF}.Debug|Any CPU.Build.0 = Debug|Any CPU
{E0F831FA-FCE1-471E-8767-D3FD7EDC7CCF}.Release|Any CPU.ActiveCfg = Release|Any CPU
{E0F831FA-FCE1-471E-8767-D3FD7EDC7CCF}.Release|Any CPU.Build.0 = Release|Any CPU
{F383E2D1-F62E-44CF-9E58-63542DCBD06E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{F383E2D1-F62E-44CF-9E58-63542DCBD06E}.Debug|Any CPU.Build.0 = Debug|Any CPU
{F383E2D1-F62E-44CF-9E58-63542DCBD06E}.Release|Any CPU.ActiveCfg = Release|Any CPU
{F383E2D1-F62E-44CF-9E58-63542DCBD06E}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE

57
mdfinder/AboutWindow.xaml Normal file
View File

@ -0,0 +1,57 @@
<Window x:Class="mdfinder.AboutWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:mdfinder="clr-namespace:mdfinder"
xmlns:loc="clr-namespace:mdfinder.Localization"
mc:Ignorable="d"
Title="AboutWindow" Height="450" Width="800">
<DockPanel HorizontalAlignment="Center" VerticalAlignment="Center" Margin="32">
<StackPanel HorizontalAlignment="Center">
<StackPanel HorizontalAlignment="Center" Orientation="Horizontal" Height="128">
<ContentControl VerticalAlignment="Center" Template="{StaticResource MdfinderUIIcon}" />
<TextBlock VerticalAlignment="Center" Text="{x:Static loc:Localization.Title}" FontSize="64" FontFamily="Segoe UI Black" />
</StackPanel>
<WrapPanel HorizontalAlignment="Center">
<TextBlock Text="{x:Static loc:Localization.VersionLabel}" />
<TextBlock Text=" - "/>
<TextBlock Name="txtVersion" Text="0.0.0.0" />
</WrapPanel>
<TextBlock Text="{x:Static loc:Localization.AboutWindowDescription}" TextAlignment="Center" />
<Separator Margin="0,15" />
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Label Grid.Row="0" Grid.Column="0" VerticalAlignment="Center" Content="{x:Static loc:Localization.DevelopersLabel}" />
<StackPanel Grid.Row="0" Grid.Column="1" VerticalAlignment="Center">
<TextBlock HorizontalAlignment="Center">
<Hyperlink NavigateUri="https://github.com/wagesj45" RequestNavigate="Hyperlink_RequestNavigate">Jordan Wages</Hyperlink>
</TextBlock>
</StackPanel>
<Label Grid.Row="1" Grid.Column="0" VerticalAlignment="Center" Content="{x:Static loc:Localization.OpenSourceCreditsLabel}" />
<StackPanel Grid.Row="1" Grid.Column="1" VerticalAlignment="Center">
<TextBlock HorizontalAlignment="Center">
Octokit
| <Hyperlink NavigateUri="https://github.com/octokit/octokit.net" RequestNavigate="Hyperlink_RequestNavigate"><TextBlock Text="{x:Static loc:Localization.AboutWindowGithubLinkLabel}" /></Hyperlink>
| <Hyperlink NavigateUri="https://github.com/octokit/octokit.net/blob/master/LICENSE.txt" RequestNavigate="Hyperlink_RequestNavigate"><TextBlock Text="{x:Static loc:Localization.AboutWindowLicenseLinkLabel}" /></Hyperlink>
</TextBlock>
<TextBlock HorizontalAlignment="Center">
LiteDB
| <Hyperlink NavigateUri="https://github.com/mbdavid/LiteDB" RequestNavigate="Hyperlink_RequestNavigate"><TextBlock Text="{x:Static loc:Localization.AboutWindowGithubLinkLabel}" /></Hyperlink>
| <Hyperlink NavigateUri="https://github.com/mbdavid/LiteDB/blob/master/LICENSEw" RequestNavigate="Hyperlink_RequestNavigate"><TextBlock Text="{x:Static loc:Localization.AboutWindowLicenseLinkLabel}" /></Hyperlink>
</TextBlock>
</StackPanel>
</Grid>
<Separator Margin="0,10" />
<TextBlock Text="{x:Static mdfinder:OctokitWrapper.CurrentVersionStatusDescription}" TextAlignment="Center" Margin="0,10" />
<Button Name="btnOK" MaxWidth="50" Content="{x:Static loc:Localization.OKLabel}" Click="btnOK_Click"/>
</StackPanel>
</DockPanel>
</Window>

View File

@ -0,0 +1,49 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
namespace mdfinder
{
/// <summary>
/// Interaction logic for AboutWindow.xaml
/// </summary>
public partial class AboutWindow : Window
{
/// <summary> Default constructor. </summary>
public AboutWindow()
{
InitializeComponent();
this.txtVersion.Text = Assembly.GetExecutingAssembly().GetName().Version.ToString();
}
/// <summary> Event handler. Called by Hyperlink for request navigate events. </summary>
/// <param name="sender"> Source of the event. </param>
/// <param name="e"> Request navigate event information. </param>
private void Hyperlink_RequestNavigate(object sender, System.Windows.Navigation.RequestNavigateEventArgs e)
{
Process.Start(e.Uri.AbsoluteUri);
e.Handled = true;
}
/// <summary> Event handler. Called by btnOK for click events. </summary>
/// <param name="sender"> Source of the event. </param>
/// <param name="e"> Routed event information. </param>
private void btnOK_Click(object sender, RoutedEventArgs e)
{
this.Close();
}
}
}

View File

@ -27,6 +27,15 @@
<setting name="FilesFoundAlert" serializeAs="String">
<value>25</value>
</setting>
<setting name="SkipEmptyFiles" serializeAs="String">
<value>True</value>
</setting>
<setting name="ProviderFolder" serializeAs="String">
<value />
</setting>
<setting name="Language" serializeAs="String">
<value>en-US</value>
</setting>
</mdfinder.Properties.Settings>
</userSettings>
</configuration>

View File

@ -25,9 +25,9 @@ namespace mdfinder
/// <value> The database. </value>
private LiteDatabase Database { get; set; }
/// <summary> Gets the file records. </summary>
/// <value> The file records. </value>
public LiteCollection<FileRecord> FileRecords
/// <summary> Gets a collection of file records. </summary>
/// <value> A collection of file records. </value>
private LiteCollection<FileRecord> FileRecordCollection
{
get
{
@ -35,15 +35,6 @@ namespace mdfinder
}
}
public IEnumerable<FileRecord> ASDF
{
get
{
return this.FileRecords.FindAll();
}
}
#endregion
#region Constructors
@ -72,8 +63,33 @@ namespace mdfinder
/// <param name="hashProvider"> The hash provider. </param>
public void InsertFileRecord(string path, long size, string hash, string hashProvider)
{
this.FileRecords.Insert(new FileRecord() { Path = path, Size = size, Hash = hash, HashProvider = hashProvider });
OnPropertyChanged("ASDF");
var fileRecord = new FileRecord() { Path = new Uri(path), Size = size, Hash = hash, HashProvider = hashProvider };
this.FileRecordCollection.Insert(fileRecord);
}
/// <summary> Gets the file records in this collection. </summary>
/// <returns>
/// An enumerator that allows foreach to be used to process the file records in this collection.
/// </returns>
public IEnumerable<FileRecord> GetFileRecords()
{
return this.FileRecordCollection.FindAll();
}
/// <summary> Gets the file records in this collection. </summary>
/// <param name="predicate"> The predicate. </param>
/// <returns>
/// An enumerator that allows foreach to be used to process the file records in this collection.
/// </returns>
public IEnumerable<FileRecord> GetFileRecords(Func<FileRecord, bool> predicate)
{
return this.FileRecordCollection.Find(fr => predicate(fr));
}
/// <summary> Clears the database to its blank/initial state. </summary>
public void Clear()
{
this.FileRecordCollection.Delete(Query.All());
}
#endregion

View File

@ -27,5 +27,20 @@ namespace mdfinder
.GroupBy(a => a.i / binSize)
.Select(grp => grp.Select(a => a.x));
}
/// <summary> An IEnumerable<T> extension method that returns the first item or a given default value if no items are in the collection. </summary>
/// <typeparam name="T"> Generic type parameter. </typeparam>
/// <param name="items"> The items to act on. </param>
/// <param name="default"> The default. </param>
/// <returns> A T. </returns>
public static T FirstOr<T>(this IEnumerable<T> items, T @default)
{
foreach(var t in items)
{
return t;
}
return @default;
}
}
}

View File

@ -16,7 +16,7 @@ namespace mdfinder
/// <summary> Gets or sets the full pathname of the file. </summary>
/// <value> The full pathname of the file. </value>
public string Path { get; set; }
public Uri Path { get; set; }
/// <summary> Gets or sets the size. </summary>
/// <value> The size. </value>

BIN
mdfinder/Icon/icon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

BIN
mdfinder/Icon/icon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 806 B

152
mdfinder/Icon/icon.svg Normal file
View File

@ -0,0 +1,152 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="64px"
height="64px"
viewBox="0 0 64 64"
version="1.1"
id="SVGRoot"
inkscape:version="0.92.4 (5da689c313, 2019-01-14)"
sodipodi:docname="icon.svg">
<defs
id="defs815" />
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="5.6568542"
inkscape:cx="-5.6227241"
inkscape:cy="50.292753"
inkscape:document-units="px"
inkscape:current-layer="layer1"
showgrid="false"
inkscape:window-width="1920"
inkscape:window-height="1057"
inkscape:window-x="-8"
inkscape:window-y="-8"
inkscape:window-maximized="1"
inkscape:grid-bbox="true"
inkscape:snap-bbox="true" />
<metadata
id="metadata818">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1">
<g
id="g1425"
transform="translate(4.125,0.75)">
<g
id="g1396">
<path
style="fill:none;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 18.875,6.0625 v 50.375"
id="path1377"
inkscape:connector-curvature="0" />
<path
style="fill:none;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 36.875,6.0625 v 50.375"
id="path1377-6"
inkscape:connector-curvature="0" />
</g>
<g
transform="rotate(90,27.875,31.25)"
id="g1396-3">
<path
style="fill:none;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 18.875,6.0625 v 50.375"
id="path1377-8"
inkscape:connector-curvature="0" />
<path
style="fill:none;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 36.875,6.0625 v 50.375"
id="path1377-6-2"
inkscape:connector-curvature="0" />
</g>
</g>
<rect
style="opacity:1;fill:#4aae59;fill-opacity:1;stroke:none;stroke-width:1;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="rect1427"
width="14.142136"
height="14.142136"
x="6.8125"
y="6.8125" />
<rect
style="opacity:1;fill:#ae4a4a;fill-opacity:1;stroke:none;stroke-width:1;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="rect1427-3"
width="14.142136"
height="14.142136"
x="24.928932"
y="24.928932" />
<rect
style="opacity:1;fill:#4a94ae;fill-opacity:1;stroke:none;stroke-width:1;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="rect1427-7"
width="14.142136"
height="14.142136"
x="24.928932"
y="6.8125" />
<rect
style="opacity:1;fill:#984aae;fill-opacity:1;stroke:none;stroke-width:1;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="rect1427-38"
width="14.142136"
height="14.142136"
x="43.045364"
y="6.8125" />
<rect
style="opacity:1;fill:#7c7c7c;fill-opacity:1;stroke:none;stroke-width:1;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="rect1427-2"
width="14.142136"
height="14.142136"
x="43.045364"
y="24.928932" />
<rect
style="opacity:1;fill:#aea74a;fill-opacity:1;stroke:none;stroke-width:1;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="rect1427-4"
width="14.142136"
height="14.142136"
x="6.8125"
y="24.928932" />
<rect
style="opacity:1;fill:#4a5cae;fill-opacity:1;stroke:none;stroke-width:1;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="rect1427-5"
width="14.142136"
height="14.142136"
x="6.8125"
y="43.045364" />
<rect
style="opacity:1;fill:#ae8a4a;fill-opacity:1;stroke:none;stroke-width:1;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="rect1427-8"
width="14.142136"
height="14.142136"
x="24.928932"
y="43.045364" />
<rect
style="opacity:1;fill:#d3dc1c;fill-opacity:1;stroke:none;stroke-width:1;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="rect1427-1"
width="14.142136"
height="14.142136"
x="43.045364"
y="43.045364" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 5.5 KiB

View File

@ -1,13 +1,53 @@
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:mdfinder">
<ControlTemplate x:Key="OptionsIcon">
<ControlTemplate x:Key="MdfinderUIIcon">
<Viewbox>
<Path Fill="#000000">
<Path.Data>
<PathGeometry Figures="M19 0h-14c-2.762 0-5 2.239-5 5v14c0 2.761 2.238 5 5 5h14c2.762 0 5-2.239 5-5v-14c0-2.761-2.238-5-5-5zm-4 4h2v3h-2v-3zm-8 0h2v8h-2v-8zm4 13h-2v3h-2v-3h-2v-3h6v3zm8-5h-2v8h-2v-8h-2v-3h6v3z" FillRule="NonZero"/>
</Path.Data>
</Path>
<Canvas Width="64" Height="64">
<Canvas Name="layer1">
<Canvas Name="g1425">
<Canvas.RenderTransform>
<TranslateTransform X="4.125" Y="0.75"/>
</Canvas.RenderTransform>
<Canvas Name="g1396">
<Path xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Name="path1377" StrokeThickness="1" Stroke="#FF000000" StrokeMiterLimit="4" StrokeLineJoin="Miter" StrokeStartLineCap="Flat" StrokeEndLineCap="Flat">
<Path.Data>
<PathGeometry Figures="m 18.875 6.0625 v 50.375" FillRule="NonZero"/>
</Path.Data>
</Path>
<Path xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Name="path13776" StrokeThickness="1" Stroke="#FF000000" StrokeMiterLimit="4" StrokeLineJoin="Miter" StrokeStartLineCap="Flat" StrokeEndLineCap="Flat">
<Path.Data>
<PathGeometry Figures="m 36.875 6.0625 v 50.375" FillRule="NonZero"/>
</Path.Data>
</Path>
</Canvas>
<Canvas Name="g13963">
<Canvas.RenderTransform>
<RotateTransform Angle="90" CenterX="27.875" CenterY="31.25"/>
</Canvas.RenderTransform>
<Path xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Name="path13778" StrokeThickness="1" Stroke="#FF000000" StrokeMiterLimit="4" StrokeLineJoin="Miter" StrokeStartLineCap="Flat" StrokeEndLineCap="Flat">
<Path.Data>
<PathGeometry Figures="m 18.875 6.0625 v 50.375" FillRule="NonZero"/>
</Path.Data>
</Path>
<Path xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Name="path137762" StrokeThickness="1" Stroke="#FF000000" StrokeMiterLimit="4" StrokeLineJoin="Miter" StrokeStartLineCap="Flat" StrokeEndLineCap="Flat">
<Path.Data>
<PathGeometry Figures="m 36.875 6.0625 v 50.375" FillRule="NonZero"/>
</Path.Data>
</Path>
</Canvas>
</Canvas>
<Rectangle xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Canvas.Left="6.8125" Canvas.Top="6.8125" Width="14.142136" Height="14.142136" Name="rect1427" Fill="#FF4AAE59" StrokeThickness="1" StrokeMiterLimit="4" StrokeStartLineCap="Round" StrokeEndLineCap="Round" Opacity="1"/>
<Rectangle xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Canvas.Left="24.928932" Canvas.Top="24.928932" Width="14.142136" Height="14.142136" Name="rect14273" Fill="#FFAE4A4A" StrokeThickness="1" StrokeMiterLimit="4" StrokeStartLineCap="Round" StrokeEndLineCap="Round" Opacity="1"/>
<Rectangle xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Canvas.Left="24.928932" Canvas.Top="6.8125" Width="14.142136" Height="14.142136" Name="rect14277" Fill="#FF4A94AE" StrokeThickness="1" StrokeMiterLimit="4" StrokeStartLineCap="Round" StrokeEndLineCap="Round" Opacity="1"/>
<Rectangle xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Canvas.Left="43.045364" Canvas.Top="6.8125" Width="14.142136" Height="14.142136" Name="rect142738" Fill="#FF984AAE" StrokeThickness="1" StrokeMiterLimit="4" StrokeStartLineCap="Round" StrokeEndLineCap="Round" Opacity="1"/>
<Rectangle xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Canvas.Left="43.045364" Canvas.Top="24.928932" Width="14.142136" Height="14.142136" Name="rect14272" Fill="#FF7C7C7C" StrokeThickness="1" StrokeMiterLimit="4" StrokeStartLineCap="Round" StrokeEndLineCap="Round" Opacity="1"/>
<Rectangle xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Canvas.Left="6.8125" Canvas.Top="24.928932" Width="14.142136" Height="14.142136" Name="rect14274" Fill="#FFAEA74A" StrokeThickness="1" StrokeMiterLimit="4" StrokeStartLineCap="Round" StrokeEndLineCap="Round" Opacity="1"/>
<Rectangle xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Canvas.Left="6.8125" Canvas.Top="43.045364" Width="14.142136" Height="14.142136" Name="rect14275" Fill="#FF4A5CAE" StrokeThickness="1" StrokeMiterLimit="4" StrokeStartLineCap="Round" StrokeEndLineCap="Round" Opacity="1"/>
<Rectangle xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Canvas.Left="24.928932" Canvas.Top="43.045364" Width="14.142136" Height="14.142136" Name="rect14278" Fill="#FFAE8A4A" StrokeThickness="1" StrokeMiterLimit="4" StrokeStartLineCap="Round" StrokeEndLineCap="Round" Opacity="1"/>
<Rectangle xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Canvas.Left="43.045364" Canvas.Top="43.045364" Width="14.142136" Height="14.142136" Name="rect14271" Fill="#FFD3DC1C" StrokeThickness="1" StrokeMiterLimit="4" StrokeStartLineCap="Round" StrokeEndLineCap="Round" Opacity="1"/>
</Canvas>
</Canvas>
</Viewbox>
</ControlTemplate>
<ControlTemplate x:Key="InfoIcon">
@ -85,4 +125,49 @@
</Path>
</Viewbox>
</ControlTemplate>
<ControlTemplate x:Key="DuplicateIcon">
<Viewbox>
<Path Fill="#000000">
<Path.Data>
<PathGeometry Figures="M18 6v-6h-18v18h6v6h18v-18h-6zm-12 10h-4v-14h14v4h-10v10zm16 6h-14v-14h14v14zm-3-8h-3v-3h-2v3h-3v2h3v3h2v-3h3v-2z" FillRule="NonZero"/>
</Path.Data>
</Path>
</Viewbox>
</ControlTemplate>
<ControlTemplate x:Key="SearchIcon">
<Viewbox>
<Path Fill="#000000">
<Path.Data>
<PathGeometry Figures="M13 8h-8v-1h8v1zm0 2h-8v-1h8v1zm-3 2h-5v-1h5v1zm11.172 12l-7.387-7.387c-1.388.874-3.024 1.387-4.785 1.387-4.971 0-9-4.029-9-9s4.029-9 9-9 9 4.029 9 9c0 1.761-.514 3.398-1.387 4.785l7.387 7.387-2.828 2.828zm-12.172-8c3.859 0 7-3.14 7-7s-3.141-7-7-7-7 3.14-7 7 3.141 7 7 7z" FillRule="NonZero"/>
</Path.Data>
</Path>
</Viewbox>
</ControlTemplate>
<ControlTemplate x:Key="ShowAllIcon">
<Viewbox>
<Path Fill="#000000">
<Path.Data>
<PathGeometry Figures="M18 15.422v.983c0 .771-1.862 1.396-4 1.396s-4-.625-4-1.396v-.983c.968.695 2.801.902 4 .902 1.202 0 3.035-.208 4-.902zm-4-1.363c-1.202 0-3.035-.209-4-.902v.973c0 .771 1.862 1.396 4 1.396s4-.625 4-1.396v-.973c-.968.695-2.801.902-4 .902zm0-5.86c-2.138 0-4 .625-4 1.396 0 .77 1.862 1.395 4 1.395s4-.625 4-1.395c0-.771-1.862-1.396-4-1.396zm0 3.591c-1.202 0-3.035-.209-4-.902v.977c0 .77 1.862 1.395 4 1.395s4-.625 4-1.395v-.977c-.968.695-2.801.902-4 .902zm-.5-9.79c-5.288 0-9.649 3.914-10.377 9h-3.123l4 5.917 4-5.917h-2.847c.711-3.972 4.174-7 8.347-7 4.687 0 8.5 3.813 8.5 8.5s-3.813 8.5-8.5 8.5c-3.015 0-5.662-1.583-7.171-3.957l-1.2 1.775c1.916 2.536 4.948 4.182 8.371 4.182 5.797 0 10.5-4.702 10.5-10.5s-4.703-10.5-10.5-10.5z" FillRule="NonZero"/>
</Path.Data>
</Path>
</Viewbox>
</ControlTemplate>
<ControlTemplate x:Key="ClearIcon">
<Viewbox>
<Path Fill="#000000">
<Path.Data>
<PathGeometry Figures="M1 3.488c0-1.926 4.656-3.488 10-3.488 5.345 0 10 1.562 10 3.488s-4.655 3.487-10 3.487c-5.344 0-10-1.561-10-3.487zm10 14.823c.34 0 .678-.007 1.011-.019.045-1.407.537-2.7 1.342-3.745-.839.067-1.643.1-2.353.1-3.006 0-7.588-.523-10-2.256v2.434c0 1.925 4.656 3.486 10 3.486zm0-5.665c5.345 0 10-1.562 10-3.487v-2.44c-2.418 1.738-7.005 2.256-10 2.256-3.006 0-7.588-.523-10-2.256v2.44c0 1.926 4.656 3.487 10 3.487zm1.254 7.635c-.438.02-.861.03-1.254.03-2.995 0-7.582-.518-10-2.256v2.458c0 1.925 4.656 3.487 10 3.487 1.284 0 2.526-.092 3.676-.256-1.155-.844-2.02-2.055-2.422-3.463zm10.746-1.781c0 2.485-2.017 4.5-4.5 4.5s-4.5-2.015-4.5-4.5 2.017-4.5 4.5-4.5 4.5 2.015 4.5 4.5zm-2-.5h-5v1h5v-1z" FillRule="NonZero"/>
</Path.Data>
</Path>
</Viewbox>
</ControlTemplate>
<ControlTemplate x:Key="OptionsIcon">
<Viewbox>
<Path Fill="#000000">
<Path.Data>
<PathGeometry Figures="M19 0h-14c-2.762 0-5 2.239-5 5v14c0 2.761 2.238 5 5 5h14c2.762 0 5-2.239 5-5v-14c0-2.761-2.238-5-5-5zm-4 4h2v3h-2v-3zm-8 0h2v8h-2v-8zm4 13h-2v3h-2v-3h-2v-3h6v3zm8-5h-2v8h-2v-8h-2v-3h6v3z" FillRule="NonZero"/>
</Path.Data>
</Path>
</Viewbox>
</ControlTemplate>
</ResourceDictionary>

View File

@ -60,6 +60,51 @@ namespace mdfinder.Localization {
}
}
/// <summary>
/// Looks up a localized string similar to About mdfinder....
/// </summary>
public static string AboutMenu {
get {
return ResourceManager.GetString("AboutMenu", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to mdfinder is a file scanning and hashing application..
/// </summary>
public static string AboutWindowDescription {
get {
return ResourceManager.GetString("AboutWindowDescription", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to github.
/// </summary>
public static string AboutWindowGithubLinkLabel {
get {
return ResourceManager.GetString("AboutWindowGithubLinkLabel", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to license.
/// </summary>
public static string AboutWindowLicenseLinkLabel {
get {
return ResourceManager.GetString("AboutWindowLicenseLinkLabel", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to About mdfinder.
/// </summary>
public static string AboutWindowTitle {
get {
return ResourceManager.GetString("AboutWindowTitle", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Actions.
/// </summary>
@ -105,6 +150,51 @@ namespace mdfinder.Localization {
}
}
/// <summary>
/// Looks up a localized string similar to Clear.
/// </summary>
public static string ClearLabel {
get {
return ResourceManager.GetString("ClearLabel", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Hash.
/// </summary>
public static string ColumnHeadingHash {
get {
return ResourceManager.GetString("ColumnHeadingHash", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Hash Provider.
/// </summary>
public static string ColumnHeadingHashProvider {
get {
return ResourceManager.GetString("ColumnHeadingHashProvider", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Path.
/// </summary>
public static string ColumnHeadingPath {
get {
return ResourceManager.GetString("ColumnHeadingPath", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Size.
/// </summary>
public static string ColumnHeadingSize {
get {
return ResourceManager.GetString("ColumnHeadingSize", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to The current version is up to date with the github repository..
/// </summary>
@ -123,6 +213,33 @@ namespace mdfinder.Localization {
}
}
/// <summary>
/// Looks up a localized string similar to md5 hash provider. This provider creates a simple md5 hash given a file..
/// </summary>
public static string DefaultHashProviderDescription {
get {
return ResourceManager.GetString("DefaultHashProviderDescription", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Default Provider.
/// </summary>
public static string DefaultHashProviderName {
get {
return ResourceManager.GetString("DefaultHashProviderName", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Developers and Contributors.
/// </summary>
public static string DevelopersLabel {
get {
return ResourceManager.GetString("DevelopersLabel", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Edit.
/// </summary>
@ -132,6 +249,15 @@ namespace mdfinder.Localization {
}
}
/// <summary>
/// Looks up a localized string similar to File Processing Threshold.
/// </summary>
public static string FileAlertThresholdLabel {
get {
return ResourceManager.GetString("FileAlertThresholdLabel", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to File.
/// </summary>
@ -141,6 +267,33 @@ namespace mdfinder.Localization {
}
}
/// <summary>
/// Looks up a localized string similar to Filters.
/// </summary>
public static string FilterBarLabel {
get {
return ResourceManager.GetString("FilterBarLabel", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Duplicates.
/// </summary>
public static string FilterDuplicatesLabel {
get {
return ResourceManager.GetString("FilterDuplicatesLabel", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Show All.
/// </summary>
public static string FilterShowAllLabel {
get {
return ResourceManager.GetString("FilterShowAllLabel", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Help.
/// </summary>
@ -150,6 +303,42 @@ namespace mdfinder.Localization {
}
}
/// <summary>
/// Looks up a localized string similar to Files.
/// </summary>
public static string ItemsLabel {
get {
return ResourceManager.GetString("ItemsLabel", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Language.
/// </summary>
public static string LanguageLabel {
get {
return ResourceManager.GetString("LanguageLabel", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to The default MD5 hash provider should not have its priorty set..
/// </summary>
public static string MD5ProviderSetPriorityException {
get {
return ResourceManager.GetString("MD5ProviderSetPriorityException", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to OK.
/// </summary>
public static string OKLabel {
get {
return ResourceManager.GetString("OKLabel", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Open File Database....
/// </summary>
@ -159,6 +348,60 @@ namespace mdfinder.Localization {
}
}
/// <summary>
/// Looks up a localized string similar to Open Source Libraries.
/// </summary>
public static string OpenSourceCreditsLabel {
get {
return ResourceManager.GetString("OpenSourceCreditsLabel", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Options....
/// </summary>
public static string OptionsMenu {
get {
return ResourceManager.GetString("OptionsMenu", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Note: Changing the user language will require a restart of the program..
/// </summary>
public static string OptionsWindowLanguageChangeNotice {
get {
return ResourceManager.GetString("OptionsWindowLanguageChangeNotice", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Options.
/// </summary>
public static string OptionsWindowTitle {
get {
return ResourceManager.GetString("OptionsWindowTitle", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Provider Location.
/// </summary>
public static string ProviderFolderLabel {
get {
return ResourceManager.GetString("ProviderFolderLabel", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Save.
/// </summary>
public static string SaveLabel {
get {
return ResourceManager.GetString("SaveLabel", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Save File Database....
/// </summary>
@ -195,6 +438,15 @@ namespace mdfinder.Localization {
}
}
/// <summary>
/// Looks up a localized string similar to Skip Empty Files.
/// </summary>
public static string SkipEmptyFilesLabel {
get {
return ResourceManager.GetString("SkipEmptyFilesLabel", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to mdfinder.
/// </summary>
@ -212,5 +464,14 @@ namespace mdfinder.Localization {
return ResourceManager.GetString("UnknownVersionStatusDescription", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Version.
/// </summary>
public static string VersionLabel {
get {
return ResourceManager.GetString("VersionLabel", resourceCulture);
}
}
}
}

View File

@ -117,6 +117,21 @@
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="AboutMenu" xml:space="preserve">
<value>About mdfinder...</value>
</data>
<data name="AboutWindowDescription" xml:space="preserve">
<value>mdfinder is a file scanning and hashing application.</value>
</data>
<data name="AboutWindowGithubLinkLabel" xml:space="preserve">
<value>github</value>
</data>
<data name="AboutWindowLicenseLinkLabel" xml:space="preserve">
<value>license</value>
</data>
<data name="AboutWindowTitle" xml:space="preserve">
<value>About mdfinder</value>
</data>
<data name="ActionBarLabel" xml:space="preserve">
<value>Actions</value>
</data>
@ -132,24 +147,90 @@
<data name="BooleanInvalidCastExceptionFormat" xml:space="preserve">
<value>Cannot convert type to {0} from or to a boolean.</value>
</data>
<data name="ClearLabel" xml:space="preserve">
<value>Clear</value>
</data>
<data name="ColumnHeadingHash" xml:space="preserve">
<value>Hash</value>
</data>
<data name="ColumnHeadingHashProvider" xml:space="preserve">
<value>Hash Provider</value>
</data>
<data name="ColumnHeadingPath" xml:space="preserve">
<value>Path</value>
</data>
<data name="ColumnHeadingSize" xml:space="preserve">
<value>Size</value>
</data>
<data name="CurrentVersionStatusDescription" xml:space="preserve">
<value>The current version is up to date with the github repository.</value>
</data>
<data name="CustomVersionStatusDescription" xml:space="preserve">
<value>The current version is ahead of the github repository, or is a custom version of butterflow-ui that cannot be compared to the github repository.</value>
</data>
<data name="DefaultHashProviderDescription" xml:space="preserve">
<value>md5 hash provider. This provider creates a simple md5 hash given a file.</value>
</data>
<data name="DefaultHashProviderName" xml:space="preserve">
<value>Default Provider</value>
</data>
<data name="DevelopersLabel" xml:space="preserve">
<value>Developers and Contributors</value>
</data>
<data name="EditMenu" xml:space="preserve">
<value>Edit</value>
</data>
<data name="FileAlertThresholdLabel" xml:space="preserve">
<value>File Processing Threshold</value>
</data>
<data name="FileMenu" xml:space="preserve">
<value>File</value>
</data>
<data name="FilterBarLabel" xml:space="preserve">
<value>Filters</value>
</data>
<data name="FilterDuplicatesLabel" xml:space="preserve">
<value>Duplicates</value>
</data>
<data name="FilterShowAllLabel" xml:space="preserve">
<value>Show All</value>
</data>
<data name="HelpMenu" xml:space="preserve">
<value>Help</value>
</data>
<data name="ItemsLabel" xml:space="preserve">
<value> Files</value>
</data>
<data name="LanguageLabel" xml:space="preserve">
<value>Language</value>
</data>
<data name="MD5ProviderSetPriorityException" xml:space="preserve">
<value>The default MD5 hash provider should not have its priorty set.</value>
</data>
<data name="OKLabel" xml:space="preserve">
<value>OK</value>
</data>
<data name="OpenMenuItem" xml:space="preserve">
<value>Open File Database...</value>
</data>
<data name="OpenSourceCreditsLabel" xml:space="preserve">
<value>Open Source Libraries</value>
</data>
<data name="OptionsMenu" xml:space="preserve">
<value>Options...</value>
</data>
<data name="OptionsWindowLanguageChangeNotice" xml:space="preserve">
<value>Note: Changing the user language will require a restart of the program.</value>
</data>
<data name="OptionsWindowTitle" xml:space="preserve">
<value>Options</value>
</data>
<data name="ProviderFolderLabel" xml:space="preserve">
<value>Provider Location</value>
</data>
<data name="SaveLabel" xml:space="preserve">
<value>Save</value>
</data>
<data name="SaveMenuItem" xml:space="preserve">
<value>Save File Database...</value>
</data>
@ -162,10 +243,16 @@
<data name="ScanTooltip" xml:space="preserve">
<value>Scan the selected path</value>
</data>
<data name="SkipEmptyFilesLabel" xml:space="preserve">
<value>Skip Empty Files</value>
</data>
<data name="Title" xml:space="preserve">
<value>mdfinder</value>
</data>
<data name="UnknownVersionStatusDescription" xml:space="preserve">
<value>Github failed to respond with the current version. This could be because of rate limits or a network failure.</value>
</data>
<data name="VersionLabel" xml:space="preserve">
<value>Version</value>
</data>
</root>

View File

@ -11,6 +11,8 @@
<mdfinder:InverseBoolConverter x:Key="InverseBoolConverter" />
<mdfinder:BoolVisibilityConverter x:Key="BoolVisibilityConverter" />
<mdfinder:InverseBoolVisibilityConverter x:Key="InverseBoolVisibilityConverter" />
<mdfinder:URIConverter x:Key="URIConverter" />
<mdfinder:SizeConverter x:Key="SizeConverter" />
</Window.Resources>
<DockPanel>
<Menu DockPanel.Dock="Top">
@ -25,6 +27,14 @@
<ContentControl Template="{StaticResource SaveIcon}" />
</MenuItem.Icon>
</MenuItem>
<MenuItem Name="menuOptions" Header="{x:Static loc:Localization.OptionsMenu}" Click="MenuOptions_Click">
<MenuItem.Icon>
<ContentControl Template="{StaticResource OptionsIcon}" />
</MenuItem.Icon>
</MenuItem>
<MenuItem Name="menuAbout" Header="{x:Static loc:Localization.AboutMenu}" Click="MenuAbout_Click">
</MenuItem>
</MenuItem>
</Menu>
<Grid x:Name="MainWindowGrid">
@ -52,24 +62,104 @@
<Button Grid.Column="2" MinWidth="25" Name="btnFilePicker" Click="btnFilePicker_Click">...</Button>
</Grid>
</GroupBox>
<GroupBox Grid.ColumnSpan="3" Grid.Row="1" Header="{x:Static loc:Localization.ActionBarLabel}">
<GroupBox Grid.Column="0" Grid.ColumnSpan="1" Grid.Row="1" Header="{x:Static loc:Localization.ActionBarLabel}">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="48" />
<RowDefinition Height="32" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Button Grid.Row="0" Name="btnScan" ToolTip="{x:Static loc:Localization.ScanTooltip}" IsEnabled="{Binding Scanner.IsScanning, Mode=OneWay, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type mdfinder:MainWindow}}, UpdateSourceTrigger=PropertyChanged, Converter={StaticResource InverseBoolConverter}}" Click="btnScan_Click">
<Button Grid.Row="0" Grid.Column="0" Name="btnScan" ToolTip="{x:Static loc:Localization.ScanTooltip}" IsEnabled="{Binding Scanner.IsScanning, Mode=OneWay, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type mdfinder:MainWindow}}, UpdateSourceTrigger=PropertyChanged, Converter={StaticResource InverseBoolConverter}}" Click="btnScan_Click">
<StackPanel Orientation="Horizontal">
<ContentControl MaxWidth="16" HorizontalAlignment="Center" Template="{StaticResource ScanIcon}" />
<Label Content="{x:Static loc:Localization.ScanLabel}" />
</StackPanel>
</Button>
<Button Grid.Row="0" Grid.Column="1" Name="btnClear" ToolTip="{x:Static loc:Localization.ScanTooltip}" IsEnabled="{Binding Scanner.IsScanning, Mode=OneWay, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type mdfinder:MainWindow}}, UpdateSourceTrigger=PropertyChanged, Converter={StaticResource InverseBoolConverter}}" Click="BtnClear_Click">
<StackPanel Orientation="Horizontal">
<ContentControl MaxWidth="16" HorizontalAlignment="Center" Template="{StaticResource ClearIcon}" />
<Label Content="{x:Static loc:Localization.ClearLabel}" />
</StackPanel>
</Button>
</Grid>
</GroupBox>
<DataGrid Grid.Row="2" Grid.Column="1" Grid.ColumnSpan="3" ItemsSource="{Binding Database.ASDF, Mode=OneWay, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type mdfinder:MainWindow}}}" />
<GroupBox Grid.Column="1" Grid.ColumnSpan="3" Grid.Row="1" Header="{x:Static loc:Localization.FilterBarLabel}">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="32" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Button Grid.Row="0" Grid.Column="0" Name="btnFilterShowAll" ToolTip="{x:Static loc:Localization.ScanTooltip}" IsEnabled="{Binding Scanner.IsScanning, Mode=OneWay, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type mdfinder:MainWindow}}, UpdateSourceTrigger=PropertyChanged, Converter={StaticResource InverseBoolConverter}}" Click="BtnFilterShowAll_Click" >
<StackPanel Orientation="Horizontal">
<ContentControl MaxWidth="16" HorizontalAlignment="Center" Template="{StaticResource ShowAllIcon}" />
<Label Content="{x:Static loc:Localization.FilterShowAllLabel}" />
</StackPanel>
</Button>
<Button Grid.Row="0" Grid.Column="1" Name="btnFilterDuplicates" ToolTip="{x:Static loc:Localization.ScanTooltip}" IsEnabled="{Binding Scanner.IsScanning, Mode=OneWay, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type mdfinder:MainWindow}}, UpdateSourceTrigger=PropertyChanged, Converter={StaticResource InverseBoolConverter}}" Click="BtnFilterDuplicates_Click" >
<StackPanel Orientation="Horizontal">
<ContentControl MaxWidth="16" HorizontalAlignment="Center" Template="{StaticResource DuplicateIcon}" />
<Label Content="{x:Static loc:Localization.FilterDuplicatesLabel}" />
</StackPanel>
</Button>
</Grid>
</GroupBox>
<DataGrid x:Name="datagridFileRecords" Grid.Row="2" Grid.Column="1" Grid.ColumnSpan="3" Initialized="DatagridFileRecords_Initialized" IsReadOnly="True" AutoGenerateColumns="False">
<DataGrid.Resources>
<Style TargetType="Hyperlink">
<EventSetter Event="Click" Handler="Hyperlink_Click"/>
</Style>
<Style TargetType="{x:Type DataGridCell}">
<Style.Triggers>
<Trigger Property="DataGridCell.IsSelected" Value="True">
<Setter Property="Background" Value="Black" />
</Trigger>
</Style.Triggers>
</Style>
</DataGrid.Resources>
<DataGrid.Columns>
<DataGridHyperlinkColumn Header="{x:Static loc:Localization.ColumnHeadingPath}" Binding="{Binding Path}" ContentBinding="{Binding Path, Converter={StaticResource URIConverter}}" Width="Auto" IsReadOnly="True" />
<DataGridTextColumn Header="{x:Static loc:Localization.ColumnHeadingSize}" Binding="{Binding Size, Converter={StaticResource SizeConverter}}" />
<DataGridTextColumn Header="{x:Static loc:Localization.ColumnHeadingHash}" Binding="{Binding Hash}" />
<DataGridTextColumn Header="{x:Static loc:Localization.ColumnHeadingHashProvider}" Binding="{Binding HashProvider}" />
</DataGrid.Columns>
<DataGrid.GroupStyle>
<GroupStyle>
<GroupStyle.HeaderTemplate>
<DataTemplate>
<StackPanel>
<TextBlock Text="{Binding Path=Hash}" />
</StackPanel>
</DataTemplate>
</GroupStyle.HeaderTemplate>
<GroupStyle.ContainerStyle>
<Style TargetType="{x:Type GroupItem}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type GroupItem}">
<Expander IsExpanded="True">
<Expander.Header>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Path=Name}" />
<TextBlock Text="{Binding Path=ItemCount}"/>
<TextBlock Text="{x:Static loc:Localization.ItemsLabel}"/>
</StackPanel>
</Expander.Header>
<ItemsPresenter />
</Expander>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</GroupStyle.ContainerStyle>
</GroupStyle>
</DataGrid.GroupStyle>
</DataGrid>
<Label x:Name="txtProgressLabel" Grid.Row="3" Grid.ColumnSpan="4" Panel.ZIndex="1" />
<ProgressBar Grid.Row="3" Grid.ColumnSpan="4" Name="progressBar" Minimum="0" Height="16"/>
</Grid>
</DockPanel>

View File

@ -14,6 +14,10 @@ using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Windows.Forms;
using System.Threading;
using mdfinder.hashprovider;
using System.Diagnostics;
using System.Reflection;
using System.IO;
namespace mdfinder
{
@ -24,10 +28,22 @@ namespace mdfinder
{
#region Properties
/// <summary> Gets or sets the database. </summary>
/// <value> The database. </value>
public DBHelper Database { get; set; }
/// <summary> Gets or sets the scanner. </summary>
/// <value> The scanner. </value>
public Scanner Scanner { get; set; }
/// <summary> Gets or sets the hash providers. </summary>
/// <value> The hash providers. </value>
public IEnumerable<IHashProvider> HashProviders { get; set; }
/// <summary> Gets or sets the default provider. </summary>
/// <value> The default provider. </value>
public IHashProvider DefaultProvider { get; set; }
#endregion
#region Constructors
@ -37,13 +53,22 @@ namespace mdfinder
{
this.Database = new DBHelper();
this.Scanner = new Scanner();
this.DefaultProvider = new MD5HashProvider();
this.HashProviders = GetProviderPlugins();
this.Scanner.DirectoryFound += (sender, args) => Dispatcher.Invoke(() => txtScanLocation.Text = args.Directory.Name);
this.Scanner.FilesFound += (sender, args) =>
this.Scanner.DirectoryFound += (sender, args) => Dispatcher.Invoke(() => txtProgressLabel.Content = args.Directory.Name);
this.Scanner.FilesFound += (sender, args) =>
{
foreach(var file in args.Files)
foreach (var file in args.Files)
{
this.Database.InsertFileRecord(file.FullName, file.Length, Guid.NewGuid().ToString(), "test");
if (Properties.Settings.Default.SkipEmptyFiles && file.Length == 0)
{
break;
}
var provider = this.HashProviders.Where(hp => hp.FileExtensions.Contains(file.Extension.ToUpper())).OrderByDescending(hp => hp.Priority).FirstOr(this.DefaultProvider);
this.Database.InsertFileRecord(file.FullName, file.Length, provider.GetHash(file), provider.Name);
Dispatcher.Invoke(() => txtProgressLabel.Content = file.FullName);
}
};
this.Scanner.ReportProgress += (sender, args) => Dispatcher.Invoke(() => { if (args.Processed > 0) { this.progressBar.Value = args.Percentage * 100; } });
@ -55,16 +80,40 @@ namespace mdfinder
#region Methods
/// <summary> Gets the provider plugins from a folder. </summary>
/// <returns>
/// An enumerator that allows foreach to be used to process the provider plugins in this
/// collection.
/// </returns>
private IEnumerable<IHashProvider> GetProviderPlugins()
{
var directory = new DirectoryInfo(Properties.Settings.Default.ProviderFolder);
foreach (var pluginFile in directory.GetFiles("*.dll"))
{
var assembly = Assembly.LoadFrom(pluginFile.FullName);
foreach (var type in assembly.GetTypes().Where(t => t.GetInterface("IHashProvider") != null))
{
yield return Activator.CreateInstance(type) as IHashProvider;
}
}
}
/// <summary> Event handler. Called by btnFilePicker for click events. </summary>
/// <param name="sender"> Source of the event. </param>
/// <param name="e"> Routed event information. </param>
private void btnFilePicker_Click(object sender, RoutedEventArgs e)
{
var fbd = new FolderBrowserDialog();
if(fbd.ShowDialog() == System.Windows.Forms.DialogResult.OK)
if (fbd.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{
txtScanLocation.Text = fbd.SelectedPath;
}
}
/// <summary> Event handler. Called by btnScan for click events. </summary>
/// <param name="sender"> Source of the event. </param>
/// <param name="e"> Routed event information. </param>
private void btnScan_Click(object sender, RoutedEventArgs e)
{
var location = txtScanLocation.Text;
@ -73,10 +122,75 @@ namespace mdfinder
new Thread(() =>
{
this.Scanner.Scan(location);
this.Dispatcher.Invoke(() => txtProgressLabel.Content = string.Empty);
this.Dispatcher.Invoke(() => datagridFileRecords.ItemsSource = this.Database.GetFileRecords());
}).Start();
}
}
/// <summary> Event handler. Called by DatagridFileRecords for initialized events. </summary>
/// <param name="sender"> Source of the event. </param>
/// <param name="e"> Event information. </param>
private void DatagridFileRecords_Initialized(object sender, EventArgs e)
{
this.datagridFileRecords.ItemsSource = this.Database.GetFileRecords();
}
/// <summary> Event handler. Called by BtnFilterDuplicates for click events. </summary>
/// <param name="sender"> Source of the event. </param>
/// <param name="e"> Routed event information. </param>
private void BtnFilterDuplicates_Click(object sender, RoutedEventArgs e)
{
this.datagridFileRecords.ItemsSource = new ListCollectionView(this.Database.GetFileRecords().GroupBy(fr => fr.Hash).Where(g => g.Count() > 1).SelectMany(g => g).ToList());
((ListCollectionView)this.datagridFileRecords.ItemsSource).GroupDescriptions.Add(new PropertyGroupDescription("Hash"));
}
/// <summary> Event handler. Called by BtnFilterShowAll for click events. </summary>
/// <param name="sender"> Source of the event. </param>
/// <param name="e"> Routed event information. </param>
private void BtnFilterShowAll_Click(object sender, RoutedEventArgs e)
{
this.datagridFileRecords.ItemsSource = this.Database.GetFileRecords();
}
/// <summary> Event handler. Called by BtnClear for click events. </summary>
/// <param name="sender"> Source of the event. </param>
/// <param name="e"> Routed event information. </param>
private void BtnClear_Click(object sender, RoutedEventArgs e)
{
this.Database.Clear();
this.datagridFileRecords.ItemsSource = Enumerable.Empty<FileRecord>();
}
/// <summary> Event handler. Called by Hyperlink for click events. </summary>
/// <param name="sender"> Source of the event. </param>
/// <param name="e"> Routed event information. </param>
private void Hyperlink_Click(object sender, RoutedEventArgs e)
{
Hyperlink link = (Hyperlink)e.OriginalSource;
Process.Start(link.NavigateUri.AbsoluteUri);
}
/// <summary> Event handler. Called by MenuOptions for click events. </summary>
/// <param name="sender"> Source of the event. </param>
/// <param name="e"> Routed event information. </param>
private void MenuOptions_Click(object sender, RoutedEventArgs e)
{
var optionsWindow = new OptionsWindow();
optionsWindow.ShowDialog();
this.HashProviders = GetProviderPlugins();
}
private void MenuAbout_Click(object sender, RoutedEventArgs e)
{
var aboutWindow = new AboutWindow();
aboutWindow.Show();
}
#endregion
}
}

View File

@ -0,0 +1,43 @@
<Window x:Class="mdfinder.OptionsWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:mdfinder="clr-namespace:mdfinder"
xmlns:settings="clr-namespace:mdfinder.Properties"
xmlns:loc="clr-namespace:mdfinder.Localization"
mc:Ignorable="d"
Title="{x:Static loc:Localization.OptionsWindowTitle}" SizeToContent="WidthAndHeight">
<DockPanel Margin="32">
<StackPanel>
<WrapPanel>
<Label Content="{x:Static loc:Localization.LanguageLabel}" />
<ComboBox DisplayMemberPath="DisplayName" ItemsSource="{Binding SupportedLanguages, Mode=TwoWay, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type mdfinder:OptionsWindow}}, UpdateSourceTrigger=PropertyChanged}" SelectedItem="{Binding Source={x:Static settings:Settings.Default}, Path=Language}" />
</WrapPanel>
<TextBlock Text="{x:Static loc:Localization.OptionsWindowLanguageChangeNotice}" Foreground="Gray" />
<WrapPanel>
<Label Content="{x:Static loc:Localization.FileAlertThresholdLabel}" />
<TextBox VerticalAlignment="Center" Text="{Binding Source={x:Static settings:Settings.Default}, Path=FilesFoundAlert, Mode=TwoWay}" TextAlignment="Center" />
</WrapPanel>
<WrapPanel>
<Label Content="{x:Static loc:Localization.SkipEmptyFilesLabel}" />
<CheckBox VerticalAlignment="Center" IsChecked="{Binding Source={x:Static settings:Settings.Default}, Path=SkipEmptyFiles, Mode=TwoWay}" />
</WrapPanel>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="77.126" />
<ColumnDefinition Width="25.874"/>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<ContentControl Grid.Column="0" Template="{StaticResource FolderIcon}" Width="16" Margin="0,0,4,0" />
<Label Grid.Column="1" Content="{x:Static loc:Localization.ProviderFolderLabel}" Grid.ColumnSpan="2" />
<TextBox x:Name="txtProviderLocation" Grid.Column="3" VerticalAlignment="Center" Text="{Binding Source={x:Static settings:Settings.Default}, Path=ProviderFolder, Mode=TwoWay}" Margin="0,4" />
<Button x:Name="btnProviderLocationDirectory" Grid.Column="4" MinWidth="25" Content="..." Click="BtnProviderLocationDirectory_Click" />
</Grid>
<Separator Margin="0,10" />
<Button Name="btnSave" MaxWidth="45" Content="{x:Static loc:Localization.SaveLabel}" Click="BtnSave_Click" />
</StackPanel>
</DockPanel>
</Window>

View File

@ -0,0 +1,67 @@
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Forms;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
namespace mdfinder
{
/// <summary>
/// Interaction logic for OptionsWindow.xaml
/// </summary>
public partial class OptionsWindow : Window
{
/// <summary> Gets or sets the supported languages. </summary>
/// <value> The supported languages. </value>
public List<CultureInfo> SupportedLanguages { get; set; } = new List<CultureInfo>(new[]
{
CultureInfo.CreateSpecificCulture("en-US"),
//CultureInfo.CreateSpecificCulture("es"),
//CultureInfo.CreateSpecificCulture("ar"),
//CultureInfo.CreateSpecificCulture("ja"),
//CultureInfo.CreateSpecificCulture("ru"),
//CultureInfo.CreateSpecificCulture("zh-CN"),
});
/// <summary> Default constructor. </summary>
public OptionsWindow()
{
InitializeComponent();
}
/// <summary> Event handler. Called by BtnSave for click events. </summary>
/// <param name="sender"> Source of the event. </param>
/// <param name="e"> Routed event information. </param>
private void BtnSave_Click(object sender, RoutedEventArgs e)
{
Properties.Settings.Default.Save();
this.Close();
}
/// <summary>
/// Event handler. Called by BtnProviderLocationDirectory for click events.
/// </summary>
/// <param name="sender"> Source of the event. </param>
/// <param name="e"> Routed event information. </param>
private void BtnProviderLocationDirectory_Click(object sender, RoutedEventArgs e)
{
var fbd = new FolderBrowserDialog();
if (fbd.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{
Properties.Settings.Default.ProviderFolder = fbd.SelectedPath;
}
}
}
}