Files

138 lines
5.4 KiB
Python

"""Editor for ordered, copy-level LaTeX remarks."""
import tkinter as tk
from tkinter import messagebox, ttk
from copienator.general_remarks import remarks_for_copy, set_remarks
from .scores import score_path_for_id
class GeneralRemarksPanel(ttk.Frame):
def __init__(self, parent, evaluation, on_change):
super().__init__(parent)
self.evaluation, self.on_change = evaluation, on_change
self.busy = False
self.valid = False
self.remarks = []
self.id_var = tk.StringVar()
self.status_var = tk.StringVar()
self.columnconfigure(1, weight=1)
ttk.Label(self, text="Id de copie").grid(row=0, column=0, sticky="w")
self.id_entry = ttk.Entry(self, textvariable=self.id_var)
self.id_entry.grid(row=0, column=1, sticky="ew")
self.listbox = tk.Listbox(self, height=4, exportselection=False)
self.listbox.grid(row=1, column=0, columnspan=2, sticky="ew", pady=6)
self.listbox.bind("<<ListboxSelect>>", self.select)
self.editor = tk.Text(self, height=5, width=50, wrap="word", undo=True)
self.editor.grid(row=2, column=0, columnspan=2, sticky="ew")
actions = ttk.Frame(self)
actions.grid(row=3, column=0, columnspan=2, sticky="w", pady=6)
self.buttons = []
for text, command in (
("Nouvelle", self.new), ("Enregistrer", self.save),
("Supprimer", self.delete), ("Monter", lambda: self.move(-1)),
("Descendre", lambda: self.move(1)),
):
button = ttk.Button(actions, text=text, command=command)
button.pack(side="left", padx=(0, 5))
self.buttons.append(button)
ttk.Label(self, text="Texte LaTeX ; chaque remarque forme un paragraphe.").grid(
row=4, column=0, columnspan=2, sticky="w")
ttk.Label(self, textvariable=self.status_var, wraplength=650).grid(
row=5, column=0, columnspan=2, sticky="w", pady=6)
self.id_var.trace_add("write", self.load)
self.load()
def load(self, *_):
self.valid = False
self.remarks = []
try:
path = score_path_for_id(self.evaluation, self.id_var.get())
self.remarks = remarks_for_copy(self.evaluation, self.id_var.get())
self.valid = True
self.status_var.set(path.parent.name)
except (OSError, ValueError) as exc:
self.status_var.set(str(exc))
self.refresh()
self.set_busy(self.busy)
def refresh(self, index=None):
self.listbox.configure(state="normal")
self.listbox.delete(0, "end")
for i, text in enumerate(self.remarks, 1):
self.listbox.insert("end", f"{i}. {' '.join(text.split())}")
self.editor.configure(state="normal")
self.editor.delete("1.0", "end")
if index is not None:
self.listbox.selection_set(index)
self.listbox.see(index)
self.editor.insert("1.0", self.remarks[index])
self.editor.edit_reset()
def select(self, *_):
if self.busy:
return
selected = self.listbox.curselection()
if selected:
self.editor.delete("1.0", "end")
self.editor.insert("1.0", self.remarks[selected[0]])
self.editor.edit_reset()
def new(self):
if self.valid and not self.busy:
self.refresh()
self.editor.focus_set()
def commit(self, remarks, index=None):
try:
previous = set_remarks(self.evaluation, self.id_var.get(), remarks)
self.remarks = remarks
self.refresh(index)
if previous != remarks:
self.on_change(self.id_var.get(), previous, remarks)
self.status_var.set("Remarques enregistrées — lecture des annotations à revalider, « Régénérer » coché.")
except (OSError, ValueError) as exc:
messagebox.showerror("Remarques générales", str(exc))
def save(self):
if not self.valid or self.busy:
return
text = self.editor.get("1.0", "end-1c").strip()
if not text:
self.status_var.set("Saisissez une remarque ou utilisez « Supprimer ».")
return
remarks = self.remarks.copy()
selected = self.listbox.curselection()
index = selected[0] if selected else len(remarks)
if selected:
remarks[index] = text
else:
remarks.append(text)
self.commit(remarks, index)
def delete(self):
selected = self.listbox.curselection()
if self.valid and not self.busy and selected:
remarks = self.remarks.copy()
remarks.pop(selected[0])
self.commit(remarks)
def move(self, offset):
selected = self.listbox.curselection()
if not self.valid or self.busy or not selected:
return
index = selected[0]
target = index + offset
if 0 <= target < len(self.remarks):
remarks = self.remarks.copy()
remarks[index], remarks[target] = remarks[target], remarks[index]
self.commit(remarks, target)
def set_busy(self, busy):
self.busy = busy
self.id_entry.configure(state="disabled" if busy else "normal")
state = "normal" if self.valid and not busy else "disabled"
self.listbox.configure(state=state)
self.editor.configure(state=state)
for button in self.buttons:
button.configure(state=state)