class ServicesSelectDialog(Dialog): def __init__(self, master: tk.BaseWidget, app: "Application", current_services: Set[str]) -> None: super().__init__(app, "Node Services", master=master) self.groups: Optional[ListboxScroll] = None self.services: Optional[CheckboxList] = None self.current: Optional[ListboxScroll] = None self.current_services: Set[str] = current_services self.draw() def draw(self) -> None: self.top.columnconfigure(0, weight=1) self.top.rowconfigure(0, weight=1) frame = ttk.LabelFrame(self.top) frame.grid(stick=tk.NSEW, pady=PADY) frame.rowconfigure(0, weight=1) for i in range(3): frame.columnconfigure(i, weight=1) label_frame = ttk.LabelFrame(frame, text="Groups", padding=FRAME_PAD) label_frame.grid(row=0, column=0, sticky=tk.NSEW) label_frame.rowconfigure(0, weight=1) label_frame.columnconfigure(0, weight=1) self.groups = ListboxScroll(label_frame) self.groups.grid(sticky=tk.NSEW) for group in sorted(self.app.core.services): self.groups.listbox.insert(tk.END, group) self.groups.listbox.bind("<<ListboxSelect>>", self.handle_group_change) self.groups.listbox.selection_set(0) label_frame = ttk.LabelFrame(frame, text="Services") label_frame.grid(row=0, column=1, sticky=tk.NSEW) label_frame.columnconfigure(0, weight=1) label_frame.rowconfigure(0, weight=1) self.services = CheckboxList(label_frame, self.app, clicked=self.service_clicked, padding=FRAME_PAD) self.services.grid(sticky=tk.NSEW) label_frame = ttk.LabelFrame(frame, text="Selected", padding=FRAME_PAD) label_frame.grid(row=0, column=2, sticky=tk.NSEW) label_frame.rowconfigure(0, weight=1) label_frame.columnconfigure(0, weight=1) self.current = ListboxScroll(label_frame) self.current.grid(sticky=tk.NSEW) for service in sorted(self.current_services): self.current.listbox.insert(tk.END, service) frame = ttk.Frame(self.top) frame.grid(stick=tk.EW) for i in range(2): frame.columnconfigure(i, weight=1) button = ttk.Button(frame, text="Save", command=self.destroy) button.grid(row=0, column=0, sticky=tk.EW, padx=PADX) button = ttk.Button(frame, text="Cancel", command=self.click_cancel) button.grid(row=0, column=1, sticky=tk.EW) # trigger group change self.groups.listbox.event_generate("<<ListboxSelect>>") def handle_group_change(self, event: tk.Event) -> None: selection = self.groups.listbox.curselection() if selection: index = selection[0] group = self.groups.listbox.get(index) self.services.clear() for name in sorted(self.app.core.services[group]): checked = name in self.current_services self.services.add(name, checked) def service_clicked(self, name: str, var: tk.BooleanVar) -> None: 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_cancel(self) -> None: self.current_services = None self.destroy()
class NodeConfigServiceDialog(Dialog): def __init__( self, master: Any, app: "Application", canvas_node: "CanvasNode", services: Set[str] = None, ): title = f"{canvas_node.core_node.name} Config Services" super().__init__(master, app, title, modal=True) self.app = app self.canvas_node = canvas_node self.node_id = canvas_node.core_node.id self.groups = None self.services = None self.current = None if services is None: services = set(canvas_node.core_node.config_services) self.current_services = services self.draw() def draw(self): self.top.columnconfigure(0, weight=1) self.top.rowconfigure(0, weight=1) frame = ttk.Frame(self.top) frame.grid(stick="nsew", pady=PADY) frame.rowconfigure(0, weight=1) for i in range(3): frame.columnconfigure(i, weight=1) label_frame = ttk.LabelFrame(frame, text="Groups", padding=FRAME_PAD) label_frame.grid(row=0, column=0, sticky="nsew") label_frame.rowconfigure(0, weight=1) label_frame.columnconfigure(0, weight=1) self.groups = ListboxScroll(label_frame) self.groups.grid(sticky="nsew") for group in sorted(self.app.core.config_services_groups): self.groups.listbox.insert(tk.END, group) self.groups.listbox.bind("<<ListboxSelect>>", self.handle_group_change) self.groups.listbox.selection_set(0) label_frame = ttk.LabelFrame(frame, text="Services") label_frame.grid(row=0, column=1, sticky="nsew") label_frame.columnconfigure(0, weight=1) label_frame.rowconfigure(0, weight=1) self.services = CheckboxList( label_frame, self.app, clicked=self.service_clicked, padding=FRAME_PAD ) self.services.grid(sticky="nsew") label_frame = ttk.LabelFrame(frame, text="Selected", padding=FRAME_PAD) label_frame.grid(row=0, column=2, sticky="nsew") label_frame.rowconfigure(0, weight=1) label_frame.columnconfigure(0, weight=1) self.current = ListboxScroll(label_frame) self.current.grid(sticky="nsew") for service in sorted(self.current_services): self.current.listbox.insert(tk.END, service) if self.is_custom_service(service): self.current.listbox.itemconfig(tk.END, bg="green") frame = ttk.Frame(self.top) frame.grid(stick="ew") for i in range(4): frame.columnconfigure(i, weight=1) button = ttk.Button(frame, text="Configure", command=self.click_configure) button.grid(row=0, column=0, sticky="ew", padx=PADX) button = ttk.Button(frame, text="Save", command=self.click_save) button.grid(row=0, column=1, sticky="ew", padx=PADX) button = ttk.Button(frame, text="Remove", command=self.click_remove) button.grid(row=0, column=2, sticky="ew", padx=PADX) button = ttk.Button(frame, text="Cancel", command=self.click_cancel) button.grid(row=0, column=3, sticky="ew") # trigger group change self.groups.listbox.event_generate("<<ListboxSelect>>") def handle_group_change(self, event: tk.Event = None): selection = self.groups.listbox.curselection() if selection: index = selection[0] group = self.groups.listbox.get(index) self.services.clear() for name in sorted(self.app.core.config_services_groups[group]): checked = name in self.current_services self.services.add(name, checked) def service_clicked(self, name: str, var: tk.IntVar): 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) if self.is_custom_service(name): self.current.listbox.itemconfig(tk.END, bg="green") self.canvas_node.core_node.config_services[:] = self.current_services def click_configure(self): current_selection = self.current.listbox.curselection() if len(current_selection): dialog = ConfigServiceConfigDialog( master=self, app=self.app, service_name=self.current.listbox.get(current_selection[0]), node_id=self.node_id, ) if not dialog.has_error: dialog.show() else: messagebox.showinfo( "Node service configuration", "Select a service to configure" ) def click_save(self): self.canvas_node.core_node.config_services[:] = self.current_services logging.info( "saved node config services: %s", self.canvas_node.core_node.config_services ) self.destroy() def click_cancel(self): self.current_services = None self.destroy() def click_remove(self): cur = self.current.listbox.curselection() if cur: service = self.current.listbox.get(cur[0]) self.current.listbox.delete(cur[0]) self.current_services.remove(service) for checkbutton in self.services.frame.winfo_children(): if checkbutton["text"] == service: checkbutton.invoke() return def is_custom_service(self, service: str) -> bool: node_configs = self.app.core.config_service_configs.get(self.node_id, {}) service_config = node_configs.get(service) if node_configs and service_config: return True else: return False
class NodeServiceDialog(Dialog): def __init__( self, master: Any, app: "Application", canvas_node: "CanvasNode", services: Set[str] = None, ): title = f"{canvas_node.core_node.name} Services" super().__init__(master, app, title, modal=True) self.app = app self.canvas_node = canvas_node self.node_id = canvas_node.core_node.id self.groups = None self.services = None self.current = None if services is None: services = canvas_node.core_node.services model = canvas_node.core_node.model if len(services) == 0: # not custom node type and node's services haven't been modified before if not NodeUtils.is_custom( canvas_node.core_node.model ) and not self.app.core.service_been_modified(self.node_id): services = set(self.app.core.default_services[model]) # services of default type nodes were modified to be empty elif canvas_node.core_node.id in self.app.core.modified_service_nodes: services = set() else: services = set( NodeUtils.get_custom_node_services( self.app.guiconfig, model)) else: services = set(services) self.current_services = services self.draw() def draw(self): self.top.columnconfigure(0, weight=1) self.top.rowconfigure(0, weight=1) frame = ttk.Frame(self.top) frame.grid(stick="nsew", pady=PADY) frame.rowconfigure(0, weight=1) for i in range(3): frame.columnconfigure(i, weight=1) label_frame = ttk.LabelFrame(frame, text="Groups", padding=FRAME_PAD) label_frame.grid(row=0, column=0, sticky="nsew") label_frame.rowconfigure(0, weight=1) label_frame.columnconfigure(0, weight=1) self.groups = ListboxScroll(label_frame) self.groups.grid(sticky="nsew") for group in sorted(self.app.core.services): self.groups.listbox.insert(tk.END, group) self.groups.listbox.bind("<<ListboxSelect>>", self.handle_group_change) self.groups.listbox.selection_set(0) label_frame = ttk.LabelFrame(frame, text="Services") label_frame.grid(row=0, column=1, sticky="nsew") label_frame.columnconfigure(0, weight=1) label_frame.rowconfigure(0, weight=1) self.services = CheckboxList(label_frame, self.app, clicked=self.service_clicked, padding=FRAME_PAD) self.services.grid(sticky="nsew") label_frame = ttk.LabelFrame(frame, text="Selected", padding=FRAME_PAD) label_frame.grid(row=0, column=2, sticky="nsew") label_frame.rowconfigure(0, weight=1) label_frame.columnconfigure(0, weight=1) self.current = ListboxScroll(label_frame) self.current.grid(sticky="nsew") for service in sorted(self.current_services): self.current.listbox.insert(tk.END, service) if self.is_custom_service(service): self.current.listbox.itemconfig(tk.END, bg="green") frame = ttk.Frame(self.top) frame.grid(stick="ew") for i in range(4): frame.columnconfigure(i, weight=1) button = ttk.Button(frame, text="Configure", command=self.click_configure) button.grid(row=0, column=0, sticky="ew", padx=PADX) button = ttk.Button(frame, text="Save", command=self.click_save) button.grid(row=0, column=1, sticky="ew", padx=PADX) button = ttk.Button(frame, text="Remove", command=self.click_remove) button.grid(row=0, column=2, sticky="ew", padx=PADX) button = ttk.Button(frame, text="Cancel", command=self.click_cancel) button.grid(row=0, column=3, sticky="ew") # trigger group change self.groups.listbox.event_generate("<<ListboxSelect>>") def handle_group_change(self, event: tk.Event = None): selection = self.groups.listbox.curselection() if selection: index = selection[0] group = self.groups.listbox.get(index) self.services.clear() for name in sorted(self.app.core.services[group]): checked = name in self.current_services self.services.add(name, checked) def service_clicked(self, name: str, var: tk.IntVar): 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) if self.is_custom_service(name): self.current.listbox.itemconfig(tk.END, bg="green") self.canvas_node.core_node.services[:] = self.current_services def click_configure(self): current_selection = self.current.listbox.curselection() if len(current_selection): dialog = ServiceConfigDialog( master=self, app=self.app, service_name=self.current.listbox.get(current_selection[0]), node_id=self.node_id, ) # if error occurred when creating ServiceConfigDialog, don't show the dialog if not dialog.has_error: dialog.show() else: dialog.destroy() else: messagebox.showinfo("Node service configuration", "Select a service to configure") def click_save(self): # if node is custom type or current services are not the default services then set core node services and add node to modified services node set if (self.canvas_node.core_node.model not in self.app.core.default_services or self.current_services != self.app.core.default_services[ self.canvas_node.core_node.model]): self.canvas_node.core_node.services[:] = self.current_services self.app.core.modified_service_nodes.add( self.canvas_node.core_node.id) else: if len(self.canvas_node.core_node.services) > 0: self.canvas_node.core_node.services[:] = [] self.destroy() def click_cancel(self): self.current_services = None self.destroy() def click_remove(self): cur = self.current.listbox.curselection() if cur: service = self.current.listbox.get(cur[0]) self.current.listbox.delete(cur[0]) self.current_services.remove(service) for checkbutton in self.services.frame.winfo_children(): if checkbutton["text"] == service: checkbutton.invoke() return def is_custom_service(self, service: str) -> bool: service_configs = self.app.core.service_configs file_configs = self.app.core.file_configs if self.node_id in service_configs and service in service_configs[ self.node_id]: return True if (self.node_id in file_configs and service in file_configs[self.node_id] and file_configs[self.node_id][service]): return True return False
class NodeServiceDialog(Dialog): def __init__(self, app: "Application", node: Node) -> None: title = f"{node.name} Services (Deprecated)" super().__init__(app, title) self.node: Node = node self.groups: Optional[ListboxScroll] = None self.services: Optional[CheckboxList] = None self.current: Optional[ListboxScroll] = None services = set(node.services) self.current_services: Set[str] = services self.protocol("WM_DELETE_WINDOW", self.click_cancel) self.draw() def draw(self) -> None: self.top.columnconfigure(0, weight=1) self.top.rowconfigure(0, weight=1) frame = ttk.Frame(self.top) frame.grid(stick="nsew", pady=PADY) frame.rowconfigure(0, weight=1) for i in range(3): frame.columnconfigure(i, weight=1) label_frame = ttk.LabelFrame(frame, text="Groups", padding=FRAME_PAD) label_frame.grid(row=0, column=0, sticky=tk.NSEW) label_frame.rowconfigure(0, weight=1) label_frame.columnconfigure(0, weight=1) self.groups = ListboxScroll(label_frame) self.groups.grid(sticky=tk.NSEW) for group in sorted(self.app.core.services): self.groups.listbox.insert(tk.END, group) self.groups.listbox.bind("<<ListboxSelect>>", self.handle_group_change) self.groups.listbox.selection_set(0) label_frame = ttk.LabelFrame(frame, text="Services") label_frame.grid(row=0, column=1, sticky=tk.NSEW) label_frame.columnconfigure(0, weight=1) label_frame.rowconfigure(0, weight=1) self.services = CheckboxList(label_frame, self.app, clicked=self.service_clicked, padding=FRAME_PAD) self.services.grid(sticky=tk.NSEW) label_frame = ttk.LabelFrame(frame, text="Selected", padding=FRAME_PAD) label_frame.grid(row=0, column=2, sticky=tk.NSEW) label_frame.rowconfigure(0, weight=1) label_frame.columnconfigure(0, weight=1) self.current = ListboxScroll(label_frame) self.current.grid(sticky=tk.NSEW) for service in sorted(self.current_services): self.current.listbox.insert(tk.END, service) if self.is_custom_service(service): self.current.listbox.itemconfig(tk.END, bg="green") frame = ttk.Frame(self.top) frame.grid(stick="ew") for i in range(4): frame.columnconfigure(i, weight=1) button = ttk.Button(frame, text="Configure", command=self.click_configure) button.grid(row=0, column=0, sticky=tk.EW, padx=PADX) button = ttk.Button(frame, text="Save", command=self.click_save) button.grid(row=0, column=1, sticky=tk.EW, padx=PADX) button = ttk.Button(frame, text="Remove", command=self.click_remove) button.grid(row=0, column=2, sticky=tk.EW, padx=PADX) button = ttk.Button(frame, text="Cancel", command=self.click_cancel) button.grid(row=0, column=3, sticky=tk.EW) # trigger group change self.handle_group_change() def handle_group_change(self, event: tk.Event = None) -> None: selection = self.groups.listbox.curselection() if selection: index = selection[0] group = self.groups.listbox.get(index) self.services.clear() for name in sorted(self.app.core.services[group]): checked = name in self.current_services self.services.add(name, checked) def service_clicked(self, name: str, var: tk.IntVar) -> None: 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.node.service_configs.pop(name, None) self.node.service_file_configs.pop(name, None) self.current.listbox.delete(0, tk.END) for name in sorted(self.current_services): self.current.listbox.insert(tk.END, name) if self.is_custom_service(name): self.current.listbox.itemconfig(tk.END, bg="green") self.node.services = self.current_services.copy() def click_configure(self) -> None: current_selection = self.current.listbox.curselection() if len(current_selection): dialog = ServiceConfigDialog( self, self.app, self.current.listbox.get(current_selection[0]), self.node, ) # if error occurred when creating ServiceConfigDialog, don't show the dialog if not dialog.has_error: dialog.show() else: dialog.destroy() else: messagebox.showinfo("Service Configuration", "Select a service to configure", parent=self) def click_cancel(self) -> None: self.destroy() def click_save(self) -> None: self.node.services = self.current_services.copy() self.destroy() def click_remove(self) -> None: cur = self.current.listbox.curselection() if cur: service = self.current.listbox.get(cur[0]) self.current.listbox.delete(cur[0]) self.current_services.remove(service) self.node.service_configs.pop(service, None) self.node.service_file_configs.pop(service, None) for checkbutton in self.services.frame.winfo_children(): if checkbutton["text"] == service: checkbutton.invoke() return def is_custom_service(self, service: str) -> bool: has_service_config = service in self.node.service_configs has_file_config = service in self.node.service_file_configs return has_service_config or has_file_config
class NodeServiceDialog(Dialog): def __init__(self, master, app, canvas_node, services=None): title = f"{canvas_node.core_node.name} Services" super().__init__(master, app, title, modal=True) self.app = app self.canvas_node = canvas_node self.node_id = canvas_node.core_node.id self.groups = None self.services = None self.current = None if services is None: services = canvas_node.core_node.services model = canvas_node.core_node.model if len(services) == 0: services = set(self.app.core.default_services[model]) else: services = set(services) self.current_services = services self.draw() def draw(self): self.top.columnconfigure(0, weight=1) self.top.rowconfigure(0, weight=1) frame = ttk.Frame(self.top) frame.grid(stick="nsew", pady=PADY) frame.rowconfigure(0, weight=1) for i in range(3): frame.columnconfigure(i, weight=1) label_frame = ttk.LabelFrame(frame, text="Groups", padding=FRAME_PAD) label_frame.grid(row=0, column=0, sticky="nsew") label_frame.rowconfigure(0, weight=1) label_frame.columnconfigure(0, weight=1) self.groups = ListboxScroll(label_frame) self.groups.grid(sticky="nsew") for group in sorted(self.app.core.services): self.groups.listbox.insert(tk.END, group) self.groups.listbox.bind("<<ListboxSelect>>", self.handle_group_change) self.groups.listbox.selection_set(0) label_frame = ttk.LabelFrame(frame, text="Services") label_frame.grid(row=0, column=1, sticky="nsew") label_frame.columnconfigure(0, weight=1) label_frame.rowconfigure(0, weight=1) self.services = CheckboxList( label_frame, self.app, clicked=self.service_clicked, padding=FRAME_PAD ) self.services.grid(sticky="nsew") label_frame = ttk.LabelFrame(frame, text="Selected", padding=FRAME_PAD) label_frame.grid(row=0, column=2, sticky="nsew") label_frame.rowconfigure(0, weight=1) label_frame.columnconfigure(0, weight=1) self.current = ListboxScroll(label_frame) self.current.grid(sticky="nsew") for service in sorted(self.current_services): self.current.listbox.insert(tk.END, service) frame = ttk.Frame(self.top) frame.grid(stick="ew") for i in range(3): frame.columnconfigure(i, weight=1) button = ttk.Button(frame, text="Configure", command=self.click_configure) button.grid(row=0, column=0, sticky="ew", padx=PADX) button = ttk.Button(frame, text="Save", command=self.click_save) button.grid(row=0, column=1, sticky="ew", padx=PADX) button = ttk.Button(frame, text="Cancel", command=self.click_cancel) button.grid(row=0, column=2, sticky="ew") # trigger group change self.groups.listbox.event_generate("<<ListboxSelect>>") def handle_group_change(self, event): selection = self.groups.listbox.curselection() if selection: index = selection[0] group = self.groups.listbox.get(index) self.services.clear() for name in sorted(self.app.core.services[group]): checked = name in self.current_services self.services.add(name, checked) 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) self.canvas_node.core_node.services[:] = self.current_services def click_configure(self): current_selection = self.current.listbox.curselection() if len(current_selection): dialog = ServiceConfigDialog( master=self, app=self.app, service_name=self.current.listbox.get(current_selection[0]), node_id=self.node_id, ) dialog.show() else: messagebox.showinfo( "Node service configuration", "Select a service to configure" ) def click_save(self): if ( self.current_services != self.app.core.default_services[self.canvas_node.core_node.model] ): self.canvas_node.core_node.services[:] = self.current_services else: if len(self.canvas_node.core_node.services) > 0: self.canvas_node.core_node.services[:] = [] self.destroy() def click_cancel(self): self.current_services = None self.destroy()