Skip to content

Commit b302fe2

Browse files
committed
SBML export
1 parent 78f9853 commit b302fe2

File tree

2 files changed

+57
-1
lines changed

2 files changed

+57
-1
lines changed

src/petab_gui/controllers/mother_controller.py

Lines changed: 46 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -341,6 +341,10 @@ def setup_actions(self):
341341
qta.icon("mdi6.table-arrow-down"), "Save This Table", self.view
342342
)
343343
actions["save_single_table"].triggered.connect(self.save_single_table)
344+
actions["save_sbml"] = QAction(
345+
qta.icon("mdi6.file-code"), "Export SBML Model", self.view
346+
)
347+
actions["save_sbml"].triggered.connect(self.save_sbml_model)
344348
# Find + Replace
345349
actions["find"] = QAction(qta.icon("mdi6.magnify"), "Find", self.view)
346350
actions["find"].setShortcut(QKeySequence.Find)
@@ -574,6 +578,7 @@ def sync_visibility_with_actions(self):
574578

575579
# Store action reference in view for context menus
576580
self.view.sbml_viewer.sbml_toggle_action = sbml_action
581+
self.view.sbml_viewer.save_sbml_action = self.actions["save_sbml"]
577582

578583
# Connect menu action to widget visibility
579584
sbml_action.toggled.connect(sbml_widget.setVisible)
@@ -655,6 +660,40 @@ def save_single_table(self):
655660
active_controller.save_table(file_name)
656661
return True
657662

663+
def save_sbml_model(self):
664+
"""Export the SBML model to an XML file."""
665+
if not self.model.sbml or not self.model.sbml.sbml_text:
666+
QMessageBox.warning(
667+
self.view,
668+
"Export SBML Model",
669+
"No SBML model to export.",
670+
)
671+
return False
672+
673+
file_name, _ = QFileDialog.getSaveFileName(
674+
self.view,
675+
"Export SBML Model",
676+
f"{self.model.sbml.model_id}.xml",
677+
"SBML Files (*.xml *.sbml);;All Files (*)",
678+
)
679+
if not file_name:
680+
return False
681+
682+
try:
683+
with open(file_name, "w") as f:
684+
f.write(self.model.sbml.sbml_text)
685+
self.logger.log_message(
686+
"SBML model exported successfully to file.", color="green"
687+
)
688+
return True
689+
except Exception as e:
690+
QMessageBox.critical(
691+
self.view,
692+
"Export SBML Model",
693+
f"Failed to export SBML model: {e}",
694+
)
695+
return False
696+
658697
def handle_selection_changed(self):
659698
"""Update the plot when selection in the measurement table changes."""
660699
self.update_plot()
@@ -736,12 +775,18 @@ def open_file(self, file_path=None, mode=None):
736775
return
737776
# handle file appropriately
738777
actionable, sep = process_file(file_path, self.logger)
739-
if actionable in ["yaml", "sbml", "omex"] and mode == "append":
778+
if actionable in ["yaml", "omex"] and mode == "append":
740779
self.logger.log_message(
741780
f"Append mode is not supported for *.{actionable} files.",
742781
color="red",
743782
)
744783
return
784+
if actionable in ["sbml"] and mode == "append":
785+
self.logger.log_message(
786+
"Append mode is not supported for SBML models.",
787+
color="orange",
788+
)
789+
return
745790
if not actionable:
746791
return
747792
if mode is None:

src/petab_gui/views/sbml_view.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ def __init__(self, parent=None, logger_view=None):
2323

2424
# Reference to menu action (set by controller)
2525
self.sbml_toggle_action = None
26+
self.save_sbml_action = None
2627

2728
# Main layout for the SBML tab
2829
layout = QVBoxLayout(self)
@@ -98,6 +99,11 @@ def _show_sbml_context_menu(self, position):
9899
menu = self.sbml_text_edit.createStandardContextMenu()
99100
menu.addSeparator()
100101

102+
# Add export SBML option
103+
if self.save_sbml_action:
104+
menu.addAction(self.save_sbml_action)
105+
menu.addSeparator()
106+
101107
# Add hide SBML option
102108
hide_action = menu.addAction(
103109
qta.icon("mdi6.chevron-left"), "Hide SBML Editor"
@@ -116,6 +122,11 @@ def _show_antimony_context_menu(self, position):
116122
menu = self.antimony_text_edit.createStandardContextMenu()
117123
menu.addSeparator()
118124

125+
# Add export SBML option
126+
if self.save_sbml_action:
127+
menu.addAction(self.save_sbml_action)
128+
menu.addSeparator()
129+
119130
# Add show/hide SBML option
120131
if self.sbml_widget.isVisible():
121132
action = menu.addAction(

0 commit comments

Comments
 (0)