From c761a3f8b42f05b930ec992ef7061601c5e7b892 Mon Sep 17 00:00:00 2001 From: PaulJonasJost Date: Wed, 14 Jan 2026 10:37:37 +0100 Subject: [PATCH 1/2] possibility to hide SBML view. --- src/petab_gui/controllers/mother_controller.py | 8 ++++++++ src/petab_gui/views/sbml_view.py | 6 +++--- src/petab_gui/views/task_bar.py | 1 + 3 files changed, 12 insertions(+), 3 deletions(-) diff --git a/src/petab_gui/controllers/mother_controller.py b/src/petab_gui/controllers/mother_controller.py index fc2ea85..030cb17 100644 --- a/src/petab_gui/controllers/mother_controller.py +++ b/src/petab_gui/controllers/mother_controller.py @@ -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( @@ -536,6 +539,11 @@ 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 + sbml_action.toggled.connect(sbml_widget.setVisible) + def save_model(self): options = QFileDialog.Options() file_name, filtering = QFileDialog.getSaveFileName( diff --git a/src/petab_gui/views/sbml_view.py b/src/petab_gui/views/sbml_view.py index 4363f4f..fb19f1f 100644 --- a/src/petab_gui/views/sbml_view.py +++ b/src/petab_gui/views/sbml_view.py @@ -58,14 +58,14 @@ def __init__(self, parent=None, logger_view=None): 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 diff --git a/src/petab_gui/views/task_bar.py b/src/petab_gui/views/task_bar.py index 408221c..99e528b 100644 --- a/src/petab_gui/views/task_bar.py +++ b/src/petab_gui/views/task_bar.py @@ -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"]) From ecd60873287c7f3bae1839c3b2d1af81c59e0e01 Mon Sep 17 00:00:00 2001 From: PaulJonasJost Date: Wed, 14 Jan 2026 15:37:25 +0100 Subject: [PATCH 2/2] Allow hiding via rightclick, added as tooltip --- .../controllers/mother_controller.py | 5 ++ src/petab_gui/models/tooltips.py | 3 +- src/petab_gui/views/sbml_view.py | 58 +++++++++++++++++++ 3 files changed, 65 insertions(+), 1 deletion(-) diff --git a/src/petab_gui/controllers/mother_controller.py b/src/petab_gui/controllers/mother_controller.py index 030cb17..a56efd1 100644 --- a/src/petab_gui/controllers/mother_controller.py +++ b/src/petab_gui/controllers/mother_controller.py @@ -542,6 +542,11 @@ def sync_visibility_with_actions(self): # 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): diff --git a/src/petab_gui/models/tooltips.py b/src/petab_gui/models/tooltips.py index 396b3ea..3cb2ff6 100644 --- a/src/petab_gui/models/tooltips.py +++ b/src/petab_gui/models/tooltips.py @@ -177,7 +177,8 @@ def cell_tip(table: str, column: str) -> str: "SBML (XML) view
" "• Edit or paste valid SBML.
" "• Use Forward → Antimony to sync.
" - "• Some constructs may not round-trip." + "• Some constructs may not round-trip.
" + "• Hide/show via View → SBML Editor menu." ) ANTIMONY_VIEW_TOOLTIP = ( diff --git a/src/petab_gui/views/sbml_view.py b/src/petab_gui/views/sbml_view.py index fb19f1f..1b1bc62 100644 --- a/src/petab_gui/views/sbml_view.py +++ b/src/petab_gui/views/sbml_view.py @@ -1,5 +1,6 @@ """Widget for viewing the SBML model.""" +import qtawesome as qta from PySide6.QtCore import Qt from PySide6.QtWidgets import ( QLabel, @@ -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) @@ -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 @@ -51,6 +60,11 @@ 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 @@ -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))