diff --git a/activity_browser/actions/__init__.py b/activity_browser/actions/__init__.py index 823e83cc3..610eb992f 100644 --- a/activity_browser/actions/__init__.py +++ b/activity_browser/actions/__init__.py @@ -30,6 +30,7 @@ from .method.method_duplicate import MethodDuplicate from .method.method_delete import MethodDelete +from .method.method_open import MethodOpen from .method.cf_uncertainty_modify import CFUncertaintyModify from .method.cf_amount_modify import CFAmountModify diff --git a/activity_browser/actions/method/method_open.py b/activity_browser/actions/method/method_open.py new file mode 100644 index 000000000..480fadee7 --- /dev/null +++ b/activity_browser/actions/method/method_open.py @@ -0,0 +1,26 @@ +from typing import List + +from PySide2 import QtWidgets, QtCore + +from activity_browser import signals +from activity_browser.actions.base import ABAction, exception_dialogs +from activity_browser.ui.icons import qicons + + +class MethodOpen(ABAction): + """ + ABAction to open one or more supplied methods in a method tab by employing signals. + + TODO: move away from using signals like this. Probably add a method to the MainWindow to add a panel instead. + """ + + icon = qicons.right + text = "Open Impact Category" + + @staticmethod + @exception_dialogs + def run(method_names: List[tuple]): + QtWidgets.QApplication.setOverrideCursor(QtCore.Qt.WaitCursor) + for method_name in method_names: + signals.method_selected.emit(method_name) + QtWidgets.QApplication.restoreOverrideCursor() diff --git a/activity_browser/ui/tables/LCA_setup.py b/activity_browser/ui/tables/LCA_setup.py index f17f47bc3..57b9a4b29 100644 --- a/activity_browser/ui/tables/LCA_setup.py +++ b/activity_browser/ui/tables/LCA_setup.py @@ -1,7 +1,7 @@ from PySide2 import QtWidgets from PySide2.QtCore import Qt, Slot -from activity_browser import log, signals +from activity_browser import log, signals, actions from activity_browser.mod.bw2data import calculation_setups from ..icons import qicons @@ -174,6 +174,8 @@ def __init__(self, parent=None): "Hold CTRL and click to select multiple rows to open or delete them." ) + self.open_method_action = actions.MethodOpen.get_QAction(self.selected_methods) + def to_python(self): return self.model.methods @@ -195,11 +197,14 @@ def contextMenuEvent(self, event) -> None: if self.indexAt(event.pos()).row() == -1: return menu = QtWidgets.QMenu() + + menu.addAction(self.open_method_action) menu.addAction( qicons.delete, - "Remove row", + "Remove rows", lambda: self.model.delete_rows(self.selectedIndexes()), ) + menu.exec_(event.globalPos()) def dragEnterEvent(self, event): @@ -225,6 +230,9 @@ def dropEvent(self, event): ): self.model.relocateRow(from_index, to_index) + def selected_methods(self): + return [self.model.get_method(p) for p in self.selectedIndexes() if p.column() == 0] + class ScenarioImportTable(ABDataFrameView): """Self-contained widget that shows the scenario headers for a given diff --git a/activity_browser/ui/tables/models/lca_setup.py b/activity_browser/ui/tables/models/lca_setup.py index 9a4341d10..ea907b30c 100644 --- a/activity_browser/ui/tables/models/lca_setup.py +++ b/activity_browser/ui/tables/models/lca_setup.py @@ -1,4 +1,4 @@ -from typing import Iterable +from typing import Iterable, List, Union import numpy as np import pandas as pd @@ -192,6 +192,13 @@ def methods(self) -> list: else self._dataframe.loc[:, "method"].to_list() ) + def get_method(self, proxy: Union[QModelIndex, int]) -> tuple: + """ + Return the method coupled to a model index + """ + idx = self.proxy_to_source(proxy) + return self._dataframe["method"][idx.row()] + def load(self, cs_name: str = None) -> None: """ Load a calculation setup defined by cs_name into the methods table.