diff --git a/CtrEditor.csproj b/CtrEditor.csproj index 8dd0289..aa9ea0d 100644 --- a/CtrEditor.csproj +++ b/CtrEditor.csproj @@ -27,22 +27,27 @@ + + + + + @@ -89,19 +94,26 @@ + + + + + + + diff --git a/Icons/allselect.png b/Icons/allselect.png new file mode 100644 index 0000000..c140b79 Binary files /dev/null and b/Icons/allselect.png differ diff --git a/Icons/analyze.png b/Icons/analyze.png new file mode 100644 index 0000000..832c577 Binary files /dev/null and b/Icons/analyze.png differ diff --git a/Icons/choose.png b/Icons/choose.png new file mode 100644 index 0000000..1b056ea Binary files /dev/null and b/Icons/choose.png differ diff --git a/Icons/extract.png b/Icons/extract.png new file mode 100644 index 0000000..37180d5 Binary files /dev/null and b/Icons/extract.png differ diff --git a/Icons/unselect.png b/Icons/unselect.png new file mode 100644 index 0000000..c6d35ce Binary files /dev/null and b/Icons/unselect.png differ diff --git a/MainViewModel.cs b/MainViewModel.cs index 809332a..7bf3740 100644 --- a/MainViewModel.cs +++ b/MainViewModel.cs @@ -17,7 +17,11 @@ using CommunityToolkit.Mvvm.ComponentModel; using Xceed.Wpf.Toolkit.PropertyGrid; using System.Text.RegularExpressions; using System.Windows.Data; - +using CtrEditor.ObjetosSim.Extraccion_Datos; +using ClosedXML.Excel; +using DocumentFormat.OpenXml.Spreadsheet; +using CommunityToolkit.Mvvm.Input; +using CtrEditor.PopUps; namespace CtrEditor { @@ -56,12 +60,21 @@ namespace CtrEditor public ICommand TBSaveCommand { get; } public ICommand TBConnectPLCCommand { get; } public ICommand TBDisconnectPLCCommand { get; } + public ICommand TBExtractTagsCommand { get; } public ICommand TBEliminarUserControlCommand { get; } public ICommand TBDuplicarUserControlCommand { get; } public ICommand OpenWorkDirectoryCommand { get; } + public ICommand TBEliminarTodosCommand { get; } + public ICommand TBEliminarAutoCreatedCommand { get; } + public ICommand TBEliminarClonedCommand { get; } + public ICommand TBAssingPagesCommand { get; } + public ICommand TBMultiPageExtractTagsCommand { get; } + public ICommand TBMultiPageAnalizeCommand { get; } + + // Evento que se dispara cuando se selecciona una nueva imagen public event EventHandler ImageSelected; public event EventHandler TickSimulacion; @@ -197,6 +210,15 @@ namespace CtrEditor TBEliminarUserControlCommand = new RelayCommand(EliminarUserControl, () => habilitarEliminarUserControl); TBDuplicarUserControlCommand = new RelayCommand(DuplicarUserControl, () => habilitarEliminarUserControl); + TBExtractTagsCommand = new RelayCommand(ExtraerTags); + + TBEliminarTodosCommand = new RelayCommand(EliminarTodosCommand); + TBEliminarAutoCreatedCommand = new RelayCommand(EliminarAutoCreatedCommand); + TBEliminarClonedCommand = new RelayCommand(EliminarClonedCommand); + TBAssingPagesCommand = new RelayCommand(AssingPagesCommand); + TBMultiPageExtractTagsCommand = new RelayCommand(MultiPageExtractTagsCommand); + TBMultiPageAnalizeCommand = new RelayCommand(MultiPageAnalizeCommand); + stopwatch_Sim = new Stopwatch(); stopwatch_Sim.Start(); } @@ -252,6 +274,8 @@ namespace CtrEditor // Asignar los datos al UserControl UserControlFactory.AssignDatos(userControl, osObjeto, simulationManager); osObjeto._mainViewModel = this; + if (osObjeto.Id == null) // Para los objetos salvados antes de usar UniqueID + osObjeto.Id = new UniqueId().ObtenerNuevaID(); MainWindow.AgregarRegistrarUserControlCanvas(userControl); @@ -316,7 +340,7 @@ namespace CtrEditor } finally { - objDuplicar.RestaurarDatosNoSerializables(); + objDuplicar.RestaurarDatosNoSerializables(); } return NuevoObjetoDuplicado; } @@ -331,6 +355,198 @@ namespace CtrEditor } } + + private void EliminarTodosCommand() + { + var objetosSimulablesCopy = new List(ObjetosSimulables); + foreach (var obj in objetosSimulablesCopy) + RemoverObjetoSimulable(obj); + } + + private void EliminarAutoCreatedCommand() + { + var objetosSimulablesCopy = new List(ObjetosSimulables); + foreach (var obj in objetosSimulablesCopy) + if (obj.AutoCreated) + RemoverObjetoSimulable(obj); + } + + private void EliminarClonedCommand() + { + var objetosSimulablesCopy = new List(ObjetosSimulables); + foreach (var obj in objetosSimulablesCopy) + if (obj is osExtraccionTag TEobj && TEobj.Cloned) + RemoverObjetoSimulable(obj); + } + + private void AssingPagesCommand() + { + var assignImagesWindow = new AssignImagesWindow(); + var assignImagesViewModel = new AssignImagesViewModel(); + assignImagesViewModel.Initialize(this, assignImagesWindow); + assignImagesWindow.DataContext = assignImagesViewModel; + assignImagesWindow.ShowDialog(); + SaveStateObjetosSimulables(); + } + + private async Task WaitForUIUpdateAsync() + { + await Task.Yield(); + Application.Current.Dispatcher.Invoke(() => { }, DispatcherPriority.ApplicationIdle); + } + + + private async void MultiPageExtractTagsCommand() + { + var ImagenesSeleccionadas = new ObservableCollection(); + + StopSimulation(); + + var selectPagesWindow = new SelectPages(); + var selectPagesViewModel = new SelectPagesViewModel(); + selectPagesViewModel.Initialize(this, selectPagesWindow, ref ImagenesSeleccionadas); + selectPagesWindow.DataContext = selectPagesViewModel; + selectPagesWindow.ShowDialog(); + + foreach (var page in ImagenesSeleccionadas) + { + SelectedImage = page; + await WaitForUIUpdateAsync(); // Espera a que la UI se actualice + ExtraerTags(); + } + } + + private async void MultiPageAnalizeCommand() + { + var ImagenesSeleccionadas = new ObservableCollection(); + + StopSimulation(); + + var selectPagesWindow = new SelectPages(); + var selectPagesViewModel = new SelectPagesViewModel(); + selectPagesViewModel.Initialize(this, selectPagesWindow, ref ImagenesSeleccionadas); + selectPagesWindow.DataContext = selectPagesViewModel; + selectPagesWindow.ShowDialog(); + + SaveStateObjetosSimulables(); // Guarda el estado antes de cambiar la imagen + + foreach (var page in ImagenesSeleccionadas) + { + SelectedImage = page; + await WaitForUIUpdateAsync(); // Espera a que la UI se actualice + AnalizePageCommand(); + await WaitForUIUpdateAsync(); // Espera a que la UI se actualice + + SaveStateObjetosSimulables(); // Guarda el estado antes de cambiar la imagen + } + + } + + private void AnalizePageCommand() + { + foreach (var obj in ObjetosSimulables) + if (obj is osBuscarCoincidencias objBC) + objBC.BuscarCoincidencias(); + + } + + + + /// + /// Extrae y formatea las etiquetas de los objetos simulables y las guarda en un archivo Excel. + /// + private void ExtraerTags() + { + // Obtiene la ruta del archivo Excel donde se guardarán los datos. + var filePath = DatosDeTrabajo.ObtenerPathAllPages(".xlsx"); + + try + { + int colFix = 0; + // Crea o abre un libro de Excel. + XLWorkbook workbook = File.Exists(filePath) ? new XLWorkbook(filePath) : new XLWorkbook(); + var sheetName = "TagsExtracted"; + // Obtiene o crea la hoja de trabajo "TagsExtracted". + var worksheet = workbook.Worksheets.Contains(sheetName) ? workbook.Worksheet(sheetName) : workbook.Worksheets.Add(sheetName); + var lastRowUsed = worksheet.LastRowUsed(); + // Determina la fila en la que se empezarán a escribir los datos. + int row = lastRowUsed == null ? 2 : lastRowUsed.RowNumber() + 1; + + // Determina la columna fija más alta. + foreach (var obj in ObjetosSimulables) + { + if (obj is osExtraccionTag objExtraccionTag && (objExtraccionTag.Id_Search_Templates == null || objExtraccionTag.Id_Search_Templates == "") && !objExtraccionTag.Cloned) + { + colFix = Math.Max(colFix, objExtraccionTag.Collumn_number); + } + } + + int colNextGroup = 0; + + // Itera sobre los objetos simulables para extraer y guardar las etiquetas. + foreach (var obj in ObjetosSimulables) + { + if (obj is osBuscarCoincidencias objBC) + { + int maxColGroup = 0; + + foreach (var objchild in ObjetosSimulables) + { + if (objchild is osExtraccionTag objExtraccionTag && objExtraccionTag.Id_Search_Templates == objBC.Nombre && objExtraccionTag.Cloned) + { + foreach (var objfix in ObjetosSimulables) + { + if (objfix is osExtraccionTag objExtraccionTagNoGroup && (objExtraccionTagNoGroup.Id_Search_Templates == null || objExtraccionTagNoGroup.Id_Search_Templates == "") && !objExtraccionTagNoGroup.Cloned) + { + if (worksheet.Cell(1, objExtraccionTagNoGroup.Collumn_number).IsEmpty()) + worksheet.Cell(1, objExtraccionTagNoGroup.Collumn_number).Value = objExtraccionTagNoGroup.Collumn_name; + objExtraccionTagNoGroup.CaptureImageAreaAndDoOCR(); + worksheet.Cell(row, objExtraccionTagNoGroup.Collumn_number).Value = objExtraccionTagNoGroup.Tag_extract; + } + } + objExtraccionTag.CaptureImageAreaAndDoOCR(); + worksheet.Cell(row, objExtraccionTag.Collumn_number + colFix + colNextGroup).Value = objExtraccionTag.Tag_extract; + if (worksheet.Cell(1, objExtraccionTag.Collumn_number + colFix + colNextGroup).IsEmpty()) + worksheet.Cell(1, objExtraccionTag.Collumn_number + colFix + colNextGroup).Value = objExtraccionTag.Collumn_name; + + maxColGroup = Math.Max(maxColGroup, objExtraccionTag.Collumn_number); + if (objExtraccionTag.New_Row) row++; + } + } + colNextGroup += maxColGroup; + } + } + + // Formatear los títulos en la fila 1 + var titleRow = worksheet.Row(1); + titleRow.Style.Font.Bold = true; + titleRow.Style.Fill.BackgroundColor = XLColor.LightGray; + titleRow.Style.Alignment.Horizontal = XLAlignmentHorizontalValues.Center; + + // Auto dimensionado de las columnas utilizadas + worksheet.Columns().AdjustToContents(); + + // Guarda el libro de Excel. + workbook.SaveAs(filePath); + } + catch (IOException ex) + { + // Muestra un diálogo de error si ocurre una excepción de IO. + var dialog = new TaskDialog + { + WindowTitle = "IOException", + MainInstruction = "Error al acceder al archivo", + Content = $"El proceso no puede acceder al archivo '{filePath}' porque está siendo utilizado por otro proceso.", + ExpandedInformation = ex.ToString(), + MainIcon = TaskDialogIcon.Error, + ButtonStyle = TaskDialogButtonStyle.Standard + }; + dialog.Buttons.Add(new TaskDialogButton(ButtonType.Ok)); + dialog.ShowDialog(); + } + } + + private void InitializeTipoSimulableList() { var baseType = typeof(osBase); @@ -473,7 +689,7 @@ namespace CtrEditor { // Guardar referencias temporales obj.SalvarDatosNoSerializables(); - if (!obj.Enable_on_all_pages) + if (!obj.Enable_On_All_Pages) _objetosSimulables.Add(obj); else _objetosSimulablesAllPages.Add(obj); diff --git a/MainWindow.xaml b/MainWindow.xaml index 5cc0c28..7f24ad1 100644 --- a/MainWindow.xaml +++ b/MainWindow.xaml @@ -91,35 +91,55 @@ + + a + + @@ -143,6 +163,7 @@ + @@ -153,8 +174,38 @@ + + + + + + + + + + - @@ -163,10 +214,10 @@