self.view.set_student(name)
+def get_table_bookmarklet(records):
+ import html
+
+ rows = [
+ ['' if v is None else str(v) for v in r] for r in records
+ ]
+ table_html = (
+ '<table style="border:1px solid black;">'
+ + '<thead>'
+ + ''.join('<th>' + html.escape(h) + '</th>' for h in DataEditModel.Record.DISPLAY_NAMES)
+ + '</thead>'
+ + '<tbody>'
+ + ''.join(
+ '<tr>'
+ + ''.join('<td>' + v + '</td>' for v in row)
+ + '</tr>'
+ for row in rows
+ )
+ + '</tbody>'
+ + '</table>'
+ )
+ assert "'" not in table_html
+ js_table_literal = "'{}'".format(table_html)
+ return (
+ 'javascript:function(){document.querySelector(\'[contenteditable=\\\'true\\\']\')'
+ + '.innerHTML+=\'<br/>\'+' + js_table_literal + '+\'<br/>\';}()'
+ )
+
+
class MainView(View):
@contextmanager
def no_propagate(self, key):
center_on_parent(dialog, self.root)
self.gen_plot_btn = ttk.Button(actions_frame, text = "Generate plot", command = on_gen_plot)
+ def on_gen_table():
+ name = self.controller.state['student']
+ command = get_table_bookmarklet(self.controller.data[name])
+ self.root.clipboard_clear()
+ self.root.clipboard_append(command)
+ messagebox.showinfo(
+ "Table Command Copied",
+ "In Gmail, make sure you have a new message box open,"
+ + " then paste the command into the address bar and press Enter."
+ ,
+ )
+ self.gen_table_btn = ttk.Button(actions_frame, text = "Generate Gmail table", command = on_gen_table)
+
self.student_sel.pack(**TK_PAD, side = tk.LEFT)
add_student_btn.pack(**TK_PAD, side = tk.LEFT)
self.del_student_btn.pack(**TK_PAD, side = tk.LEFT)
self.student_frame.pack(**TK_PAD, fill = tk.X)
self.edit_data_btn.pack(**TK_PAD, fill = tk.X)
self.gen_plot_btn.pack(**TK_PAD, fill = tk.X)
+ self.gen_table_btn.pack(**TK_PAD, fill = tk.X)
actions_frame.pack(**TK_PAD, fill = tk.X)
self.editor_views = {}
self.del_student_btn,
self.edit_data_btn,
self.gen_plot_btn,
+ self.gen_table_btn,
]
for control in students_only:
control.configure(state = state)
's_time',
])
class Record(_Record):
+ DISPLAY_NAMES = [
+ "Comment",
+ "Score (E)", "Score (M)", "Score (R)", "Score (S)",
+ "Time (E)", "Time (M)", "Time (R)", "Time (S)",
+ ]
+
@classmethod
def parse(class_, strings):
if len(strings) != len(class_._fields):
cancel_btn.pack(side = 'left', **TK_PAD)
buttons.pack()
- col_names = [
- "Comment",
- "Score (E)", "Score (M)", "Score (R)", "Score (S)",
- "Time (E)", "Time (M)", "Time (R)", "Time (S)",
- ]
- labels = [tk.Label(self.grid, text = name, width = 10) for name in col_names]
+ label_for = lambda name: tk.Label(self.grid, text = name, width = 10)
+ labels = list(map(label_for, DataEditModel.Record.DISPLAY_NAMES))
for (col, label) in enumerate(labels):
label.grid(row = 0, column = col)
self.rows = OrderedDict()