using System; using System.Collections.Generic; using System.Linq; using System.Windows; using System.Windows.Forms; using System.Windows.Input; using System.Windows.Data; using System.Windows.Controls; using System.IO; using System.Diagnostics; using KeyEventArgs = System.Windows.Input.KeyEventArgs; using MessageBox = System.Windows.MessageBox; namespace GTPCorrgir { public class NullToBooleanConverter : IValueConverter { public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) { return value != null; } public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) { throw new NotImplementedException(); } } public partial class ContextMenuWindow : Window { public class MenuOption { public string DisplayName { get; set; } public object Value { get; set; } } private readonly List modeOptions; private readonly List llmOptions; private bool optionsSelected = false; public ContextMenuWindow() { // Initialize lists in constructor modeOptions = new List { new MenuOption { DisplayName = "Corregir texto", Value = Opciones.modoDeUso.Corregir }, new MenuOption { DisplayName = "Revisar ortografía", Value = Opciones.modoDeUso.Ortografia }, new MenuOption { DisplayName = "Chat", Value = Opciones.modoDeUso.Chat }, new MenuOption { DisplayName = "Pregunta-Respuesta", Value = Opciones.modoDeUso.PreguntaRespuesta }, new MenuOption { DisplayName = "Traducir a inglés", Value = Opciones.modoDeUso.Traducir_a_Ingles }, new MenuOption { DisplayName = "Traducir a italiano", Value = Opciones.modoDeUso.Traducir_a_Italiano }, new MenuOption { DisplayName = "Traducir a español", Value = Opciones.modoDeUso.Traducir_a_Espanol }, new MenuOption { DisplayName = "Traducir a portugués", Value = Opciones.modoDeUso.Traducir_a_Portugues }, new MenuOption { DisplayName = "OCR a texto", Value = Opciones.modoDeUso.OCRaTexto } }; llmOptions = new List { new MenuOption { DisplayName = "OpenAI", Value = Opciones.LLM_a_Usar.OpenAI }, new MenuOption { DisplayName = "Ollama", Value = Opciones.LLM_a_Usar.Ollama }, new MenuOption { DisplayName = "Groq", Value = Opciones.LLM_a_Usar.Groq }, new MenuOption { DisplayName = "Grok", Value = Opciones.LLM_a_Usar.Grok }, new MenuOption { DisplayName = "Claude", Value = Opciones.LLM_a_Usar.Claude } }; InitializeComponent(); InitializeControls(); LoadSavedSelections(); // Posicionar la ventana después de que se haya cargado completamente this.Loaded += (s, e) => PositionWindowAtCursor(); } private void InitializeControls() { ModeListBox.ItemsSource = modeOptions; LLMListBox.ItemsSource = llmOptions; } private void LoadSavedSelections() { var savedSettings = MenuSettings.Instance; var savedMode = modeOptions.FirstOrDefault(x => (Opciones.modoDeUso)x.Value == savedSettings.Options.LastUsedMode); var savedLLM = llmOptions.FirstOrDefault(x => (Opciones.LLM_a_Usar)x.Value == savedSettings.Options.LastUsedLLM); if (savedMode != null) ModeListBox.SelectedItem = savedMode; if (savedLLM != null) LLMListBox.SelectedItem = savedLLM; } private void PositionWindowAtCursor() { var cursorPosition = System.Windows.Forms.Cursor.Position; var screen = Screen.FromPoint(cursorPosition); // Calculate position ensuring the window stays within screen bounds double left = cursorPosition.X; double top = cursorPosition.Y; // Get the window size (waiting for it to be rendered) this.UpdateLayout(); double windowWidth = this.ActualWidth; double windowHeight = this.ActualHeight; // Adjust position if window would go off screen if (left + windowWidth > screen.WorkingArea.Right) { left = screen.WorkingArea.Right - windowWidth; } if (top + windowHeight > screen.WorkingArea.Bottom) { top = screen.WorkingArea.Bottom - windowHeight; } // Ensure window doesn't go off the left or top of the screen left = Math.Max(screen.WorkingArea.Left, left); top = Math.Max(screen.WorkingArea.Top, top); this.Left = left; this.Top = top; } private void CloseButton_Click(object sender, RoutedEventArgs e) { // Cerrar toda la aplicación cuando se hace clic en el botón de cerrar System.Windows.Application.Current.Shutdown(); } private void Window_KeyDown(object sender, KeyEventArgs e) { if (e.Key == Key.Escape) { // Cerrar toda la aplicación cuando se presiona Esc System.Windows.Application.Current.Shutdown(); } } private void Window_Deactivated(object sender, EventArgs e) { // Elimina este evento o modifícalo para que no cierre automáticamente // if (!optionsSelected) // { // this.DialogResult = false; // this.Close(); // } } private void AcceptButton_Click(object sender, RoutedEventArgs e) { if (ModeListBox.SelectedItem is MenuOption selectedMode && LLMListBox.SelectedItem is MenuOption selectedLLM) { UpdateOptionsAndClose(selectedMode, selectedLLM); } } private void UpdateOptionsAndClose(MenuOption selectedMode, MenuOption selectedLLM) { optionsSelected = true; var modeValue = (Opciones.modoDeUso)selectedMode.Value; var llmValue = (Opciones.LLM_a_Usar)selectedLLM.Value; Opciones.Instance.modo = modeValue; Opciones.Instance.LLM = llmValue; MenuSettings.Instance.UpdateLastUsedOptions(modeValue, llmValue); // Eliminar DialogResult this.Close(); } // Manejadores del menú contextual private void OpenLog_Click(object sender, RoutedEventArgs e) { try { string logFilePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "logfile.log"); if (File.Exists(logFilePath)) { // Intentar abrir con el programa predeterminado Process.Start(new ProcessStartInfo { FileName = logFilePath, UseShellExecute = true }); } else { MessageBox.Show("El archivo de log no existe aún.", "Información", MessageBoxButton.OK, MessageBoxImage.Information); } } catch (Exception ex) { MessageBox.Show($"Error al abrir el archivo de log: {ex.Message}", "Error", MessageBoxButton.OK, MessageBoxImage.Error); } } private void ClearLog_Click(object sender, RoutedEventArgs e) { try { var result = MessageBox.Show( "¿Está seguro de que desea limpiar el archivo de log?\nEsta acción no se puede deshacer.", "Confirmar limpieza de log", MessageBoxButton.YesNo, MessageBoxImage.Warning); if (result == MessageBoxResult.Yes) { string logFilePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "logfile.log"); if (File.Exists(logFilePath)) { try { // Obtener todos los listeners de tipo TextWriterTraceListener var textWriterListeners = new List(); foreach (System.Diagnostics.TraceListener listener in System.Diagnostics.Trace.Listeners) { if (listener is System.Diagnostics.TextWriterTraceListener textListener) { textWriterListeners.Add(textListener); } } // Cerrar y remover temporalmente los listeners foreach (var listener in textWriterListeners) { listener.Flush(); listener.Close(); System.Diagnostics.Trace.Listeners.Remove(listener); } // Esperar un momento para asegurar que el archivo se libere System.Threading.Thread.Sleep(100); // Limpiar el archivo File.WriteAllText(logFilePath, string.Empty); // Recrear los listeners foreach (var listener in textWriterListeners) { var newListener = new System.Diagnostics.TextWriterTraceListener(logFilePath); System.Diagnostics.Trace.Listeners.Add(newListener); } // Reactivar AutoFlush System.Diagnostics.Trace.AutoFlush = true; MessageBox.Show("El archivo de log ha sido limpiado correctamente.", "Éxito", MessageBoxButton.OK, MessageBoxImage.Information); } catch (UnauthorizedAccessException) { MessageBox.Show( "No se puede acceder al archivo de log. Puede que esté siendo usado por otro proceso.\n" + "Intente cerrar todas las instancias de la aplicación y vuelva a intentarlo.", "Acceso denegado", MessageBoxButton.OK, MessageBoxImage.Warning); } catch (IOException ioEx) { MessageBox.Show( $"Error de E/S al acceder al archivo de log:\n{ioEx.Message}\n\n" + "El archivo puede estar siendo usado por otro proceso.", "Error de archivo", MessageBoxButton.OK, MessageBoxImage.Warning); } } else { MessageBox.Show("El archivo de log no existe.", "Información", MessageBoxButton.OK, MessageBoxImage.Information); } } } catch (Exception ex) { MessageBox.Show($"Error al limpiar el archivo de log: {ex.Message}", "Error", MessageBoxButton.OK, MessageBoxImage.Error); } } private void About_Click(object sender, RoutedEventArgs e) { var aboutDialog = new Window { Title = "Acerca de GTPCorregir", Width = 400, Height = 300, WindowStartupLocation = WindowStartupLocation.CenterOwner, Owner = this, ResizeMode = ResizeMode.NoResize, ShowInTaskbar = false, WindowStyle = WindowStyle.ToolWindow }; var stackPanel = new StackPanel { Margin = new Thickness(20) }; stackPanel.Children.Add(new System.Windows.Controls.TextBlock { Text = "GTPCorregir", FontSize = 18, FontWeight = FontWeights.Bold, HorizontalAlignment = System.Windows.HorizontalAlignment.Center, Margin = new Thickness(0, 0, 0, 10) }); stackPanel.Children.Add(new System.Windows.Controls.TextBlock { Text = "Herramienta de corrección de texto con IA", FontSize = 12, HorizontalAlignment = System.Windows.HorizontalAlignment.Center, Margin = new Thickness(0, 0, 0, 15) }); stackPanel.Children.Add(new System.Windows.Controls.TextBlock { Text = "• Corrección de ortografía y gramática", Margin = new Thickness(0, 2, 0, 2) }); stackPanel.Children.Add(new System.Windows.Controls.TextBlock { Text = "• Traducción a múltiples idiomas", Margin = new Thickness(0, 2, 0, 2) }); stackPanel.Children.Add(new System.Windows.Controls.TextBlock { Text = "• OCR con PaddleOCR", Margin = new Thickness(0, 2, 0, 2) }); stackPanel.Children.Add(new System.Windows.Controls.TextBlock { Text = "• Soporte para múltiples LLMs", Margin = new Thickness(0, 2, 0, 2) }); stackPanel.Children.Add(new System.Windows.Controls.TextBlock { Text = $"Versión: {System.Reflection.Assembly.GetExecutingAssembly().GetName().Version}", FontSize = 10, HorizontalAlignment = System.Windows.HorizontalAlignment.Center, Margin = new Thickness(0, 20, 0, 0) }); var closeButton = new System.Windows.Controls.Button { Content = "Cerrar", Width = 80, Height = 25, HorizontalAlignment = System.Windows.HorizontalAlignment.Center, Margin = new Thickness(0, 15, 0, 0) }; closeButton.Click += (s, args) => aboutDialog.Close(); stackPanel.Children.Add(closeButton); aboutDialog.Content = stackPanel; aboutDialog.ShowDialog(); } } }