diff --git a/App.xaml b/App.xaml new file mode 100644 index 0000000..750a4c6 --- /dev/null +++ b/App.xaml @@ -0,0 +1,13 @@ + + + + + + + + + diff --git a/App.xaml.cs b/App.xaml.cs new file mode 100644 index 0000000..b325e1c --- /dev/null +++ b/App.xaml.cs @@ -0,0 +1,14 @@ +using System.Configuration; +using System.Data; +using System.Windows; + +namespace GTPAsk +{ + /// + /// Interaction logic for App.xaml + /// + public partial class App : Application + { + } + +} diff --git a/AssemblyInfo.cs b/AssemblyInfo.cs new file mode 100644 index 0000000..b0ec827 --- /dev/null +++ b/AssemblyInfo.cs @@ -0,0 +1,10 @@ +using System.Windows; + +[assembly: ThemeInfo( + ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located + //(used if a resource is not found in the page, + // or application resource dictionaries) + ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located + //(used if a resource is not found in the page, + // app, or any theme specific resource dictionaries) +)] diff --git a/GTPAsk.csproj b/GTPAsk.csproj new file mode 100644 index 0000000..bb40f66 --- /dev/null +++ b/GTPAsk.csproj @@ -0,0 +1,18 @@ + + + + WinExe + net8.0-windows + enable + enable + true + + + + + + + + + + diff --git a/GTPAsk.sln b/GTPAsk.sln new file mode 100644 index 0000000..0b638cc --- /dev/null +++ b/GTPAsk.sln @@ -0,0 +1,25 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.8.34330.188 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GTPAsk", "GTPAsk.csproj", "{6342C8D0-40D6-4DAF-A0E4-8EFA577F435F}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {6342C8D0-40D6-4DAF-A0E4-8EFA577F435F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {6342C8D0-40D6-4DAF-A0E4-8EFA577F435F}.Debug|Any CPU.Build.0 = Debug|Any CPU + {6342C8D0-40D6-4DAF-A0E4-8EFA577F435F}.Release|Any CPU.ActiveCfg = Release|Any CPU + {6342C8D0-40D6-4DAF-A0E4-8EFA577F435F}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {0BC503E4-ABF3-4126-8CFF-5FEDFA7D2BEE} + EndGlobalSection +EndGlobal diff --git a/MainWindow.xaml b/MainWindow.xaml new file mode 100644 index 0000000..0cbc0cf --- /dev/null +++ b/MainWindow.xaml @@ -0,0 +1,44 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/MainWindow.xaml.cs b/MainWindow.xaml.cs new file mode 100644 index 0000000..08a65e0 --- /dev/null +++ b/MainWindow.xaml.cs @@ -0,0 +1,356 @@ +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; + + } + } +} diff --git a/instrucciones.csv b/instrucciones.csv new file mode 100644 index 0000000..0164c1f --- /dev/null +++ b/instrucciones.csv @@ -0,0 +1,58 @@ +Me puedes corregir el siguiente texto y mejorarlo para que se comprenda mejor: +Me puedes corregir el siguiente texto y mejorarlo para que se comprenda mejor: +Me puedes corregir el siguiente texto y mejorarlo para que se comprenda mejor: +Me puedes corregir el siguiente texto y mejorarlo para que se comprenda mejor: +Me puedes corregir el siguiente texto y mejorarlo para que se comprenda mejor: +Me puedes corregir el siguiente texto y mejorarlo para que se comprenda mejor: +Me puedes corregir el siguiente texto y mejorarlo para que se comprenda mejor: +Me puedes corregir el siguiente texto y mejorarlo para que se comprenda mejor: +Me puedes corregir el siguiente texto y mejorarlo para que se comprenda mejor: +Me puedes corregir el siguiente texto y mejorarlo para que se comprenda mejor: +Me puedes corregir el siguiente texto y mejorarlo para que se comprenda mejor: +Me puedes corregir el siguiente texto y mejorarlo para que se comprenda mejor: +Me puedes corregir el siguiente texto y mejorarlo para que se comprenda mejor: +Me puedes corregir el siguiente texto y mejorarlo para que se comprenda mejor: +Me puedes corregir el siguiente texto y mejorarlo para que se comprenda mejor: +Me puedes corregir el siguiente texto y mejorarlo para que se comprenda mejor: +Me puedes corregir el siguiente texto y mejorarlo para que se comprenda mejor: +Me puedes corregir el siguiente texto y mejorarlo para que se comprenda mejor: +Me puedes corregir el siguiente texto y mejorarlo para que se comprenda mejor: +Me puedes corregir el siguiente texto y mejorarlo para que se comprenda mejor: +Me puedes corregir el siguiente texto y mejorarlo para que se comprenda mejor: +Me puedes corregir el siguiente texto y mejorarlo para que se comprenda mejor: +Me puedes corregir el siguiente texto y mejorarlo para que se comprenda mejor: +Me puedes corregir el siguiente texto y mejorarlo para que se comprenda mejor: +Me puedes corregir el siguiente texto y mejorarlo para que se comprenda mejor: +Me puedes corregir el siguiente texto y mejorarlo para que se comprenda mejor: +Me puedes corregir el siguiente texto y mejorarlo para que se comprenda mejor: +Me puedes corregir el siguiente texto y mejorarlo para que se comprenda mejor: +Me puedes corregir el siguiente texto y mejorarlo para que se comprenda mejor: +Me puedes corregir el siguiente texto y mejorarlo para que se comprenda mejor: +Me puedes corregir el siguiente texto y mejorarlo para que se comprenda mejor: +Me puedes corregir el siguiente texto y mejorarlo para que se comprenda mejor: +Me puedes corregir el siguiente texto y mejorarlo para que se comprenda mejor: +Me puedes corregir el siguiente texto y mejorarlo para que se comprenda mejor: +Me puedes corregir el siguiente texto y mejorarlo para que se comprenda mejor: +Me puedes corregir el siguiente texto y mejorarlo para que se comprenda mejor: +Me puedes corregir el siguiente texto y mejorarlo para que se comprenda mejor: +Me puedes corregir el siguiente texto y mejorarlo para que se comprenda mejor: +Me puedes corregir el siguiente texto y mejorarlo para que se comprenda mejor: +Me puedes corregir el siguiente texto y mejorarlo para que se comprenda mejor: +Me puedes corregir el siguiente texto y mejorarlo para que se comprenda mejor: +Me puedes corregir el siguiente texto y mejorarlo para que se comprenda mejor: +Me puedes corregir el siguiente texto y mejorarlo para que se comprenda mejor: +Me puedes corregir el siguiente texto y mejorarlo para que se comprenda mejor: +Me puedes corregir el siguiente texto y mejorarlo para que se comprenda mejor: +Me puedes corregir el siguiente texto y mejorarlo para que se comprenda mejor: +Me puedes corregir el siguiente texto y mejorarlo para que se comprenda mejor: +Me puedes corregir el siguiente texto y mejorarlo para que se comprenda mejor: +Me puedes corregir el siguiente texto y mejorarlo para que se comprenda mejor: +Me puedes corregir el siguiente texto y mejorarlo para que se comprenda mejor: +Me puedes corregir el siguiente texto y mejorarlo para que se comprenda mejor: +Me puedes corregir el siguiente texto y mejorarlo para que se comprenda mejor: +Me puedes corregir el siguiente texto y mejorarlo para que se comprenda mejor: +Me puedes corregir el siguiente texto y mejorarlo para que se comprenda mejor: +Texto por defecto +Texto por defecto +Me puedes corregir el siguiente texto y mejorarlo para que se comprenda mejor: +