Skip to content

Commit 4aa2ad5

Browse files
author
Amir Ali
committed
refactor: renamed folder gui to context_menus
1 parent 70e116c commit 4aa2ad5

File tree

6 files changed

+688
-0
lines changed

6 files changed

+688
-0
lines changed
Lines changed: 156 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,156 @@
1+
from tkinter import filedialog
2+
from tkinter.simpledialog import askstring
3+
4+
from utils import *
5+
from tkinter import Event, TclError
6+
7+
class PatternsMenuCommands:
8+
def __init__(self, patterns_list, window):
9+
self.patterns_list = patterns_list
10+
self.window = window
11+
12+
@staticmethod
13+
def get_pattern() -> str:
14+
return askstring(title=APP_TITLE,prompt='Enter the pattern:')
15+
16+
def add_pattern(self, event : Event=None) -> None:
17+
new_pattern = self.get_pattern()
18+
self.patterns_list.insert('end',new_pattern)
19+
20+
def insert_pattern(self, event : Event=None) -> None:
21+
selected = self.patterns_list.curselection()
22+
if len(selected) == 1:
23+
new_pattern = self.get_pattern()
24+
self.patterns_list.insert(selected[0],new_pattern)
25+
26+
def swap_up(self, selected_index : int):
27+
next_index = selected_index - 1
28+
29+
next_item = self.patterns_list.get(selected_index)
30+
self.patterns_list.insert(next_index, next_item)
31+
self.patterns_list.delete(selected_index + 1)
32+
33+
def move_selected(self, event : Event = None , up = True):
34+
selected_index = self.patterns_list.curselection()[0]
35+
36+
if up:
37+
self.swap_up(selected_index)
38+
self.patterns_list.selection_set(selected_index - 1)
39+
40+
else:
41+
self.swap_up(selected_index + 1)
42+
43+
def edit_selected(self, event : Event=None) -> None:
44+
index = self.patterns_list.curselection()
45+
if len(index) == 1:
46+
value = self.patterns_list.get(index)
47+
new_value = askstring(title=APP_TITLE, prompt='Enter the pattern: ', initialvalue=value)
48+
if new_value:
49+
self.patterns_list.delete(index)
50+
self.patterns_list.insert(index, new_value)
51+
52+
def delete_selected(self, event : Event=None) -> None:
53+
selected = self.patterns_list.curselection()
54+
if selected:
55+
self.patterns_list.delete(selected[0],selected[-1])
56+
57+
def delete_all(self, event : Event=None) -> None:
58+
self.patterns_list.delete(0,'end')
59+
60+
def copy_pattern(self, event : Event=None, all : bool=False) -> None:
61+
self.window.clipboard_clear()
62+
if all:
63+
self.window.clipboard_append('\n'.join(self.patterns_list.get(0,'end')))
64+
else:
65+
selected = self.patterns_list.curselection()
66+
if selected:
67+
self.window.clipboard_append('\n'.join(self.patterns_list.get(selected[0],selected[-1])))
68+
69+
def import_from_file(self, event : Event=None) -> None:
70+
try:
71+
file_path = filedialog.askopenfilename(title='Import')
72+
if file_path:
73+
with open(file_path, encoding=ENCODING) as f:
74+
for i in f.read().strip().splitlines():
75+
self.patterns_list.insert('end', i)
76+
except UnicodeDecodeError:
77+
show_error('The patterns file cannot be a binary file')
78+
79+
def export_to_file(self, event : Event=None) -> None:
80+
try:
81+
file_path = filedialog.asksaveasfilename(title='Export')
82+
if file_path:
83+
with open(file_path, 'w',encoding=ENCODING) as f:
84+
for i in self.patterns_list.get(0,'end'):
85+
f.write(i + '\n')
86+
except Exception as err:
87+
show_error(err)
88+
89+
class LogMenuCommands:
90+
def __init__(self, log_menu, window, log_text):
91+
self.log_menu = log_menu
92+
self.log_text = log_text
93+
self.window = window
94+
95+
def toggle_log(self) -> None:
96+
WithLogging.with_logging = not WithLogging.with_logging
97+
98+
mode = self.log_menu.entrycget(3,'label')
99+
100+
if mode == LOG_MODE[0]:
101+
self.log_menu.entryconfig(3,label = LOG_MODE[1])
102+
else:
103+
self.log_menu.entryconfig(3,label = LOG_MODE[0])
104+
105+
def copy_log(self, event : Event=None) -> None:
106+
self.window.clipboard_clear()
107+
try:
108+
data = self.log_text.selection_get()
109+
except TclError:
110+
data = self.log_text.get('1.0','end')
111+
self.window.clipboard_append(data)
112+
113+
def clear_log(self, event : Event=None) -> None:
114+
self.log_text.config(state='normal')
115+
self.log_text.delete('1.0','end')
116+
self.log_text.insert('end',LOG_DEFAULT)
117+
self.log_text.config(state='disabled')
118+
119+
class CSVExcelSwitchFunctions:
120+
121+
def __init__(self, exact_var, exact_cb, exact_cb_substitute_lbl, sheet_name_lbl, sheet_name_entry, col_var, excel_var):
122+
self.exact_var = exact_var
123+
self.exact_cb = exact_cb
124+
self.exact_cb_substitute_lbl = exact_cb_substitute_lbl
125+
self.sheet_name_lbl = sheet_name_lbl
126+
self.sheet_name_entry = sheet_name_entry
127+
self.col_var = col_var
128+
self.excel_var = excel_var
129+
130+
self.exact_var_value = None
131+
132+
def hide_exact_order_cb(self) -> None:
133+
self.exact_cb.grid_remove()
134+
self.exact_var_value = self.exact_var.get()
135+
self.exact_var.set(False)
136+
self.exact_cb_substitute_lbl.grid(**EXACT_CB_GRID_ARGS)
137+
138+
def show_exact_order_cb(self) -> None:
139+
if self.excel_var.get():
140+
self.exact_cb_substitute_lbl.grid_remove()
141+
self.exact_var.set(self.exact_var_value)
142+
self.exact_cb.grid()
143+
144+
def hide_only_excel_required_widgets(self) -> None: # sheet_name_entry, sheet_name_lbl, exact_cb
145+
if self.exact_cb.winfo_ismapped():
146+
self.hide_exact_order_cb()
147+
148+
self.sheet_name_lbl.grid_remove()
149+
self.sheet_name_entry.grid_remove()
150+
151+
def show_only_excel_required_widgets(self) -> None:
152+
if self.col_var.get():
153+
self.show_exact_order_cb()
154+
155+
self.sheet_name_lbl.grid()
156+
self.sheet_name_entry.grid()
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
from tkinter.ttk import Entry
2+
from tkinter import Menu
3+
from utils import *
4+
from context_menus.context_menu_commands import *
5+
6+
class CommandsObjects:
7+
log_menu_commands = None
8+
patterns_menu_commands = None
9+
csv_excel_switch_functions = None
10+
11+
def create_commands_objects(log_menu,log_text , window, patterns_list, exact_var,
12+
exact_cb, exact_cb_substitute_lbl, sheet_name_lbl,
13+
sheet_name_entry, col_var, excel_var):
14+
15+
CommandsObjects.csv_excel_switch_functions = CSVExcelSwitchFunctions(exact_var, exact_cb, exact_cb_substitute_lbl,
16+
sheet_name_lbl, sheet_name_entry, col_var, excel_var)
17+
CommandsObjects.log_menu_commands = LogMenuCommands(log_menu, window, log_text)
18+
CommandsObjects.patterns_menu_commands = PatternsMenuCommands(patterns_list, window)
19+
20+
def browse_files(widget : Entry, is_input_file_entry : bool) -> None:
21+
TITLE = 'Browse'
22+
23+
if is_input_file_entry:
24+
file_path = filedialog.askopenfilename(title=TITLE)
25+
else:
26+
file_path = filedialog.askopenfilename(title=TITLE,filetypes=FILE_TYPES)
27+
28+
if file_path:
29+
widget.delete(0,'end')
30+
widget.insert('end',file_path)
31+
32+
class MenuCreators:
33+
34+
@staticmethod
35+
def create_patterns_menu() -> Menu:
36+
menu = Menu(tearoff=False,**MENU_COLOR_ARGS)
37+
# The numbers below the following lines are indices of context menu commands
38+
# which are used in context_menu_displayers.py module given to entryconfig method
39+
menu.add_command(label='Add Pattern', command=CommandsObjects.patterns_menu_commands.add_pattern,accelerator='Ctrl+Shift+A') # 0
40+
menu.add_command(label='Insert Pattern',command=CommandsObjects.patterns_menu_commands.insert_pattern,accelerator='Ctrl+I') # 1
41+
menu.add_separator() # 2
42+
menu.add_command(label='Move Up', command = CommandsObjects.patterns_menu_commands.move_selected) # 3
43+
menu.add_command(label='Move Down', command = lambda : CommandsObjects.patterns_menu_commands.move_selected(up = False)) # 4
44+
menu.add_separator() # 5
45+
menu.add_command(label='Edit selected', command=CommandsObjects.patterns_menu_commands.edit_selected,accelerator='F2') # 6
46+
menu.add_command(label='Delete selected', command=CommandsObjects.patterns_menu_commands.delete_selected,accelerator='Delete') # 7
47+
menu.add_command(label='Copy selected', command=CommandsObjects.patterns_menu_commands.copy_pattern,accelerator='Ctrl+C') # 8
48+
menu.add_command(label='Delete All', command=CommandsObjects.patterns_menu_commands.delete_all,accelerator='Ctrl+Shift+D') # 9
49+
menu.add_command(label='Copy All', command=lambda : CommandsObjects.patterns_menu_commands.copy_pattern(all=True),accelerator='Ctrl+Shift+C') # 10
50+
menu.add_separator() # 11
51+
menu.add_command(label='Import from file', command=CommandsObjects.patterns_menu_commands.import_from_file,accelerator='Ctrl+Shift+I') # 12
52+
menu.add_command(label='Export to file', command=CommandsObjects.patterns_menu_commands.export_to_file,accelerator='Ctrl+E') # 13
53+
return menu
54+
55+
@staticmethod
56+
def create_log_menu() -> Menu:
57+
menu = Menu(tearoff=False,**MENU_COLOR_ARGS)
58+
menu.add_command(label='Copy log',command=CommandsObjects.log_menu_commands.copy_log,accelerator='Ctrl+C') # 0
59+
menu.add_command(label='Clear log',command=CommandsObjects.log_menu_commands.clear_log,accelerator='Ctrl+D') # 1
60+
menu.add_separator() # 2
61+
menu.add_command(label=LOG_MODE[0],command=CommandsObjects.log_menu_commands.toggle_log) # 3
62+
return menu
63+
64+
@staticmethod
65+
def create_entry_menu(widget : Entry, excel_var, is_file_entry : bool=True,is_output_file_entry : bool=True) -> Menu:
66+
menu = Menu(tearoff=False,**MENU_COLOR_ARGS)
67+
menu.add_command(label='Select All', accelerator='Ctrl+A',command=lambda : widget.select_range(0,'end')) # 0
68+
menu.add_command(label='Copy', accelerator='Ctrl+C',command=lambda : widget.event_generate('<<Copy>>')) # 1
69+
menu.add_command(label='Paste', accelerator='Ctrl+V',command=lambda : widget.event_generate('<<Paste>>')) # 2
70+
menu.add_command(label='Cut', accelerator='Ctrl+X',command=lambda : widget.event_generate('<<Cut>>')) # 3
71+
menu.add_separator() # 4
72+
menu.add_command(label='Clear',accelerator='Ctrl+Shift+C',command=lambda : widget.delete(0,'end')) # 5
73+
if is_file_entry:
74+
menu.add_command(label='Browse',command=lambda : browse_files(widget, not is_output_file_entry),accelerator='Ctrl+B') # 6
75+
if is_output_file_entry:
76+
menu.add_separator() # 7
77+
menu.add_radiobutton(label='Excel',variable=excel_var,value=True,
78+
command=CommandsObjects.csv_excel_switch_functions.show_only_excel_required_widgets) # 8
79+
80+
menu.add_radiobutton(label='CSV',variable=excel_var,value=False,
81+
command=CommandsObjects.csv_excel_switch_functions.hide_only_excel_required_widgets) # 9
82+
return menu
Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
from tkinter import Menu, Event
2+
from os import name
3+
4+
def nt_get_label(self):
5+
if self.log_text.tag_ranges('sel'):
6+
return 'Copy selected'
7+
else:
8+
return 'Copy log'
9+
10+
def posix_get_label(self):
11+
return 'Copy log'
12+
13+
14+
class ContextMenuDisplayers:
15+
16+
def __init__(self,log_text, log_menu, patterns_menu, patterns_list, window,
17+
sheet_name_entry,input_file_entry, output_file_entry,
18+
sheet_name_menu, input_file_menu, output_file_menu):
19+
20+
self.log_text = log_text
21+
self.log_menu = log_menu
22+
self.patterns_menu = patterns_menu
23+
self.patterns_list = patterns_list
24+
self.window = window
25+
26+
self.sheet_name_entry = sheet_name_entry
27+
self.input_file_entry = input_file_entry
28+
self.output_file_entry = output_file_entry
29+
30+
self.sheet_name_menu = sheet_name_menu
31+
self.input_file_menu = input_file_menu
32+
self.output_file_menu = output_file_menu
33+
34+
if name == 'posix':
35+
self.get_label = posix_get_label
36+
else:
37+
self.get_label = nt_get_label
38+
39+
def show_log_menu(self ,event : Event, app : bool = False) -> None:
40+
text = self.get_label(self)
41+
42+
self.log_menu.entryconfig(0,label=text)
43+
44+
if app:
45+
self.log_menu.tk_popup(self.log_text.winfo_rootx()+100, self.log_text.winfo_rooty()+100)
46+
else:
47+
self.log_menu.tk_popup(event.x_root,event.y_root)
48+
49+
def disable_moveup_movedown(self):
50+
for i in (3,4):
51+
self.patterns_menu.entryconfig(i, state='disabled')
52+
53+
def show_patterns_menu(self ,event : Event, app : bool=False) -> None:
54+
selected = self.patterns_list.curselection()
55+
if selected:
56+
if len(selected) > 1:
57+
for i in (1,6):
58+
self.patterns_menu.entryconfig(i,state='disabled')
59+
60+
for i in (7,8):
61+
self.patterns_menu.entryconfig(i,state='active')
62+
63+
self.disable_moveup_movedown()
64+
65+
else:
66+
self.patterns_menu.entryconfig(1,state='active')
67+
68+
for i in (6,7,8):
69+
self.patterns_menu.entryconfig(i,state='active')
70+
71+
for i in (3,4):
72+
self.patterns_menu.entryconfig(i, state='active')
73+
else:
74+
self.patterns_menu.entryconfig(1,state='disabled')
75+
76+
for i in (6,7,8):
77+
self.patterns_menu.entryconfig(i,state='disabled')
78+
79+
self.disable_moveup_movedown()
80+
81+
if app:
82+
self.patterns_menu.tk_popup(self.patterns_list.winfo_rootx()+100, self.patterns_list.winfo_rooty()+100)
83+
else:
84+
self.patterns_menu.tk_popup(event.x_root, event.y_root)
85+
86+
def show_entry_menu(self, menu : Menu, event : Event, app : bool=False) -> None:
87+
if self.window.focus_get() == event.widget:
88+
for i in range(4):
89+
menu.entryconfig(i,state='active')
90+
else:
91+
for i in range(4):
92+
menu.entryconfig(i,state='disabled')
93+
if app:
94+
if event.widget == self.sheet_name_entry:
95+
menu.tk_popup(event.widget.winfo_rootx()+50,event.widget.winfo_rooty()+25)
96+
else:
97+
menu.tk_popup(event.widget.winfo_rootx()+100,event.widget.winfo_rooty()+25)
98+
else:
99+
menu.tk_popup(event.x_root,event.y_root)
100+
101+
def set_keysym(self, menu_keysym):
102+
self.input_file_entry.bind(menu_keysym,lambda event : self.show_entry_menu(self.input_file_menu,event,True))
103+
self.output_file_entry.bind(menu_keysym,lambda event : self.show_entry_menu(self.output_file_menu,event,True))
104+
self.sheet_name_entry.bind(menu_keysym,lambda event : self.show_entry_menu(self.sheet_name_menu,event,True))
105+
self.log_text.bind(menu_keysym,lambda event : self.show_log_menu(event,True))
106+
self.patterns_list.bind(menu_keysym, lambda event : self.show_patterns_menu(event, True))

0 commit comments

Comments
 (0)