Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions src/petab_gui/controllers/mother_controller.py
Original file line number Diff line number Diff line change
Expand Up @@ -444,6 +444,9 @@ def setup_actions(self):
actions["show_plot"] = QAction("Data Plot", self.view)
actions["show_plot"].setCheckable(True)
actions["show_plot"].setChecked(True)
actions["show_sbml_editor"] = QAction("SBML Editor", self.view)
actions["show_sbml_editor"].setCheckable(True)
actions["show_sbml_editor"].setChecked(True)

# What's This action
actions["whats_this"] = QAction(
Expand Down Expand Up @@ -536,6 +539,16 @@ def sync_visibility_with_actions(self):
action.toggled.connect(dock.setVisible)
dock.visibilityChanged.connect(action.setChecked)

# Connect SBML editor visibility toggle
sbml_action = self.actions["show_sbml_editor"]
sbml_widget = self.view.sbml_viewer.sbml_widget

# Store action reference in view for context menus
self.view.sbml_viewer.sbml_toggle_action = sbml_action

# Connect menu action to widget visibility
sbml_action.toggled.connect(sbml_widget.setVisible)

def save_model(self):
options = QFileDialog.Options()
file_name, filtering = QFileDialog.getSaveFileName(
Expand Down
3 changes: 2 additions & 1 deletion src/petab_gui/models/tooltips.py
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,8 @@ def cell_tip(table: str, column: str) -> str:
"<b>SBML (XML) view</b><br>"
"• Edit or paste valid SBML.<br>"
"• Use <i>Forward → Antimony</i> to sync.<br>"
"• Some constructs may not round-trip."
"• Some constructs may not round-trip.<br>"
"• Hide/show via <i>View → SBML Editor</i> menu."
)

ANTIMONY_VIEW_TOOLTIP = (
Expand Down
64 changes: 61 additions & 3 deletions src/petab_gui/views/sbml_view.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
"""Widget for viewing the SBML model."""

import qtawesome as qta
from PySide6.QtCore import Qt
from PySide6.QtWidgets import (
QLabel,
Expand All @@ -20,6 +21,9 @@ class SbmlViewer(QWidget):
def __init__(self, parent=None, logger_view=None):
super().__init__(parent)

# Reference to menu action (set by controller)
self.sbml_toggle_action = None

# Main layout for the SBML tab
layout = QVBoxLayout(self)
vertical_splitter = QSplitter(Qt.Vertical)
Expand All @@ -36,6 +40,11 @@ def __init__(self, parent=None, logger_view=None):
self.sbml_text_edit.setWhatsThis(
WHATS_THIS["sbml_view"]["sbml_editor"]
)
# Enable custom context menu
self.sbml_text_edit.setContextMenuPolicy(Qt.CustomContextMenu)
self.sbml_text_edit.customContextMenuRequested.connect(
self._show_sbml_context_menu
)
sbml_layout.addWidget(self.sbml_text_edit)

# Add forward changes button for SBML
Expand All @@ -51,21 +60,26 @@ def __init__(self, parent=None, logger_view=None):
self.sbml_text_edit.setWhatsThis(
WHATS_THIS["sbml_view"]["antimony_editor"]
)
# Enable custom context menu
self.antimony_text_edit.setContextMenuPolicy(Qt.CustomContextMenu)
self.antimony_text_edit.customContextMenuRequested.connect(
self._show_antimony_context_menu
)
antimony_layout.addWidget(self.antimony_text_edit)

# Add forward changes button for Antimony
self.forward_antimony_button = QPushButton("Forward Changes to SBML")
antimony_layout.addWidget(self.forward_antimony_button)

# Create widgets to hold SBML and Antimony sections
sbml_widget = QWidget()
sbml_widget.setLayout(sbml_layout)
self.sbml_widget = QWidget()
self.sbml_widget.setLayout(sbml_layout)

antimony_widget = QWidget()
antimony_widget.setLayout(antimony_layout)

# Add widgets to the splitter
splitter.addWidget(sbml_widget)
splitter.addWidget(self.sbml_widget)
splitter.addWidget(antimony_widget)

# Add the splitter to the main layout
Expand All @@ -75,3 +89,47 @@ def __init__(self, parent=None, logger_view=None):
layout.addWidget(vertical_splitter)
vertical_splitter.setStretchFactor(0, 7)
vertical_splitter.setStretchFactor(1, 3)

def _show_sbml_context_menu(self, position):
"""Show context menu for SBML text edit."""
if not self.sbml_toggle_action:
return

menu = self.sbml_text_edit.createStandardContextMenu()
menu.addSeparator()

# Add hide SBML option
hide_action = menu.addAction(
qta.icon("mdi6.chevron-left"), "Hide SBML Editor"
)
hide_action.triggered.connect(
lambda: self.sbml_toggle_action.setChecked(False)
)

menu.exec(self.sbml_text_edit.mapToGlobal(position))

def _show_antimony_context_menu(self, position):
"""Show context menu for Antimony text edit."""
if not self.sbml_toggle_action:
return

menu = self.antimony_text_edit.createStandardContextMenu()
menu.addSeparator()

# Add show/hide SBML option
if self.sbml_widget.isVisible():
action = menu.addAction(
qta.icon("mdi6.chevron-left"), "Hide SBML Editor"
)
action.triggered.connect(
lambda: self.sbml_toggle_action.setChecked(False)
)
else:
action = menu.addAction(
qta.icon("mdi6.chevron-right"), "Show SBML Editor"
)
action.triggered.connect(
lambda: self.sbml_toggle_action.setChecked(True)
)

menu.exec(self.antimony_text_edit.mapToGlobal(position))
1 change: 1 addition & 0 deletions src/petab_gui/views/task_bar.py
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,7 @@ def __init__(self, parent, actions):
self.menu.addAction(actions["show_plot"])
self.menu.addAction(actions["show_visualization"])
self.menu.addAction(actions["show_simulation"])
self.menu.addAction(actions["show_sbml_editor"])
self.menu.addSeparator()
self.menu.addAction(actions["reset_view"])
self.menu.addAction(actions["clear_log"])
Expand Down