33from tkinter import Menu
44from tkinter .messagebox import showinfo , askyesno
55from tkinter import simpledialog
6+ import time , threading
7+
8+ CONFIGURATION = {
9+ 'auto_save' : {
10+ 'enabled' : True ,
11+ 'time_until_next_save' : 5 , # seconds
12+ },
13+ 'undo' : {
14+ 'enabled' : True ,
15+ 'max_undo' : 20 , # use -1 for infinite
16+ 'separate_edits_from_undos' : True
17+ }
18+ }
619
720_fonts = ['Menlo' , 'Monaco' , 'Helvetica' , 'Arial' , 'Times New Roman' , 'Georgia' , 'Avenir' , 'Baskerville' , 'Futura' , 'Verdana' , 'Gill Sans' , 'Courier' , 'Optima' , 'American Typewriter' ]
821
@@ -11,6 +24,7 @@ def __init__(self, title, geometry):
1124 super ().__init__ ()
1225
1326 self .path = None
27+ self .font_size = 14
1428
1529 def newfile (event = None ):
1630 if not '*' in self .title ()[7 ]:
@@ -38,17 +52,31 @@ def save_file(event=None):
3852 save_as ()
3953 with open (self .path , 'w' , encoding = 'utf-8' ) as f :
4054 f .write (self .textbox .get ('1.0' , 'end-1c' ))
55+ self .title (f'kPad - { self .path } ' )
56+
4157
4258 def open_from_file (event = None ):
4359 self .path = askopenfilename (filetypes = [('Text files' , '.txt' ), ('kPad notefile' , '.kpad' )], defaultextension = '.txt' )
44- self .textbox .delete ('1.0' , 'end' )
45- with open (self .path , "r" ) as file :
46- self .textbox .insert ('1.0' , file .read ())
60+ if self .path :
61+ self .textbox .delete ('1.0' , 'end' )
62+ with open (self .path , "r" ) as file :
63+ self .textbox .insert ('1.0' , file .read ())
64+ else :
65+ pass
4766
4867 def set_font (font ):
4968 self .font .configure (family = font )
5069 self .textbox .configure (font = self .font )
5170
71+ def autosave ():
72+ while True :
73+ if CONFIGURATION ['auto_save' ]['enabled' ]:
74+ if self .path and 'Untitled' not in self .title ():
75+ save_file ()
76+ time .sleep (CONFIGURATION ['auto_save' ]['time_until_next_save' ])
77+
78+ threading .Thread (target = autosave , daemon = True ).start ()
79+
5280 def toggle_theme (event = None ):
5381 mode = ctk .get_appearance_mode ()
5482 ctk .set_appearance_mode ("Light" if mode == "Dark" else "Dark" )
@@ -59,6 +87,18 @@ def go_to_start(event=None):
5987 def go_to_end (event = None ):
6088 self .textbox .yview_moveto (1 )
6189
90+ def increment_font_size (event = None ):
91+ self .font_size += 2
92+ self .font = ctk .CTkFont (family = self .font ._family , size = self .font_size )
93+ self .textbox .configure (font = self .font )
94+ return "break"
95+
96+ def decrement_font_size (event = None ):
97+ self .font_size = max (2 , self .font_size - 2 )
98+ self .font = ctk .CTkFont (family = self .font ._family , size = self .font_size )
99+ self .textbox .configure (font = self .font )
100+ return "break"
101+
62102 def go_to_line (event = None ):
63103 line = simpledialog .askinteger ("Go To Line" , "Enter line number:" )
64104 if line is None :
@@ -92,7 +132,7 @@ def go_to_line(event=None):
92132
93133 self .configure (menu = menu )
94134
95- self .font = ctk .CTkFont (family = _fonts [0 ])
135+ self .font = ctk .CTkFont (family = _fonts [0 ], size = self . font_size )
96136
97137 def update_cursor_info (event = None ):
98138 pos = self .textbox .index ("insert" )
@@ -107,7 +147,7 @@ def update_cursor_info(event=None):
107147 self .title (title )
108148 self .geometry (f'{ geometry [0 ]} x{ geometry [1 ]} ' )
109149
110- self .textbox = ctk .CTkTextbox (self )
150+ self .textbox = ctk .CTkTextbox (self , undo = CONFIGURATION [ 'undo' ][ 'enabled' ], autoseparators = CONFIGURATION [ 'undo' ][ 'separate_edits_from_undos' ], maxundo = CONFIGURATION [ 'undo' ][ 'max_undo' ] )
111151 self .textbox .configure (font = self .font )
112152
113153 self .textbox .bind ("<KeyRelease>" , update_cursor_info )
@@ -117,6 +157,9 @@ def update_cursor_info(event=None):
117157 self .bind ('<Command-o>' , open_from_file )
118158 self .bind ('<Command-t>' , toggle_theme )
119159 self .bind ('<Command-n>' , newfile )
160+ self .bind ('<Command-plus>' , increment_font_size )
161+ self .bind ('<Command-minus>' , decrement_font_size )
162+
120163
121164 self .stats_text_frame = ctk .CTkFrame (self )
122165 self .stats_text_frame .pack (fill = 'x' , side = ctk .BOTTOM )
0 commit comments