diff --git a/WPFLinkTool/Logger.cs b/WPFLinkTool/Logger.cs new file mode 100644 index 0000000..781ba0f --- /dev/null +++ b/WPFLinkTool/Logger.cs @@ -0,0 +1,28 @@ +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Controls; + +namespace WPFLinkTool +{ + public class Logger + { + public ObservableCollection LogEntries; + public ScrollViewer Scroller; + + public Logger(ScrollViewer scroller) + { + LogEntries = new(); + Scroller = scroller; + } + + public void Log(string message) + { + LogEntries.Add(DateTime.Now.ToString() + " " + message); + Scroller.ScrollToBottom(); + } + } +} diff --git a/WPFLinkTool/MainWindow.xaml b/WPFLinkTool/MainWindow.xaml index 568f1e9..22dc2cb 100644 --- a/WPFLinkTool/MainWindow.xaml +++ b/WPFLinkTool/MainWindow.xaml @@ -17,7 +17,7 @@ - + @@ -53,7 +53,15 @@ - + + + + + + + + + diff --git a/WPFLinkTool/MainWindow.xaml.cs b/WPFLinkTool/MainWindow.xaml.cs index 54cc069..a3fee7c 100644 --- a/WPFLinkTool/MainWindow.xaml.cs +++ b/WPFLinkTool/MainWindow.xaml.cs @@ -26,7 +26,7 @@ public MainWindow() { InitializeComponent(); SharedViewModel shared = new(); - DataContext = new MainWindowViewModel(shared); + DataContext = new MainWindowViewModel(shared, Scroller); } } } diff --git a/WPFLinkTool/ViewModel/Commands/DeleteUnusedCommand.cs b/WPFLinkTool/ViewModel/Commands/DeleteUnusedCommand.cs index e9d225a..b0192c4 100644 --- a/WPFLinkTool/ViewModel/Commands/DeleteUnusedCommand.cs +++ b/WPFLinkTool/ViewModel/Commands/DeleteUnusedCommand.cs @@ -48,6 +48,7 @@ protected override async Task ExecuteAsync(object parameter) foreach (var file in dBFiles) { await Task.Run(() => File.Delete(dbDir + @"\" + file)); + vm.Loggerr.Log($"Deleting {file}"); vm.Progress += progressStep; } } @@ -58,6 +59,7 @@ protected override async Task ExecuteAsync(object parameter) vm.UIEnabled = true; vm.LinkButtonEnabled = true; IsExecuting = false; + vm.Loggerr.Log("Delete operation finished."); } } } diff --git a/WPFLinkTool/ViewModel/Commands/MakeHardLinksCommand.cs b/WPFLinkTool/ViewModel/Commands/MakeHardLinksCommand.cs index 7538b05..f7a9bca 100644 --- a/WPFLinkTool/ViewModel/Commands/MakeHardLinksCommand.cs +++ b/WPFLinkTool/ViewModel/Commands/MakeHardLinksCommand.cs @@ -11,7 +11,6 @@ namespace WPFLinkTool public class MakeHardLinksCommand : AsyncCommandBase { private readonly MainWindowViewModel vm; - private bool proceed = false; private bool delet = false; private string target; @@ -25,10 +24,8 @@ protected override async Task ExecuteAsync(object parameter) IsExecuting = true; vm.UIEnabled = false; vm.LinkButtonEnabled = false; - DataInstance selectedInstance = vm.SelectedInstance; - - var prompt = MessageBox.Show($"Creating hard links from {selectedInstance.InstanceName}.\nProceed to link target selection?", "Make hard links", MessageBoxButtons.YesNo, MessageBoxIcon.Question); + var prompt = MessageBox.Show($"Creating hard links from {vm.SelectedInstance.InstanceName}.\nProceed to link target selection?", "Make hard links", MessageBoxButtons.YesNo, MessageBoxIcon.Question); if (prompt == DialogResult.Yes) { FolderBrowserDialog dialog = new(); @@ -36,33 +33,17 @@ protected override async Task ExecuteAsync(object parameter) { target = dialog.SelectedPath; - foreach (var file in selectedInstance.InstanceFiles) - { - if (File.Exists(target + file.Location + @"\" + file.OriginalFileName)) - { - var prompt2 = MessageBox.Show(@$"{file.Location}\{file.OriginalFileName} already exists in the target directory!" + "\n" - + "Do you want to delete all encountered dupes before making hard links? (If you didn't know or forgot, overwriting hard linked files changes the originals) 'No' cancels the whole operation.", "Duplicate files detected!", MessageBoxButtons.YesNo, MessageBoxIcon.Warning); + vm.Loggerr.Log("Checking for duplicates..."); - if (prompt2 == DialogResult.Yes) - { - proceed = true; - delet = true; - break; - } - break; - } - else - { - proceed = true; - } - } + bool proceed = await Task.Run(() => CheckDupes()); if (delet) { - foreach (var file in selectedInstance.InstanceFiles) + foreach (var file in vm.SelectedInstance.InstanceFiles) { if (File.Exists(target + file.Location + @"\" + file.OriginalFileName)) { + vm.Loggerr.Log(@$"Deleting {target + file.Location + @"\" + file.OriginalFileName}"); File.Delete(target + file.Location + @"\" + file.OriginalFileName); } } @@ -70,25 +51,27 @@ protected override async Task ExecuteAsync(object parameter) if (proceed) { - var uniqueFolders = (from folders in selectedInstance.InstanceFiles + var uniqueFolders = (from folders in vm.SelectedInstance.InstanceFiles where folders.Location != string.Empty select folders.Location).Distinct(); - double progressStep = 100D / (selectedInstance.InstanceFiles.Count + uniqueFolders.Count()); + double progressStep = 100D / (vm.SelectedInstance.InstanceFiles.Count + uniqueFolders.Count()); foreach (var folder in uniqueFolders) { if (!Directory.Exists(target + folder)) { + vm.Loggerr.Log($@"Creating directory {target + folder}"); await Task.Run(() => Directory.CreateDirectory(target + folder)); } vm.Progress += progressStep; } - foreach (var file in selectedInstance.InstanceFiles) + foreach (var file in vm.SelectedInstance.InstanceFiles) { if (!File.Exists(target + file.Location + @"\" + file.OriginalFileName)) { + vm.Loggerr.Log($@"Linking {target + file.Location + @"\" + file.OriginalFileName}"); await Task.Run(() => CreateHardLink(target + file.Location + @"\" + file.OriginalFileName, dbDir + @"\" + file.HashedFileName, IntPtr.Zero)); } @@ -101,13 +84,37 @@ await Task.Run(() => CreateHardLink(target + file.Location + @"\" + file.Origina vm.Progress = 0; - + vm.Loggerr.Log("Link operation finished"); vm.UIEnabled = true; vm.LinkButtonEnabled = true; IsExecuting = false; } + bool CheckDupes() + { + foreach (var file in vm.SelectedInstance.InstanceFiles) + { + if (File.Exists(target + file.Location + @"\" + file.OriginalFileName)) + { + var prompt2 = MessageBox.Show(@$"{file.Location}\{file.OriginalFileName} already exists in the target directory!" + "\n" + + "Do you want to delete all encountered dupes before making hard links? (If you didn't know or forgot, overwriting hard linked files changes the originals). Nothing was linked yet. 'No' cancels the whole operation.", "Duplicate files detected!", MessageBoxButtons.YesNo, MessageBoxIcon.Warning); + + if (prompt2 == DialogResult.Yes) + { + delet = true; + return true; + } + else + { + return false; + } + } + } + return true; + } + + [DllImport("Kernel32.dll", CharSet = CharSet.Unicode)] static extern bool CreateHardLink( string lpFileName, diff --git a/WPFLinkTool/ViewModel/MainWindowViewModel.cs b/WPFLinkTool/ViewModel/MainWindowViewModel.cs index 921b632..7a4a76c 100644 --- a/WPFLinkTool/ViewModel/MainWindowViewModel.cs +++ b/WPFLinkTool/ViewModel/MainWindowViewModel.cs @@ -6,6 +6,7 @@ using System.IO; using System.Linq; using System.Threading.Tasks; +using System.Windows.Controls; using System.Windows.Forms; using System.Windows.Input; using System.Xml; @@ -18,6 +19,22 @@ public class MainWindowViewModel : ViewModelBase { public SharedViewModel Shared; + public Logger Loggerr; + + public ObservableCollection LogEntries + { + get + { + return _logEntries; + } + set + { + _logEntries = value; + OnPropertyChanged(nameof(LogEntries)); + } + } + private ObservableCollection _logEntries; + private string _dBSize; public string DBSize { @@ -130,18 +147,25 @@ public ObservableCollection InstanceList public ICommand MakeHardLinksCommand { get; private set; } public ICommand DeleteUnusedCommand { get; private set; } - public MainWindowViewModel(SharedViewModel shared) + public ScrollViewer Scroller; + + public MainWindowViewModel(SharedViewModel shared, ScrollViewer scroller) { if (!Directory.Exists(dbDir)) Directory.CreateDirectory(dbDir); Shared = shared; + Scroller = scroller; + Loggerr = new(Scroller); OpenAddInstanceWindow = new(OpenInstanceWindow); DeleteInstanceCommand = new(DeleteInstance); - MakeHardLinksCommand = new MakeHardLinksCommand(this, (ex) => HeaderText = ex.Message); - DeleteUnusedCommand = new DeleteUnusedCommand(this, (ex) => HeaderText = ex.Message); + MakeHardLinksCommand = new MakeHardLinksCommand(this, (ex) => Loggerr.Log(ex.Message)); + DeleteUnusedCommand = new DeleteUnusedCommand(this, (ex) => Loggerr.Log(ex.Message)); LoadDBInfo(); Task.Run(() => UpdateDBSize()); Task.Run(() => UpdateSumSize()); + //HeaderText = "Loading finished, probably... Have a nice day!"; + LogEntries = Loggerr.LogEntries; + Loggerr.Log("Loading finished, probably... Have a nice day!"); } private void LoadDBInfo() @@ -171,7 +195,7 @@ public void OpenInstanceWindow(object o) public void DeleteInstance(object o) { - var prompt = MessageBox.Show($"Delete {SelectedInstance.InstanceName}?", "Delete instance", MessageBoxButtons.YesNo, MessageBoxIcon.Question); + var prompt = MessageBox.Show($"Delete {SelectedInstance.InstanceName}? This will not delete the files.", "Delete instance", MessageBoxButtons.YesNo, MessageBoxIcon.Question); if (prompt == DialogResult.Yes) { Shared.Info.InstanceList.Remove(SelectedInstance); @@ -179,6 +203,7 @@ public void DeleteInstance(object o) LinkButtonEnabled = false; UpdateSumSize(); OnPropertyChanged(nameof(InstanceList)); + Loggerr.Log("Deleting instance operation finished."); } } public void UpdateDBSize() diff --git a/WPFLinkTool/WPFLinkTool.csproj b/WPFLinkTool/WPFLinkTool.csproj index 19ee4d9..1121237 100644 --- a/WPFLinkTool/WPFLinkTool.csproj +++ b/WPFLinkTool/WPFLinkTool.csproj @@ -6,6 +6,7 @@ true true otoge.ico + $(VersionPrefix)