Skip to content

Commit b87776b

Browse files
committed
Refactor TokenOptimizer: Separate configuration, optimizations, and UI logic into distinct modules
- Created `config.py` to hold default options and theme data. - Implemented `optimizations.py` for text optimization functions. - Developed `ui.py` to manage the user interface using Tkinter. - Added functionality for various optimization techniques including comment removal, keyword shortening, and type hint removal. - Enhanced UI with theme support and improved layout for input and output sections. - Integrated footer links for GitHub and roadmap access.
2 parents 7d83995 + 11c60fe commit b87776b

File tree

2 files changed

+52
-1
lines changed

2 files changed

+52
-1
lines changed

main.py

Lines changed: 51 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,16 @@
33
from tkinter import ttk, filedialog, messagebox, scrolledtext
44
import webbrowser
55
import re
6+
import os
7+
8+
# Drag-and-drop relies on native tkdnd bindings, so we import tkinterdnd2 optionally to avoid crashes when unavailable.
9+
try:
10+
from tkinterdnd2 import DND_FILES, TkinterDnD
11+
TKDND_AVAILABLE = True
12+
except ImportError:
13+
DND_FILES = None
14+
TkinterDnD = tk.Tk # fallback so type is available
15+
TKDND_AVAILABLE = False
616

717
class AITokenCrusher:
818
def __init__(self, root):
@@ -72,6 +82,9 @@ def __init__(self, root):
7282

7383
self.create_ui()
7484

85+
# Enable drag & drop if tkdnd is available
86+
self.enable_drag_and_drop()
87+
7588
def create_ui(self):
7689
theme = self.themes["dark" if self.is_dark_theme else "light"]
7790

@@ -252,6 +265,39 @@ def apply_theme(self):
252265
for link in self.link_labels:
253266
link.configure(bg=theme["bg"], fg=theme["accent"])
254267

268+
def enable_drag_and_drop(self):
269+
"""Enable drag & drop for files into the input text area (if supported)."""
270+
if not TKDND_AVAILABLE or DND_FILES is None:
271+
return
272+
try:
273+
self.input_text.drop_target_register(DND_FILES)
274+
self.input_text.dnd_bind("<<Drop>>", self.on_drop_files)
275+
except Exception:
276+
# If tkdnd is not correctly configured on the system, just skip DnD
277+
pass
278+
279+
def on_drop_files(self, event):
280+
"""Handle files dropped into the input text area."""
281+
# event.data is a Tcl list of file paths, may contain braces around paths with spaces
282+
file_paths = self.root.splitlist(event.data)
283+
allowed_exts = {".py", ".txt", ".md"}
284+
285+
for path in file_paths:
286+
ext = os.path.splitext(path)[1].lower()
287+
if ext not in allowed_exts:
288+
continue
289+
try:
290+
with open(path, "r", encoding="utf-8") as f:
291+
content = f.read()
292+
self.input_text.delete(1.0, tk.END)
293+
self.input_text.insert(tk.END, content)
294+
return
295+
except Exception as e:
296+
messagebox.showerror("Error", f"Failed to read file:\n{path}\n\n{e}")
297+
298+
# If we reach here, either no valid file was found or extensions were unsupported
299+
messagebox.showwarning("Unsupported", "You can only drop .py, .txt, or .md files here.")
300+
255301
def load_file(self):
256302
path = filedialog.askopenfilename(filetypes=[("All Files", "*.*")])
257303
if path:
@@ -321,6 +367,10 @@ def apply_optimizations(self, text):
321367
return text.strip() + "\n"
322368

323369
if __name__ == "__main__":
324-
root = tk.Tk()
370+
# Use TkinterDnD's Tk if available, otherwise fall back to standard Tk
371+
if TKDND_AVAILABLE:
372+
root = TkinterDnD.Tk()
373+
else:
374+
root = tk.Tk()
325375
app = AITokenCrusher(root)
326376
root.mainloop()

requirements.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
tkinterdnd2
12
tkinter
23
pytest
34
pyinstaller

0 commit comments

Comments
 (0)