2019-09-25 16:29:34 +01:00
|
|
|
import logging
|
|
|
|
import tkinter as tk
|
2019-11-07 22:37:08 +00:00
|
|
|
from functools import partial
|
2019-09-25 16:29:34 +01:00
|
|
|
|
2019-11-06 00:16:46 +00:00
|
|
|
from coretk.dialogs.customnodes import CustomNodesDialog
|
2019-09-30 18:11:29 +01:00
|
|
|
from coretk.graph import GraphMode
|
2019-10-11 01:02:28 +01:00
|
|
|
from coretk.images import ImageEnum, Images
|
2019-09-28 00:00:38 +01:00
|
|
|
from coretk.tooltip import CreateToolTip
|
2019-09-27 23:28:51 +01:00
|
|
|
|
2019-09-25 16:29:34 +01:00
|
|
|
|
2019-11-07 23:58:02 +00:00
|
|
|
class Toolbar(tk.Frame):
|
2019-09-25 16:29:34 +01:00
|
|
|
"""
|
|
|
|
Core toolbar class
|
|
|
|
"""
|
|
|
|
|
2019-11-07 22:37:08 +00:00
|
|
|
def __init__(self, master, app, cnf={}, **kwargs):
|
2019-09-25 16:29:34 +01:00
|
|
|
"""
|
|
|
|
Create a CoreToolbar instance
|
|
|
|
|
|
|
|
:param tkinter.Frame edit_frame: edit frame
|
|
|
|
"""
|
2019-11-07 22:37:08 +00:00
|
|
|
super().__init__(master, cnf, **kwargs)
|
2019-11-01 20:42:49 +00:00
|
|
|
self.app = app
|
|
|
|
self.master = app.master
|
2019-09-25 16:29:34 +01:00
|
|
|
self.radio_value = tk.IntVar()
|
2019-09-27 00:05:57 +01:00
|
|
|
self.exec_radio_value = tk.IntVar()
|
|
|
|
|
|
|
|
# button dimension
|
|
|
|
self.width = 32
|
|
|
|
self.height = 32
|
2019-09-25 16:29:34 +01:00
|
|
|
|
|
|
|
# Reference to the option menus
|
2019-11-07 22:37:08 +00:00
|
|
|
self.selection_tool_button = None
|
2019-09-25 16:29:34 +01:00
|
|
|
self.link_layer_option_menu = None
|
|
|
|
self.marker_option_menu = None
|
|
|
|
self.network_layer_option_menu = None
|
2019-11-07 22:37:08 +00:00
|
|
|
self.node_button = None
|
|
|
|
self.network_button = None
|
|
|
|
self.annotation_button = None
|
|
|
|
|
|
|
|
# frames
|
|
|
|
self.design_frame = None
|
|
|
|
self.runtime_frame = None
|
|
|
|
self.node_picker = None
|
|
|
|
self.network_picker = None
|
|
|
|
self.annotation_picker = None
|
|
|
|
|
|
|
|
# draw components
|
|
|
|
self.draw()
|
|
|
|
|
|
|
|
def draw(self):
|
|
|
|
self.columnconfigure(0, weight=1)
|
|
|
|
self.rowconfigure(0, weight=1)
|
|
|
|
self.draw_design_frame()
|
|
|
|
self.draw_runtime_frame()
|
|
|
|
self.design_frame.tkraise()
|
|
|
|
|
|
|
|
def draw_design_frame(self):
|
|
|
|
self.design_frame = tk.Frame(self)
|
|
|
|
self.design_frame.grid(row=0, column=0, sticky="nsew")
|
|
|
|
self.design_frame.columnconfigure(0, weight=1)
|
2019-09-30 18:11:29 +01:00
|
|
|
|
2019-11-07 22:37:08 +00:00
|
|
|
self.create_regular_button(
|
|
|
|
self.design_frame,
|
|
|
|
Images.get(ImageEnum.START),
|
|
|
|
self.click_start_session_tool,
|
|
|
|
"start the session",
|
|
|
|
)
|
|
|
|
self.create_radio_button(
|
|
|
|
self.design_frame,
|
|
|
|
Images.get(ImageEnum.SELECT),
|
|
|
|
self.click_selection_tool,
|
|
|
|
self.radio_value,
|
|
|
|
1,
|
|
|
|
"selection tool",
|
|
|
|
)
|
|
|
|
self.create_radio_button(
|
|
|
|
self.design_frame,
|
|
|
|
Images.get(ImageEnum.LINK),
|
|
|
|
self.click_link_tool,
|
|
|
|
self.radio_value,
|
|
|
|
2,
|
|
|
|
"link tool",
|
|
|
|
)
|
|
|
|
self.create_node_button()
|
2019-11-09 00:21:36 +00:00
|
|
|
self.create_network_button()
|
|
|
|
self.create_annotation_button()
|
2019-11-07 22:37:08 +00:00
|
|
|
self.radio_value.set(1)
|
2019-09-27 00:05:57 +01:00
|
|
|
|
2019-11-07 22:37:08 +00:00
|
|
|
def draw_runtime_frame(self):
|
|
|
|
self.runtime_frame = tk.Frame(self)
|
|
|
|
self.runtime_frame.grid(row=0, column=0, sticky="nsew")
|
|
|
|
self.runtime_frame.columnconfigure(0, weight=1)
|
2019-09-27 22:19:48 +01:00
|
|
|
|
2019-11-07 22:37:08 +00:00
|
|
|
self.create_regular_button(
|
|
|
|
self.runtime_frame,
|
|
|
|
Images.get(ImageEnum.STOP),
|
|
|
|
self.click_stop_button,
|
|
|
|
"stop the session",
|
|
|
|
)
|
|
|
|
self.create_radio_button(
|
|
|
|
self.runtime_frame,
|
|
|
|
Images.get(ImageEnum.SELECT),
|
|
|
|
self.click_selection_tool,
|
|
|
|
self.exec_radio_value,
|
|
|
|
1,
|
|
|
|
"selection tool",
|
|
|
|
)
|
|
|
|
self.create_observe_button()
|
|
|
|
self.create_radio_button(
|
|
|
|
self.runtime_frame,
|
|
|
|
Images.get(ImageEnum.PLOT),
|
|
|
|
self.click_plot_button,
|
|
|
|
self.exec_radio_value,
|
|
|
|
2,
|
|
|
|
"plot",
|
|
|
|
)
|
|
|
|
self.create_radio_button(
|
|
|
|
self.runtime_frame,
|
|
|
|
Images.get(ImageEnum.MARKER),
|
|
|
|
self.click_marker_button,
|
|
|
|
self.exec_radio_value,
|
|
|
|
3,
|
|
|
|
"marker",
|
|
|
|
)
|
|
|
|
self.create_radio_button(
|
|
|
|
self.runtime_frame,
|
|
|
|
Images.get(ImageEnum.TWONODE),
|
|
|
|
self.click_two_node_button,
|
|
|
|
self.exec_radio_value,
|
|
|
|
4,
|
|
|
|
"run command from one node to another",
|
|
|
|
)
|
|
|
|
self.create_regular_button(
|
|
|
|
self.runtime_frame, Images.get(ImageEnum.RUN), self.click_run_button, "run"
|
|
|
|
)
|
|
|
|
self.exec_radio_value.set(1)
|
|
|
|
|
|
|
|
def draw_node_picker(self):
|
|
|
|
self.hide_pickers()
|
|
|
|
self.node_picker = tk.Frame(self.master, padx=1, pady=1)
|
|
|
|
nodes = [
|
|
|
|
(ImageEnum.ROUTER, "router"),
|
|
|
|
(ImageEnum.HOST, "host"),
|
|
|
|
(ImageEnum.PC, "PC"),
|
|
|
|
(ImageEnum.MDR, "mdr"),
|
|
|
|
(ImageEnum.PROUTER, "prouter"),
|
|
|
|
]
|
2019-11-08 19:00:22 +00:00
|
|
|
# draw default nodes
|
2019-11-07 22:37:08 +00:00
|
|
|
for image_enum, tooltip in nodes:
|
2019-11-08 19:00:22 +00:00
|
|
|
image = Images.get(image_enum)
|
|
|
|
func = partial(self.update_button, self.node_button, image, tooltip)
|
|
|
|
self.create_button(image, func, self.node_picker, tooltip)
|
|
|
|
# draw custom nodes
|
|
|
|
for name in sorted(self.app.core.custom_nodes):
|
|
|
|
custom_node = self.app.core.custom_nodes[name]
|
|
|
|
image = custom_node.image
|
|
|
|
func = partial(self.update_button, self.node_button, image, name)
|
|
|
|
self.create_button(image, func, self.node_picker, name)
|
|
|
|
# draw edit node
|
|
|
|
image = Images.get(ImageEnum.EDITNODE)
|
|
|
|
self.create_button(
|
|
|
|
image, self.click_edit_node, self.node_picker, "custom nodes"
|
|
|
|
)
|
2019-11-07 22:37:08 +00:00
|
|
|
self.show_picker(self.node_button, self.node_picker)
|
2019-09-27 22:19:48 +01:00
|
|
|
|
2019-11-07 22:37:08 +00:00
|
|
|
def show_picker(self, button, picker):
|
|
|
|
first_button = self.winfo_children()[0]
|
|
|
|
x = button.winfo_rootx() - first_button.winfo_rootx() + 40
|
|
|
|
y = button.winfo_rooty() - first_button.winfo_rooty() - 1
|
|
|
|
picker.place(x=x, y=y)
|
2019-11-09 00:21:36 +00:00
|
|
|
self.app.bind_all("<ButtonRelease-1>", lambda e: self.hide_pickers())
|
|
|
|
picker.wait_visibility()
|
|
|
|
picker.grab_set()
|
2019-11-07 22:37:08 +00:00
|
|
|
self.wait_window(picker)
|
2019-11-09 00:21:36 +00:00
|
|
|
self.app.unbind_all("<ButtonRelease-1>")
|
2019-09-27 22:19:48 +01:00
|
|
|
|
2019-11-08 19:00:22 +00:00
|
|
|
def create_button(self, image, func, frame, tooltip):
|
2019-09-27 00:05:57 +01:00
|
|
|
"""
|
|
|
|
Create button and put it on the frame
|
|
|
|
|
2019-11-08 19:00:22 +00:00
|
|
|
:param PIL.Image image: button image
|
2019-09-27 00:05:57 +01:00
|
|
|
:param func: the command that is executed when button is clicked
|
|
|
|
:param tkinter.Frame frame: frame that contains the button
|
2019-11-08 06:00:46 +00:00
|
|
|
:param str tooltip: tooltip text
|
2019-09-27 00:05:57 +01:00
|
|
|
:return: nothing
|
|
|
|
"""
|
2019-11-08 19:00:22 +00:00
|
|
|
button = tk.Button(frame, width=self.width, height=self.height, image=image)
|
2019-11-09 00:21:36 +00:00
|
|
|
button.bind("<ButtonRelease-1>", lambda e: func())
|
2019-11-08 06:00:46 +00:00
|
|
|
button.grid(pady=1)
|
2019-11-07 22:37:08 +00:00
|
|
|
CreateToolTip(button, tooltip)
|
2019-09-27 00:05:57 +01:00
|
|
|
|
2019-09-28 00:00:38 +01:00
|
|
|
def create_radio_button(self, frame, image, func, variable, value, tooltip_msg):
|
2019-09-27 22:19:48 +01:00
|
|
|
button = tk.Radiobutton(
|
|
|
|
frame,
|
|
|
|
indicatoron=False,
|
|
|
|
width=self.width,
|
|
|
|
height=self.height,
|
|
|
|
image=image,
|
|
|
|
value=value,
|
|
|
|
variable=variable,
|
|
|
|
command=func,
|
|
|
|
)
|
2019-11-07 22:37:08 +00:00
|
|
|
button.grid()
|
2019-09-28 00:00:38 +01:00
|
|
|
CreateToolTip(button, tooltip_msg)
|
2019-09-27 22:19:48 +01:00
|
|
|
|
2019-11-07 22:37:08 +00:00
|
|
|
def create_regular_button(self, frame, image, func, tooltip):
|
2019-09-27 22:19:48 +01:00
|
|
|
button = tk.Button(
|
|
|
|
frame, width=self.width, height=self.height, image=image, command=func
|
|
|
|
)
|
2019-11-07 22:37:08 +00:00
|
|
|
button.grid()
|
|
|
|
CreateToolTip(button, tooltip)
|
2019-09-25 16:29:34 +01:00
|
|
|
|
|
|
|
def click_selection_tool(self):
|
2019-11-07 22:37:08 +00:00
|
|
|
logging.debug("clicked selection tool")
|
2019-11-08 05:46:40 +00:00
|
|
|
self.app.canvas.mode = GraphMode.SELECT
|
2019-09-25 16:29:34 +01:00
|
|
|
|
2019-10-04 00:50:49 +01:00
|
|
|
def click_start_session_tool(self):
|
2019-10-19 00:42:00 +01:00
|
|
|
"""
|
2019-11-07 22:37:08 +00:00
|
|
|
Start session handler redraw buttons, send node and link messages to grpc
|
|
|
|
server.
|
2019-10-19 00:42:00 +01:00
|
|
|
|
|
|
|
:return: nothing
|
|
|
|
"""
|
2019-11-07 22:37:08 +00:00
|
|
|
logging.debug("clicked start button")
|
2019-11-08 05:46:40 +00:00
|
|
|
self.app.canvas.mode = GraphMode.SELECT
|
2019-11-08 00:15:29 +00:00
|
|
|
self.app.core.start_session()
|
2019-11-07 22:37:08 +00:00
|
|
|
self.runtime_frame.tkraise()
|
2019-10-11 01:02:28 +01:00
|
|
|
|
2019-09-27 22:19:48 +01:00
|
|
|
def click_link_tool(self):
|
|
|
|
logging.debug("Click LINK button")
|
2019-11-08 05:46:40 +00:00
|
|
|
self.app.canvas.mode = GraphMode.EDGE
|
2019-09-25 16:29:34 +01:00
|
|
|
|
2019-11-08 19:00:22 +00:00
|
|
|
def click_edit_node(self):
|
|
|
|
dialog = CustomNodesDialog(self.app, self.app)
|
|
|
|
dialog.show()
|
|
|
|
|
|
|
|
def update_button(self, button, image, name):
|
|
|
|
logging.info("update button(%s): %s", button, name)
|
2019-11-07 22:37:08 +00:00
|
|
|
self.hide_pickers()
|
2019-11-08 19:00:22 +00:00
|
|
|
button.configure(image=image)
|
|
|
|
self.app.canvas.mode = GraphMode.NODE
|
|
|
|
self.app.canvas.draw_node_image = image
|
|
|
|
self.app.canvas.draw_node_name = name
|
2019-11-07 22:37:08 +00:00
|
|
|
|
|
|
|
def hide_pickers(self):
|
|
|
|
logging.info("hiding pickers")
|
|
|
|
if self.node_picker:
|
|
|
|
self.node_picker.destroy()
|
|
|
|
self.node_picker = None
|
|
|
|
if self.network_picker:
|
|
|
|
self.network_picker.destroy()
|
|
|
|
self.network_picker = None
|
|
|
|
if self.annotation_picker:
|
|
|
|
self.annotation_picker.destroy()
|
|
|
|
self.annotation_picker = None
|
|
|
|
|
|
|
|
def create_node_button(self):
|
2019-09-25 16:29:34 +01:00
|
|
|
"""
|
|
|
|
Create network layer button
|
|
|
|
|
|
|
|
:return: nothing
|
|
|
|
"""
|
2019-11-01 06:17:26 +00:00
|
|
|
router_image = Images.get(ImageEnum.ROUTER)
|
2019-11-07 22:37:08 +00:00
|
|
|
self.node_button = tk.Radiobutton(
|
|
|
|
self.design_frame,
|
2019-09-25 16:29:34 +01:00
|
|
|
indicatoron=False,
|
|
|
|
variable=self.radio_value,
|
2019-09-27 22:19:48 +01:00
|
|
|
value=3,
|
2019-09-27 00:05:57 +01:00
|
|
|
width=self.width,
|
|
|
|
height=self.height,
|
2019-09-25 16:29:34 +01:00
|
|
|
image=router_image,
|
|
|
|
)
|
2019-11-09 00:21:36 +00:00
|
|
|
self.node_button.bind("<ButtonRelease-1>", lambda e: self.draw_node_picker())
|
2019-11-07 22:37:08 +00:00
|
|
|
self.node_button.grid()
|
|
|
|
CreateToolTip(self.node_button, "Network-layer virtual nodes")
|
|
|
|
|
|
|
|
def draw_network_picker(self):
|
2019-09-27 00:05:57 +01:00
|
|
|
"""
|
|
|
|
Draw the options for link-layer button
|
|
|
|
|
|
|
|
:param tkinter.RadioButton link_layer_button: link-layer button
|
|
|
|
:return: nothing
|
|
|
|
"""
|
2019-11-07 22:37:08 +00:00
|
|
|
self.hide_pickers()
|
|
|
|
self.network_picker = tk.Frame(self.master, padx=1, pady=1)
|
|
|
|
nodes = [
|
|
|
|
(ImageEnum.HUB, "hub", "ethernet hub"),
|
|
|
|
(ImageEnum.SWITCH, "switch", "ethernet switch"),
|
|
|
|
(ImageEnum.WLAN, "wlan", "wireless LAN"),
|
|
|
|
(ImageEnum.EMANE, "emane", "EMANE"),
|
|
|
|
(ImageEnum.RJ45, "rj45", "rj45 physical interface tool"),
|
|
|
|
(ImageEnum.TUNNEL, "tunnel", "tunnel tool"),
|
2019-09-27 00:05:57 +01:00
|
|
|
]
|
2019-11-07 22:37:08 +00:00
|
|
|
for image_enum, name, tooltip in nodes:
|
2019-11-09 00:21:36 +00:00
|
|
|
image = Images.get(image_enum)
|
2019-09-27 22:19:48 +01:00
|
|
|
self.create_button(
|
2019-11-09 00:21:36 +00:00
|
|
|
image,
|
|
|
|
partial(self.update_button, self.network_button, image, name),
|
2019-11-07 22:37:08 +00:00
|
|
|
self.network_picker,
|
|
|
|
tooltip,
|
2019-09-25 16:29:34 +01:00
|
|
|
)
|
2019-11-07 22:37:08 +00:00
|
|
|
self.show_picker(self.network_button, self.network_picker)
|
2019-09-25 16:29:34 +01:00
|
|
|
|
2019-11-09 00:21:36 +00:00
|
|
|
def create_network_button(self):
|
2019-09-25 16:29:34 +01:00
|
|
|
"""
|
|
|
|
Create link-layer node button and the options that represent different link-layer node types
|
|
|
|
|
|
|
|
:return: nothing
|
|
|
|
"""
|
2019-11-01 06:17:26 +00:00
|
|
|
hub_image = Images.get(ImageEnum.HUB)
|
2019-11-07 22:37:08 +00:00
|
|
|
self.network_button = tk.Radiobutton(
|
|
|
|
self.design_frame,
|
2019-09-25 16:29:34 +01:00
|
|
|
indicatoron=False,
|
|
|
|
variable=self.radio_value,
|
2019-09-27 22:19:48 +01:00
|
|
|
value=4,
|
2019-09-27 00:05:57 +01:00
|
|
|
width=self.width,
|
|
|
|
height=self.height,
|
2019-09-25 16:29:34 +01:00
|
|
|
image=hub_image,
|
2019-11-09 00:21:36 +00:00
|
|
|
)
|
|
|
|
self.network_button.bind(
|
|
|
|
"<ButtonRelease-1>", lambda e: self.draw_network_picker()
|
2019-09-25 16:29:34 +01:00
|
|
|
)
|
2019-11-07 22:37:08 +00:00
|
|
|
self.network_button.grid()
|
|
|
|
CreateToolTip(self.network_button, "link-layer nodes")
|
|
|
|
|
|
|
|
def draw_annotation_picker(self):
|
2019-09-27 00:05:57 +01:00
|
|
|
"""
|
|
|
|
Draw the options for marker button
|
2019-09-25 16:29:34 +01:00
|
|
|
|
2019-09-27 00:05:57 +01:00
|
|
|
:param tkinter.Radiobutton main_button: the main button
|
|
|
|
:return: nothing
|
|
|
|
"""
|
2019-11-07 22:37:08 +00:00
|
|
|
self.hide_pickers()
|
|
|
|
self.annotation_picker = tk.Frame(self.master, padx=1, pady=1)
|
|
|
|
nodes = [
|
|
|
|
(ImageEnum.MARKER, "marker"),
|
|
|
|
(ImageEnum.OVAL, "oval"),
|
|
|
|
(ImageEnum.RECTANGLE, "rectangle"),
|
|
|
|
(ImageEnum.TEXT, "text"),
|
2019-09-27 00:05:57 +01:00
|
|
|
]
|
2019-11-07 22:37:08 +00:00
|
|
|
for image_enum, tooltip in nodes:
|
2019-09-30 18:11:29 +01:00
|
|
|
self.create_button(
|
2019-11-07 22:37:08 +00:00
|
|
|
Images.get(image_enum),
|
|
|
|
partial(self.update_annotation, image_enum),
|
|
|
|
self.annotation_picker,
|
|
|
|
tooltip,
|
2019-09-30 18:11:29 +01:00
|
|
|
)
|
2019-11-07 22:37:08 +00:00
|
|
|
self.show_picker(self.annotation_button, self.annotation_picker)
|
2019-09-25 16:29:34 +01:00
|
|
|
|
2019-11-09 00:21:36 +00:00
|
|
|
def create_annotation_button(self):
|
2019-09-25 16:29:34 +01:00
|
|
|
"""
|
|
|
|
Create marker button and options that represent different marker types
|
|
|
|
|
|
|
|
:return: nothing
|
|
|
|
"""
|
2019-11-01 06:17:26 +00:00
|
|
|
marker_image = Images.get(ImageEnum.MARKER)
|
2019-11-07 22:37:08 +00:00
|
|
|
self.annotation_button = tk.Radiobutton(
|
|
|
|
self.design_frame,
|
2019-09-25 16:29:34 +01:00
|
|
|
indicatoron=False,
|
|
|
|
variable=self.radio_value,
|
2019-09-27 22:19:48 +01:00
|
|
|
value=5,
|
2019-09-27 00:05:57 +01:00
|
|
|
width=self.width,
|
|
|
|
height=self.height,
|
2019-09-25 16:29:34 +01:00
|
|
|
image=marker_image,
|
2019-11-09 00:21:36 +00:00
|
|
|
)
|
|
|
|
self.annotation_button.bind(
|
|
|
|
"<ButtonRelease-1>", lambda e: self.draw_annotation_picker()
|
2019-09-25 16:29:34 +01:00
|
|
|
)
|
2019-11-07 22:37:08 +00:00
|
|
|
self.annotation_button.grid()
|
|
|
|
CreateToolTip(self.annotation_button, "background annotation tools")
|
2019-09-27 00:05:57 +01:00
|
|
|
|
|
|
|
def create_observe_button(self):
|
|
|
|
menu_button = tk.Menubutton(
|
2019-11-07 22:37:08 +00:00
|
|
|
self.runtime_frame,
|
2019-11-01 06:17:26 +00:00
|
|
|
image=Images.get(ImageEnum.OBSERVE),
|
2019-09-27 00:05:57 +01:00
|
|
|
width=self.width,
|
|
|
|
height=self.height,
|
|
|
|
direction=tk.RIGHT,
|
2019-09-27 22:19:48 +01:00
|
|
|
relief=tk.RAISED,
|
2019-09-27 00:05:57 +01:00
|
|
|
)
|
|
|
|
menu_button.menu = tk.Menu(menu_button, tearoff=0)
|
|
|
|
menu_button["menu"] = menu_button.menu
|
2019-11-07 22:37:08 +00:00
|
|
|
menu_button.grid()
|
2019-09-27 00:05:57 +01:00
|
|
|
|
|
|
|
menu_button.menu.add_command(label="None")
|
|
|
|
menu_button.menu.add_command(label="processes")
|
|
|
|
menu_button.menu.add_command(label="ifconfig")
|
|
|
|
menu_button.menu.add_command(label="IPv4 routes")
|
|
|
|
menu_button.menu.add_command(label="IPv6 routes")
|
|
|
|
menu_button.menu.add_command(label="OSPFv2 neighbors")
|
|
|
|
menu_button.menu.add_command(label="OSPFv3 neighbors")
|
|
|
|
menu_button.menu.add_command(label="Listening sockets")
|
|
|
|
menu_button.menu.add_command(label="IPv4 MFC entries")
|
|
|
|
menu_button.menu.add_command(label="IPv6 MFC entries")
|
|
|
|
menu_button.menu.add_command(label="firewall rules")
|
|
|
|
menu_button.menu.add_command(label="IPSec policies")
|
|
|
|
menu_button.menu.add_command(label="docker logs")
|
|
|
|
menu_button.menu.add_command(label="OSPFv3 MDR level")
|
|
|
|
menu_button.menu.add_command(label="PIM neighbors")
|
|
|
|
menu_button.menu.add_command(label="Edit...")
|
|
|
|
|
|
|
|
def click_stop_button(self):
|
2019-10-19 00:42:00 +01:00
|
|
|
"""
|
|
|
|
redraw buttons on the toolbar, send node and link messages to grpc server
|
|
|
|
|
|
|
|
:return: nothing
|
|
|
|
"""
|
2019-09-27 00:05:57 +01:00
|
|
|
logging.debug("Click on STOP button ")
|
2019-11-01 20:42:49 +00:00
|
|
|
self.app.core.stop_session()
|
2019-11-07 22:37:08 +00:00
|
|
|
self.design_frame.tkraise()
|
|
|
|
|
|
|
|
def update_annotation(self, image_enum):
|
|
|
|
logging.info("clicked annotation: ")
|
|
|
|
self.hide_pickers()
|
|
|
|
self.annotation_button.configure(image=Images.get(image_enum))
|
2019-09-27 00:05:57 +01:00
|
|
|
|
2019-09-27 22:19:48 +01:00
|
|
|
def click_run_button(self):
|
|
|
|
logging.debug("Click on RUN button")
|
|
|
|
|
|
|
|
def click_plot_button(self):
|
|
|
|
logging.debug("Click on plot button")
|
|
|
|
|
|
|
|
def click_marker_button(self):
|
|
|
|
logging.debug("Click on marker button")
|
|
|
|
|
|
|
|
def click_two_node_button(self):
|
|
|
|
logging.debug("Click TWONODE button")
|