pygui some delete node/link cleanup and added unlink option to node context menu for an easier unlinking
This commit is contained in:
parent
d158fc99c6
commit
5a8984de10
3 changed files with 49 additions and 22 deletions
|
@ -6,7 +6,7 @@ import logging
|
||||||
import os
|
import os
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from tkinter import messagebox
|
from tkinter import messagebox
|
||||||
from typing import TYPE_CHECKING, Dict, List
|
from typing import TYPE_CHECKING, Dict, Iterable, List
|
||||||
|
|
||||||
import grpc
|
import grpc
|
||||||
|
|
||||||
|
@ -830,27 +830,21 @@ class CoreClient:
|
||||||
)
|
)
|
||||||
return node
|
return node
|
||||||
|
|
||||||
def delete_graph_nodes(self, canvas_nodes: List[core_pb2.Node]):
|
def deleted_graph_nodes(self, canvas_nodes: List[core_pb2.Node]):
|
||||||
"""
|
"""
|
||||||
remove the nodes selected by the user and anything related to that node
|
remove the nodes selected by the user and anything related to that node
|
||||||
such as link, configurations, interfaces
|
such as link, configurations, interfaces
|
||||||
"""
|
"""
|
||||||
edges = set()
|
|
||||||
removed_links = []
|
|
||||||
for canvas_node in canvas_nodes:
|
for canvas_node in canvas_nodes:
|
||||||
node_id = canvas_node.core_node.id
|
node_id = canvas_node.core_node.id
|
||||||
if node_id not in self.canvas_nodes:
|
|
||||||
logging.error("unknown node: %s", node_id)
|
|
||||||
continue
|
|
||||||
del self.canvas_nodes[node_id]
|
del self.canvas_nodes[node_id]
|
||||||
for edge in canvas_node.edges:
|
|
||||||
if edge in edges:
|
def deleted_graph_edges(self, edges: Iterable[CanvasEdge]) -> None:
|
||||||
continue
|
links = []
|
||||||
edges.add(edge)
|
for edge in edges:
|
||||||
edge = self.links.pop(edge.token, None)
|
del self.links[edge.token]
|
||||||
if edge is not None:
|
links.append(edge.link)
|
||||||
removed_links.append(edge.link)
|
self.interfaces_manager.removed(links)
|
||||||
self.interfaces_manager.removed(removed_links)
|
|
||||||
|
|
||||||
def create_interface(self, canvas_node: CanvasNode) -> core_pb2.Interface:
|
def create_interface(self, canvas_node: CanvasNode) -> core_pb2.Interface:
|
||||||
node = canvas_node.core_node
|
node = canvas_node.core_node
|
||||||
|
|
|
@ -517,15 +517,13 @@ class CanvasGraph(tk.Canvas):
|
||||||
canvas_node.delete()
|
canvas_node.delete()
|
||||||
nodes.append(canvas_node)
|
nodes.append(canvas_node)
|
||||||
is_wireless = NodeUtils.is_wireless_node(canvas_node.core_node.type)
|
is_wireless = NodeUtils.is_wireless_node(canvas_node.core_node.type)
|
||||||
|
|
||||||
# delete related edges
|
# delete related edges
|
||||||
for edge in canvas_node.edges:
|
for edge in canvas_node.edges:
|
||||||
if edge in edges:
|
if edge in edges:
|
||||||
continue
|
continue
|
||||||
edges.add(edge)
|
edges.add(edge)
|
||||||
self.edges.pop(edge.token, None)
|
del self.edges[edge.token]
|
||||||
edge.delete()
|
edge.delete()
|
||||||
|
|
||||||
# update node connected to edge being deleted
|
# update node connected to edge being deleted
|
||||||
other_id = edge.src
|
other_id = edge.src
|
||||||
other_interface = edge.src_interface
|
other_interface = edge.src_interface
|
||||||
|
@ -534,10 +532,8 @@ class CanvasGraph(tk.Canvas):
|
||||||
other_interface = edge.dst_interface
|
other_interface = edge.dst_interface
|
||||||
other_node = self.nodes[other_id]
|
other_node = self.nodes[other_id]
|
||||||
other_node.edges.remove(edge)
|
other_node.edges.remove(edge)
|
||||||
try:
|
if other_interface in other_node.interfaces:
|
||||||
other_node.interfaces.remove(other_interface)
|
other_node.interfaces.remove(other_interface)
|
||||||
except ValueError:
|
|
||||||
pass
|
|
||||||
if is_wireless:
|
if is_wireless:
|
||||||
other_node.delete_antenna()
|
other_node.delete_antenna()
|
||||||
|
|
||||||
|
@ -547,7 +543,26 @@ class CanvasGraph(tk.Canvas):
|
||||||
shape.delete()
|
shape.delete()
|
||||||
|
|
||||||
self.selection.clear()
|
self.selection.clear()
|
||||||
self.core.delete_graph_nodes(nodes)
|
self.core.deleted_graph_nodes(nodes)
|
||||||
|
self.core.deleted_graph_edges(edges)
|
||||||
|
|
||||||
|
def delete_edge(self, edge: CanvasEdge):
|
||||||
|
edge.delete()
|
||||||
|
del self.edges[edge.token]
|
||||||
|
src_node = self.nodes[edge.src]
|
||||||
|
src_node.edges.discard(edge)
|
||||||
|
if edge.src_interface in src_node.interfaces:
|
||||||
|
src_node.interfaces.remove(edge.src_interface)
|
||||||
|
dst_node = self.nodes[edge.dst]
|
||||||
|
dst_node.edges.discard(edge)
|
||||||
|
if edge.dst_interface in dst_node.interfaces:
|
||||||
|
dst_node.interfaces.remove(edge.dst_interface)
|
||||||
|
src_wireless = NodeUtils.is_wireless_node(src_node.core_node.type)
|
||||||
|
if src_wireless:
|
||||||
|
dst_node.delete_antenna()
|
||||||
|
dst_wireless = NodeUtils.is_wireless_node(dst_node.core_node.type)
|
||||||
|
if dst_wireless:
|
||||||
|
src_node.delete_antenna()
|
||||||
|
|
||||||
def zoom(self, event: tk.Event, factor: float = None):
|
def zoom(self, event: tk.Event, factor: float = None):
|
||||||
if not factor:
|
if not factor:
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import functools
|
||||||
import logging
|
import logging
|
||||||
import tkinter as tk
|
import tkinter as tk
|
||||||
from typing import TYPE_CHECKING
|
from typing import TYPE_CHECKING
|
||||||
|
@ -15,6 +16,7 @@ from core.gui.dialogs.nodeservice import NodeServiceDialog
|
||||||
from core.gui.dialogs.wlanconfig import WlanConfigDialog
|
from core.gui.dialogs.wlanconfig import WlanConfigDialog
|
||||||
from core.gui.errors import show_grpc_error
|
from core.gui.errors import show_grpc_error
|
||||||
from core.gui.graph import tags
|
from core.gui.graph import tags
|
||||||
|
from core.gui.graph.edges import CanvasEdge
|
||||||
from core.gui.graph.tooltip import CanvasTooltip
|
from core.gui.graph.tooltip import CanvasTooltip
|
||||||
from core.gui.images import ImageEnum, Images
|
from core.gui.images import ImageEnum, Images
|
||||||
from core.gui.nodeutils import ANTENNA_SIZE, NodeUtils
|
from core.gui.nodeutils import ANTENNA_SIZE, NodeUtils
|
||||||
|
@ -230,6 +232,18 @@ class CanvasNode:
|
||||||
label="Link To Selected", command=self.wireless_link_selected
|
label="Link To Selected", command=self.wireless_link_selected
|
||||||
)
|
)
|
||||||
context.add_command(label="Select Members", state=tk.DISABLED)
|
context.add_command(label="Select Members", state=tk.DISABLED)
|
||||||
|
unlink_menu = tk.Menu(context)
|
||||||
|
for edge in self.edges:
|
||||||
|
other_id = edge.src
|
||||||
|
if self.id == other_id:
|
||||||
|
other_id = edge.dst
|
||||||
|
other_node = self.canvas.nodes[other_id]
|
||||||
|
func_unlink = functools.partial(self.click_unlink, edge)
|
||||||
|
unlink_menu.add_command(
|
||||||
|
label=other_node.core_node.name, command=func_unlink
|
||||||
|
)
|
||||||
|
themes.style_menu(unlink_menu)
|
||||||
|
context.add_cascade(label="Unlink", menu=unlink_menu)
|
||||||
edit_menu = tk.Menu(context)
|
edit_menu = tk.Menu(context)
|
||||||
themes.style_menu(edit_menu)
|
themes.style_menu(edit_menu)
|
||||||
edit_menu.add_command(label="Cut", command=self.click_cut)
|
edit_menu.add_command(label="Cut", command=self.click_cut)
|
||||||
|
@ -242,6 +256,10 @@ class CanvasNode:
|
||||||
self.canvas_copy()
|
self.canvas_copy()
|
||||||
self.canvas_delete()
|
self.canvas_delete()
|
||||||
|
|
||||||
|
def click_unlink(self, edge: CanvasEdge) -> None:
|
||||||
|
self.canvas.delete_edge(edge)
|
||||||
|
self.app.core.deleted_graph_edges([edge])
|
||||||
|
|
||||||
def canvas_delete(self) -> None:
|
def canvas_delete(self) -> None:
|
||||||
self.canvas.clear_selection()
|
self.canvas.clear_selection()
|
||||||
self.canvas.selection[self.id] = self
|
self.canvas.selection[self.id] = self
|
||||||
|
|
Loading…
Add table
Reference in a new issue