def update_wired_edge(self, src: CanvasNode, dst: CanvasNode, link: Link) -> None: token = create_edge_token(src.id, dst.id) edge = self.edges.get(token) if not edge: return edge.link.options = deepcopy(link.options)
def complete_edge( self, src: CanvasNode, dst: CanvasNode, edge: CanvasEdge, link: Optional[Link] = None, ) -> None: linked_wireless = self.is_linked_wireless(src.id, dst.id) edge.complete(dst.id, linked_wireless) if link is None: link = self.core.create_link(edge, src, dst) edge.link = link if link.iface1: iface1 = link.iface1 src.ifaces[iface1.id] = iface1 if link.iface2: iface2 = link.iface2 dst.ifaces[iface2.id] = iface2 src.edges.add(edge) dst.edges.add(edge) edge.token = create_edge_token(edge.link) self.arc_common_edges(edge) edge.draw_labels() edge.check_options() self.edges[edge.token] = edge self.core.save_edge(edge, src, dst)
def add_wired_edge(self, src: CanvasNode, dst: CanvasNode, link: Link) -> None: token = create_edge_token(src.id, dst.id) if token in self.edges and link.options.unidirectional: edge = self.edges[token] edge.asymmetric_link = link elif token not in self.edges: node1 = src.core_node node2 = dst.core_node src_pos = (node1.position.x, node1.position.y) dst_pos = (node2.position.x, node2.position.y) edge = CanvasEdge(self, src.id, src_pos, dst_pos) edge.token = token edge.dst = dst.id edge.set_link(link) edge.check_wireless() src.edges.add(edge) dst.edges.add(edge) self.edges[edge.token] = edge self.core.links[edge.token] = edge if link.iface1: iface1 = link.iface1 self.core.iface_to_edge[(node1.id, iface1.id)] = token src.ifaces[iface1.id] = iface1 edge.src_iface = iface1 if link.iface2: iface2 = link.iface2 self.core.iface_to_edge[(node2.id, iface2.id)] = edge.token dst.ifaces[iface2.id] = iface2 edge.dst_iface = iface2
def handle_edge_release(self, _event: tk.Event): edge = self.drawing_edge self.drawing_edge = None # not drawing edge return if edge is None: return # edge dst must be a node logging.debug("current selected: %s", self.selected) dst_node = self.nodes.get(self.selected) if not dst_node: edge.delete() return # edge dst is same as src, delete edge if edge.src == self.selected: edge.delete() return # ignore repeated edges token = create_edge_token(edge.src, self.selected) if token in self.edges: edge.delete() return # set dst node and snap edge to center edge.complete(self.selected) self.edges[edge.token] = edge node_src = self.nodes[edge.src] node_src.edges.add(edge) node_dst = self.nodes[edge.dst] node_dst.edges.add(edge) self.core.create_link(edge, node_src, node_dst)
def update_wired_edge(self, link: Link) -> None: token = create_edge_token(link) edge = self.edges.get(token) if edge: edge.link.options = deepcopy(link.options) edge.draw_link_options() edge.check_visibility()
def add_wired_edge(self, src: CanvasNode, dst: CanvasNode, link: Link) -> None: token = create_edge_token(link) if token in self.edges and link.options.unidirectional: edge = self.edges[token] edge.asymmetric_link = link elif token not in self.edges: edge = CanvasEdge(self.app, src, dst) edge.complete(dst, link)
def update_wireless_edge(self, src: CanvasNode, dst: CanvasNode, link: core_pb2.Link) -> None: if not link.label: return network_id = link.network_id if link.network_id else None token = create_edge_token(src.id, dst.id, network_id) if token not in self.wireless_edges: self.add_wireless_edge(src, dst, link) else: edge = self.wireless_edges[token] edge.middle_label_text(link.label)
def create_edge(self, source: CanvasNode, dest: CanvasNode): """ create an edge between source node and destination node """ token = create_edge_token(source.id, dest.id) if token not in self.edges: pos = (source.core_node.position.x, source.core_node.position.y) edge = CanvasEdge(self, source.id, pos, pos) edge.complete(dest.id) self.edges[edge.token] = edge self.nodes[source.id].edges.add(edge) self.nodes[dest.id].edges.add(edge) self.core.create_link(edge, source, dest)
def delete_wireless_edge(self, src: CanvasNode, dst: CanvasNode, link: core_pb2.Link) -> None: network_id = link.network_id if link.network_id else None token = create_edge_token(src.id, dst.id, network_id) if token not in self.wireless_edges: return edge = self.wireless_edges.pop(token) edge.delete() src.wireless_edges.remove(edge) dst.wireless_edges.remove(edge) # update arcs when there are multiple links common_edges = list(src.wireless_edges & dst.wireless_edges) arc_edges(common_edges)
def add_wired_edge(self, src: CanvasNode, dst: CanvasNode, link: Link) -> None: token = create_edge_token(link) if token in self.edges and link.options.unidirectional: edge = self.edges[token] edge.asymmetric_link = link elif token not in self.edges: node1 = src.core_node node2 = dst.core_node src_pos = (node1.position.x, node1.position.y) dst_pos = (node2.position.x, node2.position.y) edge = CanvasEdge(self, src.id, src_pos, dst_pos) self.complete_edge(src, dst, edge, link)
def add_wireless_edge(self, src: CanvasNode, dst: CanvasNode, link: Link) -> None: network_id = link.network_id if link.network_id else None token = create_edge_token(src.id, dst.id, network_id) if token in self.wireless_edges: logging.warning("ignoring link that already exists: %s", link) return src_pos = self.coords(src.id) dst_pos = self.coords(dst.id) edge = CanvasWirelessEdge(self, src.id, dst.id, src_pos, dst_pos, token, link) self.wireless_edges[token] = edge src.wireless_edges.add(edge) dst.wireless_edges.add(edge) self.tag_raise(src.id) self.tag_raise(dst.id) # update arcs when there are multiple links common_edges = list(src.wireless_edges & dst.wireless_edges) arc_edges(common_edges)
def handle_edge_release(self, _event: tk.Event) -> None: edge = self.drawing_edge self.drawing_edge = None # not drawing edge return if edge is None: return # edge dst must be a node logging.debug("current selected: %s", self.selected) src_node = self.nodes.get(edge.src) dst_node = self.nodes.get(self.selected) if not dst_node or not src_node: edge.delete() return # edge dst is same as src, delete edge if edge.src == self.selected: edge.delete() return # ignore repeated edges token = create_edge_token(edge.src, self.selected) if token in self.edges: edge.delete() return # rj45 nodes can only support one link if NodeUtils.is_rj45_node(src_node.core_node.type) and src_node.edges: edge.delete() return if NodeUtils.is_rj45_node(dst_node.core_node.type) and dst_node.edges: edge.delete() return # set dst node and snap edge to center edge.complete(self.selected) self.edges[edge.token] = edge src_node.edges.add(edge) dst_node.edges.add(edge) self.core.create_link(edge, src_node, dst_node)
def paste(self): if self.core.is_runtime(): logging.info("paste is disabled during runtime state") return # maps original node canvas id to copy node canvas id copy_map = {} # the edges that will be copy over to_copy_edges = [] for canvas_node in self.to_copy: core_node = canvas_node.core_node actual_x = core_node.position.x + 50 actual_y = core_node.position.y + 50 scaled_x, scaled_y = self.get_scaled_coords(actual_x, actual_y) copy = self.core.create_node(actual_x, actual_y, core_node.type, core_node.model) if not copy: continue node = CanvasNode(self.app, scaled_x, scaled_y, copy, canvas_node.image) # copy configurations and services node.core_node.services[:] = canvas_node.core_node.services node.core_node.config_services[:] = canvas_node.core_node.config_services node.emane_model_configs = deepcopy( canvas_node.emane_model_configs) node.wlan_config = deepcopy(canvas_node.wlan_config) node.mobility_config = deepcopy(canvas_node.mobility_config) node.service_configs = deepcopy(canvas_node.service_configs) node.service_file_configs = deepcopy( canvas_node.service_file_configs) node.config_service_configs = deepcopy( canvas_node.config_service_configs) copy_map[canvas_node.id] = node.id self.core.canvas_nodes[copy.id] = node self.nodes[node.id] = node for edge in canvas_node.edges: if edge.src not in self.to_copy or edge.dst not in self.to_copy: if canvas_node.id == edge.src: dst_node = self.nodes[edge.dst] self.create_edge(node, dst_node) elif canvas_node.id == edge.dst: src_node = self.nodes[edge.src] self.create_edge(src_node, node) else: to_copy_edges.append(edge) # copy link and link config for edge in to_copy_edges: src_node_id = copy_map[edge.token[0]] dst_node_id = copy_map[edge.token[1]] src_node_copy = self.nodes[src_node_id] dst_node_copy = self.nodes[dst_node_id] self.create_edge(src_node_copy, dst_node_copy) token = create_edge_token(src_node_copy.id, dst_node_copy.id) copy_edge = self.edges[token] copy_link = copy_edge.link options = edge.link.options copy_link.options.CopyFrom(options) interface_one = None if copy_link.HasField("interface_one"): interface_one = copy_link.interface_one.id interface_two = None if copy_link.HasField("interface_two"): interface_two = copy_link.interface_two.id if not options.unidirectional: copy_edge.asymmetric_link = None else: asym_interface_one = None if interface_one: asym_interface_one = core_pb2.Interface(id=interface_one) asym_interface_two = None if interface_two: asym_interface_two = core_pb2.Interface(id=interface_two) copy_edge.asymmetric_link = core_pb2.Link( node_one_id=copy_link.node_two_id, node_two_id=copy_link.node_one_id, interface_one=asym_interface_one, interface_two=asym_interface_two, options=edge.asymmetric_link.options, ) self.itemconfig( copy_edge.id, width=self.itemcget(edge.id, "width"), fill=self.itemcget(edge.id, "fill"), ) self.tag_raise(tags.NODE)
def delete_wired_edge(self, link: Link) -> None: token = create_edge_token(link) edge = self.edges.get(token) if edge: edge.delete()
def delete_wired_edge(self, src: CanvasNode, dst: CanvasNode) -> None: token = create_edge_token(src.id, dst.id) edge = self.edges.get(token) if not edge: return self.delete_edge(edge)
def draw_session(self, session: core_pb2.Session): """ Draw existing session. """ # draw existing nodes for core_node in session.nodes: logging.debug("drawing node %s", core_node) # peer to peer node is not drawn on the GUI if NodeUtils.is_ignore_node(core_node.type): continue image = NodeUtils.node_image(core_node, self.app.guiconfig, self.app.app_scale) # if the gui can't find node's image, default to the "edit-node" image if not image: image = Images.get(ImageEnum.EDITNODE, int(ICON_SIZE * self.app.app_scale)) x = core_node.position.x y = core_node.position.y node = CanvasNode(self.app, x, y, core_node, image) self.nodes[node.id] = node self.core.canvas_nodes[core_node.id] = node # draw existing links for link in session.links: logging.debug("drawing link: %s", link) canvas_node_one = self.core.canvas_nodes[link.node_one_id] node_one = canvas_node_one.core_node canvas_node_two = self.core.canvas_nodes[link.node_two_id] node_two = canvas_node_two.core_node token = create_edge_token(canvas_node_one.id, canvas_node_two.id) if link.type == core_pb2.LinkType.WIRELESS: self.add_wireless_edge(canvas_node_one, canvas_node_two, link) else: if token not in self.edges: src_pos = (node_one.position.x, node_one.position.y) dst_pos = (node_two.position.x, node_two.position.y) edge = CanvasEdge(self, canvas_node_one.id, src_pos, dst_pos) edge.token = token edge.dst = canvas_node_two.id edge.set_link(link) edge.check_wireless() canvas_node_one.edges.add(edge) canvas_node_two.edges.add(edge) self.edges[edge.token] = edge self.core.links[edge.token] = edge if link.HasField("interface_one"): canvas_node_one.interfaces.append(link.interface_one) edge.src_interface = link.interface_one if link.HasField("interface_two"): canvas_node_two.interfaces.append(link.interface_two) edge.dst_interface = link.interface_two elif link.options.unidirectional: edge = self.edges[token] edge.asymmetric_link = link else: logging.error("duplicate link received: %s", link) # raise the nodes so they on top of the links self.tag_raise(tags.NODE)
def paste(self) -> None: if self.core.is_runtime(): logging.debug("paste is disabled during runtime state") return # maps original node canvas id to copy node canvas id copy_map = {} # the edges that will be copy over to_copy_edges = set() to_copy_ids = {x.id for x in self.to_copy} for canvas_node in self.to_copy: core_node = canvas_node.core_node actual_x = core_node.position.x + 50 actual_y = core_node.position.y + 50 scaled_x, scaled_y = self.get_scaled_coords(actual_x, actual_y) copy = self.core.create_node(actual_x, actual_y, core_node.type, core_node.model) if not copy: continue node = CanvasNode(self.app, scaled_x, scaled_y, copy, canvas_node.image) # copy configurations and services node.core_node.services = core_node.services.copy() node.core_node.config_services = core_node.config_services.copy() node.core_node.emane_model_configs = deepcopy( core_node.emane_model_configs) node.core_node.wlan_config = deepcopy(core_node.wlan_config) node.core_node.mobility_config = deepcopy( core_node.mobility_config) node.core_node.service_configs = deepcopy( core_node.service_configs) node.core_node.service_file_configs = deepcopy( core_node.service_file_configs) node.core_node.config_service_configs = deepcopy( core_node.config_service_configs) copy_map[canvas_node.id] = node.id self.nodes[node.id] = node self.core.set_canvas_node(copy, node) for edge in canvas_node.edges: if edge.src not in to_copy_ids or edge.dst not in to_copy_ids: if canvas_node.id == edge.src: dst_node = self.nodes[edge.dst] self.create_edge(node, dst_node) token = create_edge_token(node.id, dst_node.id) elif canvas_node.id == edge.dst: src_node = self.nodes[edge.src] self.create_edge(src_node, node) token = create_edge_token(src_node.id, node.id) copy_edge = self.edges[token] copy_link = copy_edge.link iface1_id = copy_link.iface1.id if copy_link.iface1 else None iface2_id = copy_link.iface2.id if copy_link.iface2 else None options = edge.link.options if options: copy_edge.link.options = deepcopy(options) if options and options.unidirectional: asym_iface1 = None if iface1_id is not None: asym_iface1 = Interface(id=iface1_id) asym_iface2 = None if iface2_id is not None: asym_iface2 = Interface(id=iface2_id) copy_edge.asymmetric_link = Link( node1_id=copy_link.node2_id, node2_id=copy_link.node1_id, iface1=asym_iface2, iface2=asym_iface1, options=deepcopy(edge.asymmetric_link.options), ) copy_edge.redraw() else: to_copy_edges.add(edge) # copy link and link config for edge in to_copy_edges: src_node_id = copy_map[edge.token[0]] dst_node_id = copy_map[edge.token[1]] src_node_copy = self.nodes[src_node_id] dst_node_copy = self.nodes[dst_node_id] self.create_edge(src_node_copy, dst_node_copy) token = create_edge_token(src_node_copy.id, dst_node_copy.id) copy_edge = self.edges[token] copy_link = copy_edge.link iface1_id = copy_link.iface1.id if copy_link.iface1 else None iface2_id = copy_link.iface2.id if copy_link.iface2 else None options = edge.link.options if options: copy_link.options = deepcopy(options) if options and options.unidirectional: asym_iface1 = None if iface1_id is not None: asym_iface1 = Interface(id=iface1_id) asym_iface2 = None if iface2_id is not None: asym_iface2 = Interface(id=iface2_id) copy_edge.asymmetric_link = Link( node1_id=copy_link.node2_id, node2_id=copy_link.node1_id, iface1=asym_iface2, iface2=asym_iface1, options=deepcopy(edge.asymmetric_link.options), ) copy_edge.redraw() self.itemconfig( copy_edge.id, width=self.itemcget(edge.id, "width"), fill=self.itemcget(edge.id, "fill"), ) self.tag_raise(tags.NODE)