using System.Net.Http; using System.Text; using System.Windows; using System.Windows.Controls; using System.Windows.Data; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Imaging; using System.Windows.Navigation; using System.Windows.Shapes; using System; using System.Threading.Tasks; using Newtonsoft.Json; using System.IO; using LanguageDetection; using ToastNotifications; using ToastNotifications.Lifetime; using ToastNotifications.Messages; using ToastNotifications.Position; using System.Windows.Threading; using System; using System.Runtime.InteropServices; using System; namespace GTPAsk { public partial class MainWindow // Asumiendo que estás dentro de una clase de WPF { private readonly string openAiApiKey = "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"; private readonly string instruccionesCSV = @"D:\Proyectos\VisualStudio\GTPAsk\instrucciones.csv"; private Notifier _notifier; private Dictionary languageMap = new Dictionary { { "en", "Inglés" }, { "es", "Español" }, { "it", "Italiano" }, { "pt", "Portugués" } // Agrega más idiomas según sea necesario }; [StructLayout(LayoutKind.Sequential)] internal struct INPUT { public uint type; public InputUnion U; public static int Size => Marshal.SizeOf(typeof(INPUT)); } [StructLayout(LayoutKind.Explicit)] internal struct InputUnion { [FieldOffset(0)] public MOUSEINPUT mi; [FieldOffset(0)] public KEYBDINPUT ki; [FieldOffset(0)] public HARDWAREINPUT hi; } [StructLayout(LayoutKind.Sequential)] internal struct MOUSEINPUT { public int dx; public int dy; public uint mouseData; public uint dwFlags; public uint time; public IntPtr dwExtraInfo; } [StructLayout(LayoutKind.Sequential)] internal struct KEYBDINPUT { public ushort wVk; public ushort wScan; public uint dwFlags; public uint time; public IntPtr dwExtraInfo; } [StructLayout(LayoutKind.Sequential)] internal struct HARDWAREINPUT { public uint uMsg; public ushort wParamL; public ushort wParamH; } [DllImport("user32.dll", SetLastError = true)] private static extern uint SendInput(uint nInputs, [MarshalAs(UnmanagedType.LPArray), In] INPUT[] pInputs, int cbSize); [DllImport("user32.dll")] private static extern IntPtr GetMessageExtraInfo(); // VK and KEYEVENTF Constants const uint INPUT_KEYBOARD = 1; const ushort VK_TAB = 0x09; const ushort VK_MENU = 0x12; // ALT key const uint KEYEVENTF_KEYDOWN = 0x0000; const uint KEYEVENTF_KEYUP = 0x0002; static void VolverAUltimaAplicaicon() { // Simulate ALT key down SendKeyboardInput(VK_MENU, KEYEVENTF_KEYDOWN); // Simulate TAB key down and up SendKeyboardInput(VK_TAB, KEYEVENTF_KEYDOWN); SendKeyboardInput(VK_TAB, KEYEVENTF_KEYUP); // Simulate ALT key up SendKeyboardInput(VK_MENU, KEYEVENTF_KEYUP); } private static void SendKeyboardInput(ushort key, uint flag) { INPUT[] inputs = new INPUT[] { new INPUT { type = INPUT_KEYBOARD, U = new InputUnion { ki = new KEYBDINPUT { wVk = key, wScan = 0, dwFlags = flag, time = 0, dwExtraInfo = GetMessageExtraInfo(), } } } }; SendInput((uint)inputs.Length, inputs, INPUT.Size); } private void NotifyUserWithCursor() { // Establecer el cursor personalizado var customCursor = new Cursor(Application.GetResourceStream(new Uri("/;component/Resource/Images/BusyCursor.cur", UriKind.RelativeOrAbsolute)).Stream); Mouse.OverrideCursor = customCursor; // Crear un temporizador para revertir el cursor después de 3 segundos var timer = new DispatcherTimer { Interval = TimeSpan.FromSeconds(3) }; timer.Tick += (sender, args) => { // Revertir al cursor predeterminado Mouse.OverrideCursor = Cursors.Arrow; timer.Stop(); }; timer.Start(); } private string DetectarIdioma(string TextoACorregir) { LanguageDetector detector = new LanguageDetector(); detector.AddLanguages("en", "es", "it", "pt"); string detectedLanguageCode = detector.Detect(TextoACorregir); string detectedLanguageName = languageMap.ContainsKey(detectedLanguageCode) ? languageMap[detectedLanguageCode] : "Desconocido"; return detectedLanguageName; } private void LoadClipboardContent() { if (Clipboard.ContainsText()) { string idioma; TextoDesdePortapapeles.Text = Clipboard.GetText(); idioma = DetectarIdioma(TextoDesdePortapapeles.Text); statusTextBox.Text = "Idioma: " + idioma; _notifier.ShowInformation("Idioma detectado: " + idioma); // Verificar si la tecla Control está presionada // if (!Keyboard.IsKeyDown(Key.LeftCtrl) && !Keyboard.IsKeyDown(Key.RightCtrl)) // { CorregirTexto(); // } } } private async void CorregirTexto() { statusTextBox.Text = "Llamando a la API de OpenAI..."; var TextoACorregir = TextoDesdePortapapeles.Text; var Instrucciones = TB_Instrucciones.Text; var idioma = DetectarIdioma(TextoACorregir); // Verificar si el texto de modifiableTextBox no está en defaultTextComboBox if (!CB_ListaInstrucciones.Items.Contains(Instrucciones)) { CB_ListaInstrucciones.Items.Add(Instrucciones); } if (idioma == "Desconocido") { _notifier.ShowError("No se puede detectar el idioma del texto."); statusTextBox.Text = "No se puede detectar el idioma del texto."; return; } TextoACorregir = "El resultado debe estar en " + DetectarIdioma(TextoACorregir) + ". " + Instrucciones + "\"" + TextoACorregir + "\""; VolverAUltimaAplicaicon(); // Hacer ALT-TAB var Respuesta = await CallOpenAiApi(TextoACorregir); // Elimina comillas al principio y al final si existen Respuesta = Respuesta.Trim('\"'); resultTextBox.Text = Respuesta; Clipboard.SetText(Respuesta); // Mostrar notificación _notifier.ShowInformation("La respuesta está lista."); statusTextBox.Text = "Respuesta recibida."; NotifyUserWithCursor(); // Configurar y comenzar el temporizador para cerrar la aplicación DispatcherTimer closeTimer = new DispatcherTimer { Interval = TimeSpan.FromSeconds(10) // Establece el intervalo a 5 segundos }; closeTimer.Tick += CloseTimer_Tick; // Suscribirse al evento Tick closeTimer.Start(); } private async void ExecuteButton_Click(object sender, RoutedEventArgs e) { CorregirTexto(); } private async Task CallOpenAiApi(string input) { var httpClient = new HttpClient(); httpClient.DefaultRequestHeaders.Add("Authorization", $"Bearer {openAiApiKey}"); var requestData = new { model = "gpt-4", messages = new[] { new { role = "system", content = "Este es un mensaje del sistema inicializando la conversación" }, new { role = "user", content = input } } }; var content = new StringContent(JsonConvert.SerializeObject(requestData), Encoding.UTF8, "application/json"); var response = await httpClient.PostAsync("https://api.openai.com/v1/chat/completions", content); response.EnsureSuccessStatusCode(); var jsonResponse = await response.Content.ReadAsStringAsync(); dynamic data = JsonConvert.DeserializeObject(jsonResponse); return data.choices[0].message.content; } private void ComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e) { if (CB_ListaInstrucciones.SelectedItem != null) { var selectedItem = CB_ListaInstrucciones.SelectedItem.ToString(); // Actualizar modifiableTextBox TB_Instrucciones.Text = selectedItem; } } private void LoadComboBoxItems() { try { var lines = File.ReadAllLines(instruccionesCSV); foreach (var line in lines) { CB_ListaInstrucciones.Items.Add(line); } if (CB_ListaInstrucciones.Items.Count > 0) { CB_ListaInstrucciones.SelectedIndex = CB_ListaInstrucciones.Items.Count - 1; } } catch (FileNotFoundException) { CB_ListaInstrucciones.Items.Add("Me puedes corregir el siguiente texto y mejorarlo para que se comprenda mejor: "); CB_ListaInstrucciones.SelectedIndex = 0; } } protected override void OnClosed(EventArgs e) { statusTextBox.Text = "Guardando cambios..."; _notifier.Dispose(); base.OnClosed(e); SaveComboBoxItems(); } private void SaveComboBoxItems() { var lines = new List(); foreach (var item in CB_ListaInstrucciones.Items) { lines.Add(item.ToString()); } File.WriteAllLines(instruccionesCSV, lines); } private void MainWindow_Loaded(object sender, RoutedEventArgs e) { _notifier = new Notifier(cfg => { cfg.PositionProvider = new PrimaryScreenPositionProvider( corner: Corner.BottomRight, // Puedes cambiar esto a la esquina que prefieras offsetX: 10, offsetY: 10); cfg.LifetimeSupervisor = new TimeAndCountBasedLifetimeSupervisor( notificationLifetime: TimeSpan.FromSeconds(3), maximumNotificationCount: MaximumNotificationCount.FromCount(5)); cfg.Dispatcher = Application.Current.Dispatcher; }); LoadClipboardContent(); LoadComboBoxItems(); } private void CloseTimer_Tick(object sender, EventArgs e) { DispatcherTimer timer = (DispatcherTimer)sender; timer.Stop(); // Detener el temporizador timer.Tick -= CloseTimer_Tick; // Desuscribirse del evento this.Close(); // Cerrar la ventana actual } public MainWindow() { InitializeComponent(); this.Loaded += MainWindow_Loaded; } } }