using System.Configuration; using System.Data; using System.Windows; using System; using System.Windows.Forms; using Application = System.Windows.Application; using System.Diagnostics; using System.Threading.Tasks; using System.Globalization; using System.Windows.Data; using System.Runtime.InteropServices; namespace GTPCorrgir { public partial class App : Application { gtpask GTP = new gtpask(); NotifyIcon notificacion; System.Windows.Forms.Timer timer; bool CorreccionFinalizada = false; Stopwatch stopwatch = new Stopwatch(); private notificacion notificationWindow; private readonly int TimeoutSeconds = 60; // Timeout máximo para esperar la respuesta private CancellationTokenSource _cancellationTokenSource; KeyboardHelper pasteLogic = new KeyboardHelper(); protected override async void OnStartup(StartupEventArgs e) { base.OnStartup(e); _cancellationTokenSource = new CancellationTokenSource(); try { pasteLogic.SaveCurrentWindow(); if (Opciones.Instance.AutoCopy) { await pasteLogic.AutoCopyFromActiveWindow(); } if (System.Windows.Clipboard.ContainsText()) { GTP.TextoACorregir = await ClipboardHelper.GetText(); } if (string.IsNullOrEmpty(GTP.TextoACorregir)) { GTP.Log.Log("No hay texto en el portapapeles"); ShowCustomNotification("Error", "No hay texto para procesar"); Application.Current.Shutdown(); return; } if (Opciones.Instance.modo == Opciones.modoDeUso.Corregir || Opciones.Instance.modo == Opciones.modoDeUso.Ortografia) { GTP.Log.Log("Iniciando proceso de corrección"); stopwatch.Start(); ShowCustomNotification("Espera", $"Corrigiendo texto con {Opciones.Instance.nombreDeLLM()}..."); IniciarCronometro(); // Ejecuta la tarea de corrección con timeout _ = ProcessCorreccionWithTimeout(); } else if (Opciones.Instance.modo == Opciones.modoDeUso.Chat) { var chatWindows = new Chat(GTP); chatWindows.Show(); } } catch (Exception ex) { GTP.Log.Log($"Error en OnStartup: {ex.Message}"); GTP.Log.Log($"StackTrace: {ex.StackTrace}"); ShowCustomNotification("Error", "Se produjo un error al iniciar la aplicación"); Application.Current.Shutdown(); } } private async Task ProcessCorreccionWithTimeout() { try { using var timeoutCts = new CancellationTokenSource(TimeSpan.FromSeconds(TimeoutSeconds)); using var linkedCts = CancellationTokenSource.CreateLinkedTokenSource( timeoutCts.Token, _cancellationTokenSource.Token); var correccionTask = Task.Run(async () => { try { GTP.Log.Log("Iniciando corrección de texto"); await GTP.CorregirTexto(); GTP.Log.Log("Corrección de texto completada"); } catch (Exception ex) { GTP.Log.Log($"Error durante la corrección: {ex.Message}"); throw; } }, linkedCts.Token); await correccionTask; await Dispatcher.InvokeAsync(async () => { try { GTP.Log.Log("Procesando resultado de la corrección"); CorreccionFinalizada = true; DetenerCronometro(); if (GTP.TextoCorregido != null) { GTP.Log.Log("Copiando texto corregido al portapapeles"); await ClipboardHelper.SetText(GTP.TextoCorregido); ShowCustomNotification("Se puede pegar", $"Corrección en: {Math.Round(stopwatch.ElapsedMilliseconds / 1000.0, 1)} s"); if (Opciones.Instance.modo == Opciones.modoDeUso.Corregir) { GTP.Log.Log("Mostrando ventana de resultado"); var resultadoWindow = new VentanaResultado(GTP.TextoCorregido); resultadoWindow.Show(); await Task.Delay(1000); } else if (Opciones.Instance.modo == Opciones.modoDeUso.Ortografia) { GTP.Log.Log("Ejecutando pegado automático"); await pasteLogic.RestoreAndSimulatePaste(); } } else { GTP.Log.Log("Error: TextoCorregido es null"); ShowCustomNotification("Error", "No se pudo obtener el texto corregido"); } } catch (Exception ex) { GTP.Log.Log($"Error en el procesamiento final: {ex.Message}"); ShowCustomNotification("Error", "Error al procesar el resultado"); } finally { GTP.Log.Log("Cerrando aplicación"); Application.Current.Shutdown(); } }); } catch (OperationCanceledException) { GTP.Log.Log("Operación cancelada por timeout"); await Dispatcher.InvokeAsync(() => { ShowCustomNotification("Error", "La operación excedió el tiempo límite"); Application.Current.Shutdown(); }); } catch (Exception ex) { GTP.Log.Log($"Error no controlado: {ex.Message}"); await Dispatcher.InvokeAsync(() => { ShowCustomNotification("Error", "Se produjo un error inesperado"); Application.Current.Shutdown(); }); } } protected override void OnExit(ExitEventArgs e) { _cancellationTokenSource?.Cancel(); _cancellationTokenSource?.Dispose(); base.OnExit(e); } private void ShowCustomNotification(string title, string message) { try { GTP.Log.Log($"Mostrando notificación: {title} - {message}"); if (notificationWindow == null) { notificationWindow = new notificacion(); notificationWindow.Show(); } notificationWindow.UpdateNotification(title, message); } catch (Exception ex) { GTP.Log.Log($"Error al mostrar notificación: {ex.Message}"); } } private void IniciarCronometro() { timer = new System.Windows.Forms.Timer(); timer.Interval = 100; timer.Tick += ActualizarCronometro; timer.Start(); GTP.Log.Log("Cronómetro iniciado"); } private void ActualizarCronometro(object sender, EventArgs e) { if (!CorreccionFinalizada) { ShowCustomNotification( $"{Opciones.Instance.nombreDeLLM()} Trabajando..", $"Texto en {GTP.IdiomaDetectado} pasados: {Math.Round(stopwatch.ElapsedMilliseconds / 1000.0, 1)} s" ); } } private void DetenerCronometro() { if (timer != null) { timer.Stop(); timer.Dispose(); GTP.Log.Log("Cronómetro detenido"); } } } }