Skip to content
Snippets Groups Projects
xmlview.py 9.63 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')
    
    Benoit Favre's avatar
    Benoit Favre committed
            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')
    
    Benoit Favre's avatar
    Benoit Favre committed
            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)
    
    Benoit Favre's avatar
    Benoit Favre committed
            self.pack_start(self.title, False, False, 5)
    
    Benoit Favre's avatar
    Benoit Favre committed
            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 + ']')
    
    Benoit Favre's avatar
    Benoit Favre committed
                info.get_style_context().add_class('section-info')
    
    Benoit Favre's avatar
    Benoit Favre committed
                self.pack_start(info, False, False, 5)
    
    Benoit Favre's avatar
    Benoit Favre committed
            self.sequences = []
    
            num = 1
            for sequence in section.findall('./sequence'):
    
                self.sequences.append(Sequence(sequence, section.get('id') + '.' + str(num), int(self.name) - 1))
    
    Benoit Favre's avatar
    Benoit Favre committed
                self.pack_start(self.sequences[-1], False, False, 5)
    
    Benoit Favre's avatar
    Benoit Favre committed
                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, section):
    
    Benoit Favre's avatar
    Benoit Favre committed
            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')
    
    Benoit Favre's avatar
    Benoit Favre committed
            self.pack_start(self.label, False, False, 5)
    
    Benoit Favre's avatar
    Benoit Favre committed
    
            self.lines = []
    
    Benoit Favre's avatar
    Benoit Favre committed
    
            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
    
    Benoit Favre's avatar
    Benoit Favre committed
            elements = []
    
    Benoit Favre's avatar
    Benoit Favre committed
            for node in sequence:
    
    Benoit Favre's avatar
    Benoit Favre committed
                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))
    
    Benoit Favre's avatar
    Benoit Favre committed
                    else:
                        elements.append(Text(text))
    
    Benoit Favre's avatar
    Benoit Favre committed
                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))
    
    Benoit Favre's avatar
    Benoit Favre committed
            if len(elements) > 0:
                self.lines.append(Line(elements))
    
    Benoit Favre's avatar
    Benoit Favre committed
                self.pack_start(self.lines[-1], False, False, 5)
    
    Benoit Favre's avatar
    Benoit Favre committed
    
    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)
    
    Benoit Favre's avatar
    Benoit Favre committed
    
    class Keyword(Gtk.Label):
    
        def __init__(self, text, action, lang, section):
    
    Benoit Favre's avatar
    Benoit Favre committed
            super(Keyword, self).__init__()
    
            self.section = section
    
    Benoit Favre's avatar
    Benoit Favre committed
            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))
    
    Benoit Favre's avatar
    Benoit Favre committed
            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)
    
    Benoit Favre's avatar
    Benoit Favre committed
    
    
        def set_num(self, num):
            self.num = num
    
    Benoit Favre's avatar
    Benoit Favre committed
        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)
    
    Benoit Favre's avatar
    Benoit Favre committed
            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.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
    
    Benoit Favre's avatar
    Benoit Favre committed
            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
    
    
    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
            
            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)
    
    
    Benoit Favre's avatar
    Benoit Favre committed
            for section in root.findall(".//section"):
    
    Benoit Favre's avatar
    Benoit Favre committed
                section_widget = Section(section)
                self.sections.append(section_widget)
                vbox.pack_start(section_widget, True, True, 5)
    
    Benoit Favre's avatar
    Benoit Favre committed
                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)
    
    Benoit Favre's avatar
    Benoit Favre committed
    
    
    Benoit Favre's avatar
    Benoit Favre committed
            return vbox
    
    
    Benoit Favre's avatar
    Benoit Favre committed
        def num_sections(self):
            return len(self.sections)
    
    
    Benoit Favre's avatar
    Benoit Favre committed
        def get_section(self):
    
    Benoit Favre's avatar
    Benoit Favre committed
            return int(self.current_section.name)
    
    Benoit Favre's avatar
    Benoit Favre committed
    
        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)
    
    Benoit Favre's avatar
    Benoit Favre committed
                for keyword in self.keywords:
                    keyword.highlight(False)
    
    Benoit Favre's avatar
    Benoit Favre committed
            if scroll:
                animate.scroll_to(self, self.current_section)
    
        def section_clicked(self, current):
    
    Benoit Favre's avatar
    Benoit Favre committed
            self.set_section(int(current.name))
    
            for keyword in self.keywords:
                keyword.highlight(False)
    
    Benoit Favre's avatar
    Benoit Favre committed
    
        def highlight(self, action):
    
    Benoit Favre's avatar
    Benoit Favre committed
            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
    
    Benoit Favre's avatar
    Benoit Favre committed
                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)
    
    Benoit Favre's avatar
    Benoit Favre committed
            #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