Changeset 9b1abd2 in flexograder


Ignore:
Timestamp:
12/16/25 16:28:34 (4 months ago)
Author:
Enrico Schwass <ennoausberlin@…>
Branches:
fake-data, main, master
Children:
1a60982
Parents:
a14c6b0
Message:

fix some subtype issues, support png rendering via tk.PhotoImage and remove pillow - rename type to mtype attribute for media items

Files:
6 edited

Legend:

Unmodified
Added
Removed
  • builder/exam_elements.py

    ra14c6b0 r9b1abd2  
    9797        super()._deserialize_content(content)
    9898        self.topic = content.get("topic", "")
     99        self.subtopic = content.get("subtopic", "")
    99100        self.text = content.get("text", "")
    100101        self.media = [media_factory(m) for m in content.get("media", [])]
     
    103104        base = super()._serialize_content()
    104105        base["topic"] = self.topic
     106        base["subtopic"] = self.subtopic
    105107        base["text"] = self.text
    106108        base["media"] = [m.to_dict() for m in self.media]
     
    111113
    112114    def get_media(self):
    113         return [item for item in self.media]
     115        return list(self.media)
    114116
    115117
  • builder/media_items.py

    ra14c6b0 r9b1abd2  
    3636
    3737    @property
    38     def type(self) -> str:
     38    def mtype(self) -> str:
    3939        # logical type used for JSON, defaults to mtype
    4040        return self.mtype
     
    5757            "title": self.title,
    5858            "caption": self.caption,
    59             "type": self.type,
     59            "mtype": self.mtype,
    6060        })
    6161        return base
     
    8686
    8787    @property
    88     def type(self):
     88    def mtype(self):
    8989        return "image"
    9090
     
    9595class AudioItem(MediaItem):
    9696    @property
    97     def type(self):
     97    def mtype(self):
    9898        return "audio"
    9999
     
    104104class VideoItem(MediaItem):
    105105    @property
    106     def type(self):
     106    def mtype(self):
    107107        return "video"
    108108
     
    140140
    141141    @property
    142     def type(self):
     142    def mtype(self):
    143143        return "none"
    144144
     
    147147
    148148def media_factory(m: dict) -> MediaItem:
    149     print("Dict:", m)
    150149    mtype = m.get("mtype", "").lower()
    151150
  • gui/attach_media_dialog.py

    ra14c6b0 r9b1abd2  
    55
    66class AttachMediaDialog(tk.Toplevel):
    7     def __init__(self, parent, question_dict):
     7    def __init__(self, parent, media_list):
    88        super().__init__(parent)
    99        self.title("Media attachments")
    10         self.question_dict = question_dict
     10        self.media_list = media_list
    1111        self.result = []
    1212        # Ensure media list exists
    13         self.media_list = question_dict.get("media", [])
    1413        self.resizable(False, False)
    1514
     
    1918
    2019        for m in self.media_list:
     20            print(m)
    2121            mtype = str(m.get("mtype", "unknown")).upper()
    2222            src = m.get("src", "?")
     
    5252        media_entry = {"mtype": mtype, "src": path}
    5353        self.media_list.append(media_entry)
    54         print("List:", self.media_list)
    5554        self.listbox.insert(tk.END, f"{mtype.upper()}: {path}")
    5655
     
    6867    def on_ok(self):
    6968        """Return the final edited media list."""
    70         print("OK:", self.media_list)
    7169        self.result = self.media_list
    7270        self.destroy()
  • gui/detail_panel.py

    ra14c6b0 r9b1abd2  
    22from tkinter import ttk
    33import tkinter.font as tkfont
    4 from PIL import Image, ImageTk
     4# from PIL import Image, ImageTk
    55
    66class DetailPanel(ttk.Frame):
     
    2727        self.font_question = tkfont.Font(family="TkDefaultFont", size=13)
    2828        self.txt_question.configure(font=self.font_question)
     29
     30        # ─────────────────────────── Topic / Subtopic ─────────────────────────
     31        topic_frame = ttk.Frame(self)
     32        topic_frame.grid(row=2, column=0, sticky="ew", pady=(0, 4))
     33        topic_frame.columnconfigure(1, weight=1)
     34
     35        ttk.Label(topic_frame, text="Topic:", foreground="#555").grid(
     36            row=0, column=0, sticky="w"
     37        )
     38
     39        self.lbl_topic = ttk.Label(
     40            topic_frame,
     41            text="—",
     42            foreground="#555"
     43        )
     44        self.lbl_topic.grid(row=0, column=1, sticky="w")
     45
    2946        # ─────────────────────────── Metadata ────────────────────────────────
    3047        meta = ttk.LabelFrame(self, text="Metadata", padding=(6, 4))
    31         meta.grid(row=2, column=0, sticky="ew", pady=(0, 4))
     48        meta.grid(row=3, column=0, sticky="ew", pady=(0, 4))
    3249        meta.columnconfigure(1, weight=1)
    3350
    34         ttk.Label(meta, text="Type:").grid(row=0, column=0, sticky="w")
     51        ttk.Label(meta, text="Type:").grid(row=4, column=0, sticky="w")
    3552        self.lbl_type = ttk.Label(meta, text="—")
    3653        self.lbl_type.grid(row=0, column=1, sticky="w")
     
    5269        self.img_frame.grid(row=3, column=0, sticky="nsew", pady=(0, 4))
    5370        self.img_frame.columnconfigure(0, weight=1)
    54         self.rowconfigure(3, weight=3)  # allow preview area to expand
    5571
    56         self.img_label = ttk.Label(self.img_frame, anchor="center")
     72        self.img_frame.rowconfigure(0, weight=1)
     73        self.img_frame.columnconfigure(0, weight=1)
     74
     75        self.img_label = ttk.Label(
     76            self.img_frame,
     77            anchor="center",
     78            relief="sunken"
     79        )
    5780        self.img_label.grid(row=0, column=0, sticky="nsew")
    5881
     
    86109        """Load an image from disk and resize to fit preview area."""
    87110        try:
    88             img = Image.open(img_path)
     111            img = tk.PhotoImage(file=img_path)
    89112        except Exception:
    90113            return None
    91114
    92         img.thumbnail((self.MAX_IMG_WIDTH, self.MAX_IMG_HEIGHT), Image.Resampling.LANCZOS)
    93         return ImageTk.PhotoImage(img)
     115        w = img.width()
     116        h = img.height()
     117
     118        # Compute integer subsample factor
     119        scale_w = max(1, w // self.MAX_IMG_WIDTH)
     120        scale_h = max(1, h // self.MAX_IMG_HEIGHT)
     121        scale = max(scale_w, scale_h)
     122
     123        if scale > 1:
     124            img = img.subsample(scale, scale)
     125
     126        return img
    94127
    95128    # ───────────────────────────────────────────────────────────────────────
     
    101134
    102135        # Clear image preview
    103         self.img_label.configure(image="")
     136
    104137        self._image_ref = None
     138        self.img_label.configure(image=None)
    105139
    106140        # Clear answers
     
    111145            # Question text
    112146            self.txt_question.insert("1.0", question.text)
     147
     148            topic = getattr(question, "topic", None)
     149            subtopic = getattr(question, "subtopic", None)
     150
     151            if topic and subtopic:
     152                self.lbl_topic.config(text=f"{topic} › {subtopic}")
     153            elif topic:
     154                self.lbl_topic.config(text=topic)
     155            else:
     156                self.lbl_topic.config(text="—")
    113157
    114158            # Metadata
     
    134178
    135179        else:
     180            self.lbl_topic.config(text="—")
    136181            self.lbl_type.config(text="—")
    137182            self.lbl_state.config(text="—")
  • gui/option_question_editor.py

    ra14c6b0 r9b1abd2  
    111111
    112112    def open_media_dialog(self):
    113         dlg = AttachMediaDialog(self, self.question_dict)
     113        dlg = AttachMediaDialog(self, self.content.get("media", []))
    114114        dlg.grab_set()
    115115        self.wait_window(dlg)
    116116
    117117        if dlg.result is not None:
    118             # ensure target structure exists
    119             if "media" not in self.question_dict:
    120                 self.question_dict["media"] = []
    121 
    122118            # overwrite old list
    123119            self.question_dict["media"] = dlg.result
     
    135131
    136132        content = {"text": text,
    137                    "options": self.content.get("options", {}),
     133                   "options": self.content.get("options", []),
    138134                   "media": self.content.get("media", [])
    139135                   }
     
    144140            "version": self.meta.get("version", 1),
    145141            "domain_id": self.domain_var.get(),
    146             "subtype": self.meta["subtype"]
    147142        }
    148143
  • scripts/import3.py

    ra14c6b0 r9b1abd2  
    8686                    "answers": {},
    8787                    "domain": current_domain,
    88                     "topic": current_topic,
    89                     "subtopic": current_subtopic,
     88                    "topic": current_topic["title"] if current_topic is not None else None,
     89                    "subtopic": current_subtopic["title"] if current_subtopic is not None else None,
    9090                }
    9191                continue
     
    110110    # ---- Print results for debugging ----
    111111
    112     print(domains)
    113 
    114112    for q in questions:
    115113        options = [
     
    118116        ]
    119117        if not options:
    120             print(f"Warning: {q['qid']} has no answer options — inserting placeholder.")
     118            print(f"Warning: {q['qid']} has no answer options — inserting placeholder.")
    121119            options = [AnswerOption(id="A", text="(keine Antwortoptionen gefunden)")]
    122120        else:
     
    126124                                                      text=q["text"],
    127125                                                      topic=q["topic"],
    128                                                       subtopic=["subtopic"],
     126                                                      subtopic=q["subtopic"],
    129127                                                      options=options)
    130128        question_catalog.add_questions([current])
Note: See TracChangeset for help on using the changeset viewer.