added preferences dialog, updates to try and simplify config saving a bit, adding default preferences configurations

This commit is contained in:
Blake Harnden 2019-11-11 15:35:48 -08:00
parent f5480c8e35
commit 691013eeb8
12 changed files with 126 additions and 22 deletions

View file

@ -1,7 +1,7 @@
import logging import logging
import tkinter as tk import tkinter as tk
from coretk import appdirs from coretk import appconfig
from coretk.coreclient import CoreClient from coretk.coreclient import CoreClient
from coretk.graph import CanvasGraph from coretk.graph import CanvasGraph
from coretk.images import ImageEnum, Images from coretk.images import ImageEnum, Images
@ -26,7 +26,7 @@ class Application(tk.Frame):
self.radiovar = tk.IntVar(value=1) self.radiovar = tk.IntVar(value=1)
self.show_grid_var = tk.IntVar(value=1) self.show_grid_var = tk.IntVar(value=1)
self.adjust_to_dim_var = tk.IntVar(value=0) self.adjust_to_dim_var = tk.IntVar(value=0)
self.config = appdirs.read_config() self.config = appconfig.read()
self.core = CoreClient(self) self.core = CoreClient(self)
self.setup_app() self.setup_app()
self.draw() self.draw()
@ -70,10 +70,13 @@ class Application(tk.Frame):
menu_action = MenuAction(self, self.master) menu_action = MenuAction(self, self.master)
menu_action.on_quit() menu_action.on_quit()
def save_config(self):
appconfig.save(self.config)
if __name__ == "__main__": if __name__ == "__main__":
log_format = "%(asctime)s - %(levelname)s - %(module)s:%(funcName)s - %(message)s" log_format = "%(asctime)s - %(levelname)s - %(module)s:%(funcName)s - %(message)s"
logging.basicConfig(level=logging.DEBUG, format=log_format) logging.basicConfig(level=logging.DEBUG, format=log_format)
appdirs.check_directory() appconfig.check_directory()
app = Application() app = Application()
app.mainloop() app.mainloop()

View file

@ -1,4 +1,5 @@
import logging import logging
import os
import shutil import shutil
from pathlib import Path from pathlib import Path
@ -18,6 +19,20 @@ CONFIG_PATH = HOME_PATH.joinpath("gui.yaml")
LOCAL_ICONS_PATH = Path(__file__).parent.joinpath("icons").absolute() LOCAL_ICONS_PATH = Path(__file__).parent.joinpath("icons").absolute()
LOCAL_BACKGROUND_PATH = Path(__file__).parent.joinpath("backgrounds").absolute() LOCAL_BACKGROUND_PATH = Path(__file__).parent.joinpath("backgrounds").absolute()
# configuration data
TERMINALS = [
"$TERM",
"gnome-terminal --window --",
"lxterminal -e",
"konsole -e",
"xterm -e",
"aterm -e",
"eterm -e",
"rxvt -e",
"xfce4-terminal -x",
]
EDITORS = ["$EDITOR", "vim", "emacs", "gedit", "nano", "vi"]
class IndentDumper(yaml.Dumper): class IndentDumper(yaml.Dumper):
def increase_indent(self, flow=False, indentless=False): def increase_indent(self, flow=False, indentless=False):
@ -42,19 +57,33 @@ def check_directory():
for background in LOCAL_BACKGROUND_PATH.glob("*"): for background in LOCAL_BACKGROUND_PATH.glob("*"):
new_background = BACKGROUNDS_PATH.joinpath(background.name) new_background = BACKGROUNDS_PATH.joinpath(background.name)
shutil.copy(background, new_background) shutil.copy(background, new_background)
if "TERM" in os.environ:
terminal = TERMINALS[0]
else:
terminal = TERMINALS[1]
if "EDITOR" in os.environ:
editor = EDITORS[0]
else:
editor = EDITORS[1]
config = { config = {
"preferences": {
"editor": editor,
"terminal": terminal,
"gui3d": "/usr/local/bin/std3d.sh",
},
"servers": [{"name": "example", "address": "127.0.0.1", "port": 50051}], "servers": [{"name": "example", "address": "127.0.0.1", "port": 50051}],
"nodes": [], "nodes": [],
"observers": [], "observers": [{"name": "hello", "cmd": "echo hello"}],
} }
save_config(config) save(config)
def read_config(): def read():
with CONFIG_PATH.open("r") as f: with CONFIG_PATH.open("r") as f:
return yaml.load(f, Loader=yaml.SafeLoader) return yaml.load(f, Loader=yaml.SafeLoader)
def save_config(config): def save(config):
with CONFIG_PATH.open("w") as f: with CONFIG_PATH.open("w") as f:
yaml.dump(config, f, Dumper=IndentDumper, default_flow_style=False) yaml.dump(config, f, Dumper=IndentDumper, default_flow_style=False)

View file

