357 lines
12 KiB
C#
357 lines
12 KiB
C#
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;
|
|
|
|
}
|
|
}
|
|
}
|