From 13a7aa73a1197ff18927b8d427683cd2d64436fb Mon Sep 17 00:00:00 2001 From: Huy Pham <42948410+hpham@users.noreply.github.com> Date: Mon, 11 Nov 2019 10:57:26 -0800 Subject: [PATCH 1/2] draw node service configurations --- coretk/coretk/coreclient.py | 15 ++ coretk/coretk/dialogs/nodeconfig.py | 4 +- coretk/coretk/dialogs/nodeservice.py | 202 +++++++----------- coretk/coretk/dialogs/serviceconfiguration.py | 185 ++++++++++++++++ coretk/coretk/servicenodeconfig.py | 37 ++++ 5 files changed, 312 insertions(+), 131 deletions(-) create mode 100644 coretk/coretk/dialogs/serviceconfiguration.py create mode 100644 coretk/coretk/servicenodeconfig.py diff --git a/coretk/coretk/coreclient.py b/coretk/coretk/coreclient.py index f018a348..05a2b1e9 100644 --- a/coretk/coretk/coreclient.py +++ b/coretk/coretk/coreclient.py @@ -11,6 +11,7 @@ from coretk.emaneodelnodeconfig import EmaneModelNodeConfig from coretk.images import Images from coretk.interface import Interface, InterfaceManager from coretk.mobilitynodeconfig import MobilityNodeConfig +from coretk.servicenodeconfig import ServiceNodeConfig from coretk.wlannodeconfig import WlanNodeConfig link_layer_nodes = ["switch", "hub", "wlan", "rj45", "tunnel", "emane"] @@ -104,6 +105,7 @@ class CoreClient: self.mobilityconfig_management = MobilityNodeConfig() self.emaneconfig_management = EmaneModelNodeConfig(app) self.emane_config = None + self.serviceconfig_manager = ServiceNodeConfig(app) def read_config(self): # read distributed server @@ -327,6 +329,13 @@ class CoreClient: ) logging.debug("Start session %s, result: %s", self.session_id, response.result) + response = self.client.get_service_defaults(self.session_id) + for default in response.defaults: + print(default.node_type) + print(default.services) + response = self.client.get_node_service(self.session_id, 5, "FTP") + print(response) + def stop_session(self): response = self.client.stop_session(session_id=self.session_id) logging.debug("coregrpc.py Stop session, result: %s", response.result) @@ -453,6 +462,12 @@ class CoreClient: if node_type == core_pb2.NodeType.EMANE: self.emaneconfig_management.set_default_config(nid) + # set default service configurations + if node_type == core_pb2.NodeType.DEFAULT: + self.serviceconfig_manager.node_default_services_configuration( + node_id=nid, node_model=node_model + ) + self.nodes[canvas_id] = create_node self.core_mapping.map_core_id_to_canvas_id(nid, canvas_id) logging.debug( diff --git a/coretk/coretk/dialogs/nodeconfig.py b/coretk/coretk/dialogs/nodeconfig.py index 3f13488a..89dd7d11 100644 --- a/coretk/coretk/dialogs/nodeconfig.py +++ b/coretk/coretk/dialogs/nodeconfig.py @@ -3,7 +3,7 @@ from tkinter import ttk from coretk.dialogs.dialog import Dialog from coretk.dialogs.icondialog import IconDialog -from coretk.dialogs.nodeservice import NodeServicesDialog +from coretk.dialogs.nodeservice import NodeService NETWORKNODETYPES = ["switch", "hub", "wlan", "rj45", "tunnel"] DEFAULTNODES = ["router", "host", "PC"] @@ -87,7 +87,7 @@ class NodeConfigDialog(Dialog): button.grid(row=0, column=1, sticky="ew") def click_services(self): - dialog = NodeServicesDialog(self, self.app, self.canvas_node) + dialog = NodeService(self, self.app, self.canvas_node) dialog.show() def click_icon(self): diff --git a/coretk/coretk/dialogs/nodeservice.py b/coretk/coretk/dialogs/nodeservice.py index 6d92b98e..52421ca0 100644 --- a/coretk/coretk/dialogs/nodeservice.py +++ b/coretk/coretk/dialogs/nodeservice.py @@ -5,154 +5,98 @@ import tkinter as tk from tkinter import messagebox from coretk.dialogs.dialog import Dialog +from coretk.dialogs.serviceconfiguration import ServiceConfiguration +from coretk.widgets import CheckboxList, ListboxScroll -class NodeServicesDialog(Dialog): - def __init__(self, master, app, canvas_node): +class NodeService(Dialog): + def __init__(self, master, app, canvas_node, current_services=set()): super().__init__(master, app, "Node Services", modal=True) self.canvas_node = canvas_node - self.core_groups = [] - self.service_to_config = None - self.config_frame = None - self.services_list = None + self.groups = None + self.services = None + self.current = None + self.current_services = current_services self.draw() def draw(self): self.columnconfigure(0, weight=1) self.rowconfigure(0, weight=1) - self.config_frame = tk.Frame(self) - self.config_frame.columnconfigure(0, weight=1) - self.config_frame.columnconfigure(1, weight=1) - self.config_frame.columnconfigure(2, weight=1) - self.config_frame.rowconfigure(0, weight=1) - self.config_frame.grid(row=0, column=0, sticky="nsew") - self.draw_group() - self.draw_services() - self.draw_current_services() - self.draw_buttons() - def draw_group(self): - """ - draw the group tab - - :return: nothing - """ - frame = tk.Frame(self.config_frame) - frame.columnconfigure(0, weight=1) - frame.rowconfigure(1, weight=1) - frame.grid(row=0, column=0, padx=3, pady=3, sticky="nsew") - - label = tk.Label(frame, text="Group") - label.grid(row=0, column=0, sticky="ew") - - scrollbar = tk.Scrollbar(frame, orient=tk.VERTICAL) - scrollbar.grid(row=1, column=1, sticky="ns") - - listbox = tk.Listbox( - frame, - selectmode=tk.SINGLE, - yscrollcommand=scrollbar.set, - relief=tk.FLAT, - highlightthickness=0.5, - bd=0, - ) - listbox.grid(row=1, column=0, sticky="nsew") - listbox.bind("<>", self.handle_group_change) - - for group in sorted(self.app.core.services): - listbox.insert(tk.END, group) - - scrollbar.config(command=listbox.yview) - - def draw_services(self): - frame = tk.Frame(self.config_frame) - frame.columnconfigure(0, weight=1) - frame.rowconfigure(1, weight=1) - frame.grid(row=0, column=1, padx=3, pady=3, sticky="nsew") - - label = tk.Label(frame, text="Group services") - label.grid(row=0, column=0, sticky="ew") - - scrollbar = tk.Scrollbar(frame, orient=tk.VERTICAL) - scrollbar.grid(row=1, column=1, sticky="ns") - - self.services_list = tk.Listbox( - frame, - selectmode=tk.SINGLE, - yscrollcommand=scrollbar.set, - relief=tk.FLAT, - highlightthickness=0.5, - bd=0, - ) - self.services_list.grid(row=1, column=0, sticky="nsew") - self.services_list.bind("<>", self.handle_service_change) - - scrollbar.config(command=self.services_list.yview) - - def draw_current_services(self): - frame = tk.Frame(self.config_frame) - frame.columnconfigure(0, weight=1) - frame.rowconfigure(1, weight=1) - frame.grid(row=0, column=2, padx=3, pady=3, sticky="nsew") - - label = tk.Label(frame, text="Current services") - label.grid(row=0, column=0, sticky="ew") - - scrollbar = tk.Scrollbar(frame, orient=tk.VERTICAL) - scrollbar.grid(row=1, column=1, sticky="ns") - - listbox = tk.Listbox( - frame, - selectmode=tk.MULTIPLE, - yscrollcommand=scrollbar.set, - relief=tk.FLAT, - highlightthickness=0.5, - bd=0, - ) - listbox.grid(row=1, column=0, sticky="nsew") - - scrollbar.config(command=listbox.yview) - - def draw_buttons(self): frame = tk.Frame(self) - frame.columnconfigure(0, weight=1) - frame.columnconfigure(1, weight=1) - frame.columnconfigure(2, weight=1) - frame.grid(row=1, column=0, sticky="ew") + frame.grid(stick="nsew") + frame.rowconfigure(0, weight=1) + for i in range(3): + frame.columnconfigure(i, weight=1) + self.groups = ListboxScroll(frame, text="Groups") + self.groups.grid(row=0, column=0, sticky="nsew") + for group in sorted(self.app.core.services): + self.groups.listbox.insert(tk.END, group) + self.groups.listbox.bind("<>", self.handle_group_change) + self.groups.listbox.selection_set(0) + self.services = CheckboxList( + frame, text="Services", clicked=self.service_clicked + ) + self.services.grid(row=0, column=1, sticky="nsew") + + self.current = ListboxScroll(frame, text="Selected") + self.current.grid(row=0, column=2, sticky="nsew") + for service in sorted(self.current_services): + self.current.listbox.insert(tk.END, service) + + frame = tk.Frame(self) + frame.grid(stick="ew") + for i in range(3): + frame.columnconfigure(i, weight=1) button = tk.Button(frame, text="Configure", command=self.click_configure) button.grid(row=0, column=0, sticky="ew") - - button = tk.Button(frame, text="Apply") + button = tk.Button(frame, text="Save", command=self.click_save) button.grid(row=0, column=1, sticky="ew") - - button = tk.Button(frame, text="Cancel", command=self.destroy) + button = tk.Button(frame, text="Cancel", command=self.click_cancel) button.grid(row=0, column=2, sticky="ew") + # trigger group change + self.groups.listbox.event_generate("<>") + def handle_group_change(self, event): - listbox = event.widget - cur_selection = listbox.curselection() - if cur_selection: - s = listbox.get(listbox.curselection()) - self.display_group_services(s) + selection = self.groups.listbox.curselection() + if selection: + index = selection[0] + group = self.groups.listbox.get(index) + self.services.clear() + for service in sorted(self.app.core.services[group], key=lambda x: x.name): + checked = service.name in self.current_services + self.services.add(service.name, checked) - def display_group_services(self, group_name): - self.services_list.delete(0, tk.END) - for service in sorted(self.app.core.services[group_name], key=lambda x: x.name): - self.services_list.insert(tk.END, service.name) - - def handle_service_change(self, event): - print("select group service") - listbox = event.widget - cur_selection = listbox.curselection() - if cur_selection: - s = listbox.get(listbox.curselection()) - self.service_to_config = s - else: - self.service_to_config = None + def service_clicked(self, name, var): + if var.get() and name not in self.current_services: + self.current_services.add(name) + elif not var.get() and name in self.current_services: + self.current_services.remove(name) + self.current.listbox.delete(0, tk.END) + for name in sorted(self.current_services): + self.current.listbox.insert(tk.END, name) def click_configure(self): - if self.service_to_config is None: - messagebox.showinfo("CORE info", "Choose a service to configure.") + current_selection = self.current.listbox.curselection() + if len(current_selection): + dialog = ServiceConfiguration( + master=self, + app=self.app, + service_name=self.current.listbox.get(current_selection[0]), + canvas_node=self.canvas_node, + ) + dialog.show() else: - print(self.service_to_config) + messagebox.showinfo( + "Node service configuration", "Select a service to configure" + ) + + def click_save(self): + print("not implemented") + print(self.current_services) + + def click_cancel(self): + self.current_services = None + self.destroy() diff --git a/coretk/coretk/dialogs/serviceconfiguration.py b/coretk/coretk/dialogs/serviceconfiguration.py new file mode 100644 index 00000000..e352a2e8 --- /dev/null +++ b/coretk/coretk/dialogs/serviceconfiguration.py @@ -0,0 +1,185 @@ +"Service configuration dialog" + +import tkinter as tk +from tkinter import ttk + +from coretk.dialogs.dialog import Dialog +from coretk.images import ImageEnum, Images +from coretk.widgets import ListboxScroll + + +class ServiceConfiguration(Dialog): + def __init__(self, master, app, service_name, canvas_node): + super().__init__(master, app, service_name + " service", modal=True) + self.app = app + self.service_name = service_name + self.metadata = tk.StringVar() + self.filename = tk.StringVar() + self.radiovar = tk.IntVar() + self.radiovar.set(1) + self.startup_index = tk.IntVar() + self.start_time = tk.IntVar() + self.documentnew_img = Images.get(ImageEnum.DOCUMENTNEW) + self.editdelete_img = Images.get(ImageEnum.EDITDELETE) + self.draw() + + def draw(self): + # self.columnconfigure(1, weight=1) + frame = tk.Frame(self) + frame1 = tk.Frame(frame) + label = tk.Label(frame1, text=self.service_name) + label.grid(row=0, column=0, sticky="ew") + frame1.grid(row=0, column=0) + frame2 = tk.Frame(frame) + # frame2.columnconfigure(0, weight=1) + # frame2.columnconfigure(1, weight=4) + label = tk.Label(frame2, text="Meta-data") + label.grid(row=0, column=0) + entry = tk.Entry(frame2, textvariable=self.metadata) + entry.grid(row=0, column=1) + frame2.grid(row=1, column=0) + frame.grid(row=0, column=0) + + frame = tk.Frame(self) + tab_parent = ttk.Notebook(frame) + tab1 = ttk.Frame(tab_parent) + tab2 = ttk.Frame(tab_parent) + tab3 = ttk.Frame(tab_parent) + tab1.columnconfigure(0, weight=1) + tab2.columnconfigure(0, weight=1) + tab3.columnconfigure(0, weight=1) + + tab_parent.add(tab1, text="Files", sticky="nsew") + tab_parent.add(tab2, text="Directories", sticky="nsew") + tab_parent.add(tab3, text="Startup/shutdown", sticky="nsew") + tab_parent.grid(row=0, column=0, sticky="nsew") + frame.grid(row=1, column=0, sticky="nsew") + + # tab 1 + label = tk.Label( + tab1, text="Config files and scripts that are generated for this service." + ) + label.grid(row=0, column=0, sticky="nsew") + + frame = tk.Frame(tab1) + label = tk.Label(frame, text="File name: ") + label.grid(row=0, column=0) + entry = tk.Entry(frame, textvariable=self.filename) + entry.grid(row=0, column=1) + button = tk.Button(frame, image=self.documentnew_img) + button.grid(row=0, column=2) + button = tk.Button(frame, image=self.editdelete_img) + button.grid(row=0, column=3) + frame.grid(row=1, column=0, sticky="nsew") + + frame = tk.Frame(tab1) + button = tk.Radiobutton( + frame, + variable=self.radiovar, + text="Copy this source file:", + indicatoron=True, + ) + button.grid(row=0, column=0) + entry = tk.Entry(frame, state=tk.DISABLED) + entry.grid(row=0, column=1) + button = tk.Button(frame, text="not implemented") + button.grid(row=0, column=2) + frame.grid(row=2, column=0, sticky="nsew") + + frame = tk.Frame(tab1) + button = tk.Radiobutton( + frame, + variable=self.radiovar, + text="Use text below for file contents:", + indicatoron=True, + ) + button.grid(row=0, column=0) + button = tk.Button(frame, text="not implemented") + button.grid(row=0, column=1) + button = tk.Button(frame, text="not implemented") + button.grid(row=0, column=2) + frame.grid(row=3, column=0, sticky="nsew") + + # tab 2 + label = tk.Label( + tab2, + text="Directories required by this service that are unique for each node.", + ) + label.grid(row=0, column=0, sticky="nsew") + + # tab 3 + label_frame = tk.LabelFrame(tab3, text="Startup commands") + label_frame.columnconfigure(0, weight=1) + frame = tk.Frame(label_frame) + frame.columnconfigure(0, weight=1) + entry = tk.Entry(frame, textvariable=tk.StringVar()) + entry.grid(row=0, column=0, stick="nsew") + button = tk.Button(frame, image=self.documentnew_img) + button.grid(row=0, column=1, sticky="nsew") + button = tk.Button(frame, image=self.editdelete_img) + button.grid(row=0, column=2, sticky="nsew") + frame.grid(row=0, column=0, sticky="nsew") + listbox_scroll = ListboxScroll(label_frame) + listbox_scroll.listbox.config(height=4) + listbox_scroll.grid(row=1, column=0, sticky="nsew") + label_frame.grid(row=2, column=0, sticky="nsew") + + label_frame = tk.LabelFrame(tab3, text="Shutdown commands") + label_frame.columnconfigure(0, weight=1) + frame = tk.Frame(label_frame) + frame.columnconfigure(0, weight=1) + entry = tk.Entry(frame, textvariable=tk.StringVar()) + entry.grid(row=0, column=0, sticky="nsew") + button = tk.Button(frame, image=self.documentnew_img) + button.grid(row=0, column=1, sticky="nsew") + button = tk.Button(frame, image=self.editdelete_img) + button.grid(row=0, column=2, sticky="nsew") + frame.grid(row=0, column=0, sticky="nsew") + listbox_scroll = ListboxScroll(label_frame) + listbox_scroll.listbox.config(height=4) + listbox_scroll.grid(row=1, column=0, sticky="nsew") + label_frame.grid(row=3, column=0, sticky="nsew") + + label_frame = tk.LabelFrame(tab3, text="Validate commands") + label_frame.columnconfigure(0, weight=1) + frame = tk.Frame(label_frame) + frame.columnconfigure(0, weight=1) + entry = tk.Entry(frame, textvariable=tk.StringVar()) + entry.grid(row=0, column=0, sticky="nsew") + button = tk.Button(frame, image=self.documentnew_img) + button.grid(row=0, column=1, sticky="nsew") + button = tk.Button(frame, image=self.editdelete_img) + button.grid(row=0, column=2, sticky="nsew") + frame.grid(row=0, column=0, sticky="nsew") + listbox_scroll = ListboxScroll(label_frame) + listbox_scroll.listbox.config(height=4) + listbox_scroll.grid(row=1, column=0, sticky="nsew") + label_frame.grid(row=4, column=0, sticky="nsew") + + button = tk.Button( + self, text="onle store values that have changed from their defaults" + ) + button.grid(row=2, column=0) + + frame = tk.Frame(self) + button = tk.Button(frame, text="Apply", command=self.click_apply) + button.grid(row=0, column=0, sticky="nsew") + button = tk.Button(frame, text="Dafults", command=self.click_defaults) + button.grid(row=0, column=1, sticky="nsew") + button = tk.Button(frame, text="Copy...", command=self.click_copy) + button.grid(row=0, column=2, sticky="nsew") + button = tk.Button(frame, text="Cancel", command=self.click_cancel) + button.grid(row=0, column=3, sticky="nsew") + frame.grid(row=3, column=0) + + def click_apply(self, event): + print("not implemented") + + def click_defaults(self, event): + print("not implemented") + + def click_copy(self, event): + print("not implemented") + + def click_cancel(self, event): + print("not implemented") diff --git a/coretk/coretk/servicenodeconfig.py b/coretk/coretk/servicenodeconfig.py new file mode 100644 index 00000000..486e646d --- /dev/null +++ b/coretk/coretk/servicenodeconfig.py @@ -0,0 +1,37 @@ +""" +service node configuration +""" +import logging + + +class ServiceNodeConfig: + def __init__(self, app): + self.app = app + self.configurations = {} + self.default_services = {} + + def node_default_services_configuration(self, node_id, node_model): + """ + set the default configurations for the default services of a node + + :param coretk.graph.CanvasNode canvas_node: canvas node object + :return: nothing + """ + session_id = self.app.core.session_id + client = self.app.core.client + if len(self.default_services) == 0: + response = client.get_service_defaults(session_id) + logging.info("session default services: %s", response) + for default in response.defaults: + self.default_services[default.node_type] = default.services + + self.configurations[node_id] = {} + + for default in self.default_services[node_model]: + response = client.get_node_service(session_id, node_id, default) + logging.info( + "servicenodeconfig.py get node service (%s), result: %s", + node_id, + response, + ) + self.configurations[node_id][default] = response.service From 3dd3d928dd6bf8a6fd203a77785c5e49f0eb21b6 Mon Sep 17 00:00:00 2001 From: Huy Pham <42948410+hpham@users.noreply.github.com> Date: Mon, 11 Nov 2019 16:34:41 -0800 Subject: [PATCH 2/2] more work on designing node service configuration --- coretk/coretk/dialogs/serviceconfiguration.py | 227 ++++++++++++------ coretk/coretk/icons/document-save.gif | Bin 0 -> 1049 bytes coretk/coretk/images.py | 1 + 3 files changed, 158 insertions(+), 70 deletions(-) create mode 100644 coretk/coretk/icons/document-save.gif diff --git a/coretk/coretk/dialogs/serviceconfiguration.py b/coretk/coretk/dialogs/serviceconfiguration.py index e352a2e8..016373c8 100644 --- a/coretk/coretk/dialogs/serviceconfiguration.py +++ b/coretk/coretk/dialogs/serviceconfiguration.py @@ -16,11 +16,20 @@ class ServiceConfiguration(Dialog): self.metadata = tk.StringVar() self.filename = tk.StringVar() self.radiovar = tk.IntVar() - self.radiovar.set(1) + self.radiovar.set(2) self.startup_index = tk.IntVar() self.start_time = tk.IntVar() self.documentnew_img = Images.get(ImageEnum.DOCUMENTNEW) self.editdelete_img = Images.get(ImageEnum.EDITDELETE) + self.tab_parent = None + self.filenames = ["test1", "test2", "test3"] + + self.metadata_entry = None + self.filename_combobox = None + self.startup_commands_listbox = None + self.shutdown_commands_listbox = None + self.validate_commands_listbox = None + self.draw() def draw(self): @@ -35,24 +44,27 @@ class ServiceConfiguration(Dialog): # frame2.columnconfigure(1, weight=4) label = tk.Label(frame2, text="Meta-data") label.grid(row=0, column=0) - entry = tk.Entry(frame2, textvariable=self.metadata) - entry.grid(row=0, column=1) + self.metadata_entry = tk.Entry(frame2, textvariable=self.metadata) + self.metadata_entry.grid(row=0, column=1) frame2.grid(row=1, column=0) frame.grid(row=0, column=0) frame = tk.Frame(self) - tab_parent = ttk.Notebook(frame) - tab1 = ttk.Frame(tab_parent) - tab2 = ttk.Frame(tab_parent) - tab3 = ttk.Frame(tab_parent) + self.tab_parent = ttk.Notebook(frame) + tab1 = ttk.Frame(self.tab_parent) + tab2 = ttk.Frame(self.tab_parent) + tab3 = ttk.Frame(self.tab_parent) + tab4 = ttk.Frame(self.tab_parent) tab1.columnconfigure(0, weight=1) tab2.columnconfigure(0, weight=1) tab3.columnconfigure(0, weight=1) + tab4.columnconfigure(0, weight=1) - tab_parent.add(tab1, text="Files", sticky="nsew") - tab_parent.add(tab2, text="Directories", sticky="nsew") - tab_parent.add(tab3, text="Startup/shutdown", sticky="nsew") - tab_parent.grid(row=0, column=0, sticky="nsew") + self.tab_parent.add(tab1, text="Files", sticky="nsew") + self.tab_parent.add(tab2, text="Directories", sticky="nsew") + self.tab_parent.add(tab3, text="Startup/shutdown", sticky="nsew") + self.tab_parent.add(tab4, text="Configuration", sticky="nsew") + self.tab_parent.grid(row=0, column=0, sticky="nsew") frame.grid(row=1, column=0, sticky="nsew") # tab 1 @@ -64,11 +76,14 @@ class ServiceConfiguration(Dialog): frame = tk.Frame(tab1) label = tk.Label(frame, text="File name: ") label.grid(row=0, column=0) - entry = tk.Entry(frame, textvariable=self.filename) - entry.grid(row=0, column=1) + self.filename_combobox = ttk.Combobox(frame, values=self.filenames) + self.filename_combobox.grid(row=0, column=1) + self.filename_combobox.current(0) button = tk.Button(frame, image=self.documentnew_img) + button.bind("", self.add_filename) button.grid(row=0, column=2) button = tk.Button(frame, image=self.editdelete_img) + button.bind("", self.delete_filename) button.grid(row=0, column=3) frame.grid(row=1, column=0, sticky="nsew") @@ -78,11 +93,13 @@ class ServiceConfiguration(Dialog): variable=self.radiovar, text="Copy this source file:", indicatoron=True, + value=1, + state="disabled", ) button.grid(row=0, column=0) entry = tk.Entry(frame, state=tk.DISABLED) entry.grid(row=0, column=1) - button = tk.Button(frame, text="not implemented") + button = tk.Button(frame, image=Images.get(ImageEnum.FILEOPEN)) button.grid(row=0, column=2) frame.grid(row=2, column=0, sticky="nsew") @@ -92,11 +109,12 @@ class ServiceConfiguration(Dialog): variable=self.radiovar, text="Use text below for file contents:", indicatoron=True, + value=2, ) button.grid(row=0, column=0) - button = tk.Button(frame, text="not implemented") + button = tk.Button(frame, image=Images.get(ImageEnum.FILEOPEN)) button.grid(row=0, column=1) - button = tk.Button(frame, text="not implemented") + button = tk.Button(frame, image=Images.get(ImageEnum.DOCUMENTSAVE)) button.grid(row=0, column=2) frame.grid(row=3, column=0, sticky="nsew") @@ -108,53 +126,64 @@ class ServiceConfiguration(Dialog): label.grid(row=0, column=0, sticky="nsew") # tab 3 - label_frame = tk.LabelFrame(tab3, text="Startup commands") - label_frame.columnconfigure(0, weight=1) - frame = tk.Frame(label_frame) - frame.columnconfigure(0, weight=1) - entry = tk.Entry(frame, textvariable=tk.StringVar()) - entry.grid(row=0, column=0, stick="nsew") - button = tk.Button(frame, image=self.documentnew_img) - button.grid(row=0, column=1, sticky="nsew") - button = tk.Button(frame, image=self.editdelete_img) - button.grid(row=0, column=2, sticky="nsew") - frame.grid(row=0, column=0, sticky="nsew") - listbox_scroll = ListboxScroll(label_frame) - listbox_scroll.listbox.config(height=4) - listbox_scroll.grid(row=1, column=0, sticky="nsew") - label_frame.grid(row=2, column=0, sticky="nsew") + for i in range(3): + label_frame = None + if i == 0: + label_frame = tk.LabelFrame(tab3, text="Startup commands") + elif i == 1: + label_frame = tk.LabelFrame(tab3, text="Shutdown commands") + elif i == 2: + label_frame = tk.LabelFrame(tab3, text="Validation commands") + label_frame.columnconfigure(0, weight=1) + frame = tk.Frame(label_frame) + frame.columnconfigure(0, weight=1) + entry = tk.Entry(frame, textvariable=tk.StringVar()) + entry.grid(row=0, column=0, stick="nsew") + button = tk.Button(frame, image=self.documentnew_img) + button.bind("", self.add_command) + button.grid(row=0, column=1, sticky="nsew") + button = tk.Button(frame, image=self.editdelete_img) + button.grid(row=0, column=2, sticky="nsew") + button.bind("", self.delete_command) + frame.grid(row=0, column=0, sticky="nsew") + listbox_scroll = ListboxScroll(label_frame) + listbox_scroll.listbox.bind("<>", self.update_entry) + listbox_scroll.listbox.config(height=4) + listbox_scroll.grid(row=1, column=0, sticky="nsew") + if i == 0: + self.startup_commands_listbox = listbox_scroll.listbox + elif i == 1: + self.shutdown_commands_listbox = listbox_scroll.listbox + elif i == 2: + self.validate_commands_listbox = listbox_scroll.listbox + label_frame.grid(row=i, column=0, sticky="nsew") - label_frame = tk.LabelFrame(tab3, text="Shutdown commands") - label_frame.columnconfigure(0, weight=1) - frame = tk.Frame(label_frame) - frame.columnconfigure(0, weight=1) - entry = tk.Entry(frame, textvariable=tk.StringVar()) - entry.grid(row=0, column=0, sticky="nsew") - button = tk.Button(frame, image=self.documentnew_img) - button.grid(row=0, column=1, sticky="nsew") - button = tk.Button(frame, image=self.editdelete_img) - button.grid(row=0, column=2, sticky="nsew") - frame.grid(row=0, column=0, sticky="nsew") - listbox_scroll = ListboxScroll(label_frame) - listbox_scroll.listbox.config(height=4) - listbox_scroll.grid(row=1, column=0, sticky="nsew") - label_frame.grid(row=3, column=0, sticky="nsew") + # tab 4 + for i in range(2): + if i == 0: + label_frame = tk.LabelFrame(tab4, text="Executables") + elif i == 1: + label_frame = tk.LabelFrame(tab4, text="Dependencies") - label_frame = tk.LabelFrame(tab3, text="Validate commands") - label_frame.columnconfigure(0, weight=1) - frame = tk.Frame(label_frame) - frame.columnconfigure(0, weight=1) - entry = tk.Entry(frame, textvariable=tk.StringVar()) - entry.grid(row=0, column=0, sticky="nsew") - button = tk.Button(frame, image=self.documentnew_img) - button.grid(row=0, column=1, sticky="nsew") - button = tk.Button(frame, image=self.editdelete_img) - button.grid(row=0, column=2, sticky="nsew") - frame.grid(row=0, column=0, sticky="nsew") - listbox_scroll = ListboxScroll(label_frame) - listbox_scroll.listbox.config(height=4) - listbox_scroll.grid(row=1, column=0, sticky="nsew") - label_frame.grid(row=4, column=0, sticky="nsew") + label_frame.columnconfigure(0, weight=1) + listbox_scroll = ListboxScroll(label_frame) + listbox_scroll.listbox.config(height=4, state="disabled") + listbox_scroll.grid(row=0, column=0, sticky="nsew") + label_frame.grid(row=i, column=0, sticky="nsew") + + for i in range(3): + frame = tk.Frame(tab4) + frame.columnconfigure(0, weight=1) + if i == 0: + label = tk.Label(frame, text="Validation time:") + elif i == 1: + label = tk.Label(frame, text="Validation mode:") + elif i == 2: + label = tk.Label(frame, text="Validation period:") + label.grid(row=i, column=0) + entry = tk.Entry(frame, state="disabled", textvariable=tk.StringVar()) + entry.grid(row=i, column=1) + frame.grid(row=2 + i, column=0, sticky="nsew") button = tk.Button( self, text="onle store values that have changed from their defaults" @@ -164,22 +193,80 @@ class ServiceConfiguration(Dialog): frame = tk.Frame(self) button = tk.Button(frame, text="Apply", command=self.click_apply) button.grid(row=0, column=0, sticky="nsew") - button = tk.Button(frame, text="Dafults", command=self.click_defaults) + button = tk.Button( + frame, text="Dafults", command=self.click_defaults, state="disabled" + ) button.grid(row=0, column=1, sticky="nsew") - button = tk.Button(frame, text="Copy...", command=self.click_copy) + button = tk.Button( + frame, text="Copy...", command=self.click_copy, state="disabled" + ) button.grid(row=0, column=2, sticky="nsew") - button = tk.Button(frame, text="Cancel", command=self.click_cancel) + button = tk.Button(frame, text="Cancel", command=self.destroy) button.grid(row=0, column=3, sticky="nsew") frame.grid(row=3, column=0) - def click_apply(self, event): + def add_filename(self, event): + frame_contains_button = event.widget.master + combobox = frame_contains_button.grid_slaves(row=0, column=1)[0] + filename = combobox.get() + if filename not in combobox["values"]: + combobox["values"] += (filename,) + + def delete_filename(self, event): + frame_comntains_button = event.widget.master + combobox = frame_comntains_button.grid_slaves(row=0, column=1)[0] + filename = combobox.get() + if filename in combobox["values"]: + combobox["values"] = tuple([x for x in combobox["values"] if x != filename]) + combobox.set("") + + def add_command(self, event): + frame_contains_button = event.widget.master + listbox = frame_contains_button.master.grid_slaves(row=1, column=0)[0].listbox + command_to_add = frame_contains_button.grid_slaves(row=0, column=0)[0].get() + if command_to_add == "": + return + for cmd in listbox.get(0, tk.END): + if cmd == command_to_add: + return + listbox.insert(tk.END, command_to_add) + + def update_entry(self, event): + listbox = event.widget + current_selection = listbox.curselection() + if len(current_selection) > 0: + cmd = listbox.get(current_selection[0]) + entry = listbox.master.master.grid_slaves(row=0, column=0)[0].grid_slaves( + row=0, column=0 + )[0] + entry.delete(0, "end") + entry.insert(0, cmd) + + def delete_command(self, event): + button = event.widget + frame_contains_button = button.master + listbox = frame_contains_button.master.grid_slaves(row=1, column=0)[0].listbox + current_selection = listbox.curselection() + if len(current_selection) > 0: + listbox.delete(current_selection[0]) + entry = frame_contains_button.grid_slaves(row=0, column=0)[0] + entry.delete(0, tk.END) + + def click_apply(self): + metadata = self.metadata_entry.get() + filenames = list(self.filename_combobox["values"]) + startup_commands = self.startup_commands_listbox.get(0, "end") + shutdown_commands = self.shutdown_commands_listbox.get(0, "end") + validate_commands = self.validate_commands_listbox.get(0, "end") + print( + metadata, filenames, startup_commands, shutdown_commands, validate_commands + ) + + def click_defaults(self): print("not implemented") - def click_defaults(self, event): + def click_copy(self): print("not implemented") - def click_copy(self, event): - print("not implemented") - - def click_cancel(self, event): + def click_cancel(self): print("not implemented") diff --git a/coretk/coretk/icons/document-save.gif b/coretk/coretk/icons/document-save.gif new file mode 100644 index 0000000000000000000000000000000000000000..165bcb908bbcf12dfb5d0c06a933898ed8f3944c GIT binary patch literal 1049 zcmZ?wbhEHb6krfw_}@YinU=Z|&e<14NFF4ld44ZmzCg z9-cm4UOwJlzTVz`KE46IegS^|fqwo${sBS$K0$$j!2!Xcfx)3cp)oNjndzz7*?C3z zMP~yN%>eKber00=&?_cmGkk~>bNa@fGjG?NeY^JT=M^U&Y&`d1?~!8%PM$h?>ddk8*N$Dd za{9`Zi`TASzIprlov%mkeLME($C-x@?>~Na|H+SwPk&x|{`1<4pVuBfe(>n=gU62_ zK7R7>$Hy=K} z|M>C!r_Ue1e*OIQ+n2B3zJB}m^~aANzyJLH144iP{{8#^|9^&2K;sZl{K>+|z|h5@ z1F{E{Cm1-sF^F=Ccsy!8$gjkvB_r{uXI8tKnApdQix+hmo2Jb%Ol)TFmv^iC!Pvqf zz}X|^|3g!G#rb}@hBp$Mij5v0GmpRb7dnSnV*-j_uJ)us;Cr9J~LHYW5xwW<>NUDdbt97Hy(V% z$)(wGNaN(?!^}$Z!Q1vIwxqgFGm4t@LgC3m=0&Gx2#Oj_k-W&p?c^l?(@>>DK-r^7 z#8T-<69WeWk4D0U1x##QykZIr7Y;NuvhgYeEGT%$)W&^S(;-8_p_!5K0y9g4-(LnM KMj0k125SJ$J7sYI literal 0 HcmV?d00001 diff --git a/coretk/coretk/images.py b/coretk/coretk/images.py index f25b0eb1..03e7fc01 100644 --- a/coretk/coretk/images.py +++ b/coretk/coretk/images.py @@ -101,6 +101,7 @@ class ImageEnum(Enum): OBSERVE = "observe" RUN = "run" DOCUMENTNEW = "document-new" + DOCUMENTSAVE = "document-save" FILEOPEN = "fileopen" EDITDELETE = "edit-delete" ANTENNA = "antenna"