-
Benoit Favre authoredBenoit Favre authored
xmlview.py 9.63 KiB
import animate, actions
from gi.repository import GObject, Gtk, Pango, Gdk
from xml.etree import ElementTree as ET
class Section(Gtk.VBox):
def __init__(self, section):
super(Section, self).__init__()
self.name = section.get('id')
self.start_text = section.get('start')
self.action_start = section.get('action_start')
self.end_text = section.get('end')
self.action_end = section.get('action_end')
self.get_style_context().add_class('section-body')
self.title = Gtk.Label()
self.title.set_markup('Section [<a href="%s">%s</a>]' % (self.name, self.name))
self.title.get_style_context().add_class('section-title')
self.listeners = []
self.title.connect('activate-link', self.link_clicked)
self.pack_start(self.title, False, False, 5)
if self.start_text != None and self.end_text != None:
info = Gtk.Label('start="' + self.start_text + '" [' + self.action_start + '], end="' + self.end_text + '" [' + self.action_end + ']')
info.get_style_context().add_class('section-info')
self.pack_start(info, False, False, 5)
self.sequences = []
num = 1
for sequence in section.findall('./sequence'):
self.sequences.append(Sequence(sequence, section.get('id') + '.' + str(num), int(self.name) - 1))
self.pack_start(self.sequences[-1], False, False, 5)
num += 1
def highlight(self, active=True):
if active:
self.get_style_context().add_class('selected-section')
self.get_style_context().remove_class('section-body')
else:
self.get_style_context().remove_class('selected-section')
self.get_style_context().add_class('section-body')
def link_clicked(self, widget, uri):
for listener in self.listeners:
listener(self)
return True
def add_listener(self, listener):
self.listeners.append(listener)
class Sequence(Gtk.VBox):
def __init__(self, sequence, name, section):
super(Sequence, self).__init__()
self.name = name
self.get_style_context().add_class('sequence-body')
self.label = Gtk.Label('Sequence %s' % name)
self.label.get_style_context().add_class('sequence-title')
self.pack_start(self.label, False, False, 5)
self.lines = []
line = ''
for c in sequence.text:
if c == '\n':
line = line.strip()
if line != '':
self.lines.append(Line([Text(line)]))
self.pack_start(self.lines[-1], False, False, 5)
line = ''
else:
line += c
elements = []
for node in sequence:
line = line.strip()
if line != '':
elements.append(Text(line))
if node.tag == 'keyword':
text = str(node.text).strip()
if node.get('action').strip() != '':
elements.append(Keyword(text, node.get('action'), node.get('lang'), section))
else:
elements.append(Text(text))
line = ''
for c in node.tail:
if c == '\n':
line = line.strip()
if line != '':
elements.append(Text(line))
if len(elements) > 0:
self.lines.append(Line(elements))
self.pack_start(self.lines[-1], False, False, 5)
elements = []
line = ''
else:
line += c
line = line.strip()
if line != '':
elements.append(Text(line))
if len(elements) > 0:
self.lines.append(Line(elements))
self.pack_start(self.lines[-1], False, False, 5)
class Line(Gtk.HBox):
def __init__(self, elements):
super(Line, self).__init__()
self.pack_start(Gtk.Label(' '), False, False, 0)
for element in elements:
self.pack_start(element, False, False, 0)
self.elements = elements
self.get_style_context().add_class('text-line')
#def highlight(self, active=True, scrollable=None):
# if active:
# self.label.get_style_context().add_class('highlighted')
# else:
# self.label.get_style_context().remove_class('highlighted')
# if scrollable != None:
# animate.scroll_to(scrollable, self)
class Keyword(Gtk.Label):
def __init__(self, text, action, lang, section):
super(Keyword, self).__init__()
self.section = section
self.action = action
self.lang = lang
self.text = '\n'.join([x.strip() for x in text.split('\n')])
self.set_markup(self.text + ' [<a href="%s">%s</a>] ' % (action, action))
self.get_style_context().add_class('keyword')
self.connect('activate-link', self.link_clicked)
self.listeners = []
self.num = 0
def highlight(self, active=True, scrollable=None):
if active:
self.get_style_context().remove_class('keyword')
self.get_style_context().add_class('keyword-highlighted')
if scrollable != None:
animate.scroll_to(scrollable, self)
else:
self.get_style_context().add_class('keyword')
self.get_style_context().remove_class('keyword-highlighted')
def add_listener(self, listener):
self.listeners.append(listener)
def set_num(self, num):
self.num = num
def link_clicked(self, widget, uri):
actions.perform_action(actions.Action(uri, keyword=widget), False)
for listener in self.listeners:
listener(self, uri, self.num)
return True
class Text(Gtk.Label):
def __init__(self, text):
super(Text, self).__init__()
text = '\n'.join([x.strip() for x in text.split('\n')])
self.set_text(text + ' ')
self.get_style_context().add_class('text')
class XmlView(Gtk.ScrolledWindow):
def __init__(self, filename):
super(XmlView, self).__init__()
self.sections = []
self.words = []
self.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.ALWAYS)
self.vbox = self.parse_xml(filename)
self.add_with_viewport(self.vbox)
self.connect('scroll-event', lambda widget, event: animate.cancel())
for section in self.sections:
section.add_listener(self.section_clicked)
self.keywords = []
for section in self.sections:
for sequence in section.sequences:
for line in sequence.lines:
for element in line.elements:
if hasattr(element, 'action'):
element.set_num(len(self.keywords))
self.keywords.append(element)
self.last_highlighted = -1
self.follow = True
self.set_section(0)
def get_view(self):
return self
def parse_xml(self, filename):
self.sections = []
root = ET.parse(filename)
vbox = Gtk.VBox()
vbox.get_style_context().add_class('xmlview')
section0 = ET.fromstring('<section id="0">[empty]</section>')
section0_widget = Section(section0)
self.sections.append(section0_widget)
vbox.pack_start(self.sections[-1], True, True, 5)
for section in root.findall(".//section"):
section_widget = Section(section)
self.sections.append(section_widget)
vbox.pack_start(section_widget, True, True, 5)
info = Gtk.Label("open section " + section_widget.name + ': "' + section_widget.start_text + '"')
info.get_style_context().add_class('section-info')
section0_widget.pack_start(info, True, False, 5)
return vbox
def num_sections(self):
return len(self.sections)
def get_section(self):
return int(self.current_section.name)
def set_section(self, section_id, scroll=True):
self.current_section = self.sections[section_id]
for section in self.sections:
section.highlight(self.current_section is section)
for keyword in self.keywords:
keyword.highlight(False)
if scroll:
animate.scroll_to(self, self.current_section)
def section_clicked(self, current):
self.set_section(int(current.name))
for keyword in self.keywords:
keyword.highlight(False)
def highlight(self, action):
print 'HIGHLIGHT', action
if hasattr(action, 'keyword'):
if self.follow:
action.keyword.highlight(True, self)
else:
action.keyword.highlight(True)
elif hasattr(action, 'action_id'):
#start = min([x.num for x in self.keywords if x.section == self.get_section()])
start = 0
print action.action_id
action_id = action.action_id + start
if self.follow:
self.keywords[action_id].highlight(True, self)
else:
self.keywords[action_id].highlight(True)
#else:
# i = self.last_highlighted + 1
# while i < len(self.keywords):
# if self.keywords[i].action == action.text:
# if self.follow:
# self.keywords[i].highlight(True, self)
# else:
# self.keywords[i].highlight(True)
# self.last_highlighted = i
# #print 'HIGHLIGHT:', action.text, self.last_highlighted
# break
# i += 1