Provide set_imp(opt,imp) method to keep opt and imp mappings in sync.
Added convenience method iter_implementations(opt) to enable looping over an option's implementation list. Setting option labels now works properly when switching configurations.
This commit is contained in:
@ -29,7 +29,6 @@ import urwid
|
|||||||
import copy
|
import copy
|
||||||
from collections import defaultdict
|
from collections import defaultdict
|
||||||
|
|
||||||
|
|
||||||
Palette = [
|
Palette = [
|
||||||
('body', 'dark cyan', '', 'standout'),
|
('body', 'dark cyan', '', 'standout'),
|
||||||
('focus', 'dark red', '', 'standout'),
|
('focus', 'dark red', '', 'standout'),
|
||||||
@ -37,12 +36,11 @@ Palette = [
|
|||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
#FIXME Replace the [(name,stateval)] list imp_states with list of item names
|
|
||||||
class RadioButtonListWalker(urwid.SimpleListWalker):
|
class RadioButtonListWalker(urwid.SimpleListWalker):
|
||||||
button_dict = {}
|
|
||||||
def __init__(self, item_states, on_state_change=None, user_data=None):
|
def __init__(self, item_states, on_state_change=None, user_data=None):
|
||||||
radio_grp = []
|
radio_grp = []
|
||||||
mapped_rb_list = []
|
mapped_rb_list = []
|
||||||
|
self.button_dict = {}
|
||||||
for item,stateval in item_states:
|
for item,stateval in item_states:
|
||||||
rb = urwid.RadioButton(radio_grp, item, state=stateval, on_state_change=on_state_change, user_data=user_data)
|
rb = urwid.RadioButton(radio_grp, item, state=stateval, on_state_change=on_state_change, user_data=user_data)
|
||||||
self.button_dict[item] = rb
|
self.button_dict[item] = rb
|
||||||
@ -54,9 +52,9 @@ class RadioButtonListWalker(urwid.SimpleListWalker):
|
|||||||
|
|
||||||
|
|
||||||
class CheckBoxListWalker(urwid.SimpleListWalker):
|
class CheckBoxListWalker(urwid.SimpleListWalker):
|
||||||
button_dict = {}
|
|
||||||
def __init__(self, item_states, on_state_change = None, user_data = None):
|
def __init__(self, item_states, on_state_change = None, user_data = None):
|
||||||
mapped_cb_list = []
|
mapped_cb_list = []
|
||||||
|
self.button_dict = {}
|
||||||
for item,stateval in item_states:
|
for item,stateval in item_states:
|
||||||
cb = urwid.CheckBox(item, state = stateval, on_state_change = on_state_change, user_data = user_data)
|
cb = urwid.CheckBox(item, state = stateval, on_state_change = on_state_change, user_data = user_data)
|
||||||
self.button_dict[item] = cb
|
self.button_dict[item] = cb
|
||||||
@ -114,62 +112,28 @@ class ImpListBox(ClosedListBox):
|
|||||||
return
|
return
|
||||||
|
|
||||||
|
|
||||||
class InstConfigView(urwid.Pile):
|
|
||||||
|
|
||||||
def __init__(self, cf_dat, cf_man, dbmsg):
|
|
||||||
self.cf_dat = cf_dat
|
|
||||||
self.cf_man = cf_man
|
|
||||||
option_ListBoxes = [
|
|
||||||
self.cf_man.config_lb,
|
|
||||||
self.cf_man.opt_lb,
|
|
||||||
self.cf_man.imp_lb,
|
|
||||||
dbmsg]
|
|
||||||
super(InstConfigView, self).__init__(option_ListBoxes)
|
|
||||||
return
|
|
||||||
|
|
||||||
def keyinput(self, key):
|
|
||||||
if key == 'meta q':
|
|
||||||
raise urwid.ExitMainLoop()
|
|
||||||
elif key == 'w':
|
|
||||||
self.cf_dat.backup_files()
|
|
||||||
self.cf_dat.write_config_file()
|
|
||||||
elif key in ['right', 'tab']:
|
|
||||||
if self.get_focus() == self.cf_man.config_lb:
|
|
||||||
self.set_focus(self.cf_man.opt_lb)
|
|
||||||
elif self.get_focus() == self.cf_man.opt_lb:
|
|
||||||
self.set_focus(self.cf_man.imp_lb)
|
|
||||||
else:
|
|
||||||
self.set_focus(self.cf_man.config_lb)
|
|
||||||
elif key in ['left', 'shift tab']:
|
|
||||||
if self.get_focus() == self.cf_man.config_lb:
|
|
||||||
self.set_focus(self.cf_man.imp_lb)
|
|
||||||
elif self.get_focus() == self.cf_man.opt_lb:
|
|
||||||
self.set_focus(self.cf_man.config_lb)
|
|
||||||
else:
|
|
||||||
self.set_focus(self.cf_man.opt_lb)
|
|
||||||
return
|
|
||||||
|
|
||||||
|
|
||||||
class InstConfigData:
|
class InstConfigData:
|
||||||
msg_index = 4
|
msg_index = 4
|
||||||
# configuration_dict: dict of instrument configurations as defined below,
|
# configuration_dict: dict of instrument configurations as defined below,
|
||||||
# {configname: {'enabled':T/F, 'cascade_list':[(option, dflt_imp)]} }
|
# {configname: {'enabled':T/F, 'cascade_list':[(option, dflt_imp)]} }
|
||||||
configuration_dict = defaultdict(dict)
|
configuration_dict = defaultdict(dict)
|
||||||
|
|
||||||
# opt_dict: dict of configuration options as defined below,
|
|
||||||
# {optname:{'enabled': T/F/Always, 'imptype':optype, 'selected_imp':dflt}}
|
|
||||||
opt_dict = defaultdict(dict)
|
|
||||||
|
|
||||||
# imp_dict: dict of implementations indexed by optype,
|
# imp_dict: dict of implementations indexed by optype,
|
||||||
# {optype: [impname] }
|
# {optype: [impname] }
|
||||||
imp_dict = defaultdict(list)
|
imp_dict = defaultdict(list)
|
||||||
|
|
||||||
|
# opt_dict: dict of configuration options as defined below,
|
||||||
|
# {optname:{'enabled': T/F/Always, 'imptype':optype, 'selected_imp':dflt}}
|
||||||
|
opt_dict = defaultdict(dict)
|
||||||
|
|
||||||
# imp2opt_dict: Maps each implementation to an option or None,
|
# imp2opt_dict: Maps each implementation to an option or None,
|
||||||
# {imp: opt/None}
|
# {imp: opt/None}
|
||||||
imp2opt_dict = {}
|
imp2opt_dict = {}
|
||||||
|
|
||||||
def __init__(self):
|
# optypelist: list of (opt, optype) tuples
|
||||||
return
|
# [(opt, optype)]
|
||||||
|
optypelist = []
|
||||||
|
|
||||||
|
|
||||||
def __get_configurations(self):
|
def __get_configurations(self):
|
||||||
for s in self.file_parser.sections():
|
for s in self.file_parser.sections():
|
||||||
@ -187,6 +151,14 @@ class InstConfigData:
|
|||||||
self.configuration_dict[s]['cascade_list'] = cascade_list
|
self.configuration_dict[s]['cascade_list'] = cascade_list
|
||||||
|
|
||||||
def __get_options(self):
|
def __get_options(self):
|
||||||
|
# opt_dict: dict of configuration options as defined below,
|
||||||
|
# {optname:{'enabled': T/F/Always, 'imptype':optype, 'selected_imp':dflt}}
|
||||||
|
opt_dict = defaultdict(dict)
|
||||||
|
|
||||||
|
# imp2opt_dict: Maps each implementation to an option or None,
|
||||||
|
# {imp: opt/None}
|
||||||
|
imp2opt_dict = {}
|
||||||
|
|
||||||
for s in self.file_parser.sections():
|
for s in self.file_parser.sections():
|
||||||
if self.file_parser.has_option(s, 'implementation'):
|
if self.file_parser.has_option(s, 'implementation'):
|
||||||
selected_imp = self.file_parser.get(s, 'implementation')
|
selected_imp = self.file_parser.get(s, 'implementation')
|
||||||
@ -229,6 +201,19 @@ class InstConfigData:
|
|||||||
print 'Add imp2opt_dict[{0}] = none'.format(s)
|
print 'Add imp2opt_dict[{0}] = none'.format(s)
|
||||||
self.imp2opt_dict[s] = 'none'
|
self.imp2opt_dict[s] = 'none'
|
||||||
|
|
||||||
|
def set_imp(self, opt, new_imp):
|
||||||
|
old_imp =self.opt_dict[opt]['selected_imp']
|
||||||
|
self.imp2opt_dict[old_imp] = 'none'
|
||||||
|
self.opt_dict[opt]['selected_imp'] = new_imp
|
||||||
|
self.imp2opt_dict[new_imp] = opt
|
||||||
|
|
||||||
|
def get_optypelist (self):
|
||||||
|
return self.optypelist
|
||||||
|
|
||||||
|
def iter_implementations(self, opt):
|
||||||
|
dict = self.opt_dict[opt]
|
||||||
|
for imp in self.imp_dict[dict['imptype']]:
|
||||||
|
yield imp
|
||||||
|
|
||||||
def read_config_file(self, config_filename):
|
def read_config_file(self, config_filename):
|
||||||
self.config_filename = config_filename
|
self.config_filename = config_filename
|
||||||
@ -237,6 +222,9 @@ class InstConfigData:
|
|||||||
self.__get_options()
|
self.__get_options()
|
||||||
self.__get_implementations()
|
self.__get_implementations()
|
||||||
self.__get_configurations()
|
self.__get_configurations()
|
||||||
|
for opt,dict in self.opt_dict.iteritems():
|
||||||
|
self.optypelist.append((opt, dict['imptype']))
|
||||||
|
|
||||||
return
|
return
|
||||||
|
|
||||||
def backup_files(self):
|
def backup_files(self):
|
||||||
@ -279,11 +267,7 @@ class InstConfigData:
|
|||||||
self.configuration_dict[cfg_id]['enabled'] = new_state
|
self.configuration_dict[cfg_id]['enabled'] = new_state
|
||||||
|
|
||||||
def opt_statechange(self, checkbox, new_state, udat=None):
|
def opt_statechange(self, checkbox, new_state, udat=None):
|
||||||
if SET_LABEL:
|
opt = checkbox.get_label().split(':')[0]
|
||||||
opt = checkbox.get_label().split(':')[0]
|
|
||||||
else:
|
|
||||||
opt = checkbox.get_label()
|
|
||||||
|
|
||||||
dbg.msg(3, 'InstConfigData:opt_statechange({0},{1},{2})'.format(opt, new_state, udat))
|
dbg.msg(3, 'InstConfigData:opt_statechange({0},{1},{2})'.format(opt, new_state, udat))
|
||||||
self.opt_dict[opt]['enabled'] = new_state
|
self.opt_dict[opt]['enabled'] = new_state
|
||||||
|
|
||||||
@ -295,6 +279,42 @@ class InstConfigData:
|
|||||||
self.opt_dict[opt]['selected_imp'] = selected_imp
|
self.opt_dict[opt]['selected_imp'] = selected_imp
|
||||||
|
|
||||||
|
|
||||||
|
class InstConfigView(urwid.Pile):
|
||||||
|
|
||||||
|
def __init__(self, cf_dat, cf_man, dbmsg):
|
||||||
|
self.cf_dat = cf_dat
|
||||||
|
self.cf_man = cf_man
|
||||||
|
option_ListBoxes = [
|
||||||
|
self.cf_man.config_lb,
|
||||||
|
self.cf_man.opt_lb,
|
||||||
|
self.cf_man.imp_lb,
|
||||||
|
dbmsg]
|
||||||
|
super(InstConfigView, self).__init__(option_ListBoxes)
|
||||||
|
return
|
||||||
|
|
||||||
|
def keyinput(self, key):
|
||||||
|
if key == 'meta q':
|
||||||
|
raise urwid.ExitMainLoop()
|
||||||
|
elif key == 'w':
|
||||||
|
self.cf_dat.backup_files()
|
||||||
|
self.cf_dat.write_config_file()
|
||||||
|
elif key in ['right', 'tab']:
|
||||||
|
if self.get_focus() == self.cf_man.config_lb:
|
||||||
|
self.set_focus(self.cf_man.opt_lb)
|
||||||
|
elif self.get_focus() == self.cf_man.opt_lb:
|
||||||
|
self.set_focus(self.cf_man.imp_lb)
|
||||||
|
else:
|
||||||
|
self.set_focus(self.cf_man.config_lb)
|
||||||
|
elif key in ['left', 'shift tab']:
|
||||||
|
if self.get_focus() == self.cf_man.config_lb:
|
||||||
|
self.set_focus(self.cf_man.imp_lb)
|
||||||
|
elif self.get_focus() == self.cf_man.opt_lb:
|
||||||
|
self.set_focus(self.cf_man.config_lb)
|
||||||
|
else:
|
||||||
|
self.set_focus(self.cf_man.opt_lb)
|
||||||
|
return
|
||||||
|
|
||||||
|
|
||||||
# Contains OptionListWalker dict indexed by option
|
# Contains OptionListWalker dict indexed by option
|
||||||
# Contains ImpListBox
|
# Contains ImpListBox
|
||||||
# Connects OptionListWalker 'focus_change' signal to update_imp_lb handler
|
# Connects OptionListWalker 'focus_change' signal to update_imp_lb handler
|
||||||
@ -302,29 +322,26 @@ class InstConfigData:
|
|||||||
# and sets selection on ImpListBox
|
# and sets selection on ImpListBox
|
||||||
class InstConfigManager:
|
class InstConfigManager:
|
||||||
cf_msg_index = 8
|
cf_msg_index = 8
|
||||||
options = []
|
|
||||||
imp_lw_dict = {}
|
imp_lw_dict = {}
|
||||||
def __init__(self, cf_dat):
|
def __init__(self, cf_dat):
|
||||||
self.cf_dat = cf_dat
|
self.cf_dat = cf_dat
|
||||||
urwid.register_signal(InstConfigManager, ['focus_change'])
|
urwid.register_signal(InstConfigManager, ['focus_change'])
|
||||||
for opt,dict in cf_dat.opt_dict.iteritems():
|
self.options = self.cf_dat.get_optypelist()
|
||||||
self.options.append((opt, dict['imptype']))
|
|
||||||
|
|
||||||
self.options.sort()
|
self.options.sort()
|
||||||
firstopt = self.options[0][0]
|
firstopt = self.options[0][0]
|
||||||
self.imp_lw = self.__gen_imp_listwalker(firstopt)
|
self.imp_lw = self.__gen_imp_listwalker(firstopt)
|
||||||
self.option_lw = OptionListWalker(cf_dat.opt_dict, self.opt_statechange)
|
self.opt_lw = OptionListWalker(cf_dat.opt_dict, self.opt_statechange)
|
||||||
if (SET_LABEL):
|
for label, button in self.opt_lw.button_dict.iteritems():
|
||||||
for label, button in self.option_lw.button_dict.iteritems():
|
button.set_label('{0}:{1}'.format(label, self.cf_dat.opt_dict[label]['selected_imp']))
|
||||||
button.set_label('{0}:{1}'.format(label, self.cf_dat.opt_dict[label]['selected_imp']))
|
|
||||||
|
|
||||||
self.imp_lb = ImpListBox(self.imp_lw)
|
self.imp_lb = ImpListBox(self.imp_lw)
|
||||||
urwid.connect_signal(self.option_lw, 'focus_change', self.update_imp_lb)
|
urwid.connect_signal(self.opt_lw, 'focus_change', self.update_imp_lb)
|
||||||
item_states = [(i,d['enabled']) for i,d in cf_dat.configuration_dict.iteritems()]
|
item_states = [(i,d['enabled']) for i,d in cf_dat.configuration_dict.iteritems()]
|
||||||
item_states.sort()
|
item_states.sort()
|
||||||
self.cfg_lw = RadioButtonListWalker(item_states, on_state_change = self.cf_statechange)
|
self.cfg_lw = RadioButtonListWalker(item_states, on_state_change = self.cf_statechange)
|
||||||
self.config_lb = OptionListBox(self.cfg_lw)
|
self.config_lb = OptionListBox(self.cfg_lw)
|
||||||
self.opt_lb = OptionListBox(self.option_lw)
|
self.opt_lb = OptionListBox(self.opt_lw)
|
||||||
self.opt_lb.set_focus(0)
|
self.opt_lb.set_focus(0)
|
||||||
return
|
return
|
||||||
|
|
||||||
@ -342,11 +359,10 @@ class InstConfigManager:
|
|||||||
|
|
||||||
def __gen_imp_listwalker(self, opt):
|
def __gen_imp_listwalker(self, opt):
|
||||||
imp_items = []
|
imp_items = []
|
||||||
dict = self.cf_dat.opt_dict[opt]
|
for imp in self.cf_dat.iter_implementations(opt):
|
||||||
for imp in self.cf_dat.imp_dict[dict['imptype']]:
|
|
||||||
if self.__imp_unavailable(imp):
|
if self.__imp_unavailable(imp):
|
||||||
continue
|
continue
|
||||||
if imp == dict['selected_imp']:
|
if imp == self.cf_dat.opt_dict[opt]['selected_imp']:
|
||||||
imp_items.append((imp, True))
|
imp_items.append((imp, True))
|
||||||
else:
|
else:
|
||||||
imp_items.append((imp, False))
|
imp_items.append((imp, False))
|
||||||
@ -359,39 +375,40 @@ class InstConfigManager:
|
|||||||
self.cf_dat.cf_statechange(button, new_state, udat)
|
self.cf_dat.cf_statechange(button, new_state, udat)
|
||||||
b = button.get_label()
|
b = button.get_label()
|
||||||
cascade = self.cf_dat.configuration_dict[b]['cascade_list']
|
cascade = self.cf_dat.configuration_dict[b]['cascade_list']
|
||||||
|
|
||||||
if new_state == True:
|
if new_state == True:
|
||||||
for opt in self.cf_dat.opt_dict.keys():
|
for opt in self.cf_dat.opt_dict.keys():
|
||||||
|
# self.cf_dat.set_imp(opt, 'none')
|
||||||
|
self.opt_lw.button_dict[opt].set_state(False)
|
||||||
if self.cf_dat.opt_dict[opt]['permanent'] == False:
|
if self.cf_dat.opt_dict[opt]['permanent'] == False:
|
||||||
self.option_lw.button_dict[opt].set_state(False)
|
self.opt_lw.button_dict[opt].set_state(False)
|
||||||
for opt,imp in cascade:
|
for opt,imp in cascade:
|
||||||
self.option_lw.button_dict[opt].set_state(True)
|
self.cf_dat.set_imp(opt, imp)
|
||||||
|
self.opt_lw.button_dict[opt].set_state(True)
|
||||||
imp_lw = self.__gen_imp_listwalker(opt)
|
imp_lw = self.__gen_imp_listwalker(opt)
|
||||||
imp_lw.button_dict[imp].set_state(True)
|
# imp_lw.button_dict[imp].set_state(True)
|
||||||
currpos = self.opt_lb.get_focus()[1]
|
|
||||||
self.opt_lb.set_focus(currpos)
|
# currpos = self.opt_lb.get_focus()[1]
|
||||||
|
# self.opt_lb.set_focus(currpos)
|
||||||
|
|
||||||
dbg.msg(self.cf_msg_index, 'InstConfigManager:cf_statechange({0},{1},{2}), cascade = {3}'.format(b, new_state, udat, cascade))
|
dbg.msg(self.cf_msg_index, 'InstConfigManager:cf_statechange({0},{1},{2}), cascade = {3}'.format(b, new_state, udat, cascade))
|
||||||
self.cf_msg_index = (self.cf_msg_index - 7) % 2 + 8
|
self.cf_msg_index = (self.cf_msg_index - 7) % 2 + 8
|
||||||
return
|
return
|
||||||
|
|
||||||
def opt_statechange(self, button, new_state, udat=None):
|
def opt_statechange(self, button, new_state, udat=None):
|
||||||
if (SET_LABEL):
|
opt = button.get_label().split(':')[0]
|
||||||
opt = button.get_label().split(':')[0]
|
|
||||||
else:
|
|
||||||
opt = button.get_label()
|
|
||||||
|
|
||||||
imp = self.cf_dat.opt_dict[opt]['selected_imp']
|
imp = self.cf_dat.opt_dict[opt]['selected_imp']
|
||||||
if new_state == True:
|
if new_state == True:
|
||||||
if self.__imp_unavailable(imp):
|
if self.__imp_unavailable(imp):
|
||||||
self.cf_dat.opt_dict[opt]['selected_imp'] = 'none'
|
self.cf_dat.opt_dict[opt]['selected_imp'] = 'none'
|
||||||
imp_button = self.imp_lw.button_dict['none']
|
imp_button = self.imp_lw.button_dict['none']
|
||||||
imp_button.set_state(True)
|
imp_button.set_state(True)
|
||||||
if SET_LABEL:
|
opt_button = self.opt_lw.button_dict[opt]
|
||||||
opt_button = self.option_lw.button_dict[opt]
|
opt_button.set_label('{0}:none'.format(opt))
|
||||||
opt_button.set_label('{0}:none'.format(opt))
|
|
||||||
# FORCE DEDENT a blank line isn't enough in vim
|
|
||||||
else:
|
else:
|
||||||
self.cf_dat.imp2opt_dict[imp] = opt
|
opt_button = self.opt_lw.button_dict[opt]
|
||||||
|
opt_button.set_label('{0}:{1}'.format(opt,imp))
|
||||||
|
self.cf_dat.set_imp(opt, imp)
|
||||||
|
|
||||||
self.cf_dat.opt_statechange(button, new_state, udat)
|
self.cf_dat.opt_statechange(button, new_state, udat)
|
||||||
return
|
return
|
||||||
@ -399,10 +416,9 @@ class InstConfigManager:
|
|||||||
def imp_statechange(self, button, new_state, opt):
|
def imp_statechange(self, button, new_state, opt):
|
||||||
if new_state == True:
|
if new_state == True:
|
||||||
imp = button.get_label()
|
imp = button.get_label()
|
||||||
self.cf_dat.imp2opt_dict[imp] = opt
|
self.cf_dat.set_imp(opt, imp)
|
||||||
if SET_LABEL:
|
opt_button = self.opt_lw.button_dict[opt]
|
||||||
opt_button = self.option_lw.button_dict[opt]
|
opt_button.set_label('{0}:{1}'.format(opt, imp))
|
||||||
opt_button.set_label('{0}:{1}'.format(opt, imp))
|
|
||||||
|
|
||||||
self.cf_dat.imp_statechange(button, new_state, opt)
|
self.cf_dat.imp_statechange(button, new_state, opt)
|
||||||
return
|
return
|
||||||
@ -443,8 +459,8 @@ class DEBUG:
|
|||||||
|
|
||||||
dbg = DEBUG(enabled=True)
|
dbg = DEBUG(enabled=True)
|
||||||
def main(config_ini):
|
def main(config_ini):
|
||||||
global cf_dat, cf_man, cf_viewer, SET_LABEL
|
global cf_dat, cf_man, cf_viewer
|
||||||
SET_LABEL = True
|
|
||||||
# Make configuration data
|
# Make configuration data
|
||||||
cf_dat = InstConfigData()
|
cf_dat = InstConfigData()
|
||||||
cf_dat.read_config_file(config_ini)
|
cf_dat.read_config_file(config_ini)
|
||||||
|
Reference in New Issue
Block a user