blob: 8c9d7dbd48153b4a5579d6212730f9701ec14c84 [file] [log] [blame]
#!/usr/bin/env python3
#
#--------------------------------------------------------
# Help Window for the Project manager
#
#--------------------------------------------------------
# Written by Tim Edwards
# efabless, inc.
# September 12, 2016
# Version 0.1
#--------------------------------------------------------
import re
import tkinter
from tkinter import ttk
class HelpWindow(tkinter.Toplevel):
"""help window"""
def __init__(self, parent=None, fontsize = 11, *args, **kwargs):
'''See the __init__ for Tkinter.Toplevel.'''
tkinter.Toplevel.__init__(self, parent, *args, **kwargs)
s = ttk.Style()
s.configure('normal.TButton', font=('Helvetica', fontsize), border = 3, relief = 'raised')
self.protocol("WM_DELETE_WINDOW", self.close)
self.withdraw()
self.title('Help')
self.helptitle = ttk.Label(self, style='title.TLabel', text = '(no text)')
self.helptitle.grid(column = 0, row = 0, sticky = "news")
self.helpbar = ttk.Separator(self, orient='horizontal')
self.helpbar.grid(column = 0, row = 1, sticky = "news")
self.hframe = tkinter.Frame(self)
self.hframe.grid(column = 0, row = 2, sticky = "news")
self.hframe.helpdisplay = ttk.Frame(self.hframe)
self.hframe.helpdisplay.pack(side = 'left', fill = 'both', expand = 'true')
self.hframe.helpdisplay.helptext = tkinter.Text(self.hframe.helpdisplay, wrap='word')
self.hframe.helpdisplay.helptext.pack(side = 'top', fill = 'both', expand = 'true')
# Add scrollbar to help window
self.hframe.scrollbar = ttk.Scrollbar(self.hframe)
self.hframe.scrollbar.pack(side='right', fill='y')
# attach help window to scrollbar
self.hframe.helpdisplay.helptext.config(yscrollcommand = self.hframe.scrollbar.set)
self.hframe.scrollbar.config(command = self.hframe.helpdisplay.helptext.yview)
self.hframe.toc = ttk.Treeview(self.hframe, selectmode='browse')
self.hframe.toc.bind('<<TreeviewSelect>>', self.toc_to_page)
self.hframe.toc.bind('<<TreeviewOpen>>', self.toc_toggle)
self.hframe.toc.bind('<<TreeviewClose>>', self.toc_toggle)
self.hframe.toc.tag_configure('title', font=('Helvetica', fontsize, 'bold italic'),
foreground = 'brown', anchor = 'center')
self.hframe.toc.heading('#0', text = "Table of Contents")
self.bbar = ttk.Frame(self)
self.bbar.grid(column = 0, row = 3, sticky = "news")
self.bbar.close_button = ttk.Button(self.bbar, text='Close',
command=self.close, style = 'normal.TButton')
self.bbar.close_button.grid(column=0, row=0, padx = 5)
self.bbar.prev_button = ttk.Button(self.bbar, text='Prev',
command=self.prevpage, style = 'normal.TButton')
self.bbar.prev_button.grid(column=1, row=0, padx = 5)
self.bbar.next_button = ttk.Button(self.bbar, text='Next',
command=self.nextpage, style = 'normal.TButton')
self.bbar.next_button.grid(column=2, row=0, padx = 5)
self.bbar.contents_button = ttk.Button(self.bbar, text='Table of Contents',
command=self.page_to_toc, style = 'normal.TButton')
self.bbar.contents_button.grid(column=3, row=0, padx = 5)
self.rowconfigure(0, weight=0)
self.rowconfigure(1, weight=0)
self.rowconfigure(2, weight=1)
self.rowconfigure(3, weight=0)
self.columnconfigure(0, weight=1)
# Help pages
self.pages = []
self.pageno = -1 # No page
self.toggle = False
def grid_configure(self, padx, pady):
pass
def redisplay(self):
# remove contents
if self.pageno >= 0 and self.pageno < len(self.pages):
self.hframe.helpdisplay.helptext.delete('1.0', 'end')
self.hframe.helpdisplay.helptext.insert('end', self.pages[self.pageno]['text'])
self.helptitle.configure(text = self.pages[self.pageno]['title'])
def toc_toggle(self, event):
self.toggle = True
def toc_to_page(self, event):
treeview = event.widget
selection = treeview.item(treeview.selection())
# Make sure any open/close callback is handled first!
self.update_idletasks()
if self.toggle:
# Item was opened or closed, so consider this a 'false select' and
# do not go to the page.
self.toggle = False
return
if 'values' in selection:
pagenum = selection['values'][0]
else:
print('Unknown page selected.')
pagenum = 0
# Display a page after displaying the table of contents
self.hframe.toc.pack_forget()
self.hframe.scrollbar.pack_forget()
self.hframe.helpdisplay.pack(side='left', fill='both', expand = 'true')
self.hframe.scrollbar.pack(side='right', fill='y')
self.hframe.scrollbar.config(command = self.hframe.helpdisplay.helptext.yview)
# Enable Prev and Next buttons
self.bbar.prev_button.configure(state='enabled')
self.bbar.next_button.configure(state='enabled')
# Redisplay
self.page(pagenum)
def page_to_toc(self):
# Display the table of contents after displaying a page
self.hframe.scrollbar.pack_forget()
self.hframe.helpdisplay.pack_forget()
self.hframe.toc.pack(side='left', fill='both', expand = 'true')
self.hframe.scrollbar.pack(side='right', fill='y')
self.hframe.scrollbar.config(command = self.hframe.toc.yview)
# Disable Prev and Next buttons
self.bbar.prev_button.configure(state='disabled')
self.bbar.next_button.configure(state='disabled')
# Simple add page with a single block of plain text
def add_page(self, toc_text, text_block):
newdict = {}
newdict['text'] = text_block
newdict['title'] = toc_text
self.pages.append(newdict)
newpageno = len(self.pages)
self.hframe.toc.insert('', 'end', text=str(newpageno) + '. ' + toc_text,
tag='title', value = newpageno - 1)
if self.pageno < 0:
self.pageno = 0 # First page
# Fill the help text from a file. The format of the file is:
# <page_num>
# <title>
# <text>
# '.'
# Text is multi-line and ends when '.' is encountered by itself
def add_pages_from_file(self, filename):
endpagerex = re.compile('^\.$')
newpagerex = re.compile('^[0-9\.]+$')
commentrex = re.compile('^[\-]+$')
hierarchy = ''
print('Loading help text from file ' + filename)
with open(filename, 'r') as f:
toc_text = []
page_text = []
for line in f:
if newpagerex.match(line) or endpagerex.match(line):
if toc_text and page_text:
newdict = {}
self.pages.append(newdict)
newpageno = len(self.pages)
if '.' in hierarchy:
pageinfo = hierarchy.rsplit('.', 1)
if pageinfo[1] == '':
parentid = ''
pageid = pageinfo[0]
else:
parentid = pageinfo[0]
pageid = pageinfo[1]
else:
parentid = ''
pageid = hierarchy
if parentid:
pageid = parentid + '.' + pageid
newdict['text'] = page_text
newdict['title'] = pageid + '. ' + toc_text
self.hframe.toc.insert(parentid, 'end',
text=newdict['title'], tag='title',
value = newpageno - 1, iid = pageid)
if newpagerex.match(line):
hierarchy = line.rstrip()
toc_text = []
elif not toc_text:
toc_text = line.rstrip()
page_text = []
elif not commentrex.match(line):
if not page_text:
page_text = line
else:
page_text += line
def nextpage(self):
# Go to next page
if self.pageno < len(self.pages) - 1:
self.pageno += 1
self.redisplay()
def prevpage(self):
# Go to previous page
if self.pageno > 0:
self.pageno -= 1
self.redisplay()
def page(self, pagenum):
# Go to indicated page
if pagenum >= 0 and pagenum < len(self.pages):
self.pageno = pagenum
self.redisplay()
def close(self):
# pop down help window
self.withdraw()
def open(self):
# pop up help window
self.deiconify()
self.lift()