From 3987f9cab0cb3d0d15d0ba784db14be4472f45ca Mon Sep 17 00:00:00 2001 From: Roy Ben-Shabat Date: Tue, 23 Jul 2019 11:33:41 +0300 Subject: Implemented color catalogs module. --- .../Tango.MachineStudio.Catalogs/CatalogsModule.cs | 2 +- .../ObservableCollectionToViewSourceConverter.cs | 49 ++++ .../Excel/ColorGroup.cs | 16 ++ .../Excel/ColorItem.cs | 29 +++ .../Excel/ColorRecipe.cs | 21 ++ .../Tango.MachineStudio.Catalogs/Excel/Media.cs | 13 + .../Tango.MachineStudio.Catalogs.csproj | 10 + .../Templates/ExportTemplate - BACKUP.xlsx | Bin 0 -> 20347 bytes .../Templates/ExportTemplate - bad.xlsx | Bin 0 -> 20904 bytes .../Templates/ExportTemplate.xlsx | Bin 0 -> 21324 bytes .../ViewModels/MainViewVM.cs | 281 +++++++++++++++++++++ .../Views/CatalogView.xaml | 104 ++++---- .../Views/CatalogView.xaml.cs | 27 ++ 13 files changed, 508 insertions(+), 44 deletions(-) create mode 100644 Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Catalogs/Converters/ObservableCollectionToViewSourceConverter.cs create mode 100644 Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Catalogs/Excel/ColorGroup.cs create mode 100644 Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Catalogs/Excel/ColorItem.cs create mode 100644 Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Catalogs/Excel/ColorRecipe.cs create mode 100644 Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Catalogs/Excel/Media.cs create mode 100644 Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Catalogs/Templates/ExportTemplate - BACKUP.xlsx create mode 100644 Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Catalogs/Templates/ExportTemplate - bad.xlsx create mode 100644 Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Catalogs/Templates/ExportTemplate.xlsx (limited to 'Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Catalogs') diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Catalogs/CatalogsModule.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Catalogs/CatalogsModule.cs index 5c17bf32e..389a2cb5d 100644 --- a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Catalogs/CatalogsModule.cs +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Catalogs/CatalogsModule.cs @@ -51,7 +51,7 @@ namespace Tango.MachineStudio.Catalogs { get { - return Permissions.RunColorCaptureModule; + return Permissions.RunCatalogsModule; } } diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Catalogs/Converters/ObservableCollectionToViewSourceConverter.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Catalogs/Converters/ObservableCollectionToViewSourceConverter.cs new file mode 100644 index 000000000..050539741 --- /dev/null +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Catalogs/Converters/ObservableCollectionToViewSourceConverter.cs @@ -0,0 +1,49 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.ComponentModel; +using System.Globalization; +using System.Linq; +using System.Text; +using System.Threading; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Data; + +namespace Tango.MachineStudio.Catalogs.Converters +{ + public class ObservableCollectionToViewSourceConverter : IValueConverter + { + public object Convert(object value, Type targetType, object parameter, CultureInfo culture) + { + String sortMember = parameter != null ? parameter.ToString() : null; + IList list = value as IList; + if (list != null) + { + var view = CollectionViewSource.GetDefaultView(list); + view.SortDescriptions.Clear(); + + //Delay because the DataGrid clears the sort description after source change. + Task.Factory.StartNew(() => + { + Thread.Sleep(10); + + Application.Current.Dispatcher.BeginInvoke(new Action(() => + { + view.SortDescriptions.Add(new SortDescription(sortMember, ListSortDirection.Ascending)); + view.Refresh(); + })); + }); + return view; + } + + return value; + } + + public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) + { + throw new NotImplementedException(); + } + } +} diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Catalogs/Excel/ColorGroup.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Catalogs/Excel/ColorGroup.cs new file mode 100644 index 000000000..852311883 --- /dev/null +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Catalogs/Excel/ColorGroup.cs @@ -0,0 +1,16 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Media; + +namespace Tango.MachineStudio.Catalogs.Excel +{ + public class ColorGroup + { + public Color GroupColor { get; set; } + public String GroupName { get; set; } + public int GroupIndex { get; set; } + } +} diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Catalogs/Excel/ColorItem.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Catalogs/Excel/ColorItem.cs new file mode 100644 index 000000000..9d5011325 --- /dev/null +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Catalogs/Excel/ColorItem.cs @@ -0,0 +1,29 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Media; + +namespace Tango.MachineStudio.Catalogs.Excel +{ + public class ColorItem + { + public Color ItemColor { get; set; } + public String Group { get; set; } + public int Code { get; set; } + public String Name { get; set; } + public int ItemIndex { get; set; } + public int Red { get; set; } + public int Green { get; set; } + public int Blue { get; set; } + public double L { get; set; } + public double A { get; set; } + public double B { get; set; } + public double Cyan { get; set; } + public double Magenta { get; set; } + public double Yellow { get; set; } + public double Black { get; set; } + public int Region { get; set; } + } +} diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Catalogs/Excel/ColorRecipe.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Catalogs/Excel/ColorRecipe.cs new file mode 100644 index 000000000..724652cd4 --- /dev/null +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Catalogs/Excel/ColorRecipe.cs @@ -0,0 +1,21 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Media; + +namespace Tango.MachineStudio.Catalogs.Excel +{ + public class ColorRecipe + { + public Color R_Color { get; set; } + public String R_Name { get; set; } + public String R_Media { get; set; } + public double R_Cyan { get; set; } + public double R_Magenta { get; set; } + public double R_Yellow { get; set; } + public double R_Black { get; set; } + public int R_Region { get; set; } + } +} diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Catalogs/Excel/Media.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Catalogs/Excel/Media.cs new file mode 100644 index 000000000..d65b1a986 --- /dev/null +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Catalogs/Excel/Media.cs @@ -0,0 +1,13 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Tango.MachineStudio.Catalogs.Excel +{ + public class Media + { + public String MediaName { get; set; } + } +} diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Catalogs/Tango.MachineStudio.Catalogs.csproj b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Catalogs/Tango.MachineStudio.Catalogs.csproj index e90e00b41..5473c28bc 100644 --- a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Catalogs/Tango.MachineStudio.Catalogs.csproj +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Catalogs/Tango.MachineStudio.Catalogs.csproj @@ -68,6 +68,11 @@ + + + + + @@ -120,6 +125,7 @@ SettingsSingleFileGenerator Settings.Designer.cs + @@ -134,6 +140,10 @@ {a34ee0f0-649d-41c8-8489-b6f1cc6924ee} Tango.Core + + {ca87a608-7b17-4c98-88f2-42abee10f4c1} + Tango.Documents + {bc932dbd-7cdb-488c-99e4-f02cf441f55e} Tango.Logging diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Catalogs/Templates/ExportTemplate - BACKUP.xlsx b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Catalogs/Templates/ExportTemplate - BACKUP.xlsx new file mode 100644 index 000000000..44abd31db Binary files /dev/null and b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Catalogs/Templates/ExportTemplate - BACKUP.xlsx differ diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Catalogs/Templates/ExportTemplate - bad.xlsx b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Catalogs/Templates/ExportTemplate - bad.xlsx new file mode 100644 index 000000000..d95727038 Binary files /dev/null and b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Catalogs/Templates/ExportTemplate - bad.xlsx differ diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Catalogs/Templates/ExportTemplate.xlsx b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Catalogs/Templates/ExportTemplate.xlsx new file mode 100644 index 000000000..e57422725 Binary files /dev/null and b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Catalogs/Templates/ExportTemplate.xlsx differ diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Catalogs/ViewModels/MainViewVM.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Catalogs/ViewModels/MainViewVM.cs index a10e944f9..6494b9d2c 100644 --- a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Catalogs/ViewModels/MainViewVM.cs +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Catalogs/ViewModels/MainViewVM.cs @@ -12,6 +12,11 @@ using Tango.MachineStudio.Catalogs.Contracts; using Tango.MachineStudio.Common.Notifications; using Tango.Core.Commands; using Tango.BL.Builders; +using Tango.Documents; +using Microsoft.Win32; +using Tango.Core.Helpers; +using System.IO; +using Tango.MachineStudio.Catalogs.Excel; namespace Tango.MachineStudio.Catalogs.ViewModels { @@ -112,6 +117,16 @@ namespace Tango.MachineStudio.Catalogs.ViewModels /// public RelayCommand SaveActiveCatalogCommand { get; set; } + /// + /// Gets or sets the export excel command. + /// + public RelayCommand ExportExcelCommand { get; set; } + + /// + /// Gets or sets the import excel command. + /// + public RelayCommand ImportExcelCommand { get; set; } + #endregion #region Constructors @@ -129,6 +144,8 @@ namespace Tango.MachineStudio.Catalogs.ViewModels DeleteCatalogCommand = new RelayCommand(DeleteSelectedCatalog, () => SelectedCatalog != null); BackToCatalogsCommand = new RelayCommand(BackToCatalogs); SaveActiveCatalogCommand = new RelayCommand(SaveActiveCatalog); + ExportExcelCommand = new RelayCommand(ExportCatalogToExcel); + ImportExcelCommand = new RelayCommand(ImportCatalogFromExcel); } /// @@ -256,6 +273,21 @@ namespace Tango.MachineStudio.Catalogs.ViewModels } } + public void OnGroupDeleted(ColorCatalogsGroup group) + { + group.Delete(_activeCatalogContext); + } + + public void OnItemDeleted(ColorCatalogsItem item) + { + item.Delete(_activeCatalogContext); + } + + public void OnRecipeDeleted(ColorCatalogsItemsRecipe recipe) + { + recipe.Delete(_activeCatalogContext); + } + private async void SaveActiveCatalog() { if (ActiveCatalog != null) @@ -289,6 +321,255 @@ namespace Tango.MachineStudio.Catalogs.ViewModels #endregion + #region Export / Import Excel + + public void ExportCatalogToExcel() + { + SaveFileDialog dlg = new SaveFileDialog(); + dlg.Filter = "Excel Documents|*.xlsx"; + if (dlg.ShowDialog().Value) + { + using (_notification.PushTaskItem("Exporting catalog to file...")) + { + Task.Factory.StartNew(() => + { + try + { + IsFree = false; + + Stream stream = null; + bool dispose = false; + String file = AssemblyHelper.GetCurrentAssemblyFolder() + "\\Templates\\ExportTemplate.xlsx"; + + if (File.Exists(file)) + { + stream = File.OpenRead(file); + dispose = true; + } + else + { + stream = EmbeddedResourceHelper.GetEmbeddedResourceStream("Tango.MachineStudio.Catalogs.Templates.ExportTemplate.xlsx"); + } + + byte[] data = new byte[stream.Length]; + stream.Read(data, 0, data.Length); + File.WriteAllBytes(dlg.FileName, data); + + if (dispose) + { + stream.Dispose(); + } + + ExcelWriter writer = new ExcelWriter(dlg.FileName); + + List medias = RMLS.Select(x => new Media() + { + MediaName = x.Name, + }).ToList(); + + writer.WriteData(medias, "RML"); + + List groups = ActiveCatalog.ColorCatalogsGroups.Select(x => new ColorGroup() + { + GroupColor = x.Color, + GroupName = x.Name, + GroupIndex = x.GroupIndex, + }).ToList(); + + writer.WriteData(groups, "Groups"); + + List items = ActiveCatalog.ColorCatalogsGroups.SelectMany(x => x.ColorCatalogsItems).Select(x => new ColorItem() + { + + ItemColor = x.Color, + Group = x.ColorCatalogsGroup.Name, + Code = x.Code, + Name = x.Name, + ItemIndex = x.ItemIndex, + Red = x.Red, + Green = x.Green, + Blue = x.Blue, + L = x.L, + A = x.A, + B = x.B, + Cyan = x.Cyan, + Magenta = x.Magenta, + Yellow = x.Yellow, + Black = x.Black, + Region = x.ProcessParametersTableIndex, + + }).ToList(); + + writer.WriteData(items, "Colors"); + + List recipes = ActiveCatalog.ColorCatalogsGroups.SelectMany(x => x.ColorCatalogsItems).SelectMany(x => x.ColorCatalogsItemsRecipes).Select(x => new ColorRecipe() + { + + R_Color = x.ColorCatalogsItem.Color, + R_Name = x.ColorCatalogsItem.Name, + R_Media = x.Rml.Name, + R_Cyan = x.Cyan, + R_Magenta = x.Magenta, + R_Yellow = x.Yellow, + R_Black = x.Black, + R_Region = x.ProcessParametersTableIndex, + + + }).ToList(); + + writer.WriteData(recipes, "Recipes"); + + writer.Dispose(); + + InvokeUI(() => + { + _notification.ShowInfo("Catalog exported successfully."); + }); + } + catch (Exception ex) + { + LogManager.Log(ex, $"Error exporting color catalog to {dlg.FileName}"); + + InvokeUI(() => + { + _notification.ShowError($"An error occurred while trying to export the catalog. Make sure the selected excel file is closed and data is valid.\n{ex.FlattenMessage()}"); + }); + } + finally + { + IsFree = true; + } + }); + } + } + } + + public void ImportCatalogFromExcel() + { + OpenFileDialog dlg = new OpenFileDialog(); + dlg.Filter = "Excel Documents|*.xlsx"; + if (dlg.ShowDialog().Value) + { + using (_notification.PushTaskItem("Merging catalog from file...")) + { + Task.Factory.StartNew(() => + { + try + { + ExcelReader reader = new ExcelReader(dlg.FileName); + var groups = reader.GetData("Groups"); + reader.Dispose(); + + reader = new ExcelReader(dlg.FileName); + var colors = reader.GetData("Colors"); + reader.Dispose(); + + reader = new ExcelReader(dlg.FileName); + var recipes = reader.GetData("Recipes"); + reader.Dispose(); + + foreach (var group in groups.Where(x => !ActiveCatalog.ColorCatalogsGroups.ToList().Exists(y => y.Name == x.GroupName))) + { + ColorCatalogsGroup newGroup = new ColorCatalogsGroup(); + newGroup.Name = group.GroupName; + newGroup.GroupIndex = group.GroupIndex; + ActiveCatalog.ColorCatalogsGroups.Add(newGroup); + } + + foreach (var item in colors) + { + var existinItem = ActiveCatalog.ColorCatalogsGroups.SelectMany(x => x.ColorCatalogsItems).SingleOrDefault(x => x.Code == item.Code); + var group = ActiveCatalog.ColorCatalogsGroups.SingleOrDefault(x => x.Name == item.Group); + + bool inserting = false; + + if (existinItem == null) + { + existinItem = new ColorCatalogsItem(); + inserting = true; + } + else + { + if (existinItem.ColorCatalogsGroup != group) + { + existinItem.ColorCatalogsGroup.ColorCatalogsItems.Remove(existinItem); + group.ColorCatalogsItems.Add(existinItem); + } + } + + existinItem.ColorCatalogsGroup = group; + existinItem.Code = item.Code; + existinItem.Name = item.Name; + existinItem.ItemIndex = item.ItemIndex; + existinItem.Red = item.Red; + existinItem.Green = item.Green; + existinItem.Blue = item.Blue; + existinItem.L = item.L; + existinItem.A = item.A; + existinItem.B = item.B; + existinItem.Cyan = item.Cyan; + existinItem.Magenta = item.Magenta; + existinItem.Yellow = item.Yellow; + existinItem.Black = item.Black; + existinItem.ProcessParametersTableIndex = item.Region; + + if (inserting) + { + _activeCatalogContext.ColorCatalogsItems.Add(existinItem); + } + } + + foreach (var recipe in recipes) + { + var existingRecipe = ActiveCatalog.ColorCatalogsGroups.SelectMany(x => x.ColorCatalogsItems).SelectMany(x => x.ColorCatalogsItemsRecipes).SingleOrDefault(x => x.ColorCatalogsItem.Name == recipe.R_Name && x.Rml.Name == recipe.R_Media); + + bool inserting = false; + + if (existingRecipe == null) + { + existingRecipe = new ColorCatalogsItemsRecipe(); + existingRecipe.Rml = RMLS.SingleOrDefault(x => x.Name == recipe.R_Media); + existingRecipe.ColorCatalogsItem = ActiveCatalog.ColorCatalogsGroups.SelectMany(x => x.ColorCatalogsItems).SingleOrDefault(x => x.Name == recipe.R_Name); + inserting = true; + } + + existingRecipe.Cyan = recipe.R_Cyan; + existingRecipe.Magenta = recipe.R_Magenta; + existingRecipe.Yellow = recipe.R_Yellow; + existingRecipe.Black = recipe.R_Black; + existingRecipe.ProcessParametersTableIndex = recipe.R_Region; + + if (inserting) + { + _activeCatalogContext.ColorCatalogsItemsRecipes.Add(existingRecipe); + } + } + + InvokeUI(() => + { + _notification.ShowInfo("Catalog imported successfully."); + }); + } + catch (Exception ex) + { + LogManager.Log(ex, $"Error importing color catalog to {dlg.FileName}"); + + InvokeUI(() => + { + _notification.ShowError($"An error occurred while trying to merge the catalog. Please check your data.\n{ex.FlattenMessage()}"); + }); + } + finally + { + IsFree = true; + } + }); + } + } + } + + #endregion + #region Application Ready public async override void OnApplicationReady() diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Catalogs/Views/CatalogView.xaml b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Catalogs/Views/CatalogView.xaml index 8dc6b5d02..9f3dd701a 100644 --- a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Catalogs/Views/CatalogView.xaml +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Catalogs/Views/CatalogView.xaml @@ -5,6 +5,7 @@ xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:vm="clr-namespace:Tango.MachineStudio.Catalogs.ViewModels" xmlns:controls="clr-namespace:Tango.SharedUI.Controls;assembly=Tango.SharedUI" + xmlns:localConverters="clr-namespace:Tango.MachineStudio.Catalogs.Converters" xmlns:mahapps="http://metro.mahapps.com/winfx/xaml/controls" xmlns:enumerations="clr-namespace:Tango.BL.Enumerations;assembly=Tango.BL" xmlns:converters="clr-namespace:Tango.SharedUI.Converters;assembly=Tango.SharedUI" @@ -16,6 +17,7 @@ +