Mejorado la descripcion de las extracciones de Tag con Patrones
This commit is contained in:
parent
8573d942c4
commit
633cd71d00
|
@ -44,6 +44,8 @@
|
||||||
<None Remove="Icons\duplicate.png" />
|
<None Remove="Icons\duplicate.png" />
|
||||||
<None Remove="Icons\extract.png" />
|
<None Remove="Icons\extract.png" />
|
||||||
<None Remove="Icons\fotocelula.png" />
|
<None Remove="Icons\fotocelula.png" />
|
||||||
|
<None Remove="Icons\match.png" />
|
||||||
|
<None Remove="Icons\ocr.png" />
|
||||||
<None Remove="Icons\rotation.cur" />
|
<None Remove="Icons\rotation.cur" />
|
||||||
<None Remove="Icons\rotation32x32.cur" />
|
<None Remove="Icons\rotation32x32.cur" />
|
||||||
<None Remove="Icons\rotationRx.cur" />
|
<None Remove="Icons\rotationRx.cur" />
|
||||||
|
@ -121,6 +123,8 @@
|
||||||
<CopyToOutputDirectory></CopyToOutputDirectory>
|
<CopyToOutputDirectory></CopyToOutputDirectory>
|
||||||
</Resource>
|
</Resource>
|
||||||
<Resource Include="Icons\fotocelula.png" />
|
<Resource Include="Icons\fotocelula.png" />
|
||||||
|
<Resource Include="Icons\match.png" />
|
||||||
|
<Resource Include="Icons\ocr.png" />
|
||||||
<Resource Include="Icons\rotationRx.cur" />
|
<Resource Include="Icons\rotationRx.cur" />
|
||||||
<Resource Include="Icons\rotationSx.cur" />
|
<Resource Include="Icons\rotationSx.cur" />
|
||||||
<Resource Include="Icons\save.png" />
|
<Resource Include="Icons\save.png" />
|
||||||
|
|
|
@ -0,0 +1,383 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.ObjectModel;
|
||||||
|
using System.IO;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Windows.Controls;
|
||||||
|
using System.Windows;
|
||||||
|
using CtrEditor.ObjetosSim;
|
||||||
|
using LibS7Adv;
|
||||||
|
|
||||||
|
namespace CtrEditor
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Metadata de una página, incluyendo información sobre la imagen y configuración
|
||||||
|
/// </summary>
|
||||||
|
public class PageMetadata
|
||||||
|
{
|
||||||
|
public string PageId { get; set; }
|
||||||
|
public string PageName { get; set; }
|
||||||
|
public string ImagePath { get; set; }
|
||||||
|
public DateTime LastModified { get; set; }
|
||||||
|
public Dictionary<string, object> CustomMetadata { get; set; } = new();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Estado de un objeto dentro de una página específica
|
||||||
|
/// </summary>
|
||||||
|
public class PageObjectState
|
||||||
|
{
|
||||||
|
public string GlobalObjectId { get; set; }
|
||||||
|
public bool IsVisible { get; set; } = true;
|
||||||
|
public float Left { get; set; }
|
||||||
|
public float Top { get; set; }
|
||||||
|
public float Rotation { get; set; }
|
||||||
|
public Dictionary<string, object> CustomProperties { get; set; } = new();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Estado de una página específica
|
||||||
|
/// </summary>
|
||||||
|
public class PageState
|
||||||
|
{
|
||||||
|
public string PageId { get; set; }
|
||||||
|
public string PageName { get; set; }
|
||||||
|
public List<osBase> LocalObjects { get; set; } = new();
|
||||||
|
public Dictionary<string, PageObjectState> GlobalObjectStates { get; set; } = new();
|
||||||
|
public Dictionary<string, object> PageMetadata { get; set; } = new();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Estado global de la aplicación
|
||||||
|
/// </summary>
|
||||||
|
public class GlobalState
|
||||||
|
{
|
||||||
|
public List<osBase> SharedObjects { get; set; } = new();
|
||||||
|
public Dictionary<string, PageMetadata> PagesMetadata { get; set; } = new();
|
||||||
|
public PLCViewModel PLCConfiguration { get; set; }
|
||||||
|
public UnitConverter UnitConverter { get; set; }
|
||||||
|
public int LastUsedId { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gestor principal de estados de la aplicación
|
||||||
|
/// </summary>
|
||||||
|
public class StateManager : IDisposable
|
||||||
|
{
|
||||||
|
private readonly string _basePath;
|
||||||
|
private GlobalState _globalState;
|
||||||
|
private Dictionary<string, PageState> _loadedPages;
|
||||||
|
private string _currentPageId;
|
||||||
|
private readonly object _lockObject = new();
|
||||||
|
private bool _hasUnsavedChanges;
|
||||||
|
private MainViewModel _mainViewModel;
|
||||||
|
|
||||||
|
public event EventHandler<string> PageStateChanged;
|
||||||
|
public event EventHandler GlobalStateChanged;
|
||||||
|
|
||||||
|
public StateManager(string basePath, MainViewModel mainViewModel)
|
||||||
|
{
|
||||||
|
_basePath = basePath;
|
||||||
|
_mainViewModel = mainViewModel;
|
||||||
|
_loadedPages = new Dictionary<string, PageState>();
|
||||||
|
Directory.CreateDirectory(basePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task InitializeAsync()
|
||||||
|
{
|
||||||
|
await LoadGlobalStateAsync();
|
||||||
|
if (_mainViewModel.SelectedImage != null)
|
||||||
|
{
|
||||||
|
await LoadPageStateAsync(_mainViewModel.SelectedImage);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private JsonSerializerSettings GetSerializerSettings()
|
||||||
|
{
|
||||||
|
return new JsonSerializerSettings
|
||||||
|
{
|
||||||
|
TypeNameHandling = TypeNameHandling.Auto,
|
||||||
|
ObjectCreationHandling = ObjectCreationHandling.Replace,
|
||||||
|
Formatting = Formatting.Indented,
|
||||||
|
NullValueHandling = NullValueHandling.Ignore
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task LoadGlobalStateAsync()
|
||||||
|
{
|
||||||
|
var path = Path.Combine(_basePath, "global.json");
|
||||||
|
if (File.Exists(path))
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var json = await File.ReadAllTextAsync(path);
|
||||||
|
_globalState = JsonConvert.DeserializeObject<GlobalState>(json, GetSerializerSettings());
|
||||||
|
|
||||||
|
// Restaurar configuración global
|
||||||
|
_mainViewModel.PLCViewModel = _globalState.PLCConfiguration ?? new PLCViewModel();
|
||||||
|
if (_globalState.UnitConverter != null)
|
||||||
|
PixelToMeter.Instance.calc = _globalState.UnitConverter;
|
||||||
|
else
|
||||||
|
PixelToMeter.Instance.calc = new UnitConverter(1.0f); // Valor por defecto
|
||||||
|
|
||||||
|
// Restaurar objetos globales
|
||||||
|
foreach (var obj in _globalState.SharedObjects)
|
||||||
|
{
|
||||||
|
await RestoreObjectAsync(obj);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
// Log error y crear nuevo estado global
|
||||||
|
_globalState = new GlobalState();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_globalState = new GlobalState();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task SaveGlobalStateAsync()
|
||||||
|
{
|
||||||
|
var path = Path.Combine(_basePath, "global.json");
|
||||||
|
var backupPath = Path.ChangeExtension(path, ".bak");
|
||||||
|
|
||||||
|
// Actualizar estado global
|
||||||
|
_globalState.PLCConfiguration = _mainViewModel.PLCViewModel;
|
||||||
|
_globalState.UnitConverter = PixelToMeter.Instance.calc;
|
||||||
|
|
||||||
|
// Crear backup
|
||||||
|
if (File.Exists(path))
|
||||||
|
{
|
||||||
|
File.Copy(path, backupPath, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// Preparar objetos para serialización
|
||||||
|
foreach (var obj in _globalState.SharedObjects)
|
||||||
|
{
|
||||||
|
obj.SalvarDatosNoSerializables();
|
||||||
|
}
|
||||||
|
|
||||||
|
var json = JsonConvert.SerializeObject(_globalState, GetSerializerSettings());
|
||||||
|
await File.WriteAllTextAsync(path, json);
|
||||||
|
_hasUnsavedChanges = false;
|
||||||
|
GlobalStateChanged?.Invoke(this, EventArgs.Empty);
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
// Restaurar estado de objetos
|
||||||
|
foreach (var obj in _globalState.SharedObjects)
|
||||||
|
{
|
||||||
|
obj.RestaurarDatosNoSerializables();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<PageState> LoadPageStateAsync(string pageId)
|
||||||
|
{
|
||||||
|
// Retornar página cacheada si existe
|
||||||
|
if (_loadedPages.TryGetValue(pageId, out var cachedState))
|
||||||
|
{
|
||||||
|
return cachedState;
|
||||||
|
}
|
||||||
|
|
||||||
|
var path = Path.Combine(_basePath, $"page_{pageId}.json");
|
||||||
|
try
|
||||||
|
{
|
||||||
|
PageState pageState;
|
||||||
|
if (File.Exists(path))
|
||||||
|
{
|
||||||
|
var json = await File.ReadAllTextAsync(path);
|
||||||
|
pageState = JsonConvert.DeserializeObject<PageState>(json, GetSerializerSettings());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
pageState = new PageState
|
||||||
|
{
|
||||||
|
PageId = pageId,
|
||||||
|
PageName = _globalState.PagesMetadata.GetValueOrDefault(pageId)?.PageName ?? pageId
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
_loadedPages[pageId] = pageState;
|
||||||
|
|
||||||
|
// Restaurar objetos locales
|
||||||
|
foreach (var obj in pageState.LocalObjects)
|
||||||
|
{
|
||||||
|
await RestoreObjectAsync(obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Aplicar estados de objetos globales
|
||||||
|
ApplyGlobalObjectStates(pageState);
|
||||||
|
|
||||||
|
return pageState;
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
// Log error
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ApplyGlobalObjectStates(PageState pageState)
|
||||||
|
{
|
||||||
|
foreach (var kvp in pageState.GlobalObjectStates)
|
||||||
|
{
|
||||||
|
var globalObj = _globalState.SharedObjects.FirstOrDefault(o => o.Id.Value.ToString() == kvp.Key);
|
||||||
|
if (globalObj != null)
|
||||||
|
{
|
||||||
|
var state = kvp.Value;
|
||||||
|
globalObj.Left = state.Left;
|
||||||
|
globalObj.Top = state.Top;
|
||||||
|
globalObj.Angulo = state.Rotation;
|
||||||
|
|
||||||
|
// Actualizar Show_On_This_Page que ahora maneja internamente showOnThisPagesList
|
||||||
|
if (state.IsVisible && !globalObj.Show_On_This_Page)
|
||||||
|
globalObj.Show_On_This_Page = true;
|
||||||
|
else if (!state.IsVisible && globalObj.Show_On_This_Page)
|
||||||
|
globalObj.Show_On_This_Page = false;
|
||||||
|
|
||||||
|
// Aplicar propiedades personalizadas
|
||||||
|
foreach (var prop in state.CustomProperties)
|
||||||
|
{
|
||||||
|
var property = globalObj.GetType().GetProperty(prop.Key);
|
||||||
|
if (property != null && property.CanWrite)
|
||||||
|
{
|
||||||
|
property.SetValue(globalObj, prop.Value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task RestoreObjectAsync(osBase obj)
|
||||||
|
{
|
||||||
|
if (obj != null)
|
||||||
|
{
|
||||||
|
obj.CheckData();
|
||||||
|
await Task.Run(() =>
|
||||||
|
{
|
||||||
|
Application.Current.Dispatcher.Invoke(() =>
|
||||||
|
{
|
||||||
|
CrearUserControlDesdeObjetoSimulable(obj);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool CrearUserControlDesdeObjetoSimulable(osBase osObjeto)
|
||||||
|
{
|
||||||
|
Type tipoObjeto = osObjeto.GetType();
|
||||||
|
UserControl userControl = UserControlFactory.GetControlForType(tipoObjeto);
|
||||||
|
|
||||||
|
if (userControl != null)
|
||||||
|
{
|
||||||
|
UserControlFactory.AssignDatos(userControl, osObjeto, _mainViewModel.simulationManager);
|
||||||
|
osObjeto._mainViewModel = _mainViewModel;
|
||||||
|
|
||||||
|
if (osObjeto.Id == null)
|
||||||
|
{
|
||||||
|
osObjeto.Id = new UniqueId().ObtenerNuevaID();
|
||||||
|
}
|
||||||
|
|
||||||
|
_mainViewModel.MainWindow.AgregarRegistrarUserControlCanvas(userControl);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task SavePageStateAsync(string pageId)
|
||||||
|
{
|
||||||
|
if (!_loadedPages.TryGetValue(pageId, out var pageState))
|
||||||
|
return;
|
||||||
|
|
||||||
|
var path = Path.Combine(_basePath, $"page_{pageId}.json");
|
||||||
|
var backupPath = Path.ChangeExtension(path, ".bak");
|
||||||
|
|
||||||
|
// Crear backup
|
||||||
|
if (File.Exists(path))
|
||||||
|
{
|
||||||
|
File.Copy(path, backupPath, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Actualizar estado de objetos globales
|
||||||
|
pageState.GlobalObjectStates.Clear();
|
||||||
|
foreach (var obj in _mainViewModel.ObjetosSimulables.Where(o => o.Enable_On_All_Pages))
|
||||||
|
{
|
||||||
|
var currentPageId = _mainViewModel.SelectedImage;
|
||||||
|
pageState.GlobalObjectStates[obj.Id.Value.ToString()] = new PageObjectState
|
||||||
|
{
|
||||||
|
GlobalObjectId = obj.Id.Value.ToString(),
|
||||||
|
IsVisible = obj.Show_On_This_Page,
|
||||||
|
Left = obj.Left,
|
||||||
|
Top = obj.Top,
|
||||||
|
Rotation = obj.Angulo,
|
||||||
|
CustomProperties = CaptureCustomProperties(obj)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// Preparar objetos para serialización
|
||||||
|
foreach (var obj in pageState.LocalObjects)
|
||||||
|
{
|
||||||
|
obj.SalvarDatosNoSerializables();
|
||||||
|
}
|
||||||
|
|
||||||
|
var json = JsonConvert.SerializeObject(pageState, GetSerializerSettings());
|
||||||
|
await File.WriteAllTextAsync(path, json);
|
||||||
|
_hasUnsavedChanges = false;
|
||||||
|
PageStateChanged?.Invoke(this, pageId);
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
// Restaurar estado de objetos
|
||||||
|
foreach (var obj in pageState.LocalObjects)
|
||||||
|
{
|
||||||
|
obj.RestaurarDatosNoSerializables();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private Dictionary<string, object> CaptureCustomProperties(osBase obj)
|
||||||
|
{
|
||||||
|
var customProps = new Dictionary<string, object>();
|
||||||
|
var properties = obj.GetType().GetProperties()
|
||||||
|
.Where(p => p.GetCustomAttributes(typeof(SerializeAttribute), true).Any());
|
||||||
|
|
||||||
|
foreach (var prop in properties)
|
||||||
|
{
|
||||||
|
customProps[prop.Name] = prop.GetValue(obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
return customProps;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task SaveAllAsync()
|
||||||
|
{
|
||||||
|
foreach (var pageId in _loadedPages.Keys)
|
||||||
|
{
|
||||||
|
await SavePageStateAsync(pageId);
|
||||||
|
}
|
||||||
|
await SaveGlobalStateAsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
if (_hasUnsavedChanges)
|
||||||
|
{
|
||||||
|
SaveAllAsync().Wait();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Atributo para marcar propiedades que deben ser serializadas como propiedades personalizadas
|
||||||
|
/// </summary>
|
||||||
|
[AttributeUsage(AttributeTargets.Property)]
|
||||||
|
public class SerializeAttribute : Attribute { }
|
||||||
|
}
|
|
@ -0,0 +1,68 @@
|
||||||
|
using LanguageDetection;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.ComponentModel;
|
||||||
|
using Xceed.Wpf.Toolkit.PropertyGrid.Attributes;
|
||||||
|
|
||||||
|
namespace CtrEditor.FuncionesBase
|
||||||
|
{
|
||||||
|
public class Idiomas
|
||||||
|
{
|
||||||
|
public const string DEFAULT_LANGUAGE = "English";
|
||||||
|
|
||||||
|
private static readonly Dictionary<string, string> _languageMap = new Dictionary<string, string>
|
||||||
|
{
|
||||||
|
{ "en", "English" },
|
||||||
|
{ "es", "Spanish" },
|
||||||
|
{ "it", "Italian" },
|
||||||
|
{ "pt", "Portuguese" },
|
||||||
|
{ "fr", "French" },
|
||||||
|
{ "de", "German" }
|
||||||
|
};
|
||||||
|
|
||||||
|
private static readonly LanguageDetector _languageDetector;
|
||||||
|
|
||||||
|
static Idiomas()
|
||||||
|
{
|
||||||
|
_languageDetector = new LanguageDetector();
|
||||||
|
_languageDetector.AddLanguages("en", "es", "it", "pt", "fr", "de");
|
||||||
|
}
|
||||||
|
|
||||||
|
public static List<string> GetLanguageList()
|
||||||
|
{
|
||||||
|
return new List<string>(_languageMap.Values);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static string DetectarIdioma(string texto)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrEmpty(texto)) return DEFAULT_LANGUAGE;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
string detectedLanguageCode = _languageDetector.Detect(texto);
|
||||||
|
return _languageMap.GetValueOrDefault(detectedLanguageCode, DEFAULT_LANGUAGE);
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
return DEFAULT_LANGUAGE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static string GetLanguageCode(string languageName)
|
||||||
|
{
|
||||||
|
return _languageMap.FirstOrDefault(x => x.Value == languageName).Key ?? "en";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class IdiomasItemsSource<T> : IItemsSource
|
||||||
|
{
|
||||||
|
public ItemCollection GetValues()
|
||||||
|
{
|
||||||
|
ItemCollection items = new ItemCollection();
|
||||||
|
foreach (string language in Idiomas.GetLanguageList())
|
||||||
|
{
|
||||||
|
items.Add(language);
|
||||||
|
}
|
||||||
|
return items;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,99 @@
|
||||||
|
using System;
|
||||||
|
using System.Text.RegularExpressions;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using Xceed.Wpf.Toolkit.PropertyGrid.Attributes;
|
||||||
|
|
||||||
|
namespace CtrEditor.FuncionesBase
|
||||||
|
{
|
||||||
|
public class TagPattern
|
||||||
|
{
|
||||||
|
public const string DEFAULT_PATTERN = "DESCRIPCION";
|
||||||
|
|
||||||
|
private static readonly Dictionary<string, string> _patternDescriptions = new Dictionary<string, string>
|
||||||
|
{
|
||||||
|
{ "Descripcion", "First letter capitalized" },
|
||||||
|
{ "DESCRIPCION", "All uppercase text" },
|
||||||
|
{ "Siemens IO Input", "Format: Exxxxx.y (x: 0-65535, y: 0-7)" },
|
||||||
|
{ "Siemens IO Output", "Format: Axxxxx.y (x: 0-65535, y: 0-7)" },
|
||||||
|
{ "LETRASNUMEROS", "Format: ABC...123... (1-10 letters + numbers)" },
|
||||||
|
{ "Numero", "Numeric value" }
|
||||||
|
};
|
||||||
|
|
||||||
|
public static List<string> GetPatternList()
|
||||||
|
{
|
||||||
|
return new List<string>(_patternDescriptions.Keys);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static string ApplyPattern(string text, string pattern)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrEmpty(text)) return text;
|
||||||
|
|
||||||
|
return pattern switch
|
||||||
|
{
|
||||||
|
"Descripcion" => ApplyDescripcionPattern(text),
|
||||||
|
"DESCRIPCION" => text.ToUpper(),
|
||||||
|
"Siemens IO Input" => ApplySiemensPattern(text, "E"),
|
||||||
|
"Siemens IO Output" => ApplySiemensPattern(text, "A"),
|
||||||
|
"LETRASNUMEROS" => ApplyLetrasNumerosPattern(text),
|
||||||
|
"Numero" => ApplyNumberPattern(text),
|
||||||
|
_ => text
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
private static string ApplyDescripcionPattern(string text)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrEmpty(text)) return text;
|
||||||
|
return char.ToUpper(text[0]) + (text.Length > 1 ? text.Substring(1).ToLower() : "");
|
||||||
|
}
|
||||||
|
|
||||||
|
private static string ApplySiemensPattern(string text, string prefix)
|
||||||
|
{
|
||||||
|
var match = Regex.Match(text, $"{prefix}?(\\d{{1,5}})\\.?(\\d)?", RegexOptions.IgnoreCase);
|
||||||
|
if (match.Success)
|
||||||
|
{
|
||||||
|
int address = Math.Min(int.Parse(match.Groups[1].Value), 65535);
|
||||||
|
int bit = match.Groups[2].Success ?
|
||||||
|
Math.Min(int.Parse(match.Groups[2].Value), 7) : 0;
|
||||||
|
return $"{prefix}{address}.{bit}";
|
||||||
|
}
|
||||||
|
return $"{prefix}0.0"; // Default value if pattern doesn't match
|
||||||
|
}
|
||||||
|
|
||||||
|
private static string ApplyLetrasNumerosPattern(string text)
|
||||||
|
{
|
||||||
|
// Extract letters and numbers from the text
|
||||||
|
var letters = new string(text.Where(c => char.IsLetter(c)).Take(10).ToArray());
|
||||||
|
var numbers = new string(text.Where(c => char.IsDigit(c)).ToArray());
|
||||||
|
|
||||||
|
// If no letters found, return "A" as default
|
||||||
|
if (string.IsNullOrEmpty(letters))
|
||||||
|
letters = "A";
|
||||||
|
|
||||||
|
// If no numbers found, return "0" as default
|
||||||
|
if (string.IsNullOrEmpty(numbers))
|
||||||
|
numbers = "0";
|
||||||
|
|
||||||
|
// Combine letters (uppercase) and numbers
|
||||||
|
return $"{letters.ToUpper()}{numbers}";
|
||||||
|
}
|
||||||
|
|
||||||
|
private static string ApplyNumberPattern(string text)
|
||||||
|
{
|
||||||
|
var match = Regex.Match(text, @"-?\d+\.?\d*");
|
||||||
|
return match.Success ? match.Value : "0";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class TagPatternItemsSource<T> : IItemsSource
|
||||||
|
{
|
||||||
|
public ItemCollection GetValues()
|
||||||
|
{
|
||||||
|
ItemCollection items = new ItemCollection();
|
||||||
|
foreach (string pattern in TagPattern.GetPatternList())
|
||||||
|
{
|
||||||
|
items.Add(pattern);
|
||||||
|
}
|
||||||
|
return items;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
23
IA/gtpask.cs
23
IA/gtpask.cs
|
@ -9,6 +9,7 @@ using LanguageDetection;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using Newtonsoft.Json.Linq;
|
using Newtonsoft.Json.Linq;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
|
using CtrEditor.FuncionesBase;
|
||||||
|
|
||||||
namespace GTPCorrgir
|
namespace GTPCorrgir
|
||||||
{
|
{
|
||||||
|
@ -70,15 +71,6 @@ namespace GTPCorrgir
|
||||||
private string _grokApiKey;
|
private string _grokApiKey;
|
||||||
private readonly HttpClient _httpClient;
|
private readonly HttpClient _httpClient;
|
||||||
private bool _disposed;
|
private bool _disposed;
|
||||||
private readonly LanguageDetector _languageDetector;
|
|
||||||
|
|
||||||
private readonly Dictionary<string, string> _languageMap = new Dictionary<string, string>
|
|
||||||
{
|
|
||||||
{ "en", "English" },
|
|
||||||
{ "es", "Spanish" },
|
|
||||||
{ "it", "Italian" },
|
|
||||||
{ "pt", "Portuguese" }
|
|
||||||
};
|
|
||||||
|
|
||||||
public string IdiomaDetectado { get; private set; }
|
public string IdiomaDetectado { get; private set; }
|
||||||
public string TextoACorregir { get; set; }
|
public string TextoACorregir { get; set; }
|
||||||
|
@ -90,8 +82,6 @@ namespace GTPCorrgir
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
_httpClient = new HttpClient();
|
_httpClient = new HttpClient();
|
||||||
_languageDetector = new LanguageDetector();
|
|
||||||
_languageDetector.AddLanguages("en", "es", "it", "pt");
|
|
||||||
|
|
||||||
LoadApiKeys();
|
LoadApiKeys();
|
||||||
InitializeHttpClient();
|
InitializeHttpClient();
|
||||||
|
@ -153,20 +143,15 @@ namespace GTPCorrgir
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
IdiomaDetectado = Idiomas.DetectarIdioma(TextoACorregir);
|
||||||
string detectedLanguageCode = _languageDetector.Detect(TextoACorregir);
|
return IdiomaDetectado != "Unknown";
|
||||||
IdiomaDetectado = _languageMap.GetValueOrDefault(detectedLanguageCode, "Desconocido");
|
|
||||||
|
|
||||||
return IdiomaDetectado != "Desconocido";
|
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
private async Task ProcesarTextoConLLM( Opciones Modelo)
|
private async Task ProcesarTextoConLLM( Opciones Modelo)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
|
|
Binary file not shown.
After Width: | Height: | Size: 42 KiB |
Binary file not shown.
After Width: | Height: | Size: 19 KiB |
270
MainViewModel.cs
270
MainViewModel.cs
|
@ -43,9 +43,24 @@ namespace CtrEditor
|
||||||
|
|
||||||
public Canvas MainCanvas;
|
public Canvas MainCanvas;
|
||||||
|
|
||||||
public bool IsConnected
|
[ObservableProperty]
|
||||||
|
private bool isConnected;
|
||||||
|
|
||||||
|
partial void OnPLCViewModelChanged(PLCViewModel value)
|
||||||
{
|
{
|
||||||
get => PLCViewModel.IsConnected;
|
if (value != null)
|
||||||
|
{
|
||||||
|
value.PropertyChanged += PLCViewModel_PropertyChanged;
|
||||||
|
IsConnected = value.IsConnected;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void PLCViewModel_PropertyChanged(object sender, PropertyChangedEventArgs e)
|
||||||
|
{
|
||||||
|
if (e.PropertyName == nameof(PLCViewModel.IsConnected))
|
||||||
|
{
|
||||||
|
IsConnected = PLCViewModel.IsConnected;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
|
@ -64,8 +79,6 @@ namespace CtrEditor
|
||||||
public ICommand TBStartSimulationCommand { get; }
|
public ICommand TBStartSimulationCommand { get; }
|
||||||
public ICommand TBStopSimulationCommand { get; }
|
public ICommand TBStopSimulationCommand { get; }
|
||||||
public ICommand TBSaveCommand { get; }
|
public ICommand TBSaveCommand { get; }
|
||||||
public ICommand TBConnectPLCCommand { get; }
|
|
||||||
public ICommand TBDisconnectPLCCommand { get; }
|
|
||||||
public ICommand TBExtractTagsCommand { get; }
|
public ICommand TBExtractTagsCommand { get; }
|
||||||
|
|
||||||
public ICommand TBEliminarUserControlCommand { get; }
|
public ICommand TBEliminarUserControlCommand { get; }
|
||||||
|
@ -79,9 +92,17 @@ namespace CtrEditor
|
||||||
public ICommand TBAssingPagesCommand { get; }
|
public ICommand TBAssingPagesCommand { get; }
|
||||||
public ICommand TBMultiPageExtractTagsCommand { get; }
|
public ICommand TBMultiPageExtractTagsCommand { get; }
|
||||||
public ICommand TBMultiPageAnalizeCommand { get; }
|
public ICommand TBMultiPageAnalizeCommand { get; }
|
||||||
public ICommand TBAnalyzeMatrixCommand { get; }
|
|
||||||
public ICommand TBMultiPageMatrixCommand { get; }
|
public ICommand TBMultiPageMatrixCommand { get; }
|
||||||
|
|
||||||
|
|
||||||
|
public ICommand TBTogglePLCConnectionCommand => new RelayCommand(() =>
|
||||||
|
{
|
||||||
|
if (IsConnected)
|
||||||
|
DisconnectPLC();
|
||||||
|
else
|
||||||
|
ConnectPLC();
|
||||||
|
});
|
||||||
|
|
||||||
// Evento que se dispara cuando se selecciona una nueva imagen
|
// Evento que se dispara cuando se selecciona una nueva imagen
|
||||||
public event EventHandler<string> ImageSelected;
|
public event EventHandler<string> ImageSelected;
|
||||||
public event EventHandler<TickSimulacionEventArgs> TickSimulacion;
|
public event EventHandler<TickSimulacionEventArgs> TickSimulacion;
|
||||||
|
@ -202,27 +223,24 @@ namespace CtrEditor
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private string selectedImage;
|
private string selectedImage;
|
||||||
|
|
||||||
|
partial void OnSelectedImageChanging(string? oldValue, string newValue)
|
||||||
|
{
|
||||||
|
if (HasUnsavedChanges && !inhibitSaveChangesControl)
|
||||||
|
{
|
||||||
|
var result = MessageBox.Show("There are unsaved changes. Do you want to save them?",
|
||||||
|
"Save Changes",
|
||||||
|
MessageBoxButton.YesNo);
|
||||||
|
|
||||||
|
if (result == MessageBoxResult.Yes)
|
||||||
|
{
|
||||||
|
SaveStateObjetosSimulables();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
partial void OnSelectedImageChanged(string value)
|
partial void OnSelectedImageChanged(string value)
|
||||||
{
|
{
|
||||||
if (value != null)
|
if (value != null)
|
||||||
{
|
{
|
||||||
if (HasUnsavedChanges && !inhibitSaveChangesControl)
|
|
||||||
{
|
|
||||||
var result = MessageBox.Show("There are unsaved changes. Do you want to save them?",
|
|
||||||
"Save Changes",
|
|
||||||
MessageBoxButton.YesNoCancel);
|
|
||||||
|
|
||||||
if (result == MessageBoxResult.Cancel)
|
|
||||||
{
|
|
||||||
OnPropertyChanged(nameof(SelectedImage)); // Restore previous selection
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
else if (result == MessageBoxResult.Yes)
|
|
||||||
{
|
|
||||||
SaveStateObjetosSimulables();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
StopSimulation();
|
StopSimulation();
|
||||||
ImageSelected?.Invoke(this, datosDeTrabajo.Imagenes[value]);
|
ImageSelected?.Invoke(this, datosDeTrabajo.Imagenes[value]);
|
||||||
LoadStateObjetosSimulables();
|
LoadStateObjetosSimulables();
|
||||||
|
@ -271,6 +289,8 @@ namespace CtrEditor
|
||||||
// Constructor
|
// Constructor
|
||||||
//
|
//
|
||||||
|
|
||||||
|
private StateManager _stateManager;
|
||||||
|
|
||||||
public MainViewModel()
|
public MainViewModel()
|
||||||
{
|
{
|
||||||
OpenWorkDirectoryCommand = new RelayCommand(OpenWorkDirectory);
|
OpenWorkDirectoryCommand = new RelayCommand(OpenWorkDirectory);
|
||||||
|
@ -289,7 +309,7 @@ namespace CtrEditor
|
||||||
PLCViewModel = new PLCViewModel();
|
PLCViewModel = new PLCViewModel();
|
||||||
|
|
||||||
_timerPLCUpdate = new DispatcherTimer();
|
_timerPLCUpdate = new DispatcherTimer();
|
||||||
_timerPLCUpdate.Interval = TimeSpan.FromMilliseconds(50); // ajusta el intervalo según sea necesario
|
_timerPLCUpdate.Interval = TimeSpan.FromMilliseconds(10); // ajusta el intervalo según sea necesario
|
||||||
_timerPLCUpdate.Tick += OnRefreshEvent;
|
_timerPLCUpdate.Tick += OnRefreshEvent;
|
||||||
|
|
||||||
InitializeTipoSimulableList();
|
InitializeTipoSimulableList();
|
||||||
|
@ -306,21 +326,15 @@ namespace CtrEditor
|
||||||
TBStartSimulationCommand = new RelayCommand(StartSimulation, () => !IsSimulationRunning);
|
TBStartSimulationCommand = new RelayCommand(StartSimulation, () => !IsSimulationRunning);
|
||||||
TBStopSimulationCommand = new RelayCommand(StopSimulation, () => IsSimulationRunning);
|
TBStopSimulationCommand = new RelayCommand(StopSimulation, () => IsSimulationRunning);
|
||||||
TBSaveCommand = new RelayCommand(Save);
|
TBSaveCommand = new RelayCommand(Save);
|
||||||
TBConnectPLCCommand = new RelayCommand(ConnectPLC, () => !PLCViewModel.IsConnected);
|
|
||||||
TBDisconnectPLCCommand = new RelayCommand(DisconnectPLC, () => PLCViewModel.IsConnected);
|
|
||||||
|
|
||||||
TBEliminarUserControlCommand = new RelayCommand(EliminarUserControl, () => habilitarEliminarUserControl);
|
TBEliminarUserControlCommand = new RelayCommand(EliminarUserControl, () => habilitarEliminarUserControl);
|
||||||
TBDuplicarUserControlCommand = new RelayCommand(DuplicarUserControl, () => habilitarEliminarUserControl);
|
TBDuplicarUserControlCommand = new RelayCommand(DuplicarUserControl, () => habilitarEliminarUserControl);
|
||||||
|
|
||||||
TBExtractTagsCommand = new RelayCommand(ExtraerTags);
|
|
||||||
|
|
||||||
TBEliminarTodosCommand = new RelayCommand(EliminarTodosCommand);
|
TBEliminarTodosCommand = new RelayCommand(EliminarTodosCommand);
|
||||||
TBEliminarAutoCreatedCommand = new RelayCommand(EliminarAutoCreatedCommand);
|
TBEliminarAutoCreatedCommand = new RelayCommand(EliminarAutoCreatedCommand);
|
||||||
TBEliminarClonedCommand = new RelayCommand(EliminarClonedCommand);
|
TBEliminarClonedCommand = new RelayCommand(EliminarClonedCommand);
|
||||||
TBAssingPagesCommand = new RelayCommand(AssingPagesCommand);
|
TBAssingPagesCommand = new RelayCommand(AssingPagesCommand);
|
||||||
TBMultiPageExtractTagsCommand = new RelayCommand(MultiPageExtractTagsCommand);
|
|
||||||
TBMultiPageAnalizeCommand = new RelayCommand(MultiPageAnalizeCommand);
|
TBMultiPageAnalizeCommand = new RelayCommand(MultiPageAnalizeCommand);
|
||||||
TBAnalyzeMatrixCommand = new RelayCommand(AnalyzeMatrixCommand);
|
|
||||||
TBMultiPageMatrixCommand = new RelayCommand(MultiPageMatrixCommand);
|
TBMultiPageMatrixCommand = new RelayCommand(MultiPageMatrixCommand);
|
||||||
|
|
||||||
stopwatch_Sim = new Stopwatch();
|
stopwatch_Sim = new Stopwatch();
|
||||||
|
@ -334,6 +348,8 @@ namespace CtrEditor
|
||||||
|
|
||||||
recentDirectories = new ObservableCollection<string>(EstadoPersistente.Instance.RecentDirectories);
|
recentDirectories = new ObservableCollection<string>(EstadoPersistente.Instance.RecentDirectories);
|
||||||
OpenRecentDirectoryCommand = new RelayCommand<string>(OpenRecentDirectory);
|
OpenRecentDirectoryCommand = new RelayCommand<string>(OpenRecentDirectory);
|
||||||
|
|
||||||
|
_stateManager = new StateManager(EstadoPersistente.Instance.directorio, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OsListFilter_PropertyChanged(object? sender, PropertyChangedEventArgs e)
|
private void OsListFilter_PropertyChanged(object? sender, PropertyChangedEventArgs e)
|
||||||
|
@ -544,51 +560,6 @@ namespace CtrEditor
|
||||||
Application.Current.Dispatcher.Invoke(() => { }, DispatcherPriority.ApplicationIdle);
|
Application.Current.Dispatcher.Invoke(() => { }, DispatcherPriority.ApplicationIdle);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private async void MultiPageExtractTagsCommand()
|
|
||||||
{
|
|
||||||
if (HasUnsavedChanges)
|
|
||||||
{
|
|
||||||
var result = MessageBox.Show("There are unsaved changes. Do you want to save them?",
|
|
||||||
"Save Changes",
|
|
||||||
MessageBoxButton.YesNoCancel);
|
|
||||||
|
|
||||||
if (result == MessageBoxResult.Cancel)
|
|
||||||
return;
|
|
||||||
else if (result == MessageBoxResult.Yes)
|
|
||||||
SaveStateObjetosSimulables();
|
|
||||||
}
|
|
||||||
|
|
||||||
var ImagenesSeleccionadas = new ObservableCollection<string>
|
|
||||||
{
|
|
||||||
SelectedImage
|
|
||||||
};
|
|
||||||
|
|
||||||
StopSimulation();
|
|
||||||
|
|
||||||
var selectPagesWindow = new SelectPages();
|
|
||||||
var selectPagesViewModel = new SelectPagesViewModel();
|
|
||||||
selectPagesViewModel.Initialize(this, selectPagesWindow, ref ImagenesSeleccionadas);
|
|
||||||
selectPagesWindow.DataContext = selectPagesViewModel;
|
|
||||||
selectPagesWindow.ShowDialog();
|
|
||||||
|
|
||||||
inhibitSaveChangesControl = true;
|
|
||||||
try
|
|
||||||
{
|
|
||||||
if (selectPagesWindow.DataContext is SelectPagesViewModel dialog && dialog.CloseOK)
|
|
||||||
foreach (var page in ImagenesSeleccionadas)
|
|
||||||
{
|
|
||||||
SelectedImage = page;
|
|
||||||
await WaitForUIUpdateAsync(); // Espera a que la UI se actualice
|
|
||||||
ExtraerTags();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
finally
|
|
||||||
{
|
|
||||||
inhibitSaveChangesControl = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private async void MultiPageAnalizeCommand()
|
private async void MultiPageAnalizeCommand()
|
||||||
{
|
{
|
||||||
var ImagenesSeleccionadas = new ObservableCollection<string>
|
var ImagenesSeleccionadas = new ObservableCollection<string>
|
||||||
|
@ -641,148 +612,6 @@ namespace CtrEditor
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Extrae y formatea las etiquetas de los objetos simulables y las guarda en un archivo Excel.
|
|
||||||
/// </summary>
|
|
||||||
private void ExtraerTags()
|
|
||||||
{
|
|
||||||
// Obtiene la ruta del archivo Excel donde se guardarán los datos.
|
|
||||||
var filePath = DatosDeTrabajo.ObtenerPathAllPages(".xlsx");
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
// 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 rowOffset = lastRowUsed == null ? 2 : lastRowUsed.RowNumber() + 1;
|
|
||||||
|
|
||||||
// Determina la columna fija más alta.
|
|
||||||
List<int> columnasOcupadas = new List<int>();
|
|
||||||
int actualMaxCol = 0;
|
|
||||||
int col = 0;
|
|
||||||
|
|
||||||
// Filtrar los objetos de tipo osExtraccionTag y crear una nueva lista
|
|
||||||
var osBuscarCoincidencias_List = ObjetosSimulables
|
|
||||||
.OfType<osBuscarCoincidencias>()
|
|
||||||
.Where(tag => tag.Show_On_This_Page)
|
|
||||||
.ToList();
|
|
||||||
var osExtraccionTagBaseGrouped_List = 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 = 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 = ObjetosSimulables
|
|
||||||
.OfType<osExtraccionTag>()
|
|
||||||
.Where(tag => tag.Show_On_This_Page && tag.Cloned)
|
|
||||||
.ToList();
|
|
||||||
|
|
||||||
// Columnas Fijas para los Tags no agrupados que no son clonados
|
|
||||||
foreach (var objExtraccionTag in osExtraccionTagBaseFix_List)
|
|
||||||
if ((string.IsNullOrEmpty(objExtraccionTag.Id_Search_Templates)) && !objExtraccionTag.Cloned)
|
|
||||||
{
|
|
||||||
col = objExtraccionTag.Collumn_number;
|
|
||||||
if (col == 0 || columnasOcupadas.Contains(col))
|
|
||||||
col = ++actualMaxCol;
|
|
||||||
else
|
|
||||||
actualMaxCol = Math.Max(actualMaxCol, col);
|
|
||||||
|
|
||||||
columnasOcupadas.Add(col);
|
|
||||||
objExtraccionTag.Collumn_number = col;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Tags Agrupados no Clonados
|
|
||||||
foreach (var objBC in osBuscarCoincidencias_List)
|
|
||||||
foreach (var objExtraccionTag in osExtraccionTagBaseGrouped_List)
|
|
||||||
if (objExtraccionTag.Id_Search_Templates == objBC.Nombre && !objExtraccionTag.Cloned)
|
|
||||||
{
|
|
||||||
col = objExtraccionTag.Collumn_number;
|
|
||||||
if (col == 0 || columnasOcupadas.Contains(col))
|
|
||||||
col = ++actualMaxCol;
|
|
||||||
else
|
|
||||||
actualMaxCol = Math.Max(actualMaxCol, col);
|
|
||||||
|
|
||||||
columnasOcupadas.Add(col);
|
|
||||||
objExtraccionTag.Collumn_number = col;
|
|
||||||
}
|
|
||||||
|
|
||||||
int RowToRender = 0;
|
|
||||||
// Cloned Tag - Asignar las mismas columnas
|
|
||||||
foreach (var oFrom in osExtraccionTagBaseGrouped_List)
|
|
||||||
foreach (var oCloned in osExtraccionTagCloned_List)
|
|
||||||
{
|
|
||||||
if (oCloned.Cloned_from == oFrom.Id)
|
|
||||||
oCloned.Collumn_number = oFrom.Collumn_number;
|
|
||||||
RowToRender = Math.Max(RowToRender, oCloned.Copy_Number);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Render Rows
|
|
||||||
for (int row = 0; row < RowToRender; row++)
|
|
||||||
{
|
|
||||||
// Render Fix tags
|
|
||||||
foreach (var TagFixs in osExtraccionTagBaseFix_List)
|
|
||||||
{
|
|
||||||
col = TagFixs.Collumn_number;
|
|
||||||
if (worksheet.Cell(1, col).IsEmpty())
|
|
||||||
worksheet.Cell(1, col).Value = TagFixs.Collumn_name;
|
|
||||||
TagFixs.CaptureImageAreaAndDoOCR();
|
|
||||||
worksheet.Cell(row + rowOffset, col).Value = TagFixs.Tag_extract;
|
|
||||||
}
|
|
||||||
// Render Cloned tags
|
|
||||||
foreach (var TagCloned in osExtraccionTagCloned_List)
|
|
||||||
{
|
|
||||||
if (TagCloned.Copy_Number == row) // Estamos en la fila correcta
|
|
||||||
{
|
|
||||||
col = TagCloned.Collumn_number;
|
|
||||||
if (worksheet.Cell(1, col).IsEmpty())
|
|
||||||
worksheet.Cell(1, col).Value = TagCloned.Collumn_name;
|
|
||||||
|
|
||||||
TagCloned.CaptureImageAreaAndDoOCR();
|
|
||||||
worksheet.Cell(row + rowOffset, col).Value = TagCloned.Tag_extract;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// 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);
|
|
||||||
HasUnsavedChanges = false;
|
|
||||||
}
|
|
||||||
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()
|
private void InitializeTipoSimulableList()
|
||||||
{
|
{
|
||||||
var baseType = typeof(osBase);
|
var baseType = typeof(osBase);
|
||||||
|
@ -1142,15 +971,6 @@ namespace CtrEditor
|
||||||
Application.Current.Shutdown();
|
Application.Current.Shutdown();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void AnalyzeMatrixCommand()
|
|
||||||
{
|
|
||||||
var matrixPreviewWindow = new MatrixPreviewWindow();
|
|
||||||
var matrixPreviewViewModel = new MatrixPreviewViewModel();
|
|
||||||
matrixPreviewViewModel.Initialize(this, matrixPreviewWindow);
|
|
||||||
matrixPreviewWindow.DataContext = matrixPreviewViewModel;
|
|
||||||
matrixPreviewWindow.ShowDialog();
|
|
||||||
}
|
|
||||||
|
|
||||||
private async void MultiPageMatrixCommand()
|
private async void MultiPageMatrixCommand()
|
||||||
{
|
{
|
||||||
if (HasUnsavedChanges)
|
if (HasUnsavedChanges)
|
||||||
|
|
|
@ -27,13 +27,21 @@
|
||||||
<!-- Style for Connect/Disconnect Button -->
|
<!-- Style for Connect/Disconnect Button -->
|
||||||
<Style x:Key="ConnectDisconnectButtonStyle" TargetType="Button">
|
<Style x:Key="ConnectDisconnectButtonStyle" TargetType="Button">
|
||||||
<Setter Property="Background" Value="Transparent" />
|
<Setter Property="Background" Value="Transparent" />
|
||||||
|
<Setter Property="Padding" Value="5" />
|
||||||
|
<Setter Property="MinWidth" Value="80" />
|
||||||
<Style.Triggers>
|
<Style.Triggers>
|
||||||
<DataTrigger Binding="{Binding IsConnected}" Value="True">
|
<DataTrigger Binding="{Binding IsConnected}" Value="True">
|
||||||
<Setter Property="Background" Value="LightGreen" />
|
<Setter Property="Background" Value="#90EE90" />
|
||||||
</DataTrigger>
|
</DataTrigger>
|
||||||
</Style.Triggers>
|
</Style.Triggers>
|
||||||
</Style>
|
</Style>
|
||||||
|
|
||||||
|
<!-- Converter for PLC Connect/Disconnect button text -->
|
||||||
|
<local:ConnectStateToBtnTextConverter x:Key="ConnectStateToBtnTextConverter" />
|
||||||
|
|
||||||
|
<!-- Converter for PLC Connect/Disconnect image -->
|
||||||
|
<local:ConnectStateToImageConverter x:Key="ConnectStateToImageConverter" />
|
||||||
|
|
||||||
</Window.Resources>
|
</Window.Resources>
|
||||||
|
|
||||||
<Grid>
|
<Grid>
|
||||||
|
@ -116,42 +124,29 @@
|
||||||
<TextBlock Text="Guardar" />
|
<TextBlock Text="Guardar" />
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
</Button>
|
</Button>
|
||||||
<Button Command="{Binding TBConnectPLCCommand}" ToolTip="Conectar PLC"
|
<Button Command="{Binding TBTogglePLCConnectionCommand}"
|
||||||
|
ToolTip="{Binding IsConnected, Converter={StaticResource ConnectStateToBtnTextConverter}}"
|
||||||
Style="{StaticResource ConnectDisconnectButtonStyle}">
|
Style="{StaticResource ConnectDisconnectButtonStyle}">
|
||||||
<StackPanel>
|
<StackPanel>
|
||||||
<Image Source="Icons/connect.png" Width="24" Height="24" />
|
<Image
|
||||||
<TextBlock Text="Conectar" />
|
Source="{Binding IsConnected, Converter={StaticResource ConnectStateToImageConverter}}"
|
||||||
</StackPanel>
|
Width="24" Height="24" />
|
||||||
</Button>
|
<TextBlock
|
||||||
<Button Command="{Binding TBDisconnectPLCCommand}" ToolTip="Desconectar PLC">
|
Text="{Binding IsConnected, Converter={StaticResource ConnectStateToBtnTextConverter}}" />
|
||||||
<StackPanel>
|
|
||||||
<Image Source="Icons/disconnect.png" Width="24" Height="24" />
|
|
||||||
<TextBlock Text="Desconectar" />
|
|
||||||
</StackPanel>
|
|
||||||
</Button>
|
|
||||||
<Button Command="{Binding TBExtractTagsCommand}" ToolTip="Extraer Tags">
|
|
||||||
<StackPanel>
|
|
||||||
<Image Source="Icons/extract.png" Width="24" Height="24" />
|
|
||||||
<TextBlock Text="Extraer Tags" />
|
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
</Button>
|
</Button>
|
||||||
<Button Command="{Binding TBMultiPageAnalizeCommand}"
|
<Button Command="{Binding TBMultiPageAnalizeCommand}"
|
||||||
ToolTip="Analyze Tags in multiple pages.">
|
ToolTip="Analyze Tags in multiple pages.">
|
||||||
<StackPanel>
|
<StackPanel>
|
||||||
<Image Source="Icons/analyze.png" Width="24" Height="24" />
|
<Image Source="Icons/match.png" Width="24" Height="24" />
|
||||||
<TextBlock Text="Multi Page Analyze" />
|
<TextBlock Text="Multi Page Analyze" />
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
</Button>
|
</Button>
|
||||||
<Button Command="{Binding TBAnalyzeMatrixCommand}" ToolTip="Analyze Export Matrix">
|
|
||||||
<StackPanel>
|
|
||||||
<Image Source="Icons/analyze.png" Width="24" Height="24" />
|
|
||||||
<TextBlock Text="Analyze Matrix" />
|
|
||||||
</StackPanel>
|
|
||||||
</Button>
|
|
||||||
<Button Command="{Binding TBMultiPageMatrixCommand}" ToolTip="Analyze Matrix (Multiple Pages)">
|
<Button Command="{Binding TBMultiPageMatrixCommand}" ToolTip="Analyze Matrix (Multiple Pages)">
|
||||||
<StackPanel>
|
<StackPanel>
|
||||||
<Image Source="Icons/analyze.png" Width="24" Height="24" />
|
<Image Source="Icons/ocr.png" Width="24" Height="24" />
|
||||||
<TextBlock Text="Multi Page Matrix" />
|
<TextBlock Text="Exportar Tags a Excel" />
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
</Button>
|
</Button>
|
||||||
|
|
||||||
|
|
|
@ -288,6 +288,15 @@ namespace CtrEditor
|
||||||
new Tuple<Point, string>(new Point(rectBox.Right, rectBox.Top + rectBox.Height / 2), "CenterRight")
|
new Tuple<Point, string>(new Point(rectBox.Right, rectBox.Top + rectBox.Height / 2), "CenterRight")
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Add validation before setting Canvas position
|
||||||
|
void SetCanvasPosition(UIElement element, double left, double top)
|
||||||
|
{
|
||||||
|
if (!double.IsInfinity(left) && !double.IsNaN(left))
|
||||||
|
Canvas.SetLeft(element, left);
|
||||||
|
if (!double.IsInfinity(top) && !double.IsNaN(top))
|
||||||
|
Canvas.SetTop(element, top);
|
||||||
|
}
|
||||||
|
|
||||||
foreach (var position in positions)
|
foreach (var position in positions)
|
||||||
{
|
{
|
||||||
Rectangle rect = new Rectangle
|
Rectangle rect = new Rectangle
|
||||||
|
@ -337,8 +346,8 @@ namespace CtrEditor
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
Canvas.SetLeft(rect, position.Item1.X - rectSize / 2);
|
// Replace direct Canvas.Set calls with the validation method
|
||||||
Canvas.SetTop(rect, position.Item1.Y - rectSize / 2);
|
SetCanvasPosition(rect, position.Item1.X - rectSize / 2, position.Item1.Y - rectSize / 2);
|
||||||
|
|
||||||
rect.MouseLeftButtonDown += UserControl_MouseLeftButtonDown;
|
rect.MouseLeftButtonDown += UserControl_MouseLeftButtonDown;
|
||||||
rect.MouseMove += UserControl_MouseMove;
|
rect.MouseMove += UserControl_MouseMove;
|
||||||
|
|
|
@ -123,8 +123,6 @@ namespace CtrEditor.ObjetosSim
|
||||||
|
|
||||||
public override void UpdatePLC(PLCViewModel plc, int TotalMilliseconds)
|
public override void UpdatePLC(PLCViewModel plc, int TotalMilliseconds)
|
||||||
{
|
{
|
||||||
Stopwatch stopwatch = new Stopwatch();
|
|
||||||
stopwatch.Start();
|
|
||||||
|
|
||||||
elapsedTimeAccumulator += TotalMilliseconds;
|
elapsedTimeAccumulator += TotalMilliseconds;
|
||||||
float randomFactor = (float)(new Random().NextDouble() * 0.1); // 10% random factor
|
float randomFactor = (float)(new Random().NextDouble() * 0.1); // 10% random factor
|
||||||
|
@ -135,12 +133,9 @@ namespace CtrEditor.ObjetosSim
|
||||||
motState.UpdatePLC(plc, this, TotalMilliseconds);
|
motState.UpdatePLC(plc, this, TotalMilliseconds);
|
||||||
elapsedTimeAccumulator = 0;
|
elapsedTimeAccumulator = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
Velocidad = (Proporcional_Speed / 100) * (motState.STATUS_VFD_ACT_Speed_Hz / 10);
|
Velocidad = (Proporcional_Speed / 100) * (motState.STATUS_VFD_ACT_Speed_Hz / 10);
|
||||||
Sentido_contrario = motState.OUT_Reversal;
|
Sentido_contrario = motState.OUT_Reversal;
|
||||||
|
|
||||||
stopwatch.Stop();
|
|
||||||
Debug.WriteLine($" osVMmotorSim : {Nombre} : {stopwatch.Elapsed.TotalMilliseconds} ms");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void UpdateControl(int TotalMilliseconds)
|
public override void UpdateControl(int TotalMilliseconds)
|
||||||
|
|
|
@ -27,9 +27,40 @@ using Emgu.CV.Structure;
|
||||||
namespace CtrEditor.ObjetosSim.Extraccion_Datos
|
namespace CtrEditor.ObjetosSim.Extraccion_Datos
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Interaction logic for ucBuscarCoincidencias.xaml
|
/// Represents a template search control that identifies similar patterns in images and creates tag extraction clones.
|
||||||
|
/// This class is designed to work with OCR extraction by finding visual patterns and creating copies of extraction tags
|
||||||
|
/// at each matching location.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// Key functionalities:
|
||||||
|
/// - Template matching using OpenCV
|
||||||
|
/// - Automatic tag cloning at found locations
|
||||||
|
/// - OCR text extraction from matched regions
|
||||||
|
/// - Export capabilities to Excel
|
||||||
///
|
///
|
||||||
|
/// Workflow:
|
||||||
|
/// 1. User creates a search template by positioning and sizing the control over a pattern
|
||||||
|
/// 2. Links extraction tags to this template using Id_Search_Templates
|
||||||
|
/// 3. Activates search_templates to find similar patterns
|
||||||
|
/// 4. The system automatically:
|
||||||
|
/// - Searches for visual matches in the image
|
||||||
|
/// - Creates clones of linked extraction tags at each match
|
||||||
|
/// - Assigns incremental copy_Number to organize rows in exports
|
||||||
|
/// - Performs OCR on each cloned tag location
|
||||||
|
///
|
||||||
|
/// Properties:
|
||||||
|
/// - search_templates: Triggers the pattern search process
|
||||||
|
/// - threshold: Minimum similarity threshold for pattern matching
|
||||||
|
/// - coincidencias: Number of matches found (readonly)
|
||||||
|
/// - show_debug_ocr: Shows debug windows during OCR process
|
||||||
|
/// - export_ocr: Triggers OCR text export for all matches
|
||||||
|
///
|
||||||
|
/// Usage example:
|
||||||
|
/// 1. Position the search template over a repeating pattern
|
||||||
|
/// 2. Create extraction tags and link them to this template
|
||||||
|
/// 3. Set threshold value (default usually works well)
|
||||||
|
/// 4. Activate search_templates to find matches and create clones
|
||||||
|
/// </remarks>
|
||||||
|
|
||||||
public partial class osBuscarCoincidencias : osBase, IosBase
|
public partial class osBuscarCoincidencias : osBase, IosBase
|
||||||
{
|
{
|
||||||
|
@ -362,9 +393,6 @@ namespace CtrEditor.ObjetosSim.Extraccion_Datos
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Row++;
|
Row++;
|
||||||
if (newObj != null)
|
|
||||||
newObj.New_Row = true;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -36,7 +36,18 @@ namespace CtrEditor.ObjetosSim.Extraccion_Datos
|
||||||
bool extraer;
|
bool extraer;
|
||||||
|
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
bool new_Row;
|
[property: Category("Tag Extraction:")]
|
||||||
|
bool eliminar_enters;
|
||||||
|
|
||||||
|
[ObservableProperty]
|
||||||
|
[property: Category("Tag Extraction:")]
|
||||||
|
[property: ItemsSource(typeof(IdiomasItemsSource<Idiomas>))]
|
||||||
|
string idioma_Extraccion;
|
||||||
|
|
||||||
|
[ObservableProperty]
|
||||||
|
[property: Category("Tag Extraction:")]
|
||||||
|
[property: ItemsSource(typeof(TagPatternItemsSource<TagPattern>))]
|
||||||
|
string pattern_Type;
|
||||||
|
|
||||||
public override void TopChanged(float value)
|
public override void TopChanged(float value)
|
||||||
{
|
{
|
||||||
|
@ -147,11 +158,39 @@ namespace CtrEditor.ObjetosSim.Extraccion_Datos
|
||||||
Alto = 1;
|
Alto = 1;
|
||||||
Angulo = 0;
|
Angulo = 0;
|
||||||
Opacity_oculto = 0.1f;
|
Opacity_oculto = 0.1f;
|
||||||
|
Idioma_Extraccion = Idiomas.DEFAULT_LANGUAGE;
|
||||||
|
Pattern_Type = TagPattern.DEFAULT_PATTERN;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void CaptureImageAreaAndDoOCR()
|
public void CaptureImageAreaAndDoOCR()
|
||||||
{
|
{
|
||||||
Tag_extract = CaptureImageAreaAndDoOCR(Left, Top, Ancho, Alto, Angulo, Show_Debug_Window);
|
string extractedText = CaptureImageAreaAndDoOCR(Left, Top, Ancho, Alto, Angulo, Show_Debug_Window);
|
||||||
|
|
||||||
|
// Clean up the extracted text if eliminar_enters is true
|
||||||
|
if (Eliminar_enters && !string.IsNullOrEmpty(extractedText))
|
||||||
|
{
|
||||||
|
// Replace all types of line endings with spaces
|
||||||
|
extractedText = extractedText.Replace("\r\n", " ")
|
||||||
|
.Replace("\n", " ")
|
||||||
|
.Replace("\r", " ");
|
||||||
|
|
||||||
|
// Replace multiple consecutive spaces with a single space
|
||||||
|
extractedText = System.Text.RegularExpressions.Regex.Replace(extractedText, @"\s+", " ");
|
||||||
|
|
||||||
|
// Trim spaces at the beginning and end
|
||||||
|
extractedText = extractedText.Trim();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Apply the selected pattern
|
||||||
|
extractedText = TagPattern.ApplyPattern(extractedText, Pattern_Type);
|
||||||
|
|
||||||
|
Tag_extract = extractedText;
|
||||||
|
|
||||||
|
// Set default language to English if not set
|
||||||
|
if (string.IsNullOrEmpty(Idioma_Extraccion))
|
||||||
|
{
|
||||||
|
Idioma_Extraccion = Idiomas.DEFAULT_LANGUAGE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public int ExportToExcel(IXLWorksheet worksheet, int row, int colBase)
|
public int ExportToExcel(IXLWorksheet worksheet, int row, int colBase)
|
||||||
|
|
|
@ -312,7 +312,7 @@ namespace CtrEditor.ObjetosSim
|
||||||
if (e.PropertyName == nameof(osFramePlate.Left))
|
if (e.PropertyName == nameof(osFramePlate.Left))
|
||||||
{
|
{
|
||||||
Left += ((osFramePlate)sender).offsetX;
|
Left += ((osFramePlate)sender).offsetX;
|
||||||
OnMoveResizeRotate();
|
OnMoveResizeRotate();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (e.PropertyName == nameof(osFramePlate.Zindex_FramePlate))
|
if (e.PropertyName == nameof(osFramePlate.Zindex_FramePlate))
|
||||||
|
|
|
@ -12,7 +12,7 @@ namespace CtrEditor.PopUps
|
||||||
/// Interaction logic for AssignImagesWindow.xaml
|
/// Interaction logic for AssignImagesWindow.xaml
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public partial class AssignImagesWindow : Window
|
public partial class AssignImagesWindow : Window
|
||||||
{
|
{
|
||||||
public AssignImagesWindow()
|
public AssignImagesWindow()
|
||||||
{
|
{
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Windows;
|
using System.Windows;
|
||||||
|
using CtrEditor.FuncionesBase;
|
||||||
|
|
||||||
namespace CtrEditor.PopUps
|
namespace CtrEditor.PopUps
|
||||||
{
|
{
|
||||||
|
@ -12,15 +13,7 @@ namespace CtrEditor.PopUps
|
||||||
public string SelectedSourceLanguage { get; private set; }
|
public string SelectedSourceLanguage { get; private set; }
|
||||||
public string SelectedTargetLanguage { get; private set; }
|
public string SelectedTargetLanguage { get; private set; }
|
||||||
|
|
||||||
private static readonly List<string> SupportedLanguages = new List<string>
|
private static readonly List<string> SupportedLanguages = Idiomas.GetLanguageList();
|
||||||
{
|
|
||||||
"English",
|
|
||||||
"Spanish",
|
|
||||||
"Italian",
|
|
||||||
"French",
|
|
||||||
"German",
|
|
||||||
"Portuguese"
|
|
||||||
};
|
|
||||||
|
|
||||||
private string _sourceColumnLabel = "Idioma 1";
|
private string _sourceColumnLabel = "Idioma 1";
|
||||||
private string _targetColumnLabel = "Idioma 2";
|
private string _targetColumnLabel = "Idioma 2";
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<Window x:Class="CtrEditor.PopUps.MatrixPreviewWindow"
|
<Window x:Class="CtrEditor.PopUps.MatrixPreviewWindow"
|
||||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
Title="Export Matrix Preview" Height="600" Width="800">
|
Title="Exportar Tags Extraidos" Height="600" Width="800">
|
||||||
<Grid>
|
<Grid>
|
||||||
<Grid.RowDefinitions>
|
<Grid.RowDefinitions>
|
||||||
<RowDefinition Height="*"/>
|
<RowDefinition Height="*"/>
|
||||||
|
@ -70,23 +70,23 @@
|
||||||
HorizontalAlignment="Right"
|
HorizontalAlignment="Right"
|
||||||
Margin="5"
|
Margin="5"
|
||||||
Background="{DynamicResource {x:Static SystemColors.ControlBrushKey}}">
|
Background="{DynamicResource {x:Static SystemColors.ControlBrushKey}}">
|
||||||
<Button Content="AI Correction"
|
<Button Content="Correccion de Descripcion"
|
||||||
Command="{Binding AICorrectMatrixCommand}"
|
Command="{Binding AICorrectMatrixCommand}"
|
||||||
Margin="5"
|
Margin="5"
|
||||||
Padding="10,5"/>
|
Padding="10,5"/>
|
||||||
<Button Content="Export to Excel"
|
<Button Content="Exportar a Excel"
|
||||||
Command="{Binding ExportToExcelCommand}"
|
Command="{Binding ExportToExcelCommand}"
|
||||||
Margin="5"
|
Margin="5"
|
||||||
Padding="10,5"/>
|
Padding="10,5"/>
|
||||||
<Button Content="Regenerate Matrix"
|
<Button Content="Regenerar Matriz"
|
||||||
Command="{Binding RegenerateMatrixCommand}"
|
Command="{Binding RegenerateMatrixCommand}"
|
||||||
Margin="5"
|
Margin="5"
|
||||||
Padding="10,5"/>
|
Padding="10,5"/>
|
||||||
<Button Content="Apply Changes"
|
<Button Content="Salvar Cambios"
|
||||||
Command="{Binding ApplyChangesCommand}"
|
Command="{Binding ApplyChangesCommand}"
|
||||||
Margin="5"
|
Margin="5"
|
||||||
Padding="10,5"/>
|
Padding="10,5"/>
|
||||||
<Button Content="Close"
|
<Button Content="Cerrar"
|
||||||
Command="{Binding CloseCommand}"
|
Command="{Binding CloseCommand}"
|
||||||
Margin="5"
|
Margin="5"
|
||||||
Padding="10,5"/>
|
Padding="10,5"/>
|
||||||
|
|
|
@ -41,8 +41,8 @@ namespace CtrEditor.Services
|
||||||
|
|
||||||
public async Task<List<(string Source, string Target)>> ProcessTextBatch(
|
public async Task<List<(string Source, string Target)>> ProcessTextBatch(
|
||||||
List<(string Source, string Target)> textPairs,
|
List<(string Source, string Target)> textPairs,
|
||||||
string sourceLanguage = "Unknown",
|
string sourceLanguage = "English",
|
||||||
string targetLanguage = "Unknown")
|
string targetLanguage = "English")
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
|
|
@ -213,31 +213,60 @@ namespace CtrEditor.PopUps
|
||||||
UpdateMatrixPreview();
|
UpdateMatrixPreview();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Analyzes the current page and collects all extraction tags data for matrix preview.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// The method processes three types of extraction tags:
|
||||||
|
/// 1. Fixed Tags: Tags without Search Templates association
|
||||||
|
/// 2. Grouped Tags: Tags linked to Search Templates but not cloned
|
||||||
|
/// 3. Cloned Tags: Tags created by Search Templates pattern matching
|
||||||
|
///
|
||||||
|
/// Workflow:
|
||||||
|
/// 1. Filters objects by visibility on current page
|
||||||
|
/// 2. Groups tags by their type (fixed, grouped, cloned)
|
||||||
|
/// 3. Performs OCR extraction on each tag
|
||||||
|
/// 4. Creates MatrixItems with extracted data
|
||||||
|
///
|
||||||
|
/// Data Organization:
|
||||||
|
/// - Fixed tags maintain their original position and values
|
||||||
|
/// - Grouped tags are associated with their Search Templates
|
||||||
|
/// - Cloned tags inherit Copy_Number from their creation order in pattern matching
|
||||||
|
///
|
||||||
|
/// Related Classes:
|
||||||
|
/// - osExtraccionTag: Contains OCR extraction logic and tag properties
|
||||||
|
/// - osBuscarCoincidencias: Handles pattern matching and tag cloning
|
||||||
|
/// </remarks>
|
||||||
|
/// <returns>A list of MatrixItems containing all processed tag data for the current page</returns>
|
||||||
private List<MatrixItem> AnalyzePage()
|
private List<MatrixItem> AnalyzePage()
|
||||||
{
|
{
|
||||||
var items = new List<MatrixItem>();
|
var items = new List<MatrixItem>();
|
||||||
|
|
||||||
|
// Filter visible objects by type
|
||||||
var osBuscarCoincidencias_List = _mainViewModel.ObjetosSimulables
|
var osBuscarCoincidencias_List = _mainViewModel.ObjetosSimulables
|
||||||
.OfType<osBuscarCoincidencias>()
|
.OfType<osBuscarCoincidencias>()
|
||||||
.Where(tag => tag.Show_On_This_Page)
|
.Where(tag => tag.Show_On_This_Page)
|
||||||
.ToList();
|
.ToList();
|
||||||
|
|
||||||
|
// Get base tags that are linked to Search Templates
|
||||||
var osExtraccionTagBaseGrouped_List = _mainViewModel.ObjetosSimulables
|
var osExtraccionTagBaseGrouped_List = _mainViewModel.ObjetosSimulables
|
||||||
.OfType<osExtraccionTag>()
|
.OfType<osExtraccionTag>()
|
||||||
.Where(tag => tag.Show_On_This_Page && !tag.Cloned && tag.Id_Search_Templates != null && tag.Id_Search_Templates != "")
|
.Where(tag => tag.Show_On_This_Page && !tag.Cloned && tag.Id_Search_Templates != null && tag.Id_Search_Templates != "")
|
||||||
.ToList();
|
.ToList();
|
||||||
|
|
||||||
|
// Get fixed tags (not linked to Search Templates)
|
||||||
var osExtraccionTagBaseFix_List = _mainViewModel.ObjetosSimulables
|
var osExtraccionTagBaseFix_List = _mainViewModel.ObjetosSimulables
|
||||||
.OfType<osExtraccionTag>()
|
.OfType<osExtraccionTag>()
|
||||||
.Where(tag => tag.Show_On_This_Page && !tag.Cloned && (tag.Id_Search_Templates == null || tag.Id_Search_Templates == ""))
|
.Where(tag => tag.Show_On_This_Page && !tag.Cloned && (tag.Id_Search_Templates == null || tag.Id_Search_Templates == ""))
|
||||||
.ToList();
|
.ToList();
|
||||||
|
|
||||||
|
// Get cloned tags (created by Search Templates)
|
||||||
var osExtraccionTagCloned_List = _mainViewModel.ObjetosSimulables
|
var osExtraccionTagCloned_List = _mainViewModel.ObjetosSimulables
|
||||||
.OfType<osExtraccionTag>()
|
.OfType<osExtraccionTag>()
|
||||||
.Where(tag => tag.Show_On_This_Page && tag.Cloned)
|
.Where(tag => tag.Show_On_This_Page && tag.Cloned)
|
||||||
.ToList();
|
.ToList();
|
||||||
|
|
||||||
// Add fixed tags
|
// Process fixed tags
|
||||||
foreach (var tag in osExtraccionTagBaseFix_List)
|
foreach (var tag in osExtraccionTagBaseFix_List)
|
||||||
{
|
{
|
||||||
tag.CaptureImageAreaAndDoOCR();
|
tag.CaptureImageAreaAndDoOCR();
|
||||||
|
@ -253,7 +282,7 @@ namespace CtrEditor.PopUps
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add grouped tags
|
// Process grouped tags
|
||||||
foreach (var tag in osExtraccionTagBaseGrouped_List)
|
foreach (var tag in osExtraccionTagBaseGrouped_List)
|
||||||
{
|
{
|
||||||
tag.CaptureImageAreaAndDoOCR();
|
tag.CaptureImageAreaAndDoOCR();
|
||||||
|
@ -269,7 +298,7 @@ namespace CtrEditor.PopUps
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add cloned tags
|
// Process cloned tags
|
||||||
foreach (var tag in osExtraccionTagCloned_List)
|
foreach (var tag in osExtraccionTagCloned_List)
|
||||||
{
|
{
|
||||||
tag.CaptureImageAreaAndDoOCR();
|
tag.CaptureImageAreaAndDoOCR();
|
||||||
|
@ -282,7 +311,7 @@ namespace CtrEditor.PopUps
|
||||||
Type = "Cloned",
|
Type = "Cloned",
|
||||||
IsCloned = true,
|
IsCloned = true,
|
||||||
Id = tag.Id,
|
Id = tag.Id,
|
||||||
Copy_Number = tag.Copy_Number // Add this line
|
Copy_Number = tag.Copy_Number
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -30,6 +30,33 @@ namespace CtrEditor
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public class ConnectStateToBtnTextConverter : IValueConverter
|
||||||
|
{
|
||||||
|
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
|
||||||
|
{
|
||||||
|
return (bool)value ? "Desconectar PLC" : "Conectar PLC";
|
||||||
|
}
|
||||||
|
|
||||||
|
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class ConnectStateToImageConverter : IValueConverter
|
||||||
|
{
|
||||||
|
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
|
||||||
|
{
|
||||||
|
return (bool)value ? "Icons/disconnect.png" : "Icons/connect.png";
|
||||||
|
}
|
||||||
|
|
||||||
|
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public class ListItemPropertyDescriptor<T> : PropertyDescriptor
|
public class ListItemPropertyDescriptor<T> : PropertyDescriptor
|
||||||
{
|
{
|
||||||
private readonly IList<T> owner;
|
private readonly IList<T> owner;
|
||||||
|
|
Loading…
Reference in New Issue