gtpask/MainWindow.xaml.cs

357 lines
12 KiB
C#
Raw Normal View History

2024-04-18 12:22:19 -03:00
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<string, string> languageMap = new Dictionary<string, string>
{
{ "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("/<projectname>;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<string> 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<string>();
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;
}
}
}