From: Jakob Cornell Date: Sun, 12 Jan 2020 20:05:51 +0000 (-0600) Subject: Use clipboard for exporting tables X-Git-Url: https://jcornell.net/gitweb/gitweb.cgi?a=commitdiff_plain;h=1b88279e705874fbb5a37ceff286876972d03f31;p=tutoring-tool.git Use clipboard for exporting tables --- diff --git a/main.py b/main.py index 96f22b6..69abf53 100644 --- a/main.py +++ b/main.py @@ -1,11 +1,9 @@ from collections import defaultdict, namedtuple, OrderedDict from contextlib import contextmanager from enum import Enum -import http.server import itertools import json from matplotlib import pyplot -from threading import Thread import tkinter as tk from tkinter import ttk @@ -16,6 +14,46 @@ from tkinter import ( ) +def win_write_clipboard_html(text): + import win32clipboard as clip + fmt = clip.RegisterClipboardFormat('HTML Format') + + @contextmanager + def open_clipboard(): + clip.OpenClipboard() + yield + clip.CloseClipboard() + + def compute_payload(text): + header = '\r\n'.join( + 'Version:0.9', + 'StartHTML:{}', + 'EndHTML:{}', + 'StartFragment:{}', + 'EndFragment:{}', + '', + ) + pre = ''.encode('utf-8') + post = ''.encode('utf-8') + def offsets_for(header_len): + return ( + header_len, + header_len + len(pre + text + post), + header_len + len(pre), + header_len + len(pre + text), + ) + get_hdr = lambda offsets: header.format(*offsets).encode('utf-8') + offsets = offsets_for(0) + need_len = len(get_hdr(offsets)) + while need_len != offsets[0]: + offsets = offsets_for(need_len) + need_len = len(get_hdr(offsets)) + return get_hdr(offsets) + pre + text + post + + with open_clipboard(): + clip.SetClipboardData(fmt, compute_payload(text.encode('utf-8'))) + + TK_PAD = {'padx': 5, 'pady': 5} def center_on_parent(child, parent): @@ -273,6 +311,8 @@ class MainView(View): self.gen_plot_btn = ttk.Button(actions_frame, text = "Generate plot", command = on_gen_plot) def on_gen_table(): + from xml.etree import ElementTree + name = self.controller.state['student'] head = list(DataEditModel.Record.DISPLAY_NAMES) head.insert(5, "Score (Comp)") @@ -280,16 +320,24 @@ class MainView(View): new = list(record) new.insert(5, round(record.overall_score(), 1)) return new - rows = [head] + list(map(with_composite, self.controller.data[name])) - data = json.dumps(rows).encode('utf-8') - server = AsyncHttpServer(57853, data) - server.start() - messagebox.showinfo( - "Serving Table Data…", - "Table data is ready to be transferred to your browser. You may close this dialog when the transfer is complete.", - ) - server.stop() - self.gen_table_btn = ttk.Button(actions_frame, text = "Export table", command = on_gen_table) + rows = map(with_composite, self.controller.data[name]) + rows = [ + ['' if v is None else str(v) for v in row] + for row in rows + ] + + table = Et.Element('table') + thead = Et.SubElement(table, 'thead') + for v in head: + Et.SubElement(thead, 'th').text = v + tbody = Et.SubElement(table, 'tbody') + for row in rows: + tr = Et.SubElement(tbody, 'tr') + for v in row: + Et.SubElement(tr, 'td').text = v + + win_write_clipboard_html(Et.dump(table)) + self.gen_table_btn = ttk.Button(actions_frame, text = "Copy table to clipboard", command = on_gen_table) self.student_sel.pack(**TK_PAD, side = tk.LEFT) add_student_btn.pack(**TK_PAD, side = tk.LEFT)