Changeset 7cc3672 in flexograder
- Timestamp:
- 11/12/25 20:42:55 (5 months ago)
- Branches:
- fake-data, main, master
- Children:
- aaaa4b8
- Parents:
- f8e1cf8
- Files:
-
- 4 edited
-
builder/catalog_manager.py (modified) (1 diff)
-
gui/gui.py (modified) (8 diffs)
-
gui/menu.py (modified) (1 diff)
-
gui/session_manager.py (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
builder/catalog_manager.py
rf8e1cf8 r7cc3672 165 165 # Delete files matching pattern 166 166 for file in self._base_path.glob(f"*{catalog_id}*.json"): 167 print(file) 167 168 try: 168 169 file.unlink() -
gui/gui.py
rf8e1cf8 r7cc3672 5 5 from pathlib import Path 6 6 from datetime import datetime 7 from flexoentity import FlexOID 7 from flexoentity import FlexOID, logger 8 8 from builder.exam import Exam 9 9 from builder.question_catalog import QuestionCatalog … … 65 65 66 66 def refresh_all(self): 67 67 68 self.refresh_catalog_list() 68 69 self.refresh_exam_list() … … 72 73 self.detail_panel.refresh_details(self.require_selected_question(), 73 74 self.require_active_catalog()) 74 @property75 def active_catalog(self):76 """Return the currently active catalog, or None if none is set."""77 return self.catalog_manager.get_active()78 79 def require_active_catalog(self):80 """Return the active catalog, or show a message and return None."""81 active = self.active_catalog82 if not active:83 messagebox.showinfo("No Catalog", "Please create or open a catalog first.")84 return active85 86 75 def create_widgets(self): 87 76 self.columnconfigure(0, weight=2, uniform="columns") … … 126 115 self.recent_actions_var.set(" | ".join(self._recent_actions)) 127 116 128 def export_catalog(self): 129 """Export the currently active catalog to a JSON file.""" 130 catalog = self.catalog_manager.get_active() 131 if not catalog: 132 messagebox.showwarning("No Catalog", "No active catalog to export.") 133 return 134 135 # Ask for a file location 136 file_path = filedialog.asksaveasfilename( 137 defaultextension=".json", 138 file_types=[("JSON files", "*.json"), ("All files", "*.*")], 139 title="Export Catalog As" 140 ) 141 if not file_path: 142 return # user cancelled 143 144 try: 145 # Get catalog data as dict or JSON string 146 data = catalog.to_dict() if hasattr(catalog, "to_dict") else catalog 147 Path(file_path).write_text(json.dumps(data, indent=2, ensure_ascii=False)) 148 messagebox.showinfo("Export Successful", f"Catalog exported to:\n{file_path}") 149 except Exception as e: 150 messagebox.showerror("Export Failed", f"Error exporting catalog:\n{e}") 151 152 def open_catalog(self): 153 path = filedialog.askopenfilename(filetypes=[("Catalog JSON", "*.json")]) 154 if not path: 155 return 156 157 with open(path, "r", encoding="utf-8") as f: 158 data = json.load(f) 159 160 catalog = QuestionCatalog.from_dict(data) 161 title = simpledialog.askstring("New Catalog", "Enter title:", parent=self) 162 catalog.title = title 163 self.catalog_manager.add_catalog(catalog) 164 self.catalog_manager.set_active(catalog.flexo_id) 165 self.refresh_all() 166 167 def refresh_catalog_list(self): 168 self.catalog_dropdown["values"] = self.catalog_manager.list_titles() 169 self.catalog_var.set(self.catalog_manager.get_active_display_title()) 170 171 def refresh_status_bar(self): 172 current_catalog = self.active_catalog 173 if not current_catalog: 174 self.status_var.set("No catalog loaded") 175 return 176 q_count = len(current_catalog.questions) 177 title = current_catalog.title 178 version = current_catalog.version 179 status = ( 180 f"Catalog: {title} | Version: {version} | Questions: {q_count} | " 181 f"Status: {current_catalog.status_text}" 182 ) 183 self.status_var.set(status) 117 def on_catalog_selected(self, event=None): 118 """Called when the user selects a catalog from the dropdown.""" 119 title = self.catalog_var.get() 120 if not title: 121 return 122 self.catalog_manager.set_active_by_title(title) 123 124 self.refresh_all() 125 self.log_action(f"Catalog Switched - Active catalog: {title}") 184 126 185 127 @property 186 def questions(self): 187 if not self.active_catalog: 188 return [] 189 # Always provide deterministic order (e.g. by question ID) 190 return sorted(self.active_catalog.questions, key=lambda q: q.id) 128 def active_catalog(self): 129 """Return the currently active catalog, or None if none is set.""" 130 return self.catalog_manager.get_active() 131 132 def require_active_catalog(self): 133 """Return the active catalog, or show a message and return None.""" 134 active = self.active_catalog 135 if not active: 136 messagebox.showinfo("No Catalog", "Please create or open a catalog first.") 137 return active 191 138 192 139 def create_catalog(self): … … 214 161 self.refresh_all() 215 162 163 def export_catalog(self): 164 """Export the currently active catalog to a JSON file.""" 165 catalog = self.catalog_manager.get_active() 166 if not catalog: 167 messagebox.showwarning("No Catalog", "No active catalog to export.") 168 return 169 170 # Ask for a file location 171 file_path = filedialog.asksaveasfilename( 172 defaultextension=".json", 173 file_types=[("JSON files", "*.json"), ("All files", "*.*")], 174 title="Export Catalog As" 175 ) 176 if not file_path: 177 return # user cancelled 178 179 try: 180 # Get catalog data as dict or JSON string 181 data = catalog.to_dict() if hasattr(catalog, "to_dict") else catalog 182 Path(file_path).write_text(json.dumps(data, indent=2, 183 encoding="utf-8", 184 ensure_ascii=False)) 185 messagebox.showinfo("Export Successful", f"Catalog exported to:\n{file_path}") 186 except Exception as e: 187 messagebox.showerror("Export Failed", f"Error exporting catalog:\n{e}") 188 189 def open_catalog(self): 190 path = filedialog.askopenfilename(filetypes=[("Catalog JSON", "*.json")]) 191 if not path: 192 return 193 194 with open(path, "r", encoding="utf-8") as f: 195 data = json.load(f) 196 197 catalog = QuestionCatalog.from_dict(data) 198 title = simpledialog.askstring("New Catalog", "Enter title:", parent=self) 199 catalog.title = title 200 self.catalog_manager.add_catalog(catalog) 201 self.catalog_manager.set_active(catalog.flexo_id) 202 self.refresh_all() 203 204 def close_catalog(self): 205 if not self.catalog_manager.catalogs: 206 messagebox.showerror("Catalog not found", "No catalog left") 207 return 208 self.catalog_manager.delete(self.active_catalog.flexo_id) 209 titles = self.catalog_manager.list_titles() 210 if len(titles) == 0: 211 logger.info("No catalog left") 212 self.catalog_dropdown["values"] = [] 213 self.catalog_var.set("") 214 else: 215 self.catalog_dropdown["values"] = self.catalog_manager.list_titles() 216 self.catalog_var.set(titles[0]) 217 self.catalog_manager.set_active_by_title(titles[0]) 218 self.question_tree.selection_remove(self.question_tree.selection()) 219 self.refresh_all() 220 221 def refresh_catalog_list(self): 222 self.catalog_dropdown["values"] = self.catalog_manager.list_titles() 223 self.catalog_var.set(self.catalog_manager.get_active_display_title()) 224 225 def refresh_status_bar(self): 226 current_catalog = self.active_catalog 227 if not current_catalog: 228 self.status_var.set("No catalog loaded") 229 return 230 q_count = len(current_catalog.questions) 231 title = current_catalog.title 232 version = current_catalog.version 233 status = ( 234 f"Catalog: {title} | Version: {version} | Questions: {q_count} | " 235 f"Status: {current_catalog.status_text}" 236 ) 237 self.status_var.set(status) 238 239 @property 240 def questions(self): 241 if not self.active_catalog: 242 return [] 243 # Always provide deterministic order (e.g. by question ID) 244 return sorted(self.active_catalog.questions, key=lambda q: q.id) 245 216 246 def create_exam_dialog(self): 217 247 dialog = ExamDialog(self) … … 222 252 ) 223 253 self.refresh_all() 224 225 def on_catalog_selected(self, event=None):226 """Called when the user selects a catalog from the dropdown."""227 title = self.catalog_var.get()228 if not title:229 return230 self.catalog_manager.set_active_by_title(title)231 232 self.refresh_all()233 self.log_action(f"Catalog Switched - Active catalog: {title}")234 254 235 255 def on_exam_selected(self, event): … … 379 399 dlg = ExamLayoutDialog(self, exam) 380 400 self.wait_window(dlg) 381 print(exam)382 401 self.session.save(self.geometry()) 383 402 … … 430 449 self.question_tree.delete(*self.question_tree.get_children()) 431 450 432 active = self. require_active_catalog()451 active = self.active_catalog 433 452 if not active: 434 453 self.question_tree.insert("", "end", iid="__none__", -
gui/menu.py
rf8e1cf8 r7cc3672 18 18 catalog_menu.add_command(label="Create Catalog", command=parent.create_catalog) 19 19 catalog_menu.add_command(label="Open Catalog", command=parent.open_catalog) 20 catalog_menu.add_command(label="Close Catalog", command=parent.close_catalog) 20 21 self.add_cascade(label="Catalogs", menu=catalog_menu) 21 22 -
gui/session_manager.py
rf8e1cf8 r7cc3672 35 35 if isinstance(each.flexo_id, str): 36 36 print(f"[WARN] Catalog {each.title} has string flexo_id: {each.flexo_id}") 37 path.write_text(json.dumps(each.to_dict(), indent=2, ensure_ascii=False)) 37 path.write_text(json.dumps(each.to_dict(), indent=2, ensure_ascii=False), 38 encoding="utf-8") 38 39 39 40 # 3. Save metadata … … 44 45 "timestamp": timestamp, 45 46 } 46 self.session_file.write_text(json.dumps(data, encoding="utf-8", indent=2))47 self.session_file.write_text(json.dumps(data, indent=2), encoding="utf-8") 47 48 print(f"[Session] Saved at {timestamp}") 48 49 except Exception as e:
Note:
See TracChangeset
for help on using the changeset viewer.
