Skip to content
Snippets Groups Projects
xmlview.py 5.82 KiB
Newer Older
  • Learn to ignore specific revisions
  • Benoit Favre's avatar
    Benoit Favre committed
    import animate, actions
    
    from gi.repository import GObject, Gtk, Pango, Gdk
    
    Benoit Favre's avatar
    Benoit Favre committed
    from xml.etree import ElementTree as ET
    
    
    Benoit Favre's avatar
    Benoit Favre committed
    class Section(Gtk.VBox):
        def __init__(self, section):
            super(Section, self).__init__()
            self.name = section.get('id')
            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, True, True, 5)
            self.sequences = []
    
            num = 1
            for sequence in section.findall('./sequence'):
                self.sequences.append(Sequence(sequence, section.get('id') + '.' + str(num)))
                self.pack_start(self.sequences[-1], True, True, 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')
    
    Benoit Favre's avatar
    Benoit Favre committed
        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):
            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, True, True, 5)
    
            self.lines = []
            elements = []
            for line in sequence.text.split('\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], True, True, 5)
                elements = []
            for node in sequence:
                if node.tag == 'keyword':
                    text = str(node.text).strip()
                    if node.get('action').strip() != '':
                        elements.append(Keyword(text, node.get('action'), node.get('lang')))
                    else:
                        elements.append(Text(text))
                for line in node.tail.split('\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], True, True, 5)
                    elements = []
            if len(elements) > 0:
                self.lines.append(Line(elements))
                self.pack_start(self.lines[-1], True, True, 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):
            if active:
                self.label.get_style_context().add_class('highlighted')
            else:
                self.label.get_style_context().remove_class('highlighted')
    
    class Keyword(Gtk.Label):
        def __init__(self, text, action, lang):
            super(Keyword, self).__init__()
            self.action = action
            self.lang = lang
            text = '\n'.join([x.strip() for x in text.split('\n')])
            self.set_markup(text + ' [<a href="%s">%s</a>] ' % (action, action))
            self.get_style_context().add_class('keyword')
            self.connect('activate-link', self.link_clicked)
    
        def link_clicked(self, widget, uri):
            actions.perform_action(actions.Action(uri, keyword=widget))
            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')
    
    Benoit Favre's avatar
    Benoit Favre committed
    
    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)
    
    
    Benoit Favre's avatar
    Benoit Favre committed
            self.vbox = self.parse_xml(filename)
            self.add_with_viewport(self.vbox)
    
    Benoit Favre's avatar
    Benoit Favre committed
            self.connect('scroll-event', lambda widget, event: animate.cancel())
    
    Benoit Favre's avatar
    Benoit Favre committed
            for section in self.sections:
                section.add_listener(self.section_clicked)
            self.set_section(0)
    
    Benoit Favre's avatar
    Benoit Favre committed
    
        def get_view(self):
            return self
    
        def parse_xml(self, filename):
    
    Benoit Favre's avatar
    Benoit Favre committed
            self.sections = []
    
    Benoit Favre's avatar
    Benoit Favre committed
            root = ET.parse(filename)
    
    Benoit Favre's avatar
    Benoit Favre committed
            vbox = Gtk.VBox()
            vbox.get_style_context().add_class('xmlview')
    
    Benoit Favre's avatar
    Benoit Favre committed
            for section in root.findall(".//section"):
    
    Benoit Favre's avatar
    Benoit Favre committed
                self.sections.append(Section(section))
                vbox.pack_start(self.sections[-1], True, True, 5)
            return vbox
    
        def get_line_iterator(self):
            for section in self.sections:
                for sequence in section.sequences:
                    for line in sequence.lines:
                        yield line
    
        def get_section(self):
            return int(self.current_section.name) - 1
    
        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)
            if scroll:
                animate.scroll_to(self, self.current_section)
    
        def section_clicked(self, current):
            self.set_section(int(current.name) - 1)
    
        def highlight(self, action):
            pass