33import threading
44import os
55import datetime
6+ import json
67from crypto_manager import CryptoManager
78
89# Try to import tkinterdnd2 for Drag and Drop support
5455 "lang_label" : {"en" : "Language:" , "zh" : "语言:" }
5556}
5657
58+ CONFIG_FILE = "settings.json"
59+
5760class EncryptApp (BaseWindow ):
5861 def __init__ (self ):
5962 super ().__init__ ()
@@ -65,10 +68,38 @@ def __init__(self):
6568
6669 self .lang_code = "en"
6770 self .translatable_widgets = [] # List of (widget, key, attribute_name)
71+
72+ # Load settings before UI setup to apply language and paths
73+ self .load_settings ()
6874
6975 self .setup_ui ()
70- self .update_language () # Initial text set
76+ self .update_language () # Apply language to UI
7177
78+ def load_settings (self ):
79+ """Load settings from JSON file."""
80+ if os .path .exists (CONFIG_FILE ):
81+ try :
82+ with open (CONFIG_FILE , 'r' , encoding = 'utf-8' ) as f :
83+ settings = json .load (f )
84+ self .enc_output_path .set (settings .get ("enc_output_path" , "" ))
85+ self .dec_output_path .set (settings .get ("dec_output_path" , "" ))
86+ self .lang_code = settings .get ("language" , "en" )
87+ except Exception as e :
88+ print (f"Failed to load settings: { e } " )
89+
90+ def save_settings (self ):
91+ """Save current settings to JSON file."""
92+ settings = {
93+ "enc_output_path" : self .enc_output_path .get (),
94+ "dec_output_path" : self .dec_output_path .get (),
95+ "language" : self .lang_code
96+ }
97+ try :
98+ with open (CONFIG_FILE , 'w' , encoding = 'utf-8' ) as f :
99+ json .dump (settings , f , ensure_ascii = False , indent = 4 )
100+ except Exception as e :
101+ print (f"Failed to save settings: { e } " )
102+
72103 def tr (self , key ):
73104 """Translate a key to the current language."""
74105 return TRANSLATIONS .get (key , {}).get (self .lang_code , key )
@@ -95,6 +126,9 @@ def update_language(self, event=None):
95126 self .lang_code = "zh"
96127 else :
97128 self .lang_code = "en"
129+
130+ # Save new language preference
131+ self .save_settings ()
98132
99133 # Update registered widgets
100134 for widget , key , attr in self .translatable_widgets :
@@ -108,9 +142,6 @@ def update_language(self, event=None):
108142 print (f"Failed to update widget { widget } : { e } " )
109143
110144 # Update dynamic status labels if they are "Ready"
111- # (This is a bit tricky, but we can reset them to Ready on lang change if they were Ready)
112- # Simplified: We just leave them as is, next operation will use new lang.
113- # But we can force update the "Ready" state if idle.
114145 if self .enc_status .cget ("text" ) in ["Ready" , "就绪" ]:
115146 self .enc_status .config (text = self .tr ("ready" ))
116147 if self .dec_status .cget ("text" ) in ["Ready" , "就绪" ]:
@@ -154,7 +185,12 @@ def setup_ui(self):
154185 lbl_lang .pack (side = "left" , padx = 5 )
155186
156187 self .lang_combo = ttk .Combobox (top_frame , values = ["English" , "中文 (Chinese)" ], state = "readonly" , width = 15 )
157- self .lang_combo .set ("English" )
188+ # Set initial selection based on loaded settings
189+ if self .lang_code == "zh" :
190+ self .lang_combo .set ("中文 (Chinese)" )
191+ else :
192+ self .lang_combo .set ("English" )
193+
158194 self .lang_combo .pack (side = "left" , padx = 5 )
159195 self .lang_combo .bind ("<<ComboboxSelected>>" , self .update_language )
160196
@@ -203,14 +239,12 @@ def create_text_section(self, parent, col, title_key, btn_text_key, btn_command)
203239 log_area = scrolledtext .ScrolledText (frame , height = 15 , state = "disabled" , font = ("Consolas" , 9 ))
204240 log_area .pack (fill = "both" , expand = True , pady = (0 , 5 ))
205241
206- if "Encrypt" in self .tr (btn_text_key ) or "加密" in self .tr (btn_text_key ): # Check intent via key ideally, but simplistic here
207- # Better to use the key passed
242+ if "Encrypt" in self .tr (btn_text_key ) or "加密" in self .tr (btn_text_key ):
208243 if btn_text_key == "btn_encrypt" :
209244 self .enc_log = log_area
210245 else :
211246 self .dec_log = log_area
212247 else :
213- # Fallback if I messed up logic above, rely on passed key
214248 if btn_text_key == "btn_encrypt" :
215249 self .enc_log = log_area
216250 else :
@@ -321,11 +355,15 @@ def confirm_signature(self):
321355
322356 def select_enc_out_dir (self ):
323357 d = filedialog .askdirectory ()
324- if d : self .enc_output_path .set (d )
358+ if d :
359+ self .enc_output_path .set (d )
360+ self .save_settings ()
325361
326362 def select_dec_out_dir (self ):
327363 d = filedialog .askdirectory ()
328- if d : self .dec_output_path .set (d )
364+ if d :
365+ self .dec_output_path .set (d )
366+ self .save_settings ()
329367
330368 def select_file (self , var ):
331369 f = filedialog .askopenfilename ()
@@ -378,6 +416,14 @@ def _run_file_op(self, input_var, output_dir_var, op_func, pb, status_lbl, suffi
378416 return
379417
380418 out_dir = output_dir_var .get ()
419+ if out_dir :
420+ if not os .path .exists (out_dir ):
421+ try :
422+ os .makedirs (out_dir )
423+ except OSError :
424+ # If cannot create, fallback to input directory
425+ out_dir = ""
426+
381427 if not out_dir :
382428 out_dir = os .path .dirname (in_path )
383429
0 commit comments