Skip to content
Snippets Groups Projects
Commit 496e4e5e authored by Benoit Favre's avatar Benoit Favre
Browse files

update ui

parent 4898b8a9
No related branches found
No related tags found
No related merge requests found
...@@ -31,11 +31,12 @@ DONE global action send which deals with ...@@ -31,11 +31,12 @@ DONE global action send which deals with
DONE - show a warning (optional) DONE - show a warning (optional)
DONE - send action through osc DONE - send action through osc
DONE - show an action performed message (message log with timing?) DONE - show an action performed message (message log with timing?)
DONE click section = select that section
DONE click action = perform action
events = click action or words to resynchronize ? events = click action or words to resynchronize ?
click line = synchronize to that line click line = synchronize to that line
click section = select that section click action = synchronize to the next line
click action = perform action and synchronize to the next line
add global timer which shows elapsed time add global timer which shows elapsed time
change xml view to reflect already performed actions, already recognized text change xml view to reflect already performed actions, already recognized text
......
...@@ -3,11 +3,11 @@ import osc, log ...@@ -3,11 +3,11 @@ import osc, log
class Action: class Action:
def __init__(self, text, **kwargs): def __init__(self, text, **kwargs):
self.text = text self.text = text
for key, value in kwargs: for key, value in kwargs.items():
setattr(self, key, value) setattr(self, key, value)
class ActionManager: class ActionManager:
def __init__(self, host, port, confirmer, highlighter, logger=log.ConsoleLogger()): def __init__(self, confirmer, highlighter, logger=log.ConsoleLogger()):
#self.client = osc.Client(host, port) #self.client = osc.Client(host, port)
self.confirmer = confirmer self.confirmer = confirmer
self.highlighter = highlighter self.highlighter = highlighter
...@@ -20,13 +20,13 @@ class ActionManager: ...@@ -20,13 +20,13 @@ class ActionManager:
def perform(self, action, confirm=True, timeout=3): def perform(self, action, confirm=True, timeout=3):
if confirm: if confirm:
self.confirmer.confirm('Perform action "%s"?' % action.text, time, lambda: self.confirmed_perform(action)) self.confirmer.confirm('Perform action "%s"?' % action.text, timeout, lambda: self.confirmed_perform(action))
else: else:
self.confirmed_perform(action) self.confirmed_perform(action)
manager = None manager = None
def setup(confirmer, highlighter, logger): def setup(confirmer, highlighter, logger=log.ConsoleLogger()):
global manager global manager
manager = ActionManager(confirmer, highlighter, logger) manager = ActionManager(confirmer, highlighter, logger)
......
...@@ -5,12 +5,14 @@ def cancel(): ...@@ -5,12 +5,14 @@ def cancel():
global timer global timer
if timer: if timer:
GObject.source_remove(timer) GObject.source_remove(timer)
timer = None
LINEAR=1 LINEAR=1
DECELERATE=2 DECELERATE=2
def animate_value(callback, current, target, policy=DECELERATE, speed=32): def animate_value(callback, current, target, policy=DECELERATE, speed=32):
global timer global timer
timer = None
if current != target: if current != target:
if policy == DECELERATE: if policy == DECELERATE:
delta = abs(target - current) / 2 delta = abs(target - current) / 2
......
...@@ -26,9 +26,20 @@ class ASR(Gtk.HBox): ...@@ -26,9 +26,20 @@ class ASR(Gtk.HBox):
self.scrolled.set_size_request(-1, 100) self.scrolled.set_size_request(-1, 100)
self.pack_start(self.scrolled, True, True, 5) self.pack_start(self.scrolled, True, True, 5)
self.button = Gtk.Button("Speak") vbox = Gtk.VBox()
self.pack_start(vbox, False, False, 5)
self.button = Gtk.Button("Record")
self.button.set_size_request(100, -1)
self.button.set_sensitive(False) self.button.set_sensitive(False)
self.pack_start(self.button, False, False, 5) vbox.pack_start(self.button, True, True, 5)
#save_state = Gtk.Button("Save state")
#save_state.connect('clicked', self.save_state)
#vbox.pack_start(save_state, False, False, 5)
#load_state = Gtk.Button("Load state")
#load_state.connect('clicked', self.load_state)
#vbox.pack_start(load_state, False, False, 5)
self.button.connect('clicked', self.button_clicked) self.button.connect('clicked', self.button_clicked)
self.text.connect("size-allocate", self.autoscroll) self.text.connect("size-allocate", self.autoscroll)
...@@ -82,28 +93,30 @@ class ASR(Gtk.HBox): ...@@ -82,28 +93,30 @@ class ASR(Gtk.HBox):
GObject.idle_add(self._finished_loading_asr) GObject.idle_add(self._finished_loading_asr)
def load_state(self): def load_state(self, *args):
try: try:
with open('state.txt') as fp: with open('state.txt') as fp:
self.asr.set_property('adaptation-state', fp.read()) self.asr.set_property('adaptation-state', fp.read())
print "ASR: State loaded"
except: except:
print >> sys.stderr, 'failed to load asr state' print >> sys.stderr, 'failed to load asr state'
def save_state(self): def save_state(self, *args):
if hasattr(self, 'asr'): if hasattr(self, 'asr'):
state = self.asr.get_property('adaptation-state') state = self.asr.get_property('adaptation-state')
try: try:
with open('state.txt', 'w') as fp: with open('state.txt', 'w') as fp:
fp.write(state) fp.write(state)
print "ASR: State saved"
except: except:
print >> sys.stderr, 'failed to save asr state' print >> sys.stderr, 'failed to save asr state'
def _started_loading_asr(self): def _started_loading_asr(self):
self.button.set_sensitive(False) self.button.set_sensitive(False)
self.button.set_label("Loading...") self.button.set_label("Loading")
def _finished_loading_asr(self): def _finished_loading_asr(self):
self.button.set_label("Speak") self.button.set_label("Record")
self.button.set_sensitive(True) self.button.set_sensitive(True)
def _on_partial_result(self, asr, hyp): def _on_partial_result(self, asr, hyp):
...@@ -149,12 +162,12 @@ class ASR(Gtk.HBox): ...@@ -149,12 +162,12 @@ class ASR(Gtk.HBox):
def button_clicked(self, button): def button_clicked(self, button):
"""Handle button presses.""" """Handle button presses."""
if button.get_label() == "Speak": if button.get_label() == "Record":
button.set_label("Stop") button.set_label("Stop")
self.asr.set_property("silent", False) self.asr.set_property("silent", False)
self.hyp = [] self.hyp = []
self.buffer.set_text('...') self.buffer.set_text('...')
else: else:
button.set_label("Speak") button.set_label("Record")
self.asr.set_property("silent", True) self.asr.set_property("silent", True)
...@@ -56,6 +56,7 @@ class ConfirmationBox(Gtk.HBox): ...@@ -56,6 +56,7 @@ class ConfirmationBox(Gtk.HBox):
self.yes_button.get_child().set_text("YES (%d)" % self.counter) self.yes_button.get_child().set_text("YES (%d)" % self.counter)
self.timer = GObject.timeout_add_seconds(1, self.countdown) self.timer = GObject.timeout_add_seconds(1, self.countdown)
else: else:
self.timer = None
self.click_yes() self.click_yes()
def cancel_timer(self): def cancel_timer(self):
......
...@@ -15,7 +15,7 @@ ...@@ -15,7 +15,7 @@
font: bold; font: bold;
} }
.selected-section-title { .selected-section > .section-title {
font: bold 18; font: bold 18;
color: white; color: white;
background: #009900; background: #009900;
...@@ -31,7 +31,7 @@ ...@@ -31,7 +31,7 @@
margin: 20px; margin: 20px;
} }
.selected-section-body { .selected-section {
background: #eeffee; background: #eeffee;
margin: 20px; margin: 20px;
} }
......
...@@ -24,43 +24,27 @@ import signal ...@@ -24,43 +24,27 @@ import signal
signal.signal(signal.SIGINT, signal.SIG_DFL) signal.signal(signal.SIGINT, signal.SIG_DFL)
# import local stuff # import local stuff
import confirm, asr, actions, xmlview_widgets import confirm, asr, actions, xmlview
import sections
import levenstein, SLU, osc import levenstein, SLU, osc
class ScriptedASR(Gtk.Window): class ScriptedASR(Gtk.Window):
def __init__(self, xml_filename, asr_config_file, osc_host, osc_port): def __init__(self, xml_filename, asr_config_file, osc_host, osc_port):
super(ScriptedASR, self).__init__() super(ScriptedASR, self).__init__()
osc.setup(osc_host, osc_port)
self.connect("destroy", self.quit) self.connect("destroy", self.quit)
self.set_default_size(1024, 768) self.set_default_size(1024, 768)
self.set_border_width(10) self.set_border_width(10)
self.set_title('ASR Transcript [xml=%s asr=%s osc=%s:%s]' % (xml_filename, asr_config_file, osc_host, osc_port)) self.set_title('ASR Transcript [xml=%s asr=%s osc=%s:%s]' % (xml_filename, asr_config_file, osc_host, osc_port))
vbox = Gtk.VBox() vbox = Gtk.VBox()
self.sections = sections.SectionManager() self.xmlview = xmlview.XmlView(xml_filename)
vbox.pack_start(self.sections, False, True, 5)
self.xmlview = xmlview_widgets.XmlView(xml_filename)
vbox.pack_start(self.xmlview, True, True, 5) vbox.pack_start(self.xmlview, True, True, 5)
self.lines = [x for x in self.xmlview.get_line_iterator()] self.lines = [x for x in self.xmlview.get_line_iterator()]
self.current_line = -1 self.current_line = -1
self.xmlview.set_action_clicked_handler(self.keyword_clicked)
self.confirmer = confirm.ConfirmationBox() self.confirmer = confirm.ConfirmationBox()
vbox.pack_start(self.confirmer, False, True, 5) vbox.pack_start(self.confirmer, False, True, 5)
#self.actions = action.ActionView()
#vbox.pack_start(self.actions, False, True, 5)
self.sections.set_confirmer(self.confirmer)
#self.actions.set_confirmer(self.confirmer)
self.sections.set_highlight(self.xmlview)
self.sections.set_section(1)
# transcript view # transcript view
self.asr = asr.ASR(asr_config_file, self.hyp_changed, self.hyp_changed) self.asr = asr.ASR(asr_config_file, self.hyp_changed, self.hyp_changed)
vbox.pack_start(self.asr, False, True, 5) vbox.pack_start(self.asr, False, True, 5)
...@@ -71,7 +55,6 @@ class ScriptedASR(Gtk.Window): ...@@ -71,7 +55,6 @@ class ScriptedASR(Gtk.Window):
for section_fst in glob.glob(prefix % 'section*.fst'): for section_fst in glob.glob(prefix % 'section*.fst'):
found = re.search('section(\d+)\.fst$', section_fst) found = re.search('section(\d+)\.fst$', section_fst)
if found: if found:
print section_fst
section_id = int(found.group(1)) section_id = int(found.group(1))
self.slu[section_id] = SLU.SLU(prefix % 'dico_word.txt', prefix % 'dico_action.txt', section_fst, prefix % 'clean_tail.fst') self.slu[section_id] = SLU.SLU(prefix % 'dico_word.txt', prefix % 'dico_action.txt', section_fst, prefix % 'clean_tail.fst')
...@@ -85,6 +68,10 @@ class ScriptedASR(Gtk.Window): ...@@ -85,6 +68,10 @@ class ScriptedASR(Gtk.Window):
style_provider.load_from_data(open('data/style.css', 'rb').read()) style_provider.load_from_data(open('data/style.css', 'rb').read())
Gtk.StyleContext.add_provider_for_screen( Gdk.Screen.get_default(), style_provider, Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION) Gtk.StyleContext.add_provider_for_screen( Gdk.Screen.get_default(), style_provider, Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION)
# setup singletons
osc.setup(osc_host, osc_port)
actions.setup(self.confirmer, self.xmlview)
def line_clicked(self, widget, event): def line_clicked(self, widget, event):
if self.current_line >= 0: if self.current_line >= 0:
self.lines[self.current_line].highlight(False) self.lines[self.current_line].highlight(False)
...@@ -93,22 +80,17 @@ class ScriptedASR(Gtk.Window): ...@@ -93,22 +80,17 @@ class ScriptedASR(Gtk.Window):
self.current_line = i self.current_line = i
self.lines[self.current_line].highlight(True) self.lines[self.current_line].highlight(True)
def keyword_clicked(self, action):
self.confirmer.confirm('Force action \"%s\"?' % action, 3, None)
def hyp_changed(self, hyp): def hyp_changed(self, hyp):
#hyp = ' '.join(hyp).replace('[noise]', ' ').split() #hyp = ' '.join(hyp).replace('[noise]', ' ').split()
words = hyp[-1].strip().replace('_', ' ').split() words = hyp[-1].strip().replace('_', ' ').split()
section_id = self.sections.get_section() section_id = int(self.xmlview.current_section.name) - 1
print section_id, self.slu.keys()
if section_id in self.slu: if section_id in self.slu:
print 'SLU: ', section_id
slu = self.slu[section_id] slu = self.slu[section_id]
previous_actions = slu.num_actions() previous_actions = slu.num_actions()
slu.process(words) slu.process(words)
for action_id in range(previous_actions, slu.num_actions()): for action_id in range(previous_actions, slu.num_actions()):
action = slu.get_action(action_id) action = slu.get_action(action_id)
self.confirmer.confirm('Perform action \"%s\"?' % action, 3, None) actions.perform_action(actions.Action(action))
#if self.current_line >= len(self.lines) - 1: #if self.current_line >= len(self.lines) - 1:
# print "FINISHED" # print "FINISHED"
......
timer.py 0 → 100644
from gi.repository import Gtk, GObject
import datetime
class Timer(Gtk.Label):
def __init__(self):
super(Timer, self).__init__()
self.start_time = datetime.datetime.now()
self.timer = GObject.timeout_add(100, self.update)
self.get_style_context().add_class('timer')
def update(self):
self.current_time = datetime.datetime.now() - self.start_time
self.set_text(self.to_string())
self.timer = GObject.timeout_add(100, self.update)
def to_string(self):
time = self.current_time
return '%02d:%02d:%02d.%01d' % (time.seconds / 3600, (time.seconds / 60) % 60, time.seconds % 60, time.microseconds / 100000)
from gi.repository import GObject, Gtk, Pango import animate, actions
from gi.repository import GObject, Gtk, Pango, Gdk
from xml.etree import ElementTree as ET from xml.etree import ElementTree as ET
class Section: class Section(Gtk.VBox):
def __init__(self, name, start, end): def __init__(self, section):
self.name = name super(Section, self).__init__()
self.start = start self.name = section.get('id')
self.end = 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, 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')
class Word: def link_clicked(self, widget, uri):
def __init__(self, text, start, end): for listener in self.listeners:
self.text = text listener(self)
self.start = start return True
self.end = end
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')
class XmlView(Gtk.ScrolledWindow): class XmlView(Gtk.ScrolledWindow):
def __init__(self, filename): def __init__(self, filename):
...@@ -19,64 +119,49 @@ class XmlView(Gtk.ScrolledWindow): ...@@ -19,64 +119,49 @@ class XmlView(Gtk.ScrolledWindow):
self.sections = [] self.sections = []
self.words = [] self.words = []
self.view = Gtk.TextView()
self.view.set_editable(False)
self.view.set_cursor_visible(False)
self.buffer = self.view.get_buffer()
self.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.ALWAYS) self.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.ALWAYS)
self.add_with_viewport(self.view)
#self.inactive_section = self.buffer.create_tag("inactive_section", background="#ffffff") self.vbox = self.parse_xml(filename)
self.active_section = self.buffer.create_tag("active_section", background="red") self.add_with_viewport(self.vbox)
self.section_title = self.buffer.create_tag("section_title", scale=2, weight=Pango.Weight.BOLD, justification=Gtk.Justification.CENTER)
self.subsection_title = self.buffer.create_tag("subsection_title", scale=1.5, weight=Pango.Weight.BOLD, justification=Gtk.Justification.CENTER)
self.parse_xml(filename) self.connect('scroll-event', lambda widget, event: animate.cancel())
self.last_section = None for section in self.sections:
self.show_section(0) section.add_listener(self.section_clicked)
self.set_section(0)
def get_view(self): def get_view(self):
return self return self
def parse_sequence(self, sequence, name):
self.buffer.insert_with_tags(self.buffer.get_end_iter(), 'Sequence %s\n' % name, self.subsection_title)
text = str(sequence.text)
for node in sequence:
text += node.text
text += node.tail
for line in text.split('\n'):
line = line.strip()
if line != '':
self.buffer.insert_with_tags(self.buffer.get_end_iter(), ' %s\n' % line)
def parse_section(self, section):
name = section.get('id')
section_start = self.buffer.create_mark('section-start %s' % name, self.buffer.get_end_iter(), True)
self.buffer.insert_with_tags(self.buffer.get_end_iter(), 'Section %s\n' % section.get('id'), self.section_title)
num = 1
for sequence in section.findall('./sequence'):
self.parse_sequence(sequence, section.get('id') + '.' + str(num))
num += 1
self.sections.append(Section(name, section_start, self.buffer.create_mark('section-end %s' % name, self.buffer.get_end_iter(), True)))
def parse_xml(self, filename): def parse_xml(self, filename):
self.sections = []
root = ET.parse(filename) root = ET.parse(filename)
treestore = Gtk.TreeStore(str) vbox = Gtk.VBox()
vbox.get_style_context().add_class('xmlview')
for section in root.findall(".//section"): for section in root.findall(".//section"):
self.parse_section(section) self.sections.append(Section(section))
return treestore vbox.pack_start(self.sections[-1], True, True, 5)
return vbox
def show_section(self, section):
if self.last_section != None: def get_line_iterator(self):
self.buffer.remove_tag(self.active_section, for section in self.sections:
self.buffer.get_iter_at_mark(self.sections[self.last_section].start), for sequence in section.sequences:
self.buffer.get_iter_at_mark(self.sections[self.last_section].end)) for line in sequence.lines:
self.last_section = section yield line
self.buffer.apply_tag(self.active_section,
self.buffer.get_iter_at_mark(self.sections[section].start), def get_section(self):
self.buffer.get_iter_at_mark(self.sections[section].end)) 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
import animate
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.get_style_context().add_class('section-body')
self.title = Gtk.EventBox()
self.label = Gtk.Label('Section %s' % self.name)
self.label.get_style_context().add_class('section-title')
self.title.add(self.label)
self.title.connect('button-press-event', self.clicked)
self.handler = None
#cursor = Gdk.Cursor(Gdk.CursorType.HAND1)
#self.label.get_window().set_cursor(cursor)
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.label.get_style_context().remove_class('section-title')
self.label.get_style_context().add_class('selected-section-title')
self.get_style_context().add_class('selected-section-body')
self.get_style_context().remove_class('section-body')
else:
self.label.get_style_context().remove_class('selected-section-title')
self.label.get_style_context().add_class('section-title')
self.get_style_context().remove_class('selected-section-body')
self.get_style_context().add_class('section-body')
def clicked(self, widget, event):
if self.handler:
self.handler(int(self.name) - 1)
def set_handler(self, handler):
self.handler = handler
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 set_handler(self, handler):
for element in self.elements:
if hasattr(element, 'set_handler'):
element.set_handler(handler)
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)
self.handler = None
def set_handler(self, handler):
self.handler = handler
def link_clicked(self, widget, uri):
if self.handler:
self.handler(uri)
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.last_section = None
self.connect('scroll-event', lambda widget, event: animate.cancel())
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')
for section in root.findall(".//section"):
self.sections.append(Section(section))
vbox.pack_start(self.sections[-1], True, True, 5)
return vbox
def set_action_clicked_handler(self, handler):
for line in self.get_line_iterator():
line.set_handler(handler)
def get_line_iterator(self):
for section in self.sections:
for sequence in section.sequences:
for line in sequence.lines:
yield line
def highlight_section(self, section):
if section < 1 or section > len(self.sections):
print "invalid section", section
else:
for current in range(len(self.sections)):
self.sections[current].highlight(current == section - 1)
animate.scroll_to(self, self.sections[section - 1])
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment