using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Windows; using System.Windows.Controls; using System.Windows.Media; using InABox.Core; using Microsoft.Win32; namespace InABox.DynamicGrid { public enum DocumentAction { Replace, UseExisting, MakeCopy } public class DocumentEditorControl : DynamicEditorControl { public delegate Document FindDocumentEvent(string FileName); public delegate Document? GetDocumentEvent(Guid id); public delegate void OnUpdateOtherEditorHandler(string columnname, object value); public delegate void SaveDocumentEvent(Document document); private Document _document = new(); private TextBox Editor; public DocumentEditorControl() { OtherColumns = new Dictionary(); } public Dictionary OtherColumns { get; } public string Filter { get; set; } public event GetDocumentEvent? OnGetDocument; public event FindDocumentEvent? OnFindDocument; public event SaveDocumentEvent? OnSaveDocument; public event OnUpdateOtherEditorHandler? OnUpdateOtherEditor; protected override FrameworkElement CreateEditor() { var Grid = new Grid { VerticalAlignment = VerticalAlignment.Stretch, HorizontalAlignment = HorizontalAlignment.Stretch }; //Grid.ColumnDefinitions.Add(new ColumnDefinition() { Width = new GridLength(25, GridUnitType.Pixel) }); Grid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(1, GridUnitType.Star) }); Grid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(50, GridUnitType.Pixel) }); Grid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(50, GridUnitType.Pixel) }); Grid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(50, GridUnitType.Pixel) }); Editor = new TextBox { VerticalAlignment = VerticalAlignment.Stretch, VerticalContentAlignment = VerticalAlignment.Center, HorizontalAlignment = HorizontalAlignment.Stretch, Margin = new Thickness(0, 0, 0, 0), IsEnabled = false }; //Editor.LostFocus += (o, e) => CheckChanged(); Editor.SetValue(Grid.ColumnProperty, 0); Editor.SetValue(Grid.RowProperty, 0); Grid.Children.Add(Editor); var Select = new Button { VerticalAlignment = VerticalAlignment.Stretch, VerticalContentAlignment = VerticalAlignment.Center, HorizontalAlignment = HorizontalAlignment.Stretch, Margin = new Thickness(5, 1, 0, 1), Content = "Select", Focusable = false }; Select.SetValue(Grid.ColumnProperty, 1); Select.SetValue(Grid.RowProperty, 0); Select.Click += Select_Click; Grid.Children.Add(Select); var Clear = new Button { VerticalAlignment = VerticalAlignment.Stretch, VerticalContentAlignment = VerticalAlignment.Center, HorizontalAlignment = HorizontalAlignment.Stretch, Margin = new Thickness(5, 1, 0, 1), Content = "Clear", Focusable = false }; Clear.SetValue(Grid.ColumnProperty, 2); Clear.SetValue(Grid.RowProperty, 0); Clear.Click += Clear_Click; Grid.Children.Add(Clear); var View = new Button { VerticalAlignment = VerticalAlignment.Stretch, VerticalContentAlignment = VerticalAlignment.Center, HorizontalAlignment = HorizontalAlignment.Stretch, Margin = new Thickness(5, 1, 0, 1), Content = "View", Focusable = false }; View.SetValue(Grid.ColumnProperty, 3); View.SetValue(Grid.RowProperty, 0); View.Click += View_Click; Grid.Children.Add(View); return Grid; } private void Select_Click(object sender, RoutedEventArgs e) { var dlg = new OpenFileDialog(); dlg.Filter = Filter; if (dlg.ShowDialog() == true) { var filename = Path.GetFileName(dlg.FileName).ToLower(); var timestamp = new FileInfo(dlg.FileName).LastWriteTime; var data = File.ReadAllBytes(dlg.FileName); var crc = CoreUtils.CalculateCRC(data); var existing = OnFindDocument?.Invoke(filename); if (existing != null) { if ((existing.TimeStamp == DateTime.MinValue || existing.TimeStamp.ToString("yyyy-MM-ddThh:mm.ss.fff") .Equals(timestamp.ToString("yyyy-MM-ddThh:mm.ss.fff"))) && existing.CRC.Equals(crc)) { if (existing.TimeStamp == DateTime.MinValue) { existing.TimeStamp = timestamp; OnSaveDocument?.Invoke(existing); } _document = existing; } else { var confirm = new DocumentConfirm { FileName = filename, LocalSize = data.Length, RemoteSize = existing.Data.Length, LocalTimeStamp = timestamp, RemoteTimeStamp = existing.TimeStamp }; if (confirm.ShowDialog() == true) { if (confirm.Result == DocumentAction.Replace) { existing.Data = data; existing.TimeStamp = timestamp; existing.CRC = crc; OnSaveDocument?.Invoke(existing); _document = existing; } else if (confirm.Result == DocumentAction.UseExisting) { _document = existing; } else if (confirm.Result == DocumentAction.MakeCopy) { var basefilename = Path.GetFileNameWithoutExtension(filename); var ext = Path.GetExtension(filename); var i = 0; while (existing != null) { i++; filename = Path.ChangeExtension(string.Format("{0} ({1})", basefilename, i), ext); existing = OnFindDocument(filename); } var document = new Document { FileName = filename, Data = data, TimeStamp = timestamp, CRC = crc }; OnSaveDocument?.Invoke(document); _document = document; } } } } else { _document = new Document { FileName = filename, Data = data, TimeStamp = timestamp, CRC = crc }; OnSaveDocument?.Invoke(_document); } Editor.Text = _document.FileName; if (OtherColumns.ContainsKey("FileName")) OtherValues[OtherColumns["FileName"]] = _document.FileName; CheckChanged(); } } private void View_Click(object sender, RoutedEventArgs e) { if (_document.ID == Guid.Empty) { MessageBox.Show("Please select a document first!"); return; } var ext = Path.GetExtension(_document.FileName); var filename = Path.ChangeExtension(Path.GetTempFileName(), ext); File.WriteAllBytes(filename, _document.Data); var gsProcessInfo = new ProcessStartInfo(); gsProcessInfo.Verb = "open"; gsProcessInfo.WindowStyle = ProcessWindowStyle.Normal; gsProcessInfo.FileName = filename; gsProcessInfo.UseShellExecute = true; Process.Start(gsProcessInfo); } private void Clear_Click(object sender, RoutedEventArgs e) { _document = new Document(); Editor.Text = ""; CheckChanged(); } public override int DesiredHeight() { return 25; } public override int DesiredWidth() { return int.MaxValue; } protected override Guid RetrieveValue() { return _document.ID; } protected override void UpdateValue(Guid value) { if (value != Guid.Empty) _document = OnGetDocument?.Invoke(value) ?? new Document(); Editor.Text = _document.FileName; } public override void SetFocus() { Editor.Focus(); } public override void SetColor(Color color) { Editor.Background = new SolidColorBrush(color); } } }