Post by Uncle Buddy on Nov 25, 2022 3:54:58 GMT -8
<drive>:\treebard_gps\app\python\notes.py Last Changed 2022-11-08
# notes.py
import tkinter as tk
import sqlite3
from widgets import (
Label, Button, Entry, Canvas, LabelFrame, LabelH3, FrameHilited6, Dialogue,
LabelMovable, Toplevel, LabelHeader, Radiobutton, Frame, Border, configall,
Combobox, EntryAutoHilited, Scrollbar, ScrolledText, make_formats_dict,
create_tooltip, EntryAutoPerson)
from right_click_menu import RightClickMenu, make_rc_menus
from toykinter_widgets import run_statusbar_tooltips
from scrolling import resize_scrolled_content
from error_messages import open_yes_no_message, InputMessage
from messages_context_help import notes_dlg_help_msg, links_dlg_help_msg
from messages import notes_msg
from utes import center_dialog, OK_PRINT_KEYS
from files import get_current_file
from links import ELEMENTS
from query_strings import (
insert_note, update_note_privacy, select_note_privacy, select_note_id,
update_note_edit, update_links_links_note_order_finding, insert_links_links_new_finding_note,
update_findings_notes_order, select_findings_notes_order,
select_notes_per_finding, select_links_links_notes_findings, select_all_place_ids,
delete_links_links_unlink_note, update_note_topic, select_notes_per_assertion,
insert_links_links_new_assertion_note, select_links_links_notes_assertions,
update_links_links_note_order_assertion, select_note_id_text
)
import dev_tools as dt
from dev_tools import looky, seeline
class NotesDialog(Toplevel):
""" `toc` means Table of Contents. """
def __init__(
self, master, finding_id, header, current_person, treebard,
inwidg=None, assertion_id=None,
# person_autofill_values=None,
use_finding_table=False, use_assertion_table=False,
*args, **kwargs):
Toplevel.__init__(self, master, *args, **kwargs)
self.root = master
self.finding_id = finding_id
self.header = header
self.current_person = current_person
self.treebard = treebard
self.inwidg = inwidg
self.assertion_id = assertion_id
# self.person_autofill_values = person_autofill_values
self.use_finding_table = use_finding_table
self.use_assertion_table = use_assertion_table
self.formats = make_formats_dict()
self.current_file = get_current_file()[0]
# self.selected won't be None after a label is selected, regardless
# of whether or not a label is still highlighted.
self.selected = None
self.topics = []
self.notes = []
self.current_name = EntryAutoPerson.person_autofill_values[
# self.current_name = self.person_autofill_values[
self.current_person][0]["name"]
self.privacy = tk.IntVar()
self.rc_menu = RightClickMenu(self.root, treebard=self.treebard)
self.autoscroll_on_arrow = False
self.make_widgets()
self.make_inputs()
self.define_queries_by_link()
self.make_table_of_contents()
self.size_toc()
configall(self, self.formats)
resize_scrolled_content(self, self.canvas, self.window)
center_dialog(self, frame=self.window)
self.bind_class('Label', '<Tab>', self.stop_tab_traversal1)
self.bind_class('Label', '<Shift-Tab>', self.stop_tab_traversal2)
for widg in (self.topic_input, self.order, self.linker, self.public,
self.private, self.close):
widg.bind("<Key-Up>", self.focus_topicslist)
widg.bind("<Key-Down>", self.focus_topicslist)
self.bind('<Escape>', self.close_notes_dialog)
def make_widgets(self):
self.canvas = Border(self, self.root, self.formats)
self.canvas.title_1.config(text="Notes Dialog")
self.canvas.title_2.config(text="Current Person: {}, ID #{}".format(
self.current_name, self.current_person))
self.window = Frame(self.canvas)
self.canvas.create_window(0, 0, anchor='nw', window=self.window)
scridth = 16
scridth_n = Frame(self.window, height=scridth)
scridth_w = Frame(self.window, width=scridth)
self.treebard.scroll_mouse.append_to_list([self.canvas, self.window])
self.treebard.scroll_mouse.configure_mousewheel_scrolling()
self.window.vsb = Scrollbar(
self,
hideable=True,
command=self.canvas.yview,
width=scridth)
self.window.hsb = Scrollbar(
self,
hideable=True,
width=scridth,
orient='horizontal',
command=self.canvas.xview)
self.canvas.config(
xscrollcommand=self.window.hsb.set,
yscrollcommand=self.window.vsb.set)
self.window.vsb.grid(column=2, row=4, sticky='ns')
self.window.hsb.grid(column=1, row=5, sticky='ew')
scridth_n.grid(column=0, row=0, sticky='ew')
scridth_w.grid(column=0, row=1, sticky='ns')
self.frame = Frame(self.window)
# make table of contents scrollable
self.toc_window = FrameHilited6(self.frame)
self.toc_canvas = Canvas(self.toc_window)
self.toc = Frame(self.toc_canvas)
self.toc_canvas.create_window(0, 0, anchor='nw', window=self.toc)
sbv = Scrollbar(
self.toc_window,
command=self.toc_canvas.yview,
hideable=False)
sbv.grid(column=1, row=1, sticky="ns")
self.toc_canvas.config(yscrollcommand=sbv.set)
def make_inputs(self):
""" Height of text widget can't be less than 14. """
self.header_msg = LabelHeader(
self.frame, text=self.header, justify="left")
self.toc_head = LabelH3(
self.frame, text="TABLE OF CONTENTS", anchor="w")
self.topic_input = Entry(self.frame, width=36)
self.topic_input.bind("<FocusOut>", self.link_existing_note)
self.note = ScrolledText(self.frame)
self.note.text.config(height=13, width=56)
self.controls = Frame(self.frame)
self.linker = Button(
self.controls,
text='LINK TO...',
command=self.add_links)
self.order = Button(
self.controls,
text='CHANGE TOPIC ORDER',
command=self.reorder_notes)
radframe = LabelFrame(self.frame, text='Make selected note...', takefocus=1)
self.public = Radiobutton(
radframe,
text='...public',
anchor='w',
variable=self.privacy,
value=0,
command=self.save_privacy_setting)
self.private = Radiobutton(
radframe,
text='...private',
anchor='w',
variable=self.privacy,
value=1,
command=self.save_privacy_setting)
radframe.bind("<Enter>", self.disable_radios)
radframe.bind("<Leave>", self.enable_radios)
radframe.bind("<FocusIn>", self.disable_radios)
radframe.bind("<FocusOut>", self.enable_radios)
self.buttons = Frame(self.frame)
ok_new_note = Button(
self.buttons, text="SAVE NEW TOPIC & NOTE",
command=self.make_new_note)
self.close = Button(
self.buttons, text='CLOSE', command=self.close_notes_dialog)
# children of self.window
self.frame.grid(column=1, row=1, sticky="news")
# children of self.frame
self.header_msg.grid(
column=0, row=0, columnspan=3,
ipadx=9, ipady=9, pady=(0,12), sticky="w")
self.toc_head.grid(column=0, row=1, sticky="ew", pady=6)
self.toc_window.grid(column=0, row=2, sticky="ew")
self.controls.grid(column=0, row=3, sticky="sw")
self.topic_input.grid(
column=1, row=1, sticky="w", pady=6, padx=(6,0), columnspan=2)
self.note.grid(column=1, row=2, columnspan=2, padx=(6,0), ipady=2)
radframe.grid(column=1, row=3, sticky="w", padx=(6,0), pady=(6,0))
self.buttons.grid(column=2, row=3, sticky="se")
# children of self.toc_window
self.toc_canvas.grid(column=0, row=1, sticky="news")
# children of self.controls
self.controls.rowconfigure(0, weight=1)
self.linker.grid(column=0, row=1, sticky='sw')
self.order.grid(column=0, row=2, sticky='sw', pady=(6,0))
# children of radframe
self.public.grid(column=0, row=0, sticky='news', padx=12)
self.private.grid(column=0, row=1, sticky='news', padx=12)
# children of self.buttons
ok_new_note.grid(column=0, row=0, sticky="e", padx=(0,6))
self.close.grid(column=1, row=0, sticky='e')
visited = (
# (self.left_panel,
# 'Table of Contents',
# 'Arrow or click topic to view, rename, or unlink note.'),
(self.linker,
'Link Button',
'Opens dialog to link this note to other elements.'),
(self.public,
'Public Note Option',
'Public notes will be shared when sharing tree.'),
(self.private,
'Private Note Option',
"Private notes stay on the tree creator's copy of Treebard."),
(self.order,
'Reorder Topics Button',
'Press to reorder topics in table of contents.'),
(self.note.text,
'Note Input & Readout',
'Create and edit notes of any length.'),
(self.topic_input,
'Note Topic Input',
'Select, create, or edit a note topic.'),
)
run_statusbar_tooltips(
visited,
self.canvas.statusbar.status_label,
self.canvas.statusbar.tooltip_label)
rcm_widgets = (
self.topic_input, self.note.text, self.toc_head, self.linker,
radframe, self.order)
make_rc_menus(
rcm_widgets,
self.rc_menu,
notes_dlg_help_msg)
self.topic_input.focus_set()
self.topic_input.bind("<FocusIn>", self.display_note)
self.topic_input.bind("<KeyRelease>", self.display_note)
def focus_topicslist(self, evt):
last = self.topiclabs[self.length - 1]
first = self.topiclabs[0]
sym = evt.keysym
if sym == "Up":
last.focus_set()
self.selected = last
self.toc_canvas.yview_moveto(1.0)
elif sym == "Down":
first.focus_set()
self.selected = first
self.toc_canvas.yview_moveto(0.0)
self.display_note()
def add_links(self):
""" Never finished or tested.
This dialog is modal so all the possible value lists for the
Combobox don't have to be refreshed before the autofill entry
can be used. This way, the lists can be populated once when
this dialog opens.
"""
places = make_all_nestings(select_all_place_ids)
self.place_autofill_values = EntryAutoHilited.create_lists(places)
def close_linker():
self.link_dlg.grab_release()
self.link_dlg.destroy()
self.link_dlg = Dialogue(self)
self.link_dlg.grab_set()
self.link_dlg.canvas.title_1.config(text="Note-to-Elements Links")
self.link_dlg.canvas.title_2.config(text="")
lab = LabelHeader(
self.link_dlg.window,
text=notes_msg[1],
justify='left', wraplength=450)
lab.grid(
column=0, row=0, sticky='news', padx=12, pady=12,
columnspan=2, ipadx=6, ipady=3)
self.combo = Combobox(
self.link_dlg.window, self.root, values=sorted(ELEMENTS))
self.combo.grid(column=0, row=1, sticky="w", padx=12)
self.link_input = EntryAutoHilited(
self.link_dlg.window, width=36, autofill=True)
self.link_input.grid(column=0, row=2, pady=6, sticky="ew", padx=12)
self.link_input.bind("<FocusIn>", self.get_link_type, add="+")
buttonbox = Frame(self.link_dlg.window)
buttonbox.grid(
column=0, row=3, sticky='e', padx=(0,12), pady=12, columnspan=2)
ok_butt = Button(
buttonbox, text="OK",
command=self.save_link,
width=6)
ok_butt.grid(column=0, row=0, sticky='e')
cancel_butt = Button(
buttonbox, text="DONE", command=close_linker, width=6)
cancel_butt.grid(column=1, row=0, padx=(6,0), sticky='e')
self.combo.entry.focus_set()
self.link_dlg.resize_window()
def get_link_type(self, evt):
self.link_type = self.combo.entry.get()
self.link_input.delete(0, 'end')
if self.link_type not in ELEMENTS:
return
elif self.link_type == "persons":
self.link_input.values = EntryAutoPerson.person_autofill_values
# self.link_input.values = self.person_autofill_values
elif self.link_type == "places":
self.link_input.values = self.place_autofill_values
else:
print("line", looky(seeline()).lineno, "self.link_type:", self.link_type)
def save_link(self):
got = self.link_input.get()
if self.link_type == "persons":
element_id = got.split(" #")[1]
def ignore_changes(self, evt=None):
self.order_dlg.grab_release()
self.order_dlg.destroy()
self.focus_set()
def reorder_notes(self):
if self.length <= 1:
return
self.order_dlg = Toplevel(self)
self.order_dlg.columnconfigure(1, weight=1)
self.order_dlg_canvas = Border(self.order_dlg, self.root, self.formats)
self.order_dlg_window = Frame(self.order_dlg_canvas)
self.order_dlg_canvas.create_window(
0, 0, anchor='nw', window=self.order_dlg_window)
self.order_dlg.grab_set()
self.order_dlg.bind('<Return>', self.save_close_reorder_dlg)
self.order_dlg.bind('<Escape>', self.ignore_changes)
self.order_dlg_canvas.title_1.config(text="Re-order Topics")
self.order_dlg_canvas.title_2.config(text="")
self.make_widgets_reorder_dlg()
self.make_inputs_reorder_dlg()
configall(self.order_dlg, self.formats)
resize_scrolled_content(
self.order_dlg, self.order_dlg_canvas, self.order_dlg_window)
self.order_dlg.maxsize(
int(self.order_dlg_window.winfo_reqwidth() + 24),
int(self.winfo_screenheight() * 0.80))
def make_widgets_reorder_dlg(self):
scridth = 16
scridth_n = Frame(self.order_dlg_window, height=scridth)
scridth_w = Frame(self.order_dlg_window, width=scridth)
self.treebard.scroll_mouse.append_to_list(
[self.order_dlg_canvas, self.order_dlg_window])
self.treebard.scroll_mouse.configure_mousewheel_scrolling()
self.order_dlg_window.vsb = Scrollbar(
self.order_dlg,
hideable=True,
command=self.order_dlg_canvas.yview,
width=scridth)
self.order_dlg_window.hsb = Scrollbar(
self.order_dlg,
hideable=True,
width=scridth,
orient='horizontal',
command=self.order_dlg_canvas.xview)
self.order_dlg_canvas.config(
xscrollcommand=self.order_dlg_window.hsb.set,
yscrollcommand=self.order_dlg_window.vsb.set)
self.order_dlg_window.vsb.grid(column=2, row=4, sticky='ns')
self.order_dlg_window.hsb.grid(column=1, row=5, sticky='ew')
scridth_n.grid(column=0, row=0, sticky='ew')
scridth_w.grid(column=0, row=1, sticky='ns')
def make_inputs_reorder_dlg(self):
reorder_msg = (
'Tab or Shift + Tab selects movable topic. '
'Arrow keys change topic order up or down.')
reorder_lab = LabelHeader(
self.order_dlg_window, text=reorder_msg, wraplength=450)
self.reorder_labs = Frame(self.order_dlg_window)
e = 0
for topic in self.topics:
lab = LabelMovable(self.reorder_labs, text=topic, anchor='w')
if e == 0:
first = lab
e += 1
lab.grid(column=0, row=e, padx=3, sticky='ew')
first.focus_set()
close2 = Button(
self.order_dlg_window,
text='OK',
command=self.save_close_reorder_dlg)
reorder_lab.grid(
column=0, row=0, pady=(12,0), padx=12,
columnspan=2, ipadx=6, ipady=3)
self.reorder_labs.grid(column=0, row=1, columnspan=2, padx=12, pady=12)
self.reorder_labs.grid_columnconfigure(0, weight=1)
close2.grid(column=1, row=2, sticky='se', padx=12, pady=(0,12))
center_dialog(self.order_dlg, frame=self.order_dlg_window)
def save_close_reorder_dlg(self, evt=None):
q = 0
new_order = []
save_order = []
for child in self.reorder_labs.winfo_children():
text = child.cget('text')
new_order.append(text)
save_order.append([text, q])
q += 1
conn = sqlite3.connect(self.current_file)
conn.execute('PRAGMA foreign_keys = 1')
cur = conn.cursor()
for lst in save_order:
cur.execute(select_note_id, (lst[0],))
result = cur.fetchone()
if result:
note_id = result[0]
else:
continue
cur.execute(
self.update_note_order,
(lst[1], self.element_id, note_id))
conn.commit()
cur.close()
conn.close()
self.make_table_of_contents()
self.order_dlg.grab_release()
self.order_dlg.destroy()
self.focus_set()
def save_privacy_setting(self):
selected_topic = self.selected.cget("text")
conn = sqlite3.connect(self.current_file)
conn.execute('PRAGMA foreign_keys = 1')
cur = conn.cursor()
cur.execute(update_note_privacy, (
self.privacy.get(), selected_topic))
conn.commit()
cur.close()
conn.close()
def close_notes_dialog(self, evt=None):
self.destroy()
self.root.focus_set()
def size_toc(self):
self.update_idletasks()
self.win_ht = self.toc.winfo_reqheight()
self.canv_ht = self.note.winfo_reqheight() - self.toc_window["bd"] * 2
print("line", looky(seeline()).lineno, "self.canv_ht:", self.canv_ht)
print("line", looky(seeline()).lineno, "self.note.winfo_reqheight():", self.note.winfo_reqheight())
self.toc_canvas.config(
width=self.toc_width,
height=self.canv_ht,
scrollregion=(0, 0, self.toc_width, self.win_ht))
unzero = self.length
if unzero == 0:
unzero = 1
self.widg_ht = int(self.win_ht / unzero)
lines_fit = int(self.canv_ht / self.widg_ht)
if self.length > lines_fit:
self.autoscroll_on_arrow = True
def stop_tab_traversal1(self, evt):
'''
Two similar callbacks are needed for binding to both `Tab` and
`Shift-Tab` because Tkinter's `evt.keysym` detects `Tab` for both.
'''
widg = evt.widget
if widg not in self.topiclabs:
return
self.topic_input.focus_set()
return('break')
def stop_tab_traversal2(self, evt):
widg = evt.widget
if widg not in self.topiclabs:
return
self.done.focus_set()
return('break')
def select_item(self, evt, next_item=None, prev_item=None):
for widg in self.topiclabs:
widg.config(bg=self.formats['bg'])
sym = evt.keysym
evt_type = evt.type
if evt_type == '4':
self.selected = evt.widget
self.display_note()
elif evt_type == '2' and sym == 'Down':
self.selected = next_item
elif evt_type == '2' and sym == 'Up':
self.selected = prev_item
self.selected.config(bg=self.formats['highlight_bg'])
self.update_idletasks()
current_scrollratio = 0.0
top_of_selected = self.selected.winfo_rooty()
top_of_port = self.toc_canvas.winfo_rooty()
height_of_selected = self.selected.winfo_reqheight()
bottom_of_selected = top_of_selected + height_of_selected
bottom_of_port = top_of_port + self.canv_ht
page_ratio = self.canv_ht / self.win_ht
# autoscroll in 1-page increments during arrow traversal
# if selected widget goes out of view
if bottom_of_selected > bottom_of_port:
current_scrollratio += page_ratio
self.toc_canvas.yview_moveto(float(current_scrollratio))
elif top_of_selected < top_of_port:
if self.autoscroll_on_arrow is True:
current_scrollratio -= page_ratio
self.toc_canvas.yview_moveto(float(current_scrollratio))
self.selected.focus_set()
def traverse_on_arrow(self, evt):
widg = evt.widget
sym = evt.keysym
self.update_idletasks()
next_item = widg.tk_focusNext()
prev_item = widg.tk_focusPrev()
if sym == 'Down':
if next_item in self.topiclabs:
self.select_item(evt, next_item=next_item)
else:
next_item = self.topiclabs[0]
next_item.focus_set()
next_item.config(bg=self.formats['highlight_bg'])
self.selected = next_item
self.toc_canvas.yview_moveto(0.0)
elif sym == 'Up':
if prev_item in self.topiclabs:
self.select_item(evt, prev_item=prev_item)
else:
prev_item = self.topiclabs[self.length-1]
prev_item.focus_set()
prev_item.config(bg=self.formats['highlight_bg'])
self.selected = prev_item
if self.autoscroll_on_arrow is True:
self.toc_canvas.yview_moveto(1.0)
self.display_note()
def make_table_of_contents(self):
for child in self.toc.winfo_children():
child.destroy()
conn = sqlite3.connect(self.current_file)
cur = conn.cursor()
cur.execute(self.select_notes_query, (self.element_id,))
self.values = cur.fetchall()
cur.close()
conn.close()
self.topics = [i[0] for i in self.values]
self.notes = [i[1] for i in self.values]
self.toc_width = self.toc_head.winfo_reqwidth()
self.topiclabs = []
r = 0
for tup in self.values:
text = self.values[r][0]
lab = Label(
self.toc, takefocus=1, anchor="w",
text=text, width=self.toc_width)
self.topiclabs.append(lab)
lab.grid(column=0, row=r+1, sticky="ew")
lab.bind("<Button-1>", self.select_item)
lab.bind("<FocusIn>", self.highlight)
lab.bind("<FocusOut>", self.unhighlight)
lab.bind("<Key-Up>", self.traverse_on_arrow, add="+")
lab.bind("<Key-Down>", self.traverse_on_arrow, add="+")
lab.bind("<Delete>", self.unlink_selected_note)
lab.bind("<BackSpace>", self.rename_selected_note)
if len(text) > 17:
create_tooltip(lab, text)
r += 1
self.length = len(self.topiclabs)
def rename_selected_note(self, evt):
widg = evt.widget
old_txt = widg.cget("text")
msg = InputMessage(
self, root=self.root, return_focus_to=widg, title="Rename Note",
ok_txt="OK", cancel_txt="CANCEL", entry=True, grab=True,
head1="Rename {} to:".format(old_txt), head2="(any unique title)")
if msg.ok_was_pressed:
new_txt = msg.show()
print("line", looky(seeline()).lineno, "new_txt:", new_txt)
conn = sqlite3.connect(self.current_file)
conn.execute('PRAGMA foreign_keys = 1')
cur = conn.cursor()
cur.execute(update_note_topic, (new_txt, old_txt))
conn.commit()
cur.close()
conn.close()
self.make_table_of_contents()
def unlink_selected_note(self, evt):
def ok_unlink_note():
msg[0].grab_release()
msg[0].destroy()
self.topic_input.focus_set()
proceed()
def cancel_unlink_note():
msg[0].grab_release()
msg[0].destroy()
widg.focus_set()
def proceed():
conn = sqlite3.connect(self.current_file)
conn.execute('PRAGMA foreign_keys = 1')
cur = conn.cursor()
cur.execute(self.select_notes_by_topic, (topic, self.element_id))
to_unlink = cur.fetchone()
for num in to_unlink:
cur.execute(delete_links_links_unlink_note, (num,))
conn.commit()
cur.close()
conn.close()
# recalculate scrollregion height
win_ht_new = self.win_ht - widg_ht
self.toc_canvas.config(
width=self.toc_width,
height=self.canv_ht,
scrollregion=(0, 0, self.toc_width, win_ht_new))
self.topic_input.delete(0, "end")
self.make_table_of_contents()
if len(self.topics) == 0:
self.inwidg.config(text=" ")
widg = evt.widget
topic = widg.cget('text')
widg_ht = widg.winfo_reqheight()
msg = open_yes_no_message(
self,
notes_msg[5],
"Unlink Note Confirmation",
"OK", "CANCEL")
msg[0].grab_set()
msg[2].config(command=ok_unlink_note)
msg[3].config(command=cancel_unlink_note)
def make_new_note(self):
""" Tkinter automatically adds a newline character at the end of the
data in the Text widget, so to detect an empty Text widget, use
get(1.0, 'end-1c') instead of get(1.0, 'end'). This gets the text
up to 1 character from the end.
"""
topic = self.topic_input.get()
note = self.note.text.get(1.0, 'end-1c')
if (len(self.note.text.get(1.0, 'end-1c')) == 0 or
len(topic) == 0):
return
if topic in self.topics:
idx = self.topics.index(topic)
self.edit_note(idx, topic, note)
return
new_topic = self.topic_input.get()
new_note = note
if len(self.topiclabs) != 0:
self.topiclabs[0].focus_set()
self.save_new_note(new_topic, new_note)
self.make_table_of_contents()
self.size_toc()
resize_scrolled_content(self, self.canvas, self.window)
def edit_note(self, idx, topic, note):
def save_edited_text():
conn = sqlite3.connect(self.current_file)
conn.execute('PRAGMA foreign_keys = 1')
cur = conn.cursor()
cur.execute(update_note_edit, (final, topic))
conn.commit()
cur.close()
conn.close()
self.make_table_of_contents()
orig = self.notes[idx]
final = note
if orig == final:
pass
else:
save_edited_text()
def save_new_note(self, new_topic, new_note):
def reorder_notes():
cur.execute(select_findings_notes_order, (self.finding_id,))
order = [list(i) for i in cur.fetchall()]
for lst in order:
lst[0] += 1
for lst in order:
cur.execute(update_findings_notes_order, tuple(lst))
conn.commit()
conn = sqlite3.connect(self.current_file)
conn.execute('PRAGMA foreign_keys = 1')
cur = conn.cursor()
cur.execute(insert_note, (new_note, new_topic))
conn.commit()
new_note_id = cur.lastrowid
reorder_notes()
cur.execute(
self.insert_links_links_new_note, (
self.element_id, new_note_id, self.length))
conn.commit()
cur.close()
conn.close()
def highlight(self, evt):
evt.widget.config(bg=self.formats["highlight_bg"])
def unhighlight(self, evt):
evt.widget.config(bg=self.formats["bg"])
def display_note(self, evt=None):
def do_it(selected_topic):
if selected_topic is None:
self.note.text.delete(1.0, 'end')
return
idx = self.topics.index(selected_topic)
note_to_display = self.notes[idx]
self.topic_input.delete(0, 'end')
self.topic_input.insert(0, selected_topic)
self.note.text.delete(1.0, 'end')
self.note.text.insert(1.0, note_to_display)
self.selected = self.topiclabs[idx]
self.selected.focus_set()
conn = sqlite3.connect(self.current_file)
cur = conn.cursor()
cur.execute(select_note_privacy, (selected_topic,))
privacy_setting = cur.fetchone()[0]
cur.close()
conn.close()
if privacy_setting == 0:
self.public.select()
elif privacy_setting == 1:
self.private.select()
selected_topic = None
if evt is None:
selected_topic = self.selected.cget("text")
do_it(selected_topic)
return
etype = evt.type
widg = evt.widget
sym = evt.keysym
if etype == "4": # Button-1
selected_topic = widg.cget('text')
elif etype == "9": # FocusIn
if len(widg.get()) == 0:
pass
else:
selected_topic = widg.get().strip()
elif etype == "3": # KeyRelease
if widg is self.topic_input:
if (len(sym) == 1 or
sym in OK_PRINT_KEYS or
sym in ("BackSpace", "Delete")):
selected_topic = self.topic_input.get()
if selected_topic in self.topics:
do_it(selected_topic)
else:
self.note.text.delete(1.0, 'end')
def define_queries_by_link(self):
if self.use_finding_table is True:
self.select_notes_query = select_notes_per_finding
self.insert_links_links_new_note = insert_links_links_new_finding_note
self.select_notes_by_topic = select_links_links_notes_findings
self.update_note_order = update_links_links_note_order_finding
self.element_id = self.finding_id
elif self.use_assertion_table is True:
self.select_notes_query = select_notes_per_assertion
self.insert_links_links_new_note = insert_links_links_new_assertion_note
self.select_notes_by_topic = select_links_links_notes_assertions
self.update_note_order = update_links_links_note_order_assertion
self.element_id = self.assertion_id
def disable_radios(self, evt):
if self.selected is None:
for radio in (self.public, self.private):
radio.config(state="disabled")
def enable_radios(self, evt):
for radio in (self.public, self.private):
radio.config(state="normal")
def link_existing_note(self, evt):
typed_topic = evt.widget.get()
if len(typed_topic) == 0 or typed_topic in self.topics:
return
else:
conn = sqlite3.connect(self.current_file)
conn.execute('PRAGMA foreign_keys = 1')
cur = conn.cursor()
cur.execute(select_note_id_text, (typed_topic,))
result = cur.fetchone()
if result is None:
pass
else:
note_id, note_text = result
cur.execute(
self.insert_links_links_new_note, (
self.element_id, note_id, self.length))
conn.commit()
self.note.text.delete(1.0, "end")
self.note.text.insert(1.0, note_text)
if len(self.topics) == 0:
self.inwidg.config(text=" ... ")
self.make_table_of_contents()
if __name__ == "__main__":
finding = 1
header = ["birth", "14 Jan 1845", "Colorado, USA", "born at home"]
current_person = 3
treebard = None
def open_note():
note_dlg = NotesDialog(
root, finding, header, current_person, treebard)
root = tk.Tk()
b = Button(root, text=" ... ", command=open_note)
b.grid()
b.focus_set()
configall(root, formats)
root.mainloop()