364 lines
12 KiB
C#
364 lines
12 KiB
C#
|
using CommunityToolkit.Mvvm.ComponentModel;
|
||
|
using CommunityToolkit.Mvvm.Input;
|
||
|
using CtrEditor.ObjetosSim;
|
||
|
using CtrEditor.ObjetosSim.Extraccion_Datos;
|
||
|
using System.Collections.ObjectModel;
|
||
|
using System.Windows;
|
||
|
using System.Windows.Controls;
|
||
|
using System.Windows.Data;
|
||
|
using System.Linq;
|
||
|
|
||
|
namespace CtrEditor.PopUps
|
||
|
{
|
||
|
public class MatrixItem : ObservableObject
|
||
|
{
|
||
|
public string TagName { get; set; }
|
||
|
private string columnName;
|
||
|
public string ColumnName
|
||
|
{
|
||
|
get => columnName;
|
||
|
set => SetProperty(ref columnName, value);
|
||
|
}
|
||
|
private int columnNumber;
|
||
|
public int ColumnNumber
|
||
|
{
|
||
|
get => columnNumber;
|
||
|
set => SetProperty(ref columnNumber, value);
|
||
|
}
|
||
|
public string Value { get; set; }
|
||
|
public string Type { get; set; }
|
||
|
public bool IsCloned { get; set; }
|
||
|
public osBase SourceObject { get; set; }
|
||
|
}
|
||
|
|
||
|
public partial class MatrixPreviewViewModel : ObservableObject
|
||
|
{
|
||
|
private Window _window;
|
||
|
private MainViewModel _mainViewModel;
|
||
|
private DataGrid _dataGrid;
|
||
|
|
||
|
[ObservableProperty]
|
||
|
private ObservableCollection<MatrixItem> matrixItems;
|
||
|
|
||
|
[ObservableProperty]
|
||
|
private ObservableCollection<Dictionary<string, string>> matrixRows;
|
||
|
|
||
|
[ObservableProperty]
|
||
|
private GridLength detailsHeight = new GridLength(150);
|
||
|
|
||
|
[ObservableProperty]
|
||
|
private double detailsHeightValue = 150;
|
||
|
|
||
|
partial void OnDetailsHeightValueChanged(double value)
|
||
|
{
|
||
|
DetailsHeight = new GridLength(value);
|
||
|
}
|
||
|
|
||
|
public void Initialize(MainViewModel mainViewModel, Window window)
|
||
|
{
|
||
|
_mainViewModel = mainViewModel;
|
||
|
_window = window;
|
||
|
_dataGrid = (_window as MatrixPreviewWindow)?.MatrixPreview;
|
||
|
|
||
|
MatrixItems = new ObservableCollection<MatrixItem>();
|
||
|
MatrixRows = new ObservableCollection<Dictionary<string, string>>();
|
||
|
|
||
|
AnalyzeMatrix();
|
||
|
}
|
||
|
|
||
|
private void UpdateMatrixPreview()
|
||
|
{
|
||
|
if (_dataGrid == null) return;
|
||
|
if (MatrixRows == null) MatrixRows = new ObservableCollection<Dictionary<string, string>>();
|
||
|
|
||
|
MatrixRows.Clear();
|
||
|
_dataGrid.Columns.Clear();
|
||
|
|
||
|
if (!MatrixItems.Any()) return;
|
||
|
|
||
|
// Ordenar items por número de columna
|
||
|
var orderedItems = MatrixItems
|
||
|
.GroupBy(x => x.ColumnNumber)
|
||
|
.OrderBy(g => g.Key)
|
||
|
.Select(g => g.First())
|
||
|
.ToList();
|
||
|
|
||
|
// Crear columnas
|
||
|
foreach (var item in orderedItems)
|
||
|
{
|
||
|
var column = new DataGridTextColumn
|
||
|
{
|
||
|
Header = $"{item.ColumnNumber}:{item.ColumnName}",
|
||
|
Binding = new Binding($"[{item.ColumnNumber}]"),
|
||
|
Width = DataGridLength.Auto
|
||
|
};
|
||
|
_dataGrid.Columns.Add(column);
|
||
|
}
|
||
|
|
||
|
// Calcular número de filas necesarias
|
||
|
int maxRows = 1;
|
||
|
var clonedItems = MatrixItems.Where(x => x.IsCloned).ToList();
|
||
|
if (clonedItems.Any())
|
||
|
{
|
||
|
maxRows = clonedItems.Max(x => x.SourceObject is osExtraccionTag tag ? tag.Copy_Number : 0) + 1;
|
||
|
}
|
||
|
|
||
|
// Crear filas con valores
|
||
|
for (int row = 0; row < maxRows; row++)
|
||
|
{
|
||
|
var rowData = new Dictionary<string, string>();
|
||
|
|
||
|
// Agregar valores fijos (no clonados) en todas las filas
|
||
|
foreach (var item in MatrixItems.Where(x => !x.IsCloned))
|
||
|
{
|
||
|
if (item.ColumnNumber > 0)
|
||
|
{
|
||
|
rowData[item.ColumnNumber.ToString()] = item.Value ?? string.Empty;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Agregar valores clonados solo en su fila correspondiente
|
||
|
foreach (var item in MatrixItems.Where(x => x.IsCloned))
|
||
|
{
|
||
|
if (item.ColumnNumber > 0 && item.SourceObject is osExtraccionTag tag && tag.Copy_Number == row)
|
||
|
{
|
||
|
rowData[item.ColumnNumber.ToString()] = item.Value ?? string.Empty;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
MatrixRows.Add(rowData);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
private void UpdateColumnHeaders()
|
||
|
{
|
||
|
if (_dataGrid == null) return;
|
||
|
|
||
|
foreach (var col in _dataGrid.Columns.Cast<DataGridColumn>())
|
||
|
{
|
||
|
if (col is DataGridTextColumn textCol)
|
||
|
{
|
||
|
var item = MatrixItems.FirstOrDefault(x => x.ColumnName == (textCol.Header?.ToString() ?? "").Split(':').Last());
|
||
|
if (item != null)
|
||
|
{
|
||
|
textCol.Header = $"{item.ColumnNumber}:{item.ColumnName}";
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
private void AnalyzeMatrix()
|
||
|
{
|
||
|
var osBuscarCoincidencias_List = _mainViewModel.ObjetosSimulables
|
||
|
.OfType<osBuscarCoincidencias>()
|
||
|
.Where(tag => tag.Show_On_This_Page)
|
||
|
.ToList();
|
||
|
|
||
|
var osExtraccionTagBaseGrouped_List = _mainViewModel.ObjetosSimulables
|
||
|
.OfType<osExtraccionTag>()
|
||
|
.Where(tag => tag.Show_On_This_Page && !tag.Cloned && tag.Id_Search_Templates != null && tag.Id_Search_Templates != "")
|
||
|
.ToList();
|
||
|
|
||
|
var osExtraccionTagBaseFix_List = _mainViewModel.ObjetosSimulables
|
||
|
.OfType<osExtraccionTag>()
|
||
|
.Where(tag => tag.Show_On_This_Page && !tag.Cloned && (tag.Id_Search_Templates == null || tag.Id_Search_Templates == ""))
|
||
|
.ToList();
|
||
|
|
||
|
var osExtraccionTagCloned_List = _mainViewModel.ObjetosSimulables
|
||
|
.OfType<osExtraccionTag>()
|
||
|
.Where(tag => tag.Show_On_This_Page && tag.Cloned)
|
||
|
.ToList();
|
||
|
|
||
|
// Add fixed tags
|
||
|
foreach (var tag in osExtraccionTagBaseFix_List)
|
||
|
{
|
||
|
tag.CaptureImageAreaAndDoOCR();
|
||
|
MatrixItems.Add(new MatrixItem
|
||
|
{
|
||
|
TagName = tag.Nombre,
|
||
|
ColumnName = tag.Collumn_name,
|
||
|
ColumnNumber = tag.Collumn_number,
|
||
|
Value = tag.Tag_extract,
|
||
|
Type = "Fixed",
|
||
|
IsCloned = false,
|
||
|
SourceObject = tag
|
||
|
});
|
||
|
}
|
||
|
|
||
|
// Add grouped tags
|
||
|
foreach (var tag in osExtraccionTagBaseGrouped_List)
|
||
|
{
|
||
|
tag.CaptureImageAreaAndDoOCR();
|
||
|
MatrixItems.Add(new MatrixItem
|
||
|
{
|
||
|
TagName = tag.Nombre,
|
||
|
ColumnName = tag.Collumn_name,
|
||
|
ColumnNumber = tag.Collumn_number,
|
||
|
Value = tag.Tag_extract,
|
||
|
Type = $"Grouped ({tag.Id_Search_Templates})",
|
||
|
IsCloned = false,
|
||
|
SourceObject = tag
|
||
|
});
|
||
|
}
|
||
|
|
||
|
// Add cloned tags
|
||
|
foreach (var tag in osExtraccionTagCloned_List)
|
||
|
{
|
||
|
tag.CaptureImageAreaAndDoOCR();
|
||
|
MatrixItems.Add(new MatrixItem
|
||
|
{
|
||
|
TagName = tag.Nombre,
|
||
|
ColumnName = tag.Collumn_name,
|
||
|
ColumnNumber = tag.Collumn_number,
|
||
|
Value = tag.Tag_extract,
|
||
|
Type = "Cloned",
|
||
|
IsCloned = true,
|
||
|
SourceObject = tag
|
||
|
});
|
||
|
}
|
||
|
|
||
|
// Ordenar los items por número de columna
|
||
|
var items = MatrixItems.OrderBy(x => x.ColumnNumber).ToList();
|
||
|
MatrixItems.Clear();
|
||
|
foreach (var item in items)
|
||
|
{
|
||
|
MatrixItems.Add(item);
|
||
|
}
|
||
|
|
||
|
ResolveColumnConflicts(); // Analizar y resolver conflictos al cargar
|
||
|
UpdateMatrixPreview();
|
||
|
}
|
||
|
|
||
|
partial void OnMatrixItemsChanged(ObservableCollection<MatrixItem> value)
|
||
|
{
|
||
|
if (value != null)
|
||
|
{
|
||
|
foreach (var item in value)
|
||
|
{
|
||
|
item.PropertyChanged += (s, e) =>
|
||
|
{
|
||
|
if (e.PropertyName == nameof(MatrixItem.ColumnNumber) ||
|
||
|
e.PropertyName == nameof(MatrixItem.ColumnName))
|
||
|
{
|
||
|
UpdateColumnHeaders();
|
||
|
}
|
||
|
};
|
||
|
}
|
||
|
}
|
||
|
UpdateMatrixPreview();
|
||
|
}
|
||
|
|
||
|
[RelayCommand]
|
||
|
private void ApplyChanges()
|
||
|
{
|
||
|
// Resolver solo los conflictos reales, mantener el orden existente
|
||
|
var conflicts = MatrixItems
|
||
|
.GroupBy(x => x.ColumnNumber)
|
||
|
.Where(g => g.Select(x => x.ColumnName).Distinct().Count() > 1)
|
||
|
.Any();
|
||
|
|
||
|
if (conflicts)
|
||
|
{
|
||
|
ResolveColumnConflicts();
|
||
|
}
|
||
|
|
||
|
// Validar números de columna
|
||
|
var columnNumbers = MatrixItems.Select(x => x.ColumnNumber).OrderBy(x => x).ToList();
|
||
|
for (int i = 0; i < columnNumbers.Count; i++)
|
||
|
{
|
||
|
if (columnNumbers[i] <= 0)
|
||
|
{
|
||
|
MessageBox.Show("Column numbers must be greater than 0", "Error", MessageBoxButton.OK, MessageBoxImage.Error);
|
||
|
return;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Aplicar cambios a los objetos
|
||
|
foreach (var item in MatrixItems)
|
||
|
{
|
||
|
if (item.SourceObject is osExtraccionTag tag)
|
||
|
{
|
||
|
tag.Collumn_name = item.ColumnName;
|
||
|
tag.Collumn_number = item.ColumnNumber;
|
||
|
}
|
||
|
}
|
||
|
_mainViewModel.HasUnsavedChanges = true;
|
||
|
_window.Close();
|
||
|
}
|
||
|
|
||
|
[RelayCommand]
|
||
|
private void Close()
|
||
|
{
|
||
|
_window.Close();
|
||
|
}
|
||
|
|
||
|
[RelayCommand]
|
||
|
private void RegenerateMatrix()
|
||
|
{
|
||
|
ResolveColumnConflicts();
|
||
|
UpdateMatrixPreview();
|
||
|
}
|
||
|
|
||
|
private void ResolveColumnConflicts()
|
||
|
{
|
||
|
// Paso 1: Mantener el orden actual y resolver solo los conflictos reales
|
||
|
var columnGroups = MatrixItems
|
||
|
.GroupBy(x => x.ColumnNumber)
|
||
|
.Where(g => g.Select(x => x.ColumnName).Distinct().Count() > 1)
|
||
|
.ToList();
|
||
|
|
||
|
foreach (var group in columnGroups)
|
||
|
{
|
||
|
var nameGroups = group
|
||
|
.GroupBy(x => x.ColumnName)
|
||
|
.OrderByDescending(g => g.Count())
|
||
|
.ToList();
|
||
|
|
||
|
// El grupo más grande mantiene su número
|
||
|
var largestGroup = nameGroups.First();
|
||
|
|
||
|
// Solo reasignar números para grupos que tengan conflicto
|
||
|
for (int i = 1; i < nameGroups.Count; i++)
|
||
|
{
|
||
|
var newColumnNumber = GetNextAvailableColumnNumber();
|
||
|
foreach (var item in nameGroups[i])
|
||
|
{
|
||
|
item.ColumnNumber = newColumnNumber;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Paso 2: Asegurarse de que los números son consecutivos sin alterar el orden relativo
|
||
|
var orderedItems = MatrixItems
|
||
|
.OrderBy(x => x.ColumnNumber)
|
||
|
.GroupBy(x => x.ColumnName)
|
||
|
.ToList();
|
||
|
|
||
|
int currentNumber = 1;
|
||
|
foreach (var group in orderedItems)
|
||
|
{
|
||
|
foreach (var item in group)
|
||
|
{
|
||
|
item.ColumnNumber = currentNumber;
|
||
|
}
|
||
|
currentNumber++;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
private int GetNextAvailableColumnNumber()
|
||
|
{
|
||
|
var usedNumbers = MatrixItems.Select(x => x.ColumnNumber).Distinct().OrderBy(x => x).ToList();
|
||
|
int nextNumber = 1;
|
||
|
|
||
|
foreach (var number in usedNumbers)
|
||
|
{
|
||
|
if (number > nextNumber)
|
||
|
return nextNumber;
|
||
|
nextNumber = number + 1;
|
||
|
}
|
||
|
|
||
|
return nextNumber;
|
||
|
}
|
||
|
}
|
||
|
}
|