using System; using System.Drawing; using System.Drawing.Imaging; using System.IO; using System.Linq; using System.Windows; using System.Windows.Controls; using System.Windows.Input; using System.Windows.Media.Imaging; using Comal.Classes; using InABox.Clients; using InABox.Configuration; using InABox.Core; using InABox.Dxf; using InABox.Wpf; using InABox.WPF; using Microsoft.Win32; namespace PRSDesktop; public class ProductDockFilterButton : FilterButton { public ProductDockFilterButton() : base( new GlobalConfiguration("ProductDock.Product"), new UserConfiguration("ProductDock.Product")) { } } /// /// Interaction logic for ProductLookup.xaml /// public partial class ProductLookupDock : UserControl, IDockPanel { private ProductHoldingControl? _holdings; private Product[] Products = Array.Empty(); public ProductLookupDock() { InitializeComponent(); } public void Setup() { if (!Security.CanView()) return; if (_holdings == null) { _holdings = new ProductHoldingControl(); HoldingsTab.Content = _holdings; HoldingsTab.Visibility = Visibility.Visible; } _holdings.Refresh(true, false); } public void Refresh() { } private Filter? GetSearchFilter() { var search = Search.Text; if (!string.IsNullOrEmpty(search)) { return new Filter(x => x.Code).Contains(Search.Text).Or(x => x.Name).Contains(search); } else { return null; } } private void Reload() { var filters = new Filters(); filters.Add(GetSearchFilter()); filters.Add(FilterButton.GetFilter()); var filter = filters.Combine() ?? new Filter().None(); using (new WaitCursor()) { Products = Client.Query( filter, Columns.Required().Add(x => x.ID, x => x.Code, x => x.Name, x => x.Image.ID, x => x.Image.FileName), new SortOrder(x => x.Code)) .ToObjects().ToArray(); Items.ItemsSource = Products; if (Products.Any()) { Items.Focus(); Items.SelectedIndex = 0; var listBoxItem = (ListBoxItem)Items.ItemContainerGenerator.ContainerFromItem(Items.SelectedItem); listBoxItem?.Focus(); } } } private void Search_TextChanged(object sender, TextChangedEventArgs e) { } private void Search_KeyUp(object sender, KeyEventArgs e) { if (e.Key == Key.Enter) { Reload(); } else if (e.Key == Key.Down) { if (Products.Any()) { Items.Focus(); //Items.SelectedValue = items.First(); Items.SelectedIndex = 0; var listBoxItem = (ListBoxItem)Items.ItemContainerGenerator.ContainerFromItem(Items.SelectedItem); listBoxItem.Focus(); } } } private void Items_SelectionChanged(object sender, SelectionChangedEventArgs e) { Image.Source = null; if (e.AddedItems.Count > 0) { var item = e.AddedItems[0] as Product; if (!item.Image.ID.Equals(Guid.Empty)) new Client().Query( new Filter(x => x.ID).IsEqualTo(item.Image.ID), Columns.None().Add(x => x.ID, x => x.Data), null, CoreRange.All, (docs, error) => { var row = docs.Rows.FirstOrDefault(); if (row != null) { var id = row.Get(x => x.ID); var data = row.Get(x => x.Data); if (data?.Any() == true) { var ms = new MemoryStream(data); var bmp = new Bitmap(ms); Dispatcher.BeginInvoke( new Action(o => { if (Items.SelectedValue != null) { var sel = (Product)Items.SelectedValue; if (sel.Image.ID == o) Image.Source = bmp.AsBitmapImage(false); } }), id ); } } } ); else Image.Source = null; if (Security.CanView()) { _holdings.Product = item; _holdings.Refresh(false, true); } } else { Image.Source = null; } } private void Items_KeyUp(object sender, KeyEventArgs e) { } private void Items_KeyDown(object sender, KeyEventArgs e) { if (e.Key == Key.Up) if (Items.SelectedIndex == 0) Search.Focus(); } private void ImageMenu_Opened(object sender, RoutedEventArgs e) { var pdi = Items.SelectedItem as Product; var anyproducts = pdi != null; var validimage = pdi != null && pdi.Image.ID != Guid.Empty; LoadImageFromFile.IsEnabled = anyproducts; SaveImageToFile.IsEnabled = validimage; CopyImageToClipboard.IsEnabled = validimage; PasteImageFromClipboard.IsEnabled = anyproducts && (Clipboard.ContainsData("ProductImage") || Clipboard.ContainsImage()); ClearImage.IsEnabled = anyproducts; } private string SelectedProducts() { var product = Items.SelectedItem as Product; return product != null ? product.Code : ""; } private void UpdateProductImages(Guid id, string filename, Bitmap? bitmap) { var product = Items.SelectedItem as Product; if (product == null) return; var docid = id; if (bitmap != null && docid == Guid.Empty) { byte[] data = null; using (var ms = new MemoryStream()) { bitmap.Save(ms, ImageFormat.Png); data = ms.GetBuffer(); } var crc = CoreUtils.CalculateCRC(data); var doc = new Client().Query( new Filter(x => x.FileName).IsEqualTo(Path.GetFileName(filename)).And(x => x.CRC).IsEqualTo(crc), Columns.None().Add(x => x.ID) ).Rows.FirstOrDefault()?.ToObject(); if (doc == null) { doc = new Document { FileName = Path.GetFileName(filename), CRC = crc, TimeStamp = DateTime.Now, Data = data }; new Client().Save(doc, ""); } docid = doc.ID; } product.Image.ID = CoreUtils.FullGuid; product.CommitChanges(); product.Image.ID = docid; product.Image.FileName = Path.GetFileName(filename); new Client().Save(product, "Cleared Product Image", (p, err) => { }); Image.Source = bitmap?.AsBitmapImage(); } private Bitmap? ConvertDXFFile(string filename) { Bitmap? result = null; using (var stream = new FileStream(filename, FileMode.Open, FileAccess.Read)) { //String newfile = Path.ChangeExtension(Path.GetFileName(filename), "png"); try { result = DxfUtils.ProcessImage(stream); } catch (Exception e) { MessageWindow.ShowError("Could not load DXF file", e); result = null; } } return result; } private void LoadImageFromFile_Click(object sender, RoutedEventArgs e) { var product = Items.SelectedItem as Product; if (product == null) return; var dlg = new OpenFileDialog(); dlg.Filter = "Image Files (*.png;*.jpg;*.jpeg;*.bmp)|*.png;*.jpg;*.jpeg;*.bmp|DXF Files (*.dxf)|*.dxf"; if (dlg.ShowDialog() == true) { var filename = dlg.FileName.ToLower(); Progress.Show("Updating Images: " + Path.GetFileName(filename)); Bitmap? bmp = null; if (Path.GetExtension(filename).ToLower().Equals(".dxf")) bmp = ConvertDXFFile(filename); else bmp = System.Drawing.Image.FromFile(filename) as Bitmap; UpdateProductImages(Guid.Empty, filename, bmp); Progress.Close(); MessageBox.Show(string.Format("Imported [{0}] into [{1}]", Path.GetFileName(dlg.FileName), SelectedProducts())); } } private void SaveImageToFile_Click(object sender, RoutedEventArgs e) { var product = Items.SelectedItem as Product; if (product == null) return; var bmp = (Image.Source as BitmapImage).AsBitmap(); var dlg = new SaveFileDialog(); dlg.Filter = "Image Files (*.png)|*.png"; dlg.FileName = product.Image.FileName; if (dlg.ShowDialog() == true) bmp.Save(dlg.FileName); } private void CopyImageToClipboard_Click(object sender, RoutedEventArgs e) { var product = Items.SelectedItem as Product; if (product == null) return; var bmp = (Image.Source as BitmapImage).AsBitmap(); var data = new Tuple( product.Image.ID, product.Image.FileName, bmp ); Clipboard.SetData("ProductImage", data); } private void PasteImageFromClipboard_Click(object sender, RoutedEventArgs e) { if (Items.SelectedItem is not Product product) return; if (MessageBox.Show("Are you sure you wish to update the image for the selected product?", "Update Image", MessageBoxButton.YesNo, MessageBoxImage.Question) != MessageBoxResult.Yes) return; Progress.Show("Updating Images"); var id = Guid.Empty; var filename = ""; Bitmap? bitmap = null; if (Clipboard.ContainsData("ProductImage")) { if(Clipboard.GetData("ProductImage") is Tuple data) { id = data.Item1; filename = data.Item2; bitmap = data.Item3; } } else if (Clipboard.ContainsImage()) { var data = Clipboard.GetImage(); bitmap = data.AsBitmap2(); filename = string.Format("clip{0:yyyyMMddhhmmss}.png", DateTime.Now); if (Clipboard.ContainsFileDropList()) { var list = Clipboard.GetFileDropList(); if (list.Count > 0) filename = Path.ChangeExtension(Path.GetFileName(list[0]), ".png"); } //filename = String.Format("clip{0:yyyyMMddhhmmss}.png",DateTime.Now); //bitmap.Save(filename); id = Guid.Empty; } if (bitmap == null) { MessageBox.Show("Unable to paste data from clipboard"); return; } Progress.Show(""); UpdateProductImages(id, filename, bitmap); Progress.Close(); MessageBox.Show(string.Format("Pasted [{0}] into [{1}]", Path.GetFileName(filename), SelectedProducts())); } private void ClearImage_Click(object sender, RoutedEventArgs e) { if (MessageWindow.ShowYesNo("Are you sure you wish to clear the image for the selected product?", "Clear Image")) return; Progress.Show("Clearing Image"); UpdateProductImages(Guid.Empty, "", null); Progress.Close(); MessageBox.Show(string.Format("Cleared image from [{0}]", string.Join(", ", SelectedProducts()))); } private void Grid_MouseMove(object sender, MouseEventArgs e) { if(sender is not Grid grid || grid.Tag is not Product product || e.LeftButton != MouseButtonState.Pressed) { return; } DragDrop.DoDragDrop(grid, product, DragDropEffects.Copy); } private void FilterButton_OnFilterRefresh() { Reload(); } }