Rework layout config to flatten and build up trees
This commit is contained in:
parent
9ac5f913fa
commit
1aadbae30b
@ -206,7 +206,16 @@ DEFAULTS = {
|
||||
},
|
||||
},
|
||||
'layouts': {
|
||||
'default': "{'type': 'Window', 'children': [{'type': 'Terminal'}]}",
|
||||
'default': {
|
||||
'window0': {
|
||||
'type': 'Window',
|
||||
'parent': ''
|
||||
},
|
||||
'child1': {
|
||||
'type': 'Terminal',
|
||||
'parent': 'window0'
|
||||
}
|
||||
}
|
||||
},
|
||||
'plugins': {
|
||||
},
|
||||
@ -381,7 +390,7 @@ class ConfigBase(Borg):
|
||||
if self.layouts is None:
|
||||
self.layouts = {}
|
||||
for layout in DEFAULTS['layouts']:
|
||||
self.layouts[layout] = eval(DEFAULTS['layouts'][layout])
|
||||
self.layouts[layout] = copy(DEFAULTS['layouts'][layout])
|
||||
|
||||
def defaults_to_configspec(self):
|
||||
"""Convert our tree of default values into a ConfigObj validation
|
||||
@ -433,6 +442,15 @@ class ConfigBase(Borg):
|
||||
configspecdata['profiles'] = {}
|
||||
configspecdata['profiles']['__many__'] = section
|
||||
|
||||
section = {}
|
||||
section['type'] = 'string'
|
||||
section['parent'] = 'string'
|
||||
section['profile'] = 'string(default=default)'
|
||||
section['command'] = 'string(default="")'
|
||||
configspecdata['layouts'] = {}
|
||||
configspecdata['layouts']['__many__'] = {}
|
||||
configspecdata['layouts']['__many__']['__many__'] = section
|
||||
|
||||
configspec = ConfigObj(configspecdata)
|
||||
if DEBUG == True:
|
||||
configspec.write(open('/tmp/terminator_configspec_debug.txt', 'w'))
|
||||
@ -460,9 +478,11 @@ class ConfigBase(Borg):
|
||||
err('ConfigBase::load: config format is not valid')
|
||||
for (section_list, key, _other) in flatten_errors(parser, result):
|
||||
if key is not None:
|
||||
print('[%s]: %s is invalid' % (','.join(section_list), key))
|
||||
err('[%s]: %s is invalid' % (','.join(section_list), key))
|
||||
else:
|
||||
print ('[%s] missing' % ','.join(section_list))
|
||||
err('[%s] missing' % ','.join(section_list))
|
||||
else:
|
||||
dbg('config validated successfully')
|
||||
|
||||
for section_name in self.sections:
|
||||
dbg('ConfigBase::load: Processing section: %s' % section_name)
|
||||
@ -471,6 +491,7 @@ class ConfigBase(Borg):
|
||||
for profile in parser[section_name]:
|
||||
dbg('ConfigBase::load: Processing profile: %s' % profile)
|
||||
if not section.has_key(section_name):
|
||||
# FIXME: Should this be outside the loop?
|
||||
section[profile] = copy(DEFAULTS['profiles']['default'])
|
||||
section[profile].update(parser[section_name][profile])
|
||||
elif section_name == 'plugins':
|
||||
@ -479,17 +500,10 @@ class ConfigBase(Borg):
|
||||
part))
|
||||
section[part] = parser[section_name][part]
|
||||
elif section_name == 'layouts':
|
||||
for part in parser[section_name]:
|
||||
for layout in parser[section_name]:
|
||||
dbg('ConfigBase::load: Processing %s: %s' % (section_name,
|
||||
part))
|
||||
try:
|
||||
windows = []
|
||||
for window in parser[section_name][part]:
|
||||
windows.append(eval(window))
|
||||
section[part] = windows
|
||||
except Exception, ex:
|
||||
err('Unable to parse layout: %s (%s: %s)' % (part, ex,
|
||||
window))
|
||||
layout))
|
||||
section[layout] = parser[section_name][layout]
|
||||
else:
|
||||
try:
|
||||
section.update(parser[section_name])
|
||||
@ -519,13 +533,7 @@ class ConfigBase(Borg):
|
||||
parser['layouts'] = {}
|
||||
for layout in self.layouts:
|
||||
dbg('ConfigBase::save: Processing layout: %s' % layout)
|
||||
if layout == 'default' and \
|
||||
str(self.layouts[layout]) == DEFAULTS['layouts']['default']:
|
||||
continue;
|
||||
parser['layouts'][layout] = []
|
||||
# FIXME: This look seems pointless and broken
|
||||
for window in self.layouts[layout]:
|
||||
parser['layouts'][layout].append(str(self.layouts[layout]))
|
||||
parser['layouts'][layout] = self.layouts[layout]
|
||||
|
||||
parser['plugins'] = {}
|
||||
for plugin in self.plugins:
|
||||
|
@ -190,7 +190,7 @@ the %s will also close all terminals within it.') % (reqtype, reqtype))
|
||||
|
||||
return(terminals)
|
||||
|
||||
def describe_layout(self):
|
||||
def describe_layout(self, count, parent, global_layout):
|
||||
"""Describe our current layout"""
|
||||
layout = {}
|
||||
maker = Factory()
|
||||
@ -200,11 +200,16 @@ the %s will also close all terminals within it.') % (reqtype, reqtype))
|
||||
return({})
|
||||
|
||||
layout['type'] = mytype
|
||||
layout['children'] = []
|
||||
for child in self.get_children():
|
||||
layout['children'].append(child.describe_layout())
|
||||
layout['parent'] = parent
|
||||
name = 'child%d' % count
|
||||
count = count + 1
|
||||
|
||||
return(layout)
|
||||
global_layout[name] = layout
|
||||
|
||||
for child in self.get_children():
|
||||
count = child.describe_layout(count, name, global_layout)
|
||||
|
||||
return(count)
|
||||
|
||||
def create_layout(self, layout):
|
||||
"""Apply settings for our layout"""
|
||||
|
@ -190,8 +190,9 @@ class Paned(Container):
|
||||
err('incorrect number of children for Paned: %s' % layout)
|
||||
return
|
||||
|
||||
for num in xrange(0, 2):
|
||||
child = children[num]
|
||||
num = 0
|
||||
for child_key in children:
|
||||
child = children[child_key]
|
||||
if child['type'] == 'Terminal':
|
||||
continue
|
||||
elif child['type'] == 'VPaned':
|
||||
@ -208,9 +209,12 @@ class Paned(Container):
|
||||
self.split_axis(terminal, False)
|
||||
else:
|
||||
err('unknown child type: %s' % child['type'])
|
||||
num = num + 1
|
||||
|
||||
self.get_child1().create_layout(children[0])
|
||||
self.get_child2().create_layout(children[1])
|
||||
keys = children.keys()
|
||||
keys.sort()
|
||||
self.get_child1().create_layout(children[keys[0]])
|
||||
self.get_child2().create_layout(children[keys[1]])
|
||||
|
||||
class HPaned(Paned, gtk.HPaned):
|
||||
"""Merge gtk.HPaned into our base Paned Container"""
|
||||
|
@ -1165,11 +1165,15 @@ for %s (%s)' % (name, urlplugin.__class__.__name__))
|
||||
window = util.get_top_window(self)
|
||||
window.set_urgency_hint(True)
|
||||
|
||||
def describe_layout(self):
|
||||
def describe_layout(self, count, parent, global_layout):
|
||||
"""Describe our layout"""
|
||||
layout = {}
|
||||
layout['type'] = 'Terminal'
|
||||
return(layout)
|
||||
layout['parent'] = parent
|
||||
name = 'terminal%d' % count
|
||||
count = count + 1
|
||||
global_layout[name] = layout
|
||||
return(count)
|
||||
|
||||
def create_layout(self, layout):
|
||||
"""Apply our layout"""
|
||||
|
@ -106,6 +106,7 @@ class Terminator(Borg):
|
||||
def create_layout(self, layoutname):
|
||||
"""Create all the parts necessary to satisfy the specified layout"""
|
||||
layout = None
|
||||
objects = {}
|
||||
|
||||
layout = self.config.layout_get_config(layoutname)
|
||||
if not layout:
|
||||
@ -113,12 +114,45 @@ class Terminator(Borg):
|
||||
err('layout %s not defined' % layout)
|
||||
raise(KeyError)
|
||||
|
||||
# Wind the flat objects into a hierarchy
|
||||
hierarchy = {}
|
||||
count = 0
|
||||
# Loop over the layout until we have consumed it, or hit 1000 loops.
|
||||
# This is a stupid artificial limit, but it's safe.
|
||||
while len(layout) > 0 and count < 1000:
|
||||
count = count + 1
|
||||
if count == 1000:
|
||||
err('hit maximum loop boundary. THIS IS VERY LIKELY A BUG')
|
||||
for obj in layout.keys():
|
||||
if layout[obj]['type'].lower() == 'window':
|
||||
hierarchy[obj] = {}
|
||||
hierarchy[obj]['type'] = 'Window'
|
||||
hierarchy[obj]['children'] = {}
|
||||
objects[obj] = hierarchy[obj]
|
||||
del(layout[obj])
|
||||
else:
|
||||
# Now examine children to see if their parents exist yet
|
||||
if not layout[obj].has_key('parent'):
|
||||
err('Invalid object: %s' % obj)
|
||||
del(layout[obj])
|
||||
continue
|
||||
if objects.has_key(layout[obj]['parent']):
|
||||
# Our parent has been created
|
||||
childobj = {}
|
||||
childobj['type'] = layout[obj]['type']
|
||||
childobj['children'] = {}
|
||||
objects[layout[obj]['parent']]['children'][obj] = childobj
|
||||
objects[obj] = childobj
|
||||
del(layout[obj])
|
||||
|
||||
layout = hierarchy
|
||||
|
||||
for windef in layout:
|
||||
if windef['type'] != 'Window':
|
||||
if layout[windef]['type'] != 'Window':
|
||||
err('invalid layout format. %s' % layout)
|
||||
raise(ValueError)
|
||||
window, terminal = self.new_window()
|
||||
window.create_layout(windef)
|
||||
window.create_layout(layout[windef])
|
||||
|
||||
def reconfigure(self):
|
||||
"""Update configuration for the whole application"""
|
||||
@ -230,9 +264,11 @@ class Terminator(Borg):
|
||||
|
||||
def describe_layout(self):
|
||||
"""Describe our current layout"""
|
||||
layout = []
|
||||
layout = {}
|
||||
count = 0
|
||||
for window in self.windows:
|
||||
layout.append(window.describe_layout())
|
||||
parent = ''
|
||||
count = window.describe_layout(count, parent, layout)
|
||||
|
||||
return(layout)
|
||||
|
||||
|
@ -586,7 +586,7 @@ class Window(Container, gtk.Window):
|
||||
err('incorrect number of children for Window: %s' % layout)
|
||||
return
|
||||
|
||||
child = children[0]
|
||||
child = children[children.keys()[0]]
|
||||
terminal = self.get_children()[0]
|
||||
if child['type'] == 'VPaned':
|
||||
self.split_axis(terminal, True)
|
||||
|
Loading…
Reference in New Issue
Block a user