bfr/BFR/MainWindow.xaml.cs

145 lines
5.7 KiB
C#
Raw Normal View History

using System;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using System.Collections.Generic;
using System.Text.RegularExpressions;
using Avalonia;
using Avalonia.Controls;
using Avalonia.Markup.Xaml;
using BFR.Helpers;
using BFR.DataModels;
using Avalonia.Interactivity;
using Avalonia.Input;
using Avalonia.LogicalTree;
using Avalonia.VisualTree;
namespace BFR
{
public partial class MainWindow : Window
{
public readonly AvaloniaProperty[] HandledProperties = new AvaloniaProperty[] { TextBox.TextProperty, ComboBox.SelectedItemProperty, NumericUpDown.ValueProperty, CheckBox.IsCheckedProperty };
private bool HandleEvents = false;
public async Task OpenDirectoryButtonClick() => OpenDirectory(await new OpenFolderDialog() { Directory = WorkingDirectory }.ShowAsync(this));
public void OpenDirectory(string directory)
{
WorkingDirectory = directory;
AllFiles.ReplaceAll(Directory.GetFiles(WorkingDirectory).Select(x => new FileModel(x)));
Filter();
}
public void FilterChanged(object sender, AvaloniaPropertyChangedEventArgs e)
{
if(HandledProperties.Contains(e.Property) && HandleEvents)
Filter(); // Bind to PropertyChanged
}
public void Filter()
{
// Filter all files in the directory for those satisfying the given filters
Files.ReplaceAll(AllFiles.Where(x =>
(FilterExtension == "" || x.OldExtension == FilterExtension)
&& (FilterFullName ? x.OldFullName : x.OldName).RegexContains(FilterRegex ? FilterPattern : Regex.Escape(FilterPattern))));
Preview();
}
public void PreviewChanged(object sender, AvaloniaPropertyChangedEventArgs e)
{
if (HandledProperties.Contains(e.Property) && HandleEvents)
Preview(); // Bind to PropertyChanged
}
public void Preview()
{
// Reset all files to how they currently exist
foreach (var file in Files)
file.Path = file.OldPath;
// Apply operations
foreach (var operation in Operations)
operation.ApplyTo(Files);
// Validate that there are any changes, and that the new file names are all unique.
IsCommitButtonEnabled =
Files.Any(x => x.Path != x.OldPath) // Check for changes
&& Files.GroupBy(x => x.Path).All(g => g.Count() == 1) // Check for duplicates
&& !Files.Any(x => x.FullName == "") // Check for empty file names
&& !Files.Any(x => "?%*:<>|/\\\"".Any(y => x.FullName.Contains(y))); // Check for invalid characters
// Refresh the file list to guarantee that changes are displayed. TODO: Find a better way to do this.
Files.ReplaceAll(new List<FileModel>(Files));
}
public void AddOperation()
{
HandleEvents = false;
if (Operations.Count >= 1)
Operations.Insert(
SelectedOperation >= 0 ? SelectedOperation + 1 : Operations.Count,
OperationTypes[SelectedOperationType].Create());
else Operations.Add(OperationTypes[SelectedOperationType].Create());
HandleEvents = true;
Preview();
}
private ListBox OperationsListBox;
private ListBoxItem DragItem;
public void DeleteOperation(object sender, PointerReleasedEventArgs e)
{
var hoveredItem = (ListBoxItem)OperationsListBox.GetLogicalChildren().FirstOrDefault(x => this.GetVisualsAt(e.GetPosition(this)).Contains(((IVisual)x).GetVisualChildren().First()));
if(hoveredItem != null) Operations.RemoveAt(OperationsListBox.GetLogicalChildren().ToList().IndexOf(hoveredItem));
Preview();
}
public void StartMoveOperation(object sender, PointerPressedEventArgs e) =>
DragItem = OperationsListBox.GetLogicalChildren().Cast<ListBoxItem>().Single(x => x.IsPointerOver);
public void EndMoveOperation(object sender, PointerReleasedEventArgs e)
{
var hoveredItem = (ListBoxItem)OperationsListBox.GetLogicalChildren().FirstOrDefault(x => this.GetVisualsAt(e.GetPosition(this)).Contains(((IVisual)x).GetVisualChildren().First()));
if (DragItem == null ||
hoveredItem == null ||
DragItem == hoveredItem)
return;
Operations.Move(
OperationsListBox.GetLogicalChildren().ToList().IndexOf(DragItem),
OperationsListBox.GetLogicalChildren().ToList().IndexOf(hoveredItem));
DragItem = null;
Preview();
}
public void Commit()
{
foreach (var file in Files)
if (file.OldPath != file.Path)
File.Move(file.OldPath, file.Path);
UndoStack.Push(new List<FileModel>(Files));
UndoCount = UndoStack.Count;
OpenDirectory(WorkingDirectory);
}
public void Undo()
{
foreach (var file in UndoStack.Pop())
File.Move(file.Path, file.OldPath);
UndoCount = UndoStack.Count;
OpenDirectory(WorkingDirectory);
}
public MainWindow() => InitializeComponent();
private void InitializeComponent()
{
AvaloniaXamlLoader.Load(this);
DataContext = this;
OpenDirectory(Environment.OSVersion.Platform == PlatformID.Win32NT ? @"C:\Users" : @"\home");
HandleEvents = true;
OperationsListBox = this.Find<ListBox>("OperationsListBox");
}
}
}