@ -15,7 +15,7 @@ from coretk.wlannodeconfig import WlanNodeConfig
NETWORK_NODES = {"switch", "hub", "wlan", "rj45", "tunnel", "emane"} NETWORK_NODES = {"switch", "hub", "wlan", "rj45", "tunnel", "emane"}
DEFAULT_NODES = {"router", "host", "PC", "mdr", "prouter"} DEFAULT_NODES = {"router", "host", "PC", "mdr", "prouter"}
OBSERVER_WIDGETS = { OBSERVERS = {
"processes": "ps", "processes": "ps",
"ifconfig": "ifconfig", "ifconfig": "ifconfig",
"IPV4 Routes": "ip -4 ro", "IPV4 Routes": "ip -4 ro",

View file

@ -8,7 +8,7 @@ from tkinter import filedialog
from PIL import Image, ImageTk from PIL import Image, ImageTk
from coretk.appdirs import BACKGROUNDS_PATH from coretk.appconfig import BACKGROUNDS_PATH
from coretk.dialogs.dialog import Dialog from coretk.dialogs.dialog import Dialog

View file

@ -2,7 +2,6 @@ import logging
import tkinter as tk import tkinter as tk
from pathlib import Path from pathlib import Path
from coretk import appdirs
from coretk.coreclient import CustomNode from coretk.coreclient import CustomNode
from coretk.dialogs.dialog import Dialog from coretk.dialogs.dialog import Dialog
from coretk.dialogs.icondialog import IconDialog from coretk.dialogs.icondialog import IconDialog
@ -189,7 +188,8 @@ class CustomNodesDialog(Dialog):
} }
) )
logging.info("saving custom nodes: %s", self.app.config["nodes"]) logging.info("saving custom nodes: %s", self.app.config["nodes"])
appdirs.save_config(self.app.config) self.app.save_config()
self.destroy()
def click_create(self): def click_create(self):
name = self.name.get() name = self.name.get()

View file

@ -1,7 +1,7 @@
import tkinter as tk import tkinter as tk
from tkinter import filedialog from tkinter import filedialog
from coretk.appdirs import ICONS_PATH from coretk.appconfig import ICONS_PATH
from coretk.dialogs.dialog import Dialog from coretk.dialogs.dialog import Dialog
from coretk.images import Images from coretk.images import Images

View file

@ -1,6 +1,5 @@
import tkinter as tk import tkinter as tk
from coretk import appdirs
from coretk.coreclient import Observer from coretk.coreclient import Observer
from coretk.dialogs.dialog import Dialog from coretk.dialogs.dialog import Dialog
@ -96,7 +95,7 @@ class ObserverDialog(Dialog):
observer = self.app.core.custom_observers[name] observer = self.app.core.custom_observers[name]
observers.append({"name": observer.name, "cmd": observer.cmd}) observers.append({"name": observer.name, "cmd": observer.cmd})
self.app.config["observers"] = observers self.app.config["observers"] = observers
appdirs.save_config(self.app.config) self.app.save_config()
self.destroy() self.destroy()
def click_create(self): def click_create(self):

View file

@ -0,0 +1,67 @@
import tkinter as tk
from tkinter import ttk
from coretk import appconfig
from coretk.dialogs.dialog import Dialog
class PreferencesDialog(Dialog):
def __init__(self, master, app):
super().__init__(master, app, "Preferences", modal=True)
preferences = self.app.config["preferences"]
self.editor = tk.StringVar(value=preferences["editor"])
self.terminal = tk.StringVar(value=preferences["terminal"])
self.gui3d = tk.StringVar(value=preferences["gui3d"])
self.draw()
def draw(self):
self.columnconfigure(0, weight=1)
self.draw_programs()
self.draw_buttons()
def draw_programs(self):
frame = ttk.LabelFrame(self, text="Programs")
frame.grid(sticky="ew", pady=2)
frame.columnconfigure(1, weight=1)
label = ttk.Label(frame, text="Editor")
label.grid(row=0, column=0, pady=2, padx=2, sticky="w")
combobox = ttk.Combobox(
frame, textvariable=self.editor, values=appconfig.EDITORS, state="readonly"
)
combobox.grid(row=0, column=1, sticky="ew")
label = ttk.Label(frame, text="Terminal")
label.grid(row=1, column=0, pady=2, padx=2, sticky="w")
combobox = ttk.Combobox(
frame,
textvariable=self.terminal,
values=appconfig.TERMINALS,
state="readonly",
)
combobox.grid(row=1, column=1, sticky="ew")
label = ttk.Label(frame, text="3D GUI")
label.grid(row=2, column=0, pady=2, padx=2, sticky="w")
entry = ttk.Entry(frame, textvariable=self.gui3d)
entry.grid(row=2, column=1, sticky="ew")
def draw_buttons(self):
frame = ttk.Frame(self)
frame.grid(sticky="ew")
for i in range(2):
frame.columnconfigure(i, weight=1)
button = ttk.Button(frame, text="Save", command=self.click_save)
button.grid(row=0, column=0, sticky="ew")
button = ttk.Button(frame, text="Cancel", command=self.destroy)
button.grid(row=0, column=1, sticky="ew")
def click_save(self):
preferences = self.app.config["preferences"]
preferences["terminal"] = self.terminal.get()
preferences["editor"] = self.editor.get()
preferences["gui3d"] = self.gui3d.get()
self.app.save_config()
self.destroy()

View file

@ -1,6 +1,5 @@
import tkinter as tk import tkinter as tk
from coretk import appdirs
from coretk.coreclient import CoreServer from coretk.coreclient import CoreServer
from coretk.dialogs.dialog import Dialog from coretk.dialogs.dialog import Dialog
@ -116,7 +115,7 @@ class ServersDialog(Dialog):
{"name": server.name, "address": server.address, "port": server.port} {"name": server.name, "address": server.address, "port": server.port}
) )
self.app.config["servers"] = servers self.app.config["servers"] = servers
appdirs.save_config(self.app.config) self.app.save_config()
self.destroy() self.destroy()
def click_create(self): def click_create(self):

View file

@ -4,7 +4,7 @@ from enum import Enum
from PIL import Image, ImageTk from PIL import Image, ImageTk
from core.api.grpc import core_pb2 from core.api.grpc import core_pb2
from coretk.appdirs import LOCAL_ICONS_PATH from coretk.appconfig import LOCAL_ICONS_PATH
class Images: class Images:

View file

@ -7,11 +7,12 @@ import webbrowser
from tkinter import filedialog, messagebox from tkinter import filedialog, messagebox
from core.api.grpc import core_pb2 from core.api.grpc import core_pb2
from coretk.appdirs import XML_PATH from coretk.appconfig import XML_PATH
from coretk.dialogs.canvasbackground import CanvasBackgroundDialog from coretk.dialogs.canvasbackground import CanvasBackgroundDialog
from coretk.dialogs.canvassizeandscale import SizeAndScaleDialog from coretk.dialogs.canvassizeandscale import SizeAndScaleDialog
from coretk.dialogs.hooks import HooksDialog from coretk.dialogs.hooks import HooksDialog
from coretk.dialogs.observers import ObserverDialog from coretk.dialogs.observers import ObserverDialog
from coretk.dialogs.preferences import PreferencesDialog
from coretk.dialogs.servers import ServersDialog from coretk.dialogs.servers import ServersDialog
from coretk.dialogs.sessionoptions import SessionOptionsDialog from coretk.dialogs.sessionoptions import SessionOptionsDialog
from coretk.dialogs.sessions import SessionsDialog from coretk.dialogs.sessions import SessionsDialog
@ -83,6 +84,10 @@ class MenuAction:
self.prompt_save_running_session() self.prompt_save_running_session()
self.app.core.open_xml(file_path) self.app.core.open_xml(file_path)
def gui_preferences(self):
dialog = PreferencesDialog(self.app, self.app)
dialog.show()
def canvas_size_and_scale(self): def canvas_size_and_scale(self):
dialog = SizeAndScaleDialog(self.app, self.app) dialog = SizeAndScaleDialog(self.app, self.app)
dialog.show() dialog.show()

View file

@ -2,7 +2,7 @@ import tkinter as tk
from functools import partial from functools import partial
import coretk.menuaction as action import coretk.menuaction as action
from coretk.coreclient import OBSERVER_WIDGETS from coretk.coreclient import OBSERVERS
class Menubar(tk.Menu): class Menubar(tk.Menu):
@ -94,7 +94,9 @@ class Menubar(tk.Menu):
menu.add_separator() menu.add_separator()
menu.add_command(label="Find...", accelerator="Ctrl+F", state=tk.DISABLED) menu.add_command(label="Find...", accelerator="Ctrl+F", state=tk.DISABLED)
menu.add_command(label="Clear marker", state=tk.DISABLED) menu.add_command(label="Clear marker", state=tk.DISABLED)
menu.add_command(label="Preferences...", state=tk.DISABLED) menu.add_command(
label="Preferences...", command=self.menuaction.gui_preferences
)
self.add_cascade(label="Edit", menu=menu) self.add_cascade(label="Edit", menu=menu)
def draw_canvas_menu(self): def draw_canvas_menu(self):
@ -379,8 +381,8 @@ class Menubar(tk.Menu):
value="none", value="none",
command=lambda: self.app.core.set_observer(None), command=lambda: self.app.core.set_observer(None),
) )
for name in sorted(OBSERVER_WIDGETS): for name in sorted(OBSERVERS):
cmd = OBSERVER_WIDGETS[name] cmd = OBSERVERS[name]
menu.add_radiobutton( menu.add_radiobutton(
label=name, label=name,
variable=var, variable=var,