mirror of
https://github.com/wagesj45/mdfinder.git
synced 2024-12-22 00:12:42 -06:00
Updates
Bug fixes and UI redesigns.
This commit is contained in:
parent
1de70724b0
commit
f230812765
6 changed files with 265 additions and 84 deletions
|
@ -17,7 +17,7 @@ namespace mdfinder
|
||||||
/// <summary> The default database file name. </summary>
|
/// <summary> The default database file name. </summary>
|
||||||
private const string DEFAULT_DB_FILE_NAME = "mdfinder.db";
|
private const string DEFAULT_DB_FILE_NAME = "mdfinder.db";
|
||||||
|
|
||||||
#endregion
|
#endregion Members
|
||||||
|
|
||||||
#region Properties
|
#region Properties
|
||||||
|
|
||||||
|
@ -35,7 +35,7 @@ namespace mdfinder
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion Properties
|
||||||
|
|
||||||
#region Constructors
|
#region Constructors
|
||||||
|
|
||||||
|
@ -52,7 +52,7 @@ namespace mdfinder
|
||||||
this.Database = new LiteDatabase(database);
|
this.Database = new LiteDatabase(database);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion Constructors
|
||||||
|
|
||||||
#region Methods
|
#region Methods
|
||||||
|
|
||||||
|
@ -67,11 +67,11 @@ namespace mdfinder
|
||||||
this.FileRecordCollection.Upsert(fileRecord);
|
this.FileRecordCollection.Upsert(fileRecord);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary> Removes the file record described by ID. </summary>
|
/// <summary> Removes the file record described by its path. </summary>
|
||||||
/// <param name="id"> The identifier. </param>
|
/// <param name="id"> The <see cref="Guid"/> ID of the file. </param>
|
||||||
public void RemoveFileRecord(string path)
|
public void RemoveFileRecord(string id)
|
||||||
{
|
{
|
||||||
this.FileRecordCollection.Delete(fr => fr.Id == path);
|
this.FileRecordCollection.Delete(fr => fr.Id == id);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary> Gets the file records in this collection. </summary>
|
/// <summary> Gets the file records in this collection. </summary>
|
||||||
|
@ -99,6 +99,6 @@ namespace mdfinder
|
||||||
this.FileRecordCollection.Delete(Query.All());
|
this.FileRecordCollection.Delete(Query.All());
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion Methods
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -28,7 +28,7 @@ namespace mdfinder
|
||||||
/// <summary> True to keep. </summary>
|
/// <summary> True to keep. </summary>
|
||||||
private bool keep;
|
private bool keep;
|
||||||
|
|
||||||
#endregion
|
#endregion Members
|
||||||
|
|
||||||
#region Properties
|
#region Properties
|
||||||
|
|
||||||
|
@ -122,7 +122,7 @@ namespace mdfinder
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion Properties
|
||||||
|
|
||||||
#region Constructors
|
#region Constructors
|
||||||
|
|
||||||
|
@ -142,14 +142,13 @@ namespace mdfinder
|
||||||
/// <param name="hashProvider"> The hash provider. </param>
|
/// <param name="hashProvider"> The hash provider. </param>
|
||||||
public FileRecord(string path, long size, string hash, string hashProvider)
|
public FileRecord(string path, long size, string hash, string hashProvider)
|
||||||
{
|
{
|
||||||
this.Id = path;
|
this.Id = Guid.NewGuid().ToString();
|
||||||
this.Path = new Uri(path);
|
this.Path = new Uri(path);
|
||||||
this.Size = size;
|
this.Size = size;
|
||||||
this.Hash = hash;
|
this.Hash = hash;
|
||||||
this.HashProvider = hashProvider;
|
this.HashProvider = hashProvider;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion Constructors
|
||||||
}
|
}
|
||||||
}
|
}
|
9
mdfinder/Localization/Localization.Designer.cs
generated
9
mdfinder/Localization/Localization.Designer.cs
generated
|
@ -375,6 +375,15 @@ namespace mdfinder.Localization {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Looks up a localized string similar to Not A Duplicate.
|
||||||
|
/// </summary>
|
||||||
|
public static string NotDupliateLabel {
|
||||||
|
get {
|
||||||
|
return ResourceManager.GetString("NotDupliateLabel", resourceCulture);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Looks up a localized string similar to OK.
|
/// Looks up a localized string similar to OK.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
|
@ -282,4 +282,7 @@
|
||||||
<data name="SizeOnDiskLabel" xml:space="preserve">
|
<data name="SizeOnDiskLabel" xml:space="preserve">
|
||||||
<value>Size On Disk:</value>
|
<value>Size On Disk:</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="NotDupliateLabel" xml:space="preserve">
|
||||||
|
<value>Not A Duplicate</value>
|
||||||
|
</data>
|
||||||
</root>
|
</root>
|
|
@ -7,7 +7,7 @@
|
||||||
xmlns:mdfinder="clr-namespace:mdfinder"
|
xmlns:mdfinder="clr-namespace:mdfinder"
|
||||||
xmlns:loc="clr-namespace:mdfinder.Localization"
|
xmlns:loc="clr-namespace:mdfinder.Localization"
|
||||||
mc:Ignorable="d"
|
mc:Ignorable="d"
|
||||||
Title="{x:Static loc:Localization.Title}" Height="520.293" Width="814.505">
|
Title="{x:Static loc:Localization.Title}" Height="520.293" Width="1055.509">
|
||||||
<Window.Resources>
|
<Window.Resources>
|
||||||
<mdfinder:InverseBoolConverter x:Key="InverseBoolConverter" />
|
<mdfinder:InverseBoolConverter x:Key="InverseBoolConverter" />
|
||||||
<mdfinder:BoolVisibilityConverter x:Key="BoolVisibilityConverter" />
|
<mdfinder:BoolVisibilityConverter x:Key="BoolVisibilityConverter" />
|
||||||
|
@ -34,7 +34,6 @@
|
||||||
</MenuItem.Icon>
|
</MenuItem.Icon>
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
<MenuItem Name="menuAbout" Header="{x:Static loc:Localization.AboutMenu}" Click="MenuAbout_Click">
|
<MenuItem Name="menuAbout" Header="{x:Static loc:Localization.AboutMenu}" Click="MenuAbout_Click">
|
||||||
|
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
</Menu>
|
</Menu>
|
||||||
|
@ -47,7 +46,7 @@
|
||||||
</Grid.RowDefinitions>
|
</Grid.RowDefinitions>
|
||||||
<Grid.ColumnDefinitions>
|
<Grid.ColumnDefinitions>
|
||||||
<ColumnDefinition Width="0.5*" />
|
<ColumnDefinition Width="0.5*" />
|
||||||
<ColumnDefinition Width="0.5*"/>
|
<ColumnDefinition Width="0.5*" />
|
||||||
<ColumnDefinition Width="*" />
|
<ColumnDefinition Width="*" />
|
||||||
<ColumnDefinition Width="Auto" />
|
<ColumnDefinition Width="Auto" />
|
||||||
</Grid.ColumnDefinitions>
|
</Grid.ColumnDefinitions>
|
||||||
|
@ -71,6 +70,7 @@
|
||||||
<Grid.ColumnDefinitions>
|
<Grid.ColumnDefinitions>
|
||||||
<ColumnDefinition Width="Auto" />
|
<ColumnDefinition Width="Auto" />
|
||||||
<ColumnDefinition Width="Auto" />
|
<ColumnDefinition Width="Auto" />
|
||||||
|
<ColumnDefinition Width="Auto" />
|
||||||
</Grid.ColumnDefinitions>
|
</Grid.ColumnDefinitions>
|
||||||
<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">
|
<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">
|
<StackPanel Orientation="Horizontal">
|
||||||
|
@ -78,7 +78,13 @@
|
||||||
<Label Content="{x:Static loc:Localization.ScanLabel}" />
|
<Label Content="{x:Static loc:Localization.ScanLabel}" />
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
</Button>
|
</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">
|
<Button Grid.Row="0" Grid.Column="1" Name="btnNotDuplicate" 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="BtnNotDuplicate_Click">
|
||||||
|
<StackPanel Orientation="Horizontal">
|
||||||
|
<ContentControl MaxWidth="16" HorizontalAlignment="Center" Template="{StaticResource ClearIcon}" />
|
||||||
|
<Label Content="{x:Static loc:Localization.NotDupliateLabel}" />
|
||||||
|
</StackPanel>
|
||||||
|
</Button>
|
||||||
|
<Button Grid.Row="0" Grid.Column="2" 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">
|
<StackPanel Orientation="Horizontal">
|
||||||
<ContentControl MaxWidth="16" HorizontalAlignment="Center" Template="{StaticResource ClearIcon}" />
|
<ContentControl MaxWidth="16" HorizontalAlignment="Center" Template="{StaticResource ClearIcon}" />
|
||||||
<Label Content="{x:Static loc:Localization.ClearLabel}" />
|
<Label Content="{x:Static loc:Localization.ClearLabel}" />
|
||||||
|
@ -86,7 +92,7 @@
|
||||||
</Button>
|
</Button>
|
||||||
</Grid>
|
</Grid>
|
||||||
</GroupBox>
|
</GroupBox>
|
||||||
<GroupBox Grid.Column="1" Grid.ColumnSpan="3" Grid.Row="1" Header="{x:Static loc:Localization.ActionBarLabel}">
|
<GroupBox Name="SingleFileGroupDuplicateActions" Grid.Column="1" Grid.ColumnSpan="3" Grid.Row="1" Header="{x:Static loc:Localization.ActionBarLabel}">
|
||||||
<StackPanel Orientation="Horizontal" Grid.Row="0" Grid.Column="1">
|
<StackPanel Orientation="Horizontal" Grid.Row="0" Grid.Column="1">
|
||||||
<Button Grid.Row="0" Grid.Column="1" Name="btnKeepLargest" 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}}" Tag="largest" Click="PerformDuplicateAction_Click">
|
<Button Grid.Row="0" Grid.Column="1" Name="btnKeepLargest" 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}}" Tag="largest" Click="PerformDuplicateAction_Click">
|
||||||
<StackPanel Orientation="Horizontal">
|
<StackPanel Orientation="Horizontal">
|
||||||
|
@ -109,6 +115,22 @@
|
||||||
<CheckBox Name="checkboxArchiveRemainingFiles" VerticalAlignment="Center" IsChecked="True" Content="{x:Static loc:Localization.ActionArchiveLabel}" />
|
<CheckBox Name="checkboxArchiveRemainingFiles" VerticalAlignment="Center" IsChecked="True" Content="{x:Static loc:Localization.ActionArchiveLabel}" />
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
</GroupBox>
|
</GroupBox>
|
||||||
|
<GroupBox Name="AllFileGroupsDuplicateActions" Grid.Column="1" Grid.ColumnSpan="3" Grid.Row="1" Header="{x:Static loc:Localization.ActionBarLabel}" Visibility="Hidden">
|
||||||
|
<StackPanel Orientation="Horizontal" Grid.Row="0" Grid.Column="1">
|
||||||
|
<Button Grid.Row="0" Grid.Column="1" Name="btnAllKeepLargest" 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}}" Tag="largest" Click="PerformDuplicateActionAll_Click">
|
||||||
|
<StackPanel Orientation="Horizontal">
|
||||||
|
<ContentControl MaxWidth="16" HorizontalAlignment="Center" Template="{StaticResource LargeFileIcon}" />
|
||||||
|
<Label Content="{x:Static loc:Localization.ActionLargestLabel}" />
|
||||||
|
</StackPanel>
|
||||||
|
</Button>
|
||||||
|
<Button Grid.Row="0" Grid.Column="1" Name="btnAllKeepSmallest" 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}}" Tag="smallest" Click="PerformDuplicateActionAll_Click">
|
||||||
|
<StackPanel Orientation="Horizontal">
|
||||||
|
<ContentControl MaxWidth="16" HorizontalAlignment="Center" Template="{StaticResource SmallFileIcon}" />
|
||||||
|
<Label Content="{x:Static loc:Localization.ActionSmallestLabel}" />
|
||||||
|
</StackPanel>
|
||||||
|
</Button>
|
||||||
|
</StackPanel>
|
||||||
|
</GroupBox>
|
||||||
<ListBox x:Name="listBoxDupes" Grid.Row="2" Grid.Column="0" Initialized="ListBoxDupes_Initialized" ItemsSource="{Binding ScanResults.DuplicateFiles, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type mdfinder:MainWindow}}}" SelectionChanged="ListBoxDupes_SelectionChanged">
|
<ListBox x:Name="listBoxDupes" Grid.Row="2" Grid.Column="0" Initialized="ListBoxDupes_Initialized" ItemsSource="{Binding ScanResults.DuplicateFiles, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type mdfinder:MainWindow}}}" SelectionChanged="ListBoxDupes_SelectionChanged">
|
||||||
<ListBox.ItemTemplate>
|
<ListBox.ItemTemplate>
|
||||||
<DataTemplate>
|
<DataTemplate>
|
||||||
|
@ -128,8 +150,8 @@
|
||||||
<RowDefinition Height="*" />
|
<RowDefinition Height="*" />
|
||||||
</Grid.RowDefinitions>
|
</Grid.RowDefinitions>
|
||||||
<Grid.ColumnDefinitions>
|
<Grid.ColumnDefinitions>
|
||||||
<ColumnDefinition Width="*"/>
|
<ColumnDefinition Width="*" />
|
||||||
<ColumnDefinition Width="*"/>
|
<ColumnDefinition Width="*" />
|
||||||
</Grid.ColumnDefinitions>
|
</Grid.ColumnDefinitions>
|
||||||
<StackPanel Orientation="Vertical">
|
<StackPanel Orientation="Vertical">
|
||||||
<StackPanel Orientation="Horizontal">
|
<StackPanel Orientation="Horizontal">
|
||||||
|
@ -144,7 +166,7 @@
|
||||||
<DataGrid Name="datagridFileList" Grid.Row="1" Grid.Column="0" AutoGenerateColumns="False" CanUserAddRows="False" CanUserDeleteRows="False" ItemsSource="{Binding ScanResults.SelectedDuplicateFileGroup.FileRecords, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type mdfinder:MainWindow}}}" SelectionChanged="DatagridFileList_SelectionChanged">
|
<DataGrid Name="datagridFileList" Grid.Row="1" Grid.Column="0" AutoGenerateColumns="False" CanUserAddRows="False" CanUserDeleteRows="False" ItemsSource="{Binding ScanResults.SelectedDuplicateFileGroup.FileRecords, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type mdfinder:MainWindow}}}" SelectionChanged="DatagridFileList_SelectionChanged">
|
||||||
<DataGrid.Resources>
|
<DataGrid.Resources>
|
||||||
<Style TargetType="Hyperlink">
|
<Style TargetType="Hyperlink">
|
||||||
<EventSetter Event="Click" Handler="Hyperlink_Click"/>
|
<EventSetter Event="Click" Handler="Hyperlink_Click" />
|
||||||
<Setter Property="Foreground" Value="DarkGreen"></Setter>
|
<Setter Property="Foreground" Value="DarkGreen"></Setter>
|
||||||
<Style.Triggers>
|
<Style.Triggers>
|
||||||
<DataTrigger Binding="{Binding IsSelected, RelativeSource= {RelativeSource AncestorType={x:Type DataGridRow}}}" Value="True">
|
<DataTrigger Binding="{Binding IsSelected, RelativeSource= {RelativeSource AncestorType={x:Type DataGridRow}}}" Value="True">
|
||||||
|
@ -166,7 +188,7 @@
|
||||||
</DataGridTemplateColumn.CellTemplate>
|
</DataGridTemplateColumn.CellTemplate>
|
||||||
</DataGridTemplateColumn>
|
</DataGridTemplateColumn>
|
||||||
<DataGridTextColumn IsReadOnly="True" Header="{x:Static loc:Localization.ColumnHeadingPath}" Binding="{Binding Path, Converter={StaticResource URIConverter}}" />
|
<DataGridTextColumn IsReadOnly="True" Header="{x:Static loc:Localization.ColumnHeadingPath}" Binding="{Binding Path, Converter={StaticResource URIConverter}}" />
|
||||||
<DataGridTextColumn IsReadOnly="True" Header="{x:Static loc:Localization.ColumnHeadingSize}" Binding="{Binding Size, Converter={StaticResource SizeConverter}}"/>
|
<DataGridTextColumn IsReadOnly="True" Header="{x:Static loc:Localization.ColumnHeadingSize}" Binding="{Binding Size, Converter={StaticResource SizeConverter}}" />
|
||||||
<DataGridTemplateColumn Header="{x:Static loc:Localization.ColumnHeaderKeep}">
|
<DataGridTemplateColumn Header="{x:Static loc:Localization.ColumnHeaderKeep}">
|
||||||
<DataGridTemplateColumn.CellTemplate>
|
<DataGridTemplateColumn.CellTemplate>
|
||||||
<DataTemplate>
|
<DataTemplate>
|
||||||
|
@ -240,7 +262,9 @@
|
||||||
</Grid>
|
</Grid>
|
||||||
</Grid>
|
</Grid>
|
||||||
</Grid>
|
</Grid>
|
||||||
<Image Name="imagePreview" Visibility="Hidden" />
|
<Grid Name="imagePanel" Visibility="Hidden">
|
||||||
|
<!--<Image Name="imagePreview" Visibility="Visible" />-->
|
||||||
|
</Grid>
|
||||||
<TextBlock Name="textPreview" Visibility="Hidden" />
|
<TextBlock Name="textPreview" Visibility="Hidden" />
|
||||||
<StackPanel Name="stackNoPreview" Orientation="Vertical" VerticalAlignment="Center">
|
<StackPanel Name="stackNoPreview" Orientation="Vertical" VerticalAlignment="Center">
|
||||||
<ContentControl Grid.Column="0" Template="{StaticResource NoPreviewIcon}" Width="64" Margin="0,0,4,0" />
|
<ContentControl Grid.Column="0" Template="{StaticResource NoPreviewIcon}" Width="64" Margin="0,0,4,0" />
|
||||||
|
@ -248,8 +272,8 @@
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
</Grid>
|
</Grid>
|
||||||
</Grid>
|
</Grid>
|
||||||
<Label x:Name="txtProgressLabel" Grid.Row="3" Grid.ColumnSpan="4" Panel.ZIndex="1" />
|
<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"/>
|
<ProgressBar Grid.Row="3" Grid.ColumnSpan="4" Name="progressBar" Minimum="0" Height="16" />
|
||||||
</Grid>
|
</Grid>
|
||||||
</DockPanel>
|
</DockPanel>
|
||||||
</Window>
|
</Window>
|
|
@ -36,7 +36,6 @@ namespace mdfinder
|
||||||
/// <summary> The text extentions. </summary>
|
/// <summary> The text extentions. </summary>
|
||||||
private static readonly string[] TEXT_EXTENTIONS = new[] { ".TXT", ".XML", ".HTM", ".HTML", ".JS", ".CSS" };
|
private static readonly string[] TEXT_EXTENTIONS = new[] { ".TXT", ".XML", ".HTM", ".HTML", ".JS", ".CSS" };
|
||||||
|
|
||||||
|
|
||||||
#region Properties
|
#region Properties
|
||||||
|
|
||||||
/// <summary> Gets or sets the database. </summary>
|
/// <summary> Gets or sets the database. </summary>
|
||||||
|
@ -59,7 +58,7 @@ namespace mdfinder
|
||||||
/// <value> The scan results. </value>
|
/// <value> The scan results. </value>
|
||||||
public ScanResults ScanResults { get; set; }
|
public ScanResults ScanResults { get; set; }
|
||||||
|
|
||||||
#endregion
|
#endregion Properties
|
||||||
|
|
||||||
#region Constructors
|
#region Constructors
|
||||||
|
|
||||||
|
@ -75,9 +74,9 @@ namespace mdfinder
|
||||||
this.Scanner.DirectoryFound += (sender, args) => Dispatcher.Invoke(() => txtProgressLabel.Content = args.Directory.Name);
|
this.Scanner.DirectoryFound += (sender, args) => Dispatcher.Invoke(() => txtProgressLabel.Content = args.Directory.Name);
|
||||||
this.Scanner.FilesFound += (sender, args) =>
|
this.Scanner.FilesFound += (sender, args) =>
|
||||||
{
|
{
|
||||||
foreach (var file in args.Files)
|
foreach(var file in args.Files)
|
||||||
{
|
{
|
||||||
if (Properties.Settings.Default.SkipEmptyFiles && file.Length == 0)
|
if(Properties.Settings.Default.SkipEmptyFiles && file.Length == 0)
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -87,12 +86,12 @@ namespace mdfinder
|
||||||
Dispatcher.Invoke(() => txtProgressLabel.Content = file.FullName);
|
Dispatcher.Invoke(() => txtProgressLabel.Content = file.FullName);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
this.Scanner.ReportProgress += (sender, args) => Dispatcher.Invoke(() => { if (args.Processed > 0) { this.progressBar.Value = args.Percentage * 100; } });
|
this.Scanner.ReportProgress += (sender, args) => Dispatcher.Invoke(() => { if(args.Processed > 0) { this.progressBar.Value = args.Percentage * 100; } });
|
||||||
|
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion Constructors
|
||||||
|
|
||||||
#region Methods
|
#region Methods
|
||||||
|
|
||||||
|
@ -103,13 +102,13 @@ namespace mdfinder
|
||||||
/// </returns>
|
/// </returns>
|
||||||
private IEnumerable<IHashProvider> GetProviderPlugins()
|
private IEnumerable<IHashProvider> GetProviderPlugins()
|
||||||
{
|
{
|
||||||
if (!string.IsNullOrWhiteSpace(Properties.Settings.Default.ProviderFolder) && Directory.Exists(Properties.Settings.Default.ProviderFolder))
|
if(!string.IsNullOrWhiteSpace(Properties.Settings.Default.ProviderFolder) && Directory.Exists(Properties.Settings.Default.ProviderFolder))
|
||||||
{
|
{
|
||||||
var directory = new DirectoryInfo(Properties.Settings.Default.ProviderFolder);
|
var directory = new DirectoryInfo(Properties.Settings.Default.ProviderFolder);
|
||||||
foreach (var pluginFile in directory.GetFiles("*.dll"))
|
foreach(var pluginFile in directory.GetFiles("*.dll"))
|
||||||
{
|
{
|
||||||
var assembly = Assembly.LoadFrom(pluginFile.FullName);
|
var assembly = Assembly.LoadFrom(pluginFile.FullName);
|
||||||
foreach (var type in assembly.GetTypes().Where(t => t.GetInterface("IHashProvider") != null))
|
foreach(var type in assembly.GetTypes().Where(t => t.GetInterface("IHashProvider") != null))
|
||||||
{
|
{
|
||||||
yield return Activator.CreateInstance(type) as IHashProvider;
|
yield return Activator.CreateInstance(type) as IHashProvider;
|
||||||
}
|
}
|
||||||
|
@ -140,11 +139,12 @@ namespace mdfinder
|
||||||
this.mediaPreview.Stop();
|
this.mediaPreview.Stop();
|
||||||
|
|
||||||
this.mediaPreview.Source = null;
|
this.mediaPreview.Source = null;
|
||||||
this.imagePreview.Source = null;
|
this.imagePanel.RowDefinitions.Clear();
|
||||||
|
this.imagePanel.Children.Clear();
|
||||||
this.textPreview.Text = string.Empty;
|
this.textPreview.Text = string.Empty;
|
||||||
|
|
||||||
this.mediaPreviewContainer.Visibility = Visibility.Hidden;
|
this.mediaPreviewContainer.Visibility = Visibility.Hidden;
|
||||||
this.imagePreview.Visibility = Visibility.Hidden;
|
this.imagePanel.Visibility = Visibility.Hidden;
|
||||||
this.textPreview.Visibility = Visibility.Hidden;
|
this.textPreview.Visibility = Visibility.Hidden;
|
||||||
this.stackNoPreview.Visibility = Visibility.Visible;
|
this.stackNoPreview.Visibility = Visibility.Visible;
|
||||||
}
|
}
|
||||||
|
@ -156,7 +156,7 @@ namespace mdfinder
|
||||||
{
|
{
|
||||||
var fbd = new FolderBrowserDialog();
|
var fbd = new FolderBrowserDialog();
|
||||||
|
|
||||||
if (fbd.ShowDialog() == System.Windows.Forms.DialogResult.OK)
|
if(fbd.ShowDialog() == System.Windows.Forms.DialogResult.OK)
|
||||||
{
|
{
|
||||||
txtScanLocation.Text = fbd.SelectedPath;
|
txtScanLocation.Text = fbd.SelectedPath;
|
||||||
}
|
}
|
||||||
|
@ -169,7 +169,7 @@ namespace mdfinder
|
||||||
{
|
{
|
||||||
var location = txtScanLocation.Text;
|
var location = txtScanLocation.Text;
|
||||||
ResetMediaPreview();
|
ResetMediaPreview();
|
||||||
if (!this.Scanner.IsScanning)
|
if(!this.Scanner.IsScanning)
|
||||||
{
|
{
|
||||||
new Thread(() =>
|
new Thread(() =>
|
||||||
{
|
{
|
||||||
|
@ -191,6 +191,20 @@ namespace mdfinder
|
||||||
SetDuplicateFileCollection(Enumerable.Empty<DuplicateFileGroup>());
|
SetDuplicateFileCollection(Enumerable.Empty<DuplicateFileGroup>());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void BtnNotDuplicate_Click(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
if(this.ScanResults.SelectedDuplicateFileGroup != null)
|
||||||
|
{
|
||||||
|
foreach(var fileRecord in this.ScanResults.SelectedDuplicateFileGroup.FileRecords)
|
||||||
|
{
|
||||||
|
this.Database.RemoveFileRecord(fileRecord.Id);
|
||||||
|
}
|
||||||
|
ResetMediaPreview();
|
||||||
|
this.ScanResults.DuplicateFiles = this.ScanResults.DuplicateFiles.Except(new[] { this.ScanResults.SelectedDuplicateFileGroup });
|
||||||
|
this.ScanResults.SelectedDuplicateFileGroup = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary> Event handler. Called by Hyperlink for click events. </summary>
|
/// <summary> Event handler. Called by Hyperlink for click events. </summary>
|
||||||
/// <param name="sender"> Source of the event. </param>
|
/// <param name="sender"> Source of the event. </param>
|
||||||
/// <param name="e"> Routed event information. </param>
|
/// <param name="e"> Routed event information. </param>
|
||||||
|
@ -238,9 +252,67 @@ namespace mdfinder
|
||||||
/// <param name="e"> Selection changed event information. </param>
|
/// <param name="e"> Selection changed event information. </param>
|
||||||
private void ListBoxDupes_SelectionChanged(object sender, SelectionChangedEventArgs e)
|
private void ListBoxDupes_SelectionChanged(object sender, SelectionChangedEventArgs e)
|
||||||
{
|
{
|
||||||
if (e.AddedItems.Count > 0)
|
if(e.AddedItems.Count > 0)
|
||||||
{
|
{
|
||||||
this.ScanResults.SelectedDuplicateFileGroup = e.AddedItems[0] as DuplicateFileGroup;
|
this.mediaPreview.Source = null;
|
||||||
|
this.imagePanel.Children.Clear();
|
||||||
|
this.imagePanel.RowDefinitions.Clear();
|
||||||
|
this.textPreview.Text = string.Empty;
|
||||||
|
|
||||||
|
var rowCount = 0;
|
||||||
|
var selectedGroup = e.AddedItems[0] as DuplicateFileGroup;
|
||||||
|
|
||||||
|
if(selectedGroup.FileRecords.All(f => IMAGE_EXTENTIONS.Contains(System.IO.Path.GetExtension(f.Path.LocalPath).ToUpper())))
|
||||||
|
{
|
||||||
|
this.SingleFileGroupDuplicateActions.Visibility = Visibility.Hidden;
|
||||||
|
this.AllFileGroupsDuplicateActions.Visibility = Visibility.Visible;
|
||||||
|
|
||||||
|
for(int i = 0; i < selectedGroup.FileRecords.Count; i++)
|
||||||
|
{
|
||||||
|
var rowDefinition = new RowDefinition();
|
||||||
|
rowDefinition.Height = new GridLength(1, GridUnitType.Star);
|
||||||
|
this.imagePanel.RowDefinitions.Add(rowDefinition);
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach(var item in selectedGroup.FileRecords)
|
||||||
|
{
|
||||||
|
var fileRecord = item as FileRecord;
|
||||||
|
|
||||||
|
var extension = System.IO.Path.GetExtension(fileRecord.Path.LocalPath).ToUpper();
|
||||||
|
if(IMAGE_EXTENTIONS.Contains(extension))
|
||||||
|
{
|
||||||
|
this.mediaPreview.Source = null;
|
||||||
|
var image = new Image();
|
||||||
|
image.Source = new BitmapImage(fileRecord.Path);
|
||||||
|
this.imagePanel.Children.Add(image);
|
||||||
|
Grid.SetRow(image, rowCount++);
|
||||||
|
this.textPreview.Text = string.Empty;
|
||||||
|
|
||||||
|
this.mediaPreviewContainer.Visibility = Visibility.Hidden;
|
||||||
|
this.imagePanel.Visibility = Visibility.Visible;
|
||||||
|
this.textPreview.Visibility = Visibility.Hidden;
|
||||||
|
this.stackNoPreview.Visibility = Visibility.Hidden;
|
||||||
|
}
|
||||||
|
else if(TEXT_EXTENTIONS.Contains(extension))
|
||||||
|
{
|
||||||
|
this.mediaPreview.Source = null;
|
||||||
|
this.imagePanel.Children.Clear();
|
||||||
|
this.imagePanel.RowDefinitions.Clear();
|
||||||
|
this.textPreview.Text = File.ReadAllText(fileRecord.Path.LocalPath);
|
||||||
|
|
||||||
|
this.mediaPreviewContainer.Visibility = Visibility.Hidden;
|
||||||
|
this.imagePanel.Visibility = Visibility.Hidden;
|
||||||
|
this.textPreview.Visibility = Visibility.Visible;
|
||||||
|
this.stackNoPreview.Visibility = Visibility.Hidden;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.ScanResults.SelectedDuplicateFileGroup = selectedGroup;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
this.ScanResults.SelectedDuplicateFileGroup = e.AddedItems[0] as DuplicateFileGroup;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -260,47 +332,107 @@ namespace mdfinder
|
||||||
|
|
||||||
ResetMediaPreview();
|
ResetMediaPreview();
|
||||||
|
|
||||||
if (duplicateFileGroup != null)
|
new Thread(() =>
|
||||||
{
|
{
|
||||||
if(tag == "largest")
|
if(duplicateFileGroup != null)
|
||||||
{
|
{
|
||||||
actionableFiles = duplicateFileGroup.FileRecords.OrderByDescending(fr => fr.Size).Skip(1);
|
if(tag == "largest")
|
||||||
}
|
{
|
||||||
else if(tag == "smallest")
|
actionableFiles = duplicateFileGroup.FileRecords.OrderByDescending(fr => fr.Size).Skip(1);
|
||||||
{
|
}
|
||||||
actionableFiles = duplicateFileGroup.FileRecords.OrderBy(fr => fr.Size).Skip(1);
|
else if(tag == "smallest")
|
||||||
}
|
{
|
||||||
else
|
actionableFiles = duplicateFileGroup.FileRecords.OrderBy(fr => fr.Size).Skip(1);
|
||||||
{
|
}
|
||||||
actionableFiles = duplicateFileGroup.FileRecords.Where(fr => !fr.Keep);
|
else
|
||||||
}
|
{
|
||||||
|
actionableFiles = duplicateFileGroup.FileRecords.Where(fr => !fr.Keep);
|
||||||
|
}
|
||||||
|
|
||||||
ZipArchive zipFile = null;
|
ZipArchive zipFile = null;
|
||||||
|
|
||||||
if (archive)
|
if(archive)
|
||||||
{
|
{
|
||||||
zipFile = ZipFile.Open(System.IO.Path.Combine(Properties.Settings.Default.ArchiveFolder, duplicateFileGroup.Hash + ".zip"), ZipArchiveMode.Update);
|
zipFile = ZipFile.Open(System.IO.Path.Combine(Properties.Settings.Default.ArchiveFolder, duplicateFileGroup.Hash + ".zip"), ZipArchiveMode.Update);
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (var file in actionableFiles)
|
|
||||||
{
|
|
||||||
if(archive && zipFile != null)
|
if(archive && zipFile != null)
|
||||||
|
{
|
||||||
|
//Zip everything up.
|
||||||
|
foreach(var file in actionableFiles)
|
||||||
|
{
|
||||||
|
zipFile.CreateEntryFromFile(file.Path.LocalPath, System.IO.Path.GetFileName(file.Path.LocalPath));
|
||||||
|
}
|
||||||
|
zipFile.Dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach(var file in actionableFiles)
|
||||||
|
{
|
||||||
|
//Do the deletion
|
||||||
|
File.Delete(file.Path.LocalPath);
|
||||||
|
|
||||||
|
this.Database.RemoveFileRecord(file.Id);
|
||||||
|
}
|
||||||
|
|
||||||
|
SetDuplicateFileCollection(GetDuplicateFiles());
|
||||||
|
}
|
||||||
|
}).Start();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void PerformDuplicateActionAll_Click(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
var tag = (sender as System.Windows.Controls.Button).Tag.ToString();
|
||||||
|
var duplicateFileGroups = new List<DuplicateFileGroup>();
|
||||||
|
var actionableFiles = new List<FileRecord>();
|
||||||
|
|
||||||
|
foreach(var item in this.listBoxDupes.Items)
|
||||||
|
{
|
||||||
|
duplicateFileGroups.Add(item as DuplicateFileGroup);
|
||||||
|
}
|
||||||
|
|
||||||
|
ResetMediaPreview();
|
||||||
|
|
||||||
|
this.IsEnabled = false;
|
||||||
|
|
||||||
|
new Thread(() =>
|
||||||
|
{
|
||||||
|
foreach(var duplicateFileGroup in duplicateFileGroups)
|
||||||
|
{
|
||||||
|
if(tag == "largest")
|
||||||
|
{
|
||||||
|
actionableFiles.AddRange(duplicateFileGroup.FileRecords.Where(fr => !fr.Keep).OrderByDescending(fr => fr.Size).Skip(1));
|
||||||
|
}
|
||||||
|
else if(tag == "smallest")
|
||||||
|
{
|
||||||
|
actionableFiles.AddRange(duplicateFileGroup.FileRecords.Where(fr => !fr.Keep).OrderBy(fr => fr.Size).Skip(1));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var zipFile = ZipFile.Open(System.IO.Path.Combine(Properties.Settings.Default.ArchiveFolder, "archive.zip"), ZipArchiveMode.Update);
|
||||||
|
|
||||||
|
//Zip all the actionable files at once.
|
||||||
|
if(zipFile != null)
|
||||||
|
{
|
||||||
|
foreach(var file in actionableFiles)
|
||||||
{
|
{
|
||||||
zipFile.CreateEntryFromFile(file.Path.LocalPath, System.IO.Path.GetFileName(file.Path.LocalPath));
|
zipFile.CreateEntryFromFile(file.Path.LocalPath, System.IO.Path.GetFileName(file.Path.LocalPath));
|
||||||
}
|
}
|
||||||
|
|
||||||
File.Delete(file.Path.LocalPath);
|
|
||||||
|
|
||||||
this.Database.RemoveFileRecord(file.Id);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(zipFile != null)
|
|
||||||
{
|
|
||||||
zipFile.Dispose();
|
zipFile.Dispose();
|
||||||
|
|
||||||
|
foreach(var file in actionableFiles)
|
||||||
|
{
|
||||||
|
//Do the deletions
|
||||||
|
File.Delete(file.Path.LocalPath);
|
||||||
|
|
||||||
|
this.Database.RemoveFileRecord(file.Id);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SetDuplicateFileCollection(GetDuplicateFiles());
|
SetDuplicateFileCollection(GetDuplicateFiles());
|
||||||
}
|
|
||||||
|
Dispatcher.Invoke(() => this.IsEnabled = true);
|
||||||
|
}).Start();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -310,43 +442,58 @@ namespace mdfinder
|
||||||
/// <param name="e"> Selection changed event information. </param>
|
/// <param name="e"> Selection changed event information. </param>
|
||||||
private void DatagridFileList_SelectionChanged(object sender, SelectionChangedEventArgs e)
|
private void DatagridFileList_SelectionChanged(object sender, SelectionChangedEventArgs e)
|
||||||
{
|
{
|
||||||
if (e.AddedItems.Count == 1)
|
if(e.AddedItems.Count == 1)
|
||||||
{
|
{
|
||||||
var fileRecord = e.AddedItems[0] as FileRecord;
|
var fileRecord = e.AddedItems[0] as FileRecord;
|
||||||
if (fileRecord != null)
|
|
||||||
|
if(fileRecord != null)
|
||||||
{
|
{
|
||||||
|
this.SingleFileGroupDuplicateActions.Visibility = Visibility.Visible;
|
||||||
|
this.AllFileGroupsDuplicateActions.Visibility = Visibility.Hidden;
|
||||||
|
|
||||||
var extension = System.IO.Path.GetExtension(fileRecord.Path.LocalPath).ToUpper();
|
var extension = System.IO.Path.GetExtension(fileRecord.Path.LocalPath).ToUpper();
|
||||||
|
|
||||||
if (MEDIA_EXTENTIONS.Contains(extension))
|
if(MEDIA_EXTENTIONS.Contains(extension))
|
||||||
{
|
{
|
||||||
this.mediaPreview.Source = fileRecord.Path;
|
this.mediaPreview.Source = fileRecord.Path;
|
||||||
this.imagePreview.Source = null;
|
this.imagePanel.Children.Clear();
|
||||||
|
this.imagePanel.RowDefinitions.Clear();
|
||||||
this.textPreview.Text = string.Empty;
|
this.textPreview.Text = string.Empty;
|
||||||
|
|
||||||
this.mediaPreviewContainer.Visibility = Visibility.Visible;
|
this.mediaPreviewContainer.Visibility = Visibility.Visible;
|
||||||
this.imagePreview.Visibility = Visibility.Hidden;
|
this.imagePanel.Visibility = Visibility.Hidden;
|
||||||
this.textPreview.Visibility = Visibility.Hidden;
|
this.textPreview.Visibility = Visibility.Hidden;
|
||||||
this.stackNoPreview.Visibility = Visibility.Hidden;
|
this.stackNoPreview.Visibility = Visibility.Hidden;
|
||||||
}
|
}
|
||||||
else if (IMAGE_EXTENTIONS.Contains(extension))
|
else if(IMAGE_EXTENTIONS.Contains(extension))
|
||||||
{
|
{
|
||||||
|
var rowDefinition = new RowDefinition();
|
||||||
|
rowDefinition.Height = new GridLength(1, GridUnitType.Star);
|
||||||
|
var image = new Image();
|
||||||
|
image.Source = new BitmapImage(fileRecord.Path);
|
||||||
|
Grid.SetRow(image, 0);
|
||||||
|
|
||||||
this.mediaPreview.Source = null;
|
this.mediaPreview.Source = null;
|
||||||
this.imagePreview.Source = new BitmapImage(fileRecord.Path);
|
this.imagePanel.Children.Clear();
|
||||||
|
this.imagePanel.RowDefinitions.Clear();
|
||||||
|
this.imagePanel.RowDefinitions.Add(rowDefinition);
|
||||||
|
this.imagePanel.Children.Add(image);
|
||||||
this.textPreview.Text = string.Empty;
|
this.textPreview.Text = string.Empty;
|
||||||
|
|
||||||
this.mediaPreviewContainer.Visibility = Visibility.Hidden;
|
this.mediaPreviewContainer.Visibility = Visibility.Hidden;
|
||||||
this.imagePreview.Visibility = Visibility.Visible;
|
this.imagePanel.Visibility = Visibility.Visible;
|
||||||
this.textPreview.Visibility = Visibility.Hidden;
|
this.textPreview.Visibility = Visibility.Hidden;
|
||||||
this.stackNoPreview.Visibility = Visibility.Hidden;
|
this.stackNoPreview.Visibility = Visibility.Hidden;
|
||||||
}
|
}
|
||||||
else if (TEXT_EXTENTIONS.Contains(extension))
|
else if(TEXT_EXTENTIONS.Contains(extension))
|
||||||
{
|
{
|
||||||
this.mediaPreview.Source = null;
|
this.mediaPreview.Source = null;
|
||||||
this.imagePreview.Source = null;
|
this.imagePanel.Children.Clear();
|
||||||
|
this.imagePanel.RowDefinitions.Clear();
|
||||||
this.textPreview.Text = File.ReadAllText(fileRecord.Path.LocalPath);
|
this.textPreview.Text = File.ReadAllText(fileRecord.Path.LocalPath);
|
||||||
|
|
||||||
this.mediaPreviewContainer.Visibility = Visibility.Hidden;
|
this.mediaPreviewContainer.Visibility = Visibility.Hidden;
|
||||||
this.imagePreview.Visibility = Visibility.Hidden;
|
this.imagePanel.Visibility = Visibility.Hidden;
|
||||||
this.textPreview.Visibility = Visibility.Visible;
|
this.textPreview.Visibility = Visibility.Visible;
|
||||||
this.stackNoPreview.Visibility = Visibility.Hidden;
|
this.stackNoPreview.Visibility = Visibility.Hidden;
|
||||||
}
|
}
|
||||||
|
@ -358,7 +505,6 @@ namespace mdfinder
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endregion
|
|
||||||
|
|
||||||
|
|
||||||
|
#endregion Methods
|
||||||
}
|
}
|
Loading…
Reference in a new issue