diff --git a/src/View/Network/ContextMenu.py b/src/View/Network/ContextMenu.py new file mode 100644 index 0000000000000000000000000000000000000000..4e29fefe5d562177de7575166a5c18b9980cd493 --- /dev/null +++ b/src/View/Network/ContextMenu.py @@ -0,0 +1,84 @@ +# ContextMenu.py -- Pamhyr +# Copyright (C) 2024 INRAE +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <https://www.gnu.org/licenses/>. + +# -*- coding: utf-8 -*- + +from PyQt5.QtWidgets import ( + QMenu, +) + + +class AbstractMenu(object): + def __init__(self, event=None, pos=None, items=[], + trad=None, parent=None): + super(AbstractMenu, self).__init__() + + self._menu = QMenu(parent) + self._event = event + self._pos = pos + self._items = items + + self._trad = trad + self._parent = parent + + def map_to_global(self): + return self._parent.mapToGlobal(self._event.pos()) + + def _exec(self): + return self._menu.exec_(self.map_to_global()) + + def run(self): + return + + +class DefaultMenu(AbstractMenu): + def run(self): + add_node = self._menu.addAction(self._trad["menu_add_node"]) + + action = self._exec() + if action == add_node: + self._parent.add_node(self._pos) + + +class NodeMenu(AbstractMenu): + def run(self): + delete = self._menu.addAction(self._trad["menu_del_node"]) + + action = self._exec() + if action == delete: + self._parent.del_node(self._items[0]) + + +class EdgeMenu(AbstractMenu): + def run(self): + it = self._items[0] + + reverse = self._menu.addAction(self._trad["menu_rev_edge"]) + delete = self._menu.addAction(self._trad["menu_del_edge"]) + if self._parent.graph.is_enable_edge(it.edge): + enable = self._menu.addAction(self._trad["menu_dis_edge"]) + is_enable = True + else: + enable = self._menu.addAction(self._trad["menu_ena_edge"]) + is_enable = False + + action = self._exec() + if action == delete: + self._parent.del_edge(it) + elif action == enable: + self._parent.enable_edge(it, is_enable) + elif action == reverse: + self._parent.reverse_edge(it) diff --git a/src/View/Network/GraphWidget.py b/src/View/Network/GraphWidget.py index 54da854b3cee31c4e174897613b305eba7e53956..b3e321cdad8b8cb4c23a71729c3fec4f2d1a838c 100644 --- a/src/View/Network/GraphWidget.py +++ b/src/View/Network/GraphWidget.py @@ -39,6 +39,9 @@ from Model.Network.Edge import Edge from Model.Network.Graph import Graph from View.Network.UndoCommand import * +from View.Network.ContextMenu import ( + DefaultMenu, NodeMenu, EdgeMenu, +) logger = logging.getLogger() @@ -292,7 +295,8 @@ class GraphWidget(QGraphicsView): def __init__(self, graph, parent=None, min_size=(400, 400), max_size=None, - size=None, only_display=False, undo=None): + size=None, only_display=False, undo=None, + trad=None): super(GraphWidget, self).__init__(parent=parent) self.timerId = 0 @@ -300,6 +304,7 @@ class GraphWidget(QGraphicsView): self._state = "move" self._only_display = only_display self._undo = undo + self._trad = trad self.graph = graph @@ -813,45 +818,6 @@ class GraphWidget(QGraphicsView): # Contextual menu - def _menu_default(self, event, pos, items, menu): - add_node = menu.addAction(_translate("Network", "Add node")) - - action = menu.exec_(self.mapToGlobal(event.pos())) - - if action == add_node: - self.add_node(pos) - - def _menu_node(self, event, pos, items, menu): - delete = menu.addAction(_translate("Network", "Delete the node")) - disable = menu.addAction(_translate("Network", "Disable the node")) - - action = menu.exec_(self.mapToGlobal(event.pos())) - - if action == delete: - self.del_node(items[0]) - - def _menu_edge(self, event, pos, items, menu): - delete = menu.addAction(_translate("Network", "Delete the reach")) - - if self.graph.is_enable_edge(items[0].edge): - enable = menu.addAction(_translate("Network", "Disable the reach")) - is_enable = True - else: - enable = menu.addAction(_translate("Network", "Enable the reach")) - is_enable = False - - reverse = menu.addAction(_translate( - "Network", "Reverse the reach orientation")) - - action = menu.exec_(self.mapToGlobal(event.pos())) - - if action == delete: - self.del_edge(items[0]) - elif action == enable: - self.enable_edge(items[0], is_enable) - elif action == reverse: - self.reverse_edge(items[0]) - def contextMenuEvent(self, event): if self._only_display: return @@ -859,10 +825,17 @@ class GraphWidget(QGraphicsView): pos = self.mapToScene(event.pos()) items = self.items(event.pos()) - menu = QMenu(self) + # Select current menu if len(items) == 0: - self._menu_default(event, pos, items, menu) + m_type = DefaultMenu elif type(items[0]) is NodeItem: - self._menu_node(event, pos, items, menu) + m_type = NodeMenu elif type(items[0]) is EdgeItem: - self._menu_edge(event, pos, items, menu) + m_type = EdgeMenu + + # Create and exec menu + m = m_type( + event=event, pos=pos, items=items, + trad=self._trad, parent=self + ) + m.run() diff --git a/src/View/Network/Window.py b/src/View/Network/Window.py index 17a95b2f8baa1fe016369ab1008477c3dfeceddd..18763bc6ce28dba855fef6b96d2f653f1314783e 100644 --- a/src/View/Network/Window.py +++ b/src/View/Network/Window.py @@ -117,7 +117,8 @@ class NetworkWindow(PamhyrWindow): def setup_graph(self): self._graph_widget = GraphWidget( self._graph, parent=self, - undo=self._undo_stack + undo=self._undo_stack, + trad=self._trad, ) self._graph_layout = self.find(QHBoxLayout, "horizontalLayout_graph") self._graph_layout.addWidget(self._graph_widget) diff --git a/src/View/Network/translate.py b/src/View/Network/translate.py index 089dc9a13aabc3903155ea52141718a2947a4856..ff5440b81b3d6a9bfdff6d139d813acc674f3d43 100644 --- a/src/View/Network/translate.py +++ b/src/View/Network/translate.py @@ -31,6 +31,16 @@ class NetworkTranslate(MainTranslate): "Network", "River network" ) + self._dict["menu_add_node"] = _translate("Network", "Add node") + self._dict["menu_del_node"] = _translate("Network", "Delete the node") + + self._dict["menu_del_edge"] = _translate("Network", "Delete the reach") + self._dict["menu_ena_edge"] = _translate("Network", "Enable the reach") + self._dict["menu_dis_edge"] = _translate("Network", "Disable the reach") + self._dict["menu_rev_edge"] = _translate( + "Network", "Reverse the reach orientation" + ) + self._sub_dict["table_headers_node"] = { "name": self._dict['name'], "type": self._dict['type'],