1
0
Fork 0
mirror of https://github.com/wagesj45/mdfinder.git synced 2024-12-21 16:02:30 -06:00
Bug fixes and UI redesigns.
This commit is contained in:
Jordan Wages 2020-06-20 13:46:52 -05:00
parent 1de70724b0
commit f230812765
6 changed files with 265 additions and 84 deletions

View file

@ -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
} }
} }

View file

@ -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
} }
} }

View file

@ -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>

View file

@ -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>

View file

@ -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>

View file

@ -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
} }