GTPCorrgir/App.xaml.cs

379 lines
15 KiB
C#

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;
private CancellationTokenSource _cancellationTokenSource;
private Window _mainWindow;
KeyboardHelper pasteLogic = new KeyboardHelper();
protected override async void OnStartup(StartupEventArgs e)
{
ShutdownMode = ShutdownMode.OnExplicitShutdown;
base.OnStartup(e);
_cancellationTokenSource = new CancellationTokenSource();
try
{
pasteLogic.SaveCurrentWindow();
if (Opciones.Instance.modo == Opciones.modoDeUso.Menu)
{
_mainWindow = new ContextMenuWindow();
(_mainWindow as ContextMenuWindow).Closed += async (s, args) =>
{
if (Opciones.Instance.modo != Opciones.modoDeUso.Menu)
{
await InitializeSelectedMode();
}
else
{
Application.Current.Shutdown();
}
};
_mainWindow.Show();
}
else
{
await InitializeSelectedMode();
}
}
catch (Exception ex)
{
GTP.Log.Log($"Error en OnStartup: {ex.Message}");
ShowCustomNotification("Error", "Se produjo un error al iniciar la aplicación");
Application.Current.Shutdown();
}
}
private async Task InitializeSelectedMode()
{
switch (Opciones.Instance.modo)
{
case Opciones.modoDeUso.OCRaTexto:
_mainWindow = new ScreenCaptureWindow();
_mainWindow.Closed += (s, e) => Application.Current.Shutdown();
break;
case Opciones.modoDeUso.Chat:
_mainWindow = new Chat(GTP);
_mainWindow.Closed += (s, e) => Application.Current.Shutdown();
break;
case Opciones.modoDeUso.Corregir:
case Opciones.modoDeUso.Ortografia:
case Opciones.modoDeUso.PreguntaRespuesta:
case Opciones.modoDeUso.ClaudeWebSearch:
case Opciones.modoDeUso.Traducir_a_Espanol:
case Opciones.modoDeUso.Traducir_a_Ingles:
case Opciones.modoDeUso.Traducir_a_Italiano:
case Opciones.modoDeUso.Traducir_a_Portugues:
await HandleTextCorrection();
return;
}
if (_mainWindow != null)
_mainWindow.Show();
}
private async Task HandleTextCorrection()
{
if (Opciones.Instance.AutoCopy)
{
await pasteLogic.AutoCopyFromActiveWindow();
}
if (!System.Windows.Clipboard.ContainsText())
{
ShowCustomNotification("Error", "No hay texto para procesar");
Application.Current.Shutdown();
return;
}
GTP.TextoACorregir = await ClipboardHelper.GetText();
stopwatch.Start();
ShowCustomNotification("Espera", $"Procesando texto con {Opciones.Instance.nombreDeLLM()}...");
IniciarCronometro();
await ProcessCorreccionWithTimeout();
}
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 || Opciones.Instance.modo == Opciones.modoDeUso.Ortografia ||
Opciones.Instance.modo == Opciones.modoDeUso.PreguntaRespuesta || Opciones.Instance.modo == Opciones.modoDeUso.ClaudeWebSearch ||
Opciones.Instance.modo == Opciones.modoDeUso.Traducir_a_Espanol || Opciones.Instance.modo == Opciones.modoDeUso.Traducir_a_Ingles ||
Opciones.Instance.modo == Opciones.modoDeUso.Traducir_a_Italiano || Opciones.Instance.modo == Opciones.modoDeUso.Traducir_a_Portugues)
{
if (Opciones.Instance.FuncionesOpcionales == Opciones.funcionesOpcionales.MostrarPopUp)
{
GTP.Log.Log("Mostrando ventana de resultado");
var resultadoWindow = new VentanaResultado(GTP.TextoCorregido);
resultadoWindow.Show();
await Task.Delay(1000);
}
else
{
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}");
try
{
// Intentar usar el fallback con Grok para este error también
string recentLogs = GTP.Log.GetRecentLogs("Iniciando corrección de texto");
string resultadoFallback = await GTP.ExplicarErrorConGrok(GTP.TextoACorregir ?? "Texto no disponible", recentLogs);
if (!string.IsNullOrEmpty(resultadoFallback))
{
await ClipboardHelper.SetText(resultadoFallback);
ShowCustomNotification("Error explicado", "Error analizado y copiado al portapapeles");
}
else
{
ShowCustomNotification("Error", "Error al procesar el resultado");
}
}
catch (Exception fallbackEx)
{
GTP.Log.Log($"Error en fallback para procesamiento final: {fallbackEx.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(async () =>
{
try
{
// Intentar usar el fallback con Grok para explicar el timeout
await TryErrorFallbackWithGrok(new TimeoutException("La operación excedió el tiempo límite"));
}
catch (Exception fallbackEx)
{
GTP.Log.Log($"Error en fallback para timeout: {fallbackEx.Message}");
ShowCustomNotification("Error", "La operación excedió el tiempo límite");
}
finally
{
Application.Current.Shutdown();
}
});
}
catch (Exception ex)
{
GTP.Log.Log($"Error no controlado: {ex.Message}");
await Dispatcher.InvokeAsync(async () =>
{
try
{
// Intentar usar el fallback con Grok para explicar el error
await TryErrorFallbackWithGrok(ex);
}
catch (Exception fallbackEx)
{
GTP.Log.Log($"Error en fallback: {fallbackEx.Message}");
ShowCustomNotification("Error", "Se produjo un error inesperado");
}
finally
{
Application.Current.Shutdown();
}
});
}
}
protected override void OnExit(ExitEventArgs e)
{
_cancellationTokenSource?.Cancel();
_cancellationTokenSource?.Dispose();
// Limpiar recursos de PaddleOCR
PaddleOCRManager.Cleanup();
base.OnExit(e);
}
private void ShowCustomNotification(string title, string message)
{
try
{
// GTP.Log.Log($"Mostrando notificación: {title} - {message}"); // Comentado para limpiar logs
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");
}
}
/// <summary>
/// Intenta usar Grok como fallback para explicar errores cuando el procesamiento principal falla
/// </summary>
private async Task TryErrorFallbackWithGrok(Exception originalError)
{
try
{
GTP.Log.Log("Iniciando sistema de fallback para explicar error");
// Obtener los logs recientes de la última interacción
string recentLogs = GTP.Log.GetRecentLogs("Iniciando corrección de texto");
if (string.IsNullOrEmpty(recentLogs))
{
GTP.Log.Log("No se pudieron obtener logs recientes para el fallback");
ShowCustomNotification("Error", "Se produjo un error inesperado");
return;
}
GTP.Log.Log("Intentando explicar error con Grok usando logs recientes");
// Usar el método de fallback de Grok para explicar el error
string resultadoFallback = await GTP.ExplicarErrorConGrok(GTP.TextoACorregir ?? "Texto no disponible", recentLogs);
if (!string.IsNullOrEmpty(resultadoFallback))
{
// Si Grok pudo explicar el error, copiar el resultado al portapapeles
await ClipboardHelper.SetText(resultadoFallback);
DetenerCronometro();
ShowCustomNotification("Error explicado", "Error analizado y copiado al portapapeles");
// Mostrar ventana de resultado si está configurado
if (Opciones.Instance.FuncionesOpcionales == Opciones.funcionesOpcionales.MostrarPopUp)
{
var resultadoWindow = new VentanaResultado(resultadoFallback);
resultadoWindow.Show();
await Task.Delay(1000);
}
else
{
// Restaurar ventana y pegar automáticamente
await pasteLogic.RestoreAndSimulatePaste();
}
GTP.Log.Log("Fallback con Grok completado exitosamente");
}
else
{
GTP.Log.Log("Grok no pudo explicar el error, usando notificación de error estándar");
ShowCustomNotification("Error", "Se produjo un error inesperado");
}
}
catch (Exception ex)
{
GTP.Log.Log($"Error en sistema de fallback: {ex.Message}");
throw; // Re-lanzar para que sea manejado por el caller
}
}
}
}