roles.py
Nov 25, 2022 18:04:30 GMT -8
Post by Uncle Buddy on Nov 25, 2022 18:04:30 GMT -8
<drive>:\treebard\roles.py Last Changed 2024-07-25
# roles.py
import tkinter as tk
import sqlite3
from base import tree_path
from widgets import (
configall, make_formats_dict, ScrolledDialog, Combobox, ButtonQuiet,
run_statusbar_tooltips, RightClickMenu, make_rc_menus, get_color_scheme_id)
from persons import get_original, open_new_person_dialog, EntryAutoPerson
from messages_context_help import roles_dlg_help_msg, role_edit_help_msg
from unigeds_queries import (
select_roles_links_roles, select_role_types, select_role_type_id,
update_roles_links_role_type, update_roles_links_person_id,
insert_roles_links_role_person, delete_events_role, insert_role_type,
select_count_events_roles)
import dev_tools as dt
from dev_tools import look, seeline
class RolesDialog(ScrolledDialog):
def __init__(
self, master, treebard, event_id, header, inwidg=None,
person_autofill_values=None, linked_element=None, *args, **kwargs):
ScrolledDialog.__init__(self, master, *args, **kwargs)
self.tree = master
self.treebard = treebard
self.event_id = event_id
self.header = header
self.inwidg = inwidg
self.protocol("WM_DELETE_WINDOW", self.close_roles_dialog)
self.geometry("0x0+0+0")
self.role_types = []
self.roles_per_event = []
self.widget = None
self.person_inputs = []
self.current_name = self.tree.person_autofill_values[
self.tree.persid][0]["name"]
self.title(
f"Roles Dialog Current Person: {self.current_name}, ID #{self.tree.persid}")
self.rc_menu = RightClickMenu(self.tree, self.treebard)
self.make_widgets()
self.make_inputs()
ScrolledDialog.bind_canvas_to_mousewheel(self.canvas)
color_scheme_id = get_color_scheme_id(self.tree.tree_id)
self.formats = make_formats_dict(
self.tree.tree_id, color_scheme_id=color_scheme_id)
configall(self, self.formats)
self.resize_scrolled_content(self, self.canvas, add_x=16, add_y=24)
def make_widgets(self):
self.columnconfigure(1, weight=1)
self.window.columnconfigure(2, weight=1)
self.window.rowconfigure(1, minsize=60)
self.window.columnconfigure(0, weight=1)
self.window.rowconfigure(0, weight=1)
self.header_msg = tk.Label(self.window, text=self.header, justify="left")
def make_inputs(self):
conn = sqlite3.connect(self.tree.file)
conn.execute('PRAGMA foreign_keys = 1')
cur = conn.cursor()
self.role_types = self.get_role_types(cur)
self.rolfrm = tk.Frame(self.window)
new_roles_area = tk.Frame(self.window)
self.make_roles_table(conn, cur)
new_roles_header = tk.Label(new_roles_area, text='Create New Role')
self.role_type_input = Combobox(
new_roles_area, self.formats, self.tree, values=self.role_types)
self.role_type_input.entry.focus_set()
self.person_input = EntryAutoPerson(
new_roles_area, self.tree, width=32,
autofill=True, values=self.tree.person_autofill_values)
self.person_input.bind("<FocusIn>", get_original, add="+")
self.tree.person_autofills.append(self.person_input)
self.add_butt = tk.Button(
new_roles_area,
text='ADD',
command=self.get_add_state)
self.close_butt = tk.Button(
new_roles_area,
text='CLOSE',
command=self.close_roles_dialog)
self.bind('<Escape>', self.close_roles_dialog)
# children of self.window
self.header_msg.grid(column=0, row=0, ipadx=9, ipady=9)
self.rolfrm.grid(column=0, row=1, columnspan=2)
new_roles_area.grid(column=0, row=2)
# children of new_roles_area
new_roles_header.grid(column=0, row=0)
self.role_type_input.grid(column=0, row=1)
self.person_input.grid(column=1, row=1, padx=(6,0))
self.add_butt.grid(column=2, row=1, padx=(6,0))
self.close_butt.grid(column=4, row=1, padx=(6,0))
cur.close()
conn.close()
visited = (
(self.header_msg,
'',
'Event-type, date, place & particulars of this conclusion if known.'),
(self.role_type_input.entry,
'New Role: Type Input',
'Select a role type or create a new one.'),
(self.person_input,
'New Role: Person Input',
'Select a role person or add a new person.'),
(self.add_butt,
'Add New Role Button',
'Make a new role and leave the dialog open.'),
(self.close_butt,
'Close Dialog Button',
'Close the dialog.'))
run_statusbar_tooltips(
visited,
self.statusbar.status_label,
self.statusbar.tooltip_label, self)
rcm_widgets = (
self.role_type_input.entry, self.person_input, self.add_butt,
self.close_butt)
make_rc_menus(
rcm_widgets,
self.rc_menu,
roles_dlg_help_msg)
def make_roles_list(self, cur):
cur.execute(select_roles_links_roles, (self.event_id,))
roles_per_event = cur.fetchall()
if roles_per_event:
self.roles_per_event = [list(i) for i in roles_per_event]
for idx,lst in enumerate(list(self.roles_per_event)):
iD = lst[2]
name = self.tree.person_autofill_values[iD][0]["name"]
self.roles_per_event[idx].append(name)
def make_roles_table(self, conn, cur):
def get_clicked_row(evt):
self.got_row = evt.widget.grid_info()['row']
self.edited_role_id = self.roles_per_event[self.got_row][0]
def on_hover(evt):
evt.widget.config(fg=self.formats["fg"])
def on_unhover(evt):
evt.widget.config(fg=self.formats["bg"])
self.make_roles_list(cur)
self.rolfrm.columnconfigure(4, weight=1)
first_butt = None
for idx, lst in enumerate(list(self.roles_per_event)):
if type(lst[2]) is tuple:
self.roles_per_event[idx][2] = "({}) {}".format(lst[2][1], lst[2][0])
labelr = tk.Label(self.rolfrm, text=lst[1], anchor='e')
sep = tk.Label(self.rolfrm, text='|', anchor='w')
labelp = tk.Label(self.rolfrm, text=lst[4], anchor='w')
deleter = ButtonQuiet(
self.rolfrm, self.formats, text='DELETE ROLE',
overrelief=tk.GROOVE, command=self.delete_role)
labelr.grid(column=0, row=idx, padx=6, pady=3, sticky='ew')
sep.grid(column=1, row=idx)
labelp.grid(column=2, row=idx, padx=6, pady=3, sticky='ew')
deleter.grid(column=3, row=idx, padx=6, pady=3, ipadx=3, ipady=3)
if idx == 0:
first_butt = deleter
deleter.bind('<Enter>', on_hover)
deleter.bind('<Leave>', on_unhover)
deleter.bind('<Button-1>', get_clicked_row)
deleter.bind('<space>', get_clicked_row)
self.rc_menu.loop_made[deleter] = role_edit_help_msg
if first_butt:
first_butt.focus_set()
configall(self.rolfrm, self.formats)
def delete_role(self):
def delete_role_from_db():
nonlocal role_count_per_event
conn = sqlite3.connect(self.tree.file)
conn.execute('PRAGMA foreign_keys = 1')
cur = conn.cursor()
cur.execute(delete_events_role, (self.edited_role_id,))
conn.commit()
cur.execute(select_count_events_roles, (self.event_id,))
role_count_per_event = cur.fetchone()[0]
self.make_roles_list(cur)
cur.close()
conn.close()
role_count_per_event = 0
delete_role_from_db()
if role_count_per_event == 0:
self.inwidg.config(text=' ')
for child in self.rolfrm.winfo_children():
if child.winfo_class() == 'Frame':
pass
elif child.grid_info()['row'] == self.got_row:
child.destroy()
elif child.grid_info()['row'] > self.got_row:
row = child.grid_info()['row']
child.grid(row=row-1)
self.resize_scrolled_content(self, self.canvas, add_x=16, add_y=24)
def get_role_types(self, cur):
cur.execute(select_role_types)
role_types = sorted([i[0] for i in cur.fetchall()])
return role_types
def get_add_state(self):
conn = sqlite3.connect(self.tree.file)
conn.execute('PRAGMA foreign_keys = 1')
cur = conn.cursor()
for widg in (self.role_type_input.entry, self.person_input):
if len(widg.get()) == 0:
widg.focus_set()
return
chosen_role_type = self.role_type_input.entry.get()
self.user_input_person = self.person_input.get()
if chosen_role_type not in self.role_types:
chosen_role_type = self.make_new_role_type(chosen_role_type, conn, cur)
self.make_new_role(chosen_role_type, conn, cur)
cur.close()
conn.close()
def make_new_role_type(self, new_role_type, conn, cur):
cur.execute(insert_role_type, (new_role_type,))
conn.commit()
return new_role_type
def close_roles_dialog(self, evt=None):
self.destroy()
def make_new_role(self, role_type, conn, cur):
got = self.person_input.get()
if len(self.user_input_person) == 0:
self.person_input.focus_set()
return
name_data = self.person_input.check_name(cur)
if name_data is None:
redo = f"{got}+"
name_data = self.person_input.check_name(cur, redo=redo)
if name_data == "add_new_person":
role_person_id = open_new_person_dialog(
self.tree, self.treebard, inwidg=self.person_input, got=got)
self.tree.person_autofill_values = self.tree.update_person_autofill_values()
else:
role_person_id = name_data[1]
cur.execute(select_role_type_id, (role_type,))
role_type_id = cur.fetchone()[0]
cur.execute(
insert_roles_links_role_person,
(self.event_id, role_type_id, role_person_id))
conn.commit()
self.make_roles_table(conn, cur)
self.inwidg.config(text=' ... ')
self.role_type_input.entry.delete(0, 'end')
self.person_input.delete(0, 'end')
self.resize_scrolled_content(self, self.canvas, add_x=16, add_y=24)
self.make_roles_list(cur)