diff --git a/.gitignore b/.gitignore index 7b1819b..f076bdd 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ .vscode/settings.json shortcut.txt src/__pycache__/config.cpython-313.pyc +src/__pycache__/startup.cpython-313.pyc diff --git a/config&run.bat b/config&run.bat index 2e00b21..d21be38 100644 --- a/config&run.bat +++ b/config&run.bat @@ -1,6 +1,5 @@ @echo off -REM run.bat -REM Activates the virtual environment and runs your main Python script. +cd /d "%~dp0" REM Activate the virtual environment call venv\Scripts\activate.bat diff --git a/config.json b/config.json new file mode 100644 index 0000000..6b90feb --- /dev/null +++ b/config.json @@ -0,0 +1,5 @@ +{ + "run_on_startup": true, + "shortcut": "ctrl+shift+B", + "lang_change": true +} \ No newline at end of file diff --git a/run.bat b/run.bat index f159447..2f820d2 100644 --- a/run.bat +++ b/run.bat @@ -1,11 +1,9 @@ @echo off -REM run.bat -REM Activates the virtual environment and runs your main Python script. +cd /d "%~dp0" -REM Activate the virtual environment call venv\Scripts\activate.bat +echo Starting the application... -REM Run your main Python script (replace main.py with your script name if different) start "OopsWrongLang" /B pythonw src\main.pyw -echo application is running in the background. you can close this window. + pause \ No newline at end of file diff --git a/src/__pycache__/config.cpython-312.pyc b/src/__pycache__/config.cpython-312.pyc new file mode 100644 index 0000000..5dd0e83 Binary files /dev/null and b/src/__pycache__/config.cpython-312.pyc differ diff --git a/src/__pycache__/startup.cpython-312.pyc b/src/__pycache__/startup.cpython-312.pyc new file mode 100644 index 0000000..9b6c328 Binary files /dev/null and b/src/__pycache__/startup.cpython-312.pyc differ diff --git a/src/config.py b/src/config.py index 72051be..3bb85a3 100644 --- a/src/config.py +++ b/src/config.py @@ -1,14 +1,46 @@ import os +import json import keyboard import time -CONFIG_FILE = "shortcut.txt" +import msvcrt + +CONFIG_FILE = "config.json" +SHORTCUT_FILE = "shortcut.txt" # For migrating old config + +def load_config(): + """ + Loads the configuration from config.json. + If the file doesn't exist, it creates it with default values. + It also migrates the old shortcut.txt if it exists. + """ + if not os.path.exists(CONFIG_FILE): + config = {"run_on_startup": False, "shortcut": "ctrl+shift+b","lang_change": True} + if os.path.exists(SHORTCUT_FILE): + with open(SHORTCUT_FILE, "r") as f: + shortcut = f.read().strip() + if shortcut: + config["shortcut"] = shortcut + os.remove(SHORTCUT_FILE) # remove old config file + save_config(config) + return config + else: + with open(CONFIG_FILE, "r") as f: + return json.load(f) + +def save_config(config): + """ + Saves the configuration to config.json. + """ + with open(CONFIG_FILE, "w") as f: + json.dump(config, f, indent=4) def get_shortcut(): """ Retrieves the shortcut from the config file. If the file doesn't exist, it prompts the user to create one by pressing the desired keys. """ - if not os.path.exists(CONFIG_FILE): + config = load_config() + if "shortcut" not in config: print("It seems this is the first time you are running the application.") while True: print("Please press the key combination you want to use as a shortcut and then press ESC.") @@ -16,37 +48,40 @@ def get_shortcut(): print(f"You pressed: {shortcut}") confirm = input("Is this correct? (y/n): ").lower() if confirm == 'y': - with open(CONFIG_FILE, "w") as f: - f.write(shortcut) + config["shortcut"] = shortcut + save_config(config) return shortcut else: print("Let's try again.") - else: - with open(CONFIG_FILE, "r") as f: - return f.read().strip() + return config["shortcut"] if __name__ == "__main__": - shortcut = get_shortcut() - print(f"Your shortcut is set to: {shortcut}") - print("You can now use this shortcut in the application.") - print('do you want to change the shortcut? (y/n): ', end='') + config = load_config() + print(f"Your shortcut is set to: {config.get('shortcut', 'Not set')}") + print(f"Run on startup is set to: {config.get('run_on_startup', 'Not set')}") + print(f"Change language layout after transformation is set to: {config.get('lang_change', 'Not set')}") + + print('Do you want to change the shortcut? (y/n): ', end='') if input().lower() == 'y': while True: time.sleep(0.2) print("Please press the key combination you want to use as a shortcut and then press ESC.") new_shortcut = keyboard.read_hotkey(suppress=False) print(f"You pressed: {new_shortcut}") - time.sleep(0.5) + time.sleep(0.01) + # Clear the input buffer + while msvcrt.kbhit(): + msvcrt.getch() + confirm = input("Is this correct? (y/n): ").lower() if confirm.lower() == 'y': - with open(CONFIG_FILE, "w") as f: - f.write(new_shortcut) + config['shortcut'] = new_shortcut + save_config(config) print("Shortcut updated successfully.") break else: print("Let's try again.") - else: print("No changes made to the shortcut.") print("Exiting without changes.") - input("Press Enter to exit.") \ No newline at end of file + input("Press Enter to exit.") diff --git a/src/main.pyw b/src/main.pyw index ed43ea8..33c97cb 100644 --- a/src/main.pyw +++ b/src/main.pyw @@ -8,7 +8,8 @@ import threading import pystray from PIL import Image import re -from config import get_shortcut +from config import load_config, save_config, get_shortcut +from startup import add_to_startup, remove_from_startup, is_in_startup def convert_en_characters(input_str): """ @@ -121,21 +122,53 @@ def on_shortcut(): print(f"Converted text: {converted_text}") keyboard.press_and_release('ctrl+v') # Paste the converted text time.sleep(0.2) - keyboard.press_and_release('windows+space') + if load_config().get("lang_change", True): + # Change the keyboard layout to Persian + keyboard.press_and_release('windows+space') def quit_app(icon, item): icon.stop() import os os._exit(0) -def setup_tray(): - image = Image.open("assets/icon.png") # Make sure icon.png exists in your project folder - menu = pystray.Menu(pystray.MenuItem('Quit', quit_app)) +def setup_tray(config): + def on_toggle_lang_change(icon, item): + config["lang_change"] = not item.checked + save_config(config) + + def on_toggle_startup(icon, item): + config["run_on_startup"] = not item.checked + save_config(config) + if config["run_on_startup"]: + add_to_startup() + else: + remove_from_startup() + + image = Image.open("assets/icon.png") + menu = pystray.Menu( + pystray.MenuItem(f'Current Shortcut: {get_shortcut()}',lambda icon, item: None), + pystray.MenuItem( + 'change keyboard language layout after transformation', + on_toggle_lang_change, + checked=lambda item: config["lang_change"] + ), + pystray.MenuItem( + 'Run on Startup', + on_toggle_startup, + checked=lambda item: config["run_on_startup"] + ), + pystray.MenuItem('Quit', quit_app) + ) icon = pystray.Icon("oopswronglang", image, "OopsWrongLang", menu) icon.run() def main(): + config = load_config() + # Sync startup state just in case it was changed externally + config["run_on_startup"] = is_in_startup() + save_config(config) + # Start the tray icon in a separate thread - tray_thread = threading.Thread(target=setup_tray, daemon=True) + tray_thread = threading.Thread(target=lambda: setup_tray(config), daemon=True) tray_thread.start() # Register the keyboard shortcut @@ -144,7 +177,7 @@ def main(): print(f"Press {shortcut} to convert text to Persian.") # Keep the script running - keyboard.wait() + keyboard.wait(suppress=True) if __name__ == "__main__": main() diff --git a/src/startup.py b/src/startup.py new file mode 100644 index 0000000..c77f124 --- /dev/null +++ b/src/startup.py @@ -0,0 +1,49 @@ +import os +import winreg + +APP_NAME = "OopsWrongLang" +RUN_BAT_PATH = os.path.abspath("run.bat") + +def add_to_startup(): + """ + Adds the application to Windows startup. + """ + try: + key = winreg.HKEY_CURRENT_USER + sub_key = r"Software\Microsoft\Windows\CurrentVersion\Run" + print(f'bat file path: {RUN_BAT_PATH}') + with winreg.OpenKey(key, sub_key, 0, winreg.KEY_SET_VALUE) as registry_key: + winreg.SetValueEx(registry_key, APP_NAME, 0, winreg.REG_SZ, f'"{RUN_BAT_PATH}"') + except OSError as e: + print(f"Error adding to startup: {e}") + +def remove_from_startup(): + """ + Removes the application from Windows startup. + """ + try: + key = winreg.HKEY_CURRENT_USER + sub_key = r"Software\Microsoft\Windows\CurrentVersion\Run" + with winreg.OpenKey(key, sub_key, 0, winreg.KEY_SET_VALUE) as registry_key: + winreg.DeleteValue(registry_key, APP_NAME) + except FileNotFoundError: + # This is fine, it means the key doesn't exist + pass + except OSError as e: + print(f"Error removing from startup: {e}") + +def is_in_startup(): + """ + Checks if the application is in Windows startup. + """ + try: + key = winreg.HKEY_CURRENT_USER + sub_key = r"Software\Microsoft\Windows\CurrentVersion\Run" + with winreg.OpenKey(key, sub_key, 0, winreg.KEY_READ) as registry_key: + winreg.QueryValueEx(registry_key, APP_NAME) + return True + except FileNotFoundError: + return False + except OSError as e: + print(f"Error checking startup status: {e}") + return False