Beispiel #1
0
    def generate_buffer_content(self):
        b=self.textview.get_buffer()
        # Clear the buffer
        begin,end=b.get_bounds()
        b.delete(begin, end)

        l=list(self.model)
        for a in l:
            if self.options['display-time']:
                b.insert_at_cursor("[%s]" % helper.format_time(a.begin))

            mark = b.create_mark("b_%s" % a.id,
                                 b.get_iter_at_mark(b.get_insert()),
                                 left_gravity=True)
            mark.set_visible(self.options['display-bounds'])

            b.insert_at_cursor(unicode(self.representation(a)))
            mark = b.create_mark("e_%s" % a.id,
                                 b.get_iter_at_mark(b.get_insert()),
                                 left_gravity=True)
            mark.set_visible(self.options['display-bounds'])

            if self.options['display-time']:
                b.insert_at_cursor("[%s]" % helper.format_time(a.end))

            b.insert_at_cursor(self.options['separator'])
        return
Beispiel #2
0
def formatted (target, context):
    """Return a formatted timestamp as hh:mm:ss.mmmm

    This method applies to either integers (in this case, it directly
    returns the formated string), or to fragments. It returns a
    dictionary with begin, end and duration keys.
    """
    import advene.model.fragment
    from advene.util.helper import format_time
    import time

    if isinstance(target, int) or isinstance(target, long):
        return format_time(target)

    if not isinstance(target, advene.model.fragment.MillisecondFragment):
        return None

    res = {
        'begin': u'--:--:--.---',
        'end'  : u'--:--:--.---',
        'duration': u'--:--:--.---'
        }
    for k in res.keys():
        t=getattr(target, k)
        res[k] = format_time(t)
    return res
Beispiel #3
0
 def build_pixbuf(self):
     if self.annotation is None:
         pixbuf=png_to_pixbuf(self.controller.package.imagecache.not_yet_available_image,
                              width=self.width)
     elif 'overlay' in self.presentation:
         pixbuf=overlay_svg_as_pixbuf(self.annotation.rootPackage.imagecache[self.annotation.fragment.begin],
                                      self.annotation.content.data,
                                      width=self.width)
     elif 'snapshot' in self.presentation:
         if 'timestamp' in self.presentation:
             pixbuf=overlay_svg_as_pixbuf(self.annotation.rootPackage.imagecache[self.annotation.fragment.begin],
                                          helper.format_time(self.annotation.fragment.begin),
                                          width=self.width)
         else:
             pixbuf=png_to_pixbuf(self.annotation.rootPackage.imagecache[self.annotation.fragment.begin],
                                  width=self.width)
     elif 'timestamp' in self.presentation:
         # Generate only a timestamp
         pixbuf = self.render_text(helper.format_time(self.annotation.fragment.begin))
     elif 'content' in self.presentation:
         # Display text
         pixbuf = self.render_text(self.controller.get_title(self.annotation))
     else:
         pixbuf=png_to_pixbuf(self.controller.package.imagecache.not_yet_available_image,
                              width=self.width)
     pixbuf.as_html=self.as_html
     pixbuf._placeholder=self
     pixbuf._tag='span'
     pixbuf._attr=[]
     return pixbuf
Beispiel #4
0
    def build_model(self, elements, custom_data=None):
        """Build the ListStore containing the data.

        See set_element docstring for the custom_data method explanation.
        """
        if custom_data is not None:
            custom = custom_data
        else:
            def custom(a):
                return tuple()
        args = (object, str, str, str, int, int, str, str, str, GdkPixbuf.Pixbuf, str, str) + custom(None)
        l=Gtk.ListStore(*args)
        if not elements:
            return l
        for a in elements:
            if isinstance(a, Annotation):
                l.append( (a,
                           self.controller.get_title(a),
                           self.controller.get_title(a.type),
                           a.id,
                           a.fragment.begin,
                           a.fragment.end,
                           helper.format_time(a.fragment.duration),
                           helper.format_time(a.fragment.begin),
                           helper.format_time(a.fragment.end),
                           png_to_pixbuf(self.controller.get_snapshot(annotation=a),
                                         height=32),
                           self.controller.get_element_color(a),
                           a.ownerPackage.getTitle()
                           ) + custom(a),
                          )
        return l
Beispiel #5
0
 def build_pixbuf(self):
     if self.annotation is None:
         pixbuf=png_to_pixbuf(self.controller.package.imagecache.not_yet_available_image,
                              width=self.width)
     elif 'overlay' in self.presentation:
         pixbuf=overlay_svg_as_pixbuf(self.annotation.rootPackage.imagecache[self.annotation.fragment.begin],
                                      self.annotation.content.data,
                                      width=self.width)
     elif 'snapshot' in self.presentation:
         if 'timestamp' in self.presentation:
             pixbuf=overlay_svg_as_pixbuf(self.annotation.rootPackage.imagecache[self.annotation.fragment.begin],
                                          helper.format_time(self.annotation.fragment.begin),
                                          width=self.width)
         else:
             pixbuf=png_to_pixbuf(self.annotation.rootPackage.imagecache[self.annotation.fragment.begin],
                                  width=self.width)
     elif 'timestamp' in self.presentation:
         # Generate only a timestamp
         pixbuf = self.render_text(helper.format_time(self.annotation.fragment.begin))
     elif 'content' in self.presentation:
         # Display text
         pixbuf = self.render_text(self.controller.get_title(self.annotation))
     else:
         pixbuf=png_to_pixbuf(self.controller.package.imagecache.not_yet_available_image,
                              width=self.width)
     pixbuf.as_html=self.as_html
     pixbuf._placeholder=self
     pixbuf._tag='span'
     pixbuf._attr=[]
     return pixbuf
Beispiel #6
0
    def build_model(self, elements, custom_data=None):
        """Build the ListStore containing the data.

        See set_element docstring for the custom_data method explanation.
        """
        if custom_data is not None:
            custom = custom_data
        else:

            def custom(a):
                return tuple()

        args = (object, str, str, str, int, int, str, str, str,
                GdkPixbuf.Pixbuf, str, str) + custom(None)
        l = Gtk.ListStore(*args)
        if not elements:
            return l
        for a in elements:
            if isinstance(a, Annotation):
                l.append(
                    (a, self.controller.get_title(a),
                     self.controller.get_title(a.type), a.id, a.fragment.begin,
                     a.fragment.end, helper.format_time(a.fragment.duration),
                     helper.format_time(
                         a.fragment.begin), helper.format_time(a.fragment.end),
                     png_to_pixbuf(self.controller.get_snapshot(annotation=a),
                                   height=32),
                     self.controller.get_element_color(a),
                     a.ownerPackage.getTitle()) + custom(a), )
        return l
Beispiel #7
0
def formatted (target, context):
    """Return a formatted timestamp as hh:mm:ss.mmmm

    This method applies to either integers (in this case, it directly
    returns the formated string), or to fragments. It returns a
    dictionary with begin, end and duration keys.
    """
    import advene.model.fragment
    from advene.util.helper import format_time

    if isinstance(target, int):
        return format_time(target)

    if not isinstance(target, advene.model.fragment.MillisecondFragment):
        return None

    res = {
        'begin': '--:--:--.---',
        'end'  : '--:--:--.---',
        'duration': '--:--:--.---'
        }
    for k in res:
        t=getattr(target, k)
        res[k] = format_time(t)
    res['begin_s'] = target.begin / 1000.
    res['end_s'] = target.end / 1000.
    return res
Beispiel #8
0
 def extract_fragment(self, m, ann):
     """Extract the fragment corresponding to an annotation.
     """
     title = self.controller.get_title(ann)
     begin = helper.format_time(ann.fragment.begin)
     end = helper.format_time(ann.fragment.end)
     self.controller.gui.render_montage_dialog([ ann ],
                                               basename = ann.id + "-" + helper.title2id(title) + ".ogv",
                                               title = _("Extracting %s") % title,
                                               label = _("Exporting annotation %(title)s\nfrom %(begin)s to %(end)s\nto %%(filename)s") % locals())
     return True
Beispiel #9
0
 def display_stats(self, m, at):
     """Display statistics about the annotation type.
     """
     msg=_("<b>Statistics about %s</b>\n\n") % self.controller.get_title(at)
     msg += "%d annotations\n" % len(at.annotations)
     msg += "Min duration : %s\n" % helper.format_time(min( a.duration for a in at.annotations))
     msg += "Max duration : %s\n" % helper.format_time(max( a.duration for a in at.annotations))
     msg += "Mean duration : %s\n" % helper.format_time(sum( a.duration for a in at.annotations) / len(at.annotations))
     msg += "Total duration : %s\n" % helper.format_time(sum( a.duration for a in at.annotations))
     dialog.message_dialog(msg)
     return True
Beispiel #10
0
 def set_cursor(wid, t=None, precision=None):
     if t is None:
         t = self.annotation
     if precision is None:
         precision = config.data.preferences[
             'bookmark-snapshot-precision']
     if self.no_image_pixbuf is None:
         self.no_image_pixbuf = png_to_pixbuf(
             self.controller.get_snapshot(position=-1),
             width=config.data.preferences['drag-snapshot-width'])
     if not t == w._current:
         if isinstance(t, int):
             snap = self.controller.get_snapshot(
                 position=t,
                 annotation=self.annotation,
                 precision=precision)
             if snap.is_default:
                 pixbuf = self.no_image_pixbuf
             else:
                 pixbuf = png_to_pixbuf(
                     snap,
                     width=config.data.
                     preferences['drag-snapshot-width'])
             begin.set_from_pixbuf(pixbuf)
             if resize:
                 end.set_from_pixbuf(resize_pixbuf[resize])
                 l.set_text(helper.format_time(t))
             else:
                 end.hide()
                 padding.hide()
                 l.set_text(helper.format_time(t))
         elif isinstance(t, Annotation):
             # It can be an annotation
             begin.set_from_pixbuf(
                 png_to_pixbuf(
                     self.controller.get_snapshot(annotation=t),
                     width=config.data.
                     preferences['drag-snapshot-width']))
             end.set_from_pixbuf(
                 png_to_pixbuf(self.controller.get_snapshot(
                     annotation=t, position=t.fragment.end),
                               width=config.data.
                               preferences['drag-snapshot-width']))
             end.show()
             padding.show()
             if widgets:
                 l.set_text(_("Set of %s annotations") % len(widgets))
             else:
                 l.set_text(self.controller.get_title(t))
     wid._current = t
     return True
Beispiel #11
0
    def on_bus_message(self, bus, message):
        def finalize():
            """Finalize data creation.
            """
            GObject.idle_add(
                lambda: self.pipeline.set_state(Gst.State.NULL) and False)
            self.generate_annotations()
            if self.end_callback:
                self.end_callback()
            return False

        s = message.get_structure()
        if message.type == Gst.MessageType.EOS:
            finalize()
        elif s:
            logger.debug("MSG ", s.get_name(), s.to_string())
            if s.get_name() == 'progress' and self.progress is not None:
                if not self.progress(
                        s['percent-double'] / 100,
                        _("%(count)d utterances until %(time)s") % {
                            'count': len(self.buffer_list),
                            'time': helper.format_time(s['current'] * 1000)
                        }):
                    finalize()
        return True
Beispiel #12
0
 def refresh(self):
     """Update the display of the widget according to self._value and self.width
     """
     if self._value is None:
         v=-1
     else:
         v=self._value
     if self.width < 9:
         self.image.hide()
         self.set_size_request(6, 12)
     else:
         png = self.controller.get_snapshot(position=v, media=self._media, precision=self.precision)
         self.valid_screenshot = not png.is_default
         self.image.set_from_pixbuf(png_to_pixbuf(bytes(png), width=self.width))
         self.set_size_request(-1, -1)
         self.image.show()
     ts=helper.format_time(self._value)
     self.label.set_markup(self._text % { 'timestamp': ts })
     self.label.get_style_context().add_class("timestamp_label")
     if self.visible_label and self.label.get_child_requisition().width <= 1.2 * self.image.get_child_requisition().width:
         self.label.show()
     else:
         self.label.hide()
     self.set_tooltip_text(ts)
     return True
Beispiel #13
0
 def set_cursor(wid, t=None, precision=None):
     if t is None:
         t = self.annotation
     if precision is None:
         precision = config.data.preferences['bookmark-snapshot-precision']
     if self.no_image_pixbuf is None:
         self.no_image_pixbuf = png_to_pixbuf(self.controller.get_snapshot(position=-1), width=config.data.preferences['drag-snapshot-width'])
     if not t == w._current:
         if isinstance(t, int):
             snap = self.controller.get_snapshot(position=t, annotation=self.annotation, precision=precision)
             if snap.is_default:
                 pixbuf = self.no_image_pixbuf
             else:
                 pixbuf = png_to_pixbuf(snap, width=config.data.preferences['drag-snapshot-width'])
             begin.set_from_pixbuf(pixbuf)
             end.hide()
             padding.hide()
             l.set_text(helper.format_time(t))
         elif isinstance(t, Annotation):
             # It can be an annotation
             begin.set_from_pixbuf(png_to_pixbuf(self.controller.get_snapshot(annotation=t),
                                                 width=config.data.preferences['drag-snapshot-width']))
             end.set_from_pixbuf(png_to_pixbuf(self.controller.get_snapshot(annotation=t, position=t.fragment.end),
                                               width=config.data.preferences['drag-snapshot-width']))
             end.show()
             padding.show()
             if widgets:
                 l.set_text(_("Set of %s annotations") % len(widgets))
             else:
                 l.set_text(self.controller.get_title(t))
     wid._current=t
     return True
Beispiel #14
0
    def add_data(self, message, position, url=None):
        # Check for identical data already pushed
        l = [t for t in self.data if t[2] == message and t[3] == url]
        if l:
            return True

        hb = Gtk.HBox()

        b = Gtk.Button(message)
        # Make the message left-aligned
        b.get_child().set_alignment(0.0, 0.5)
        b.connect('clicked', self.goto_url, url)
        b.set_tooltip_text(_("Go to %s") % url)
        hb.add(b)

        b = Gtk.Button(helper.format_time(position))
        b.get_child().set_alignment(0.0, 0.5)
        b.connect('clicked', self.goto_position, position)
        b.set_tooltip_text(_("Go to the given position"))
        hb.pack_start(b, False, True, 0)

        hb.show_all()

        self.datawidget.pack_start(hb, False, True, 0)
        self.data.append((time.time(), position, message, url, hb))
        return True
Beispiel #15
0
    def add_data(self, message, position, url=None):
        # Check for identical data already pushed
        l=[ t
            for t in self.data
            if t[2] == message and t[3] == url ]
        if l:
            return True

        hb=Gtk.HBox()

        b=Gtk.Button(message)
        # Make the message left-aligned
        b.get_child().set_alignment(0.0, 0.5)
        b.connect('clicked', self.goto_url, url)
        b.set_tooltip_text(_("Go to %s") % url)
        hb.add(b)

        b=Gtk.Button(helper.format_time(position))
        b.get_child().set_alignment(0.0, 0.5)
        b.connect('clicked', self.goto_position, position)
        b.set_tooltip_text(_("Go to the given position"))
        hb.pack_start(b, False, True, 0)

        hb.show_all()

        self.datawidget.pack_start(hb, False, True, 0)
        self.data.append( (time.time(), position, message, url, hb) )
        return True
Beispiel #16
0
    def on_bus_message(self, bus, message):
        def finalize():
            """Finalize data creation.
            """
            gobject.idle_add(
                lambda: self.pipeline.set_state(gst.STATE_NULL) and False)
            self.generate_annotations()
            if self.end_callback:
                self.end_callback()
            return False

        if message.type == gst.MESSAGE_EOS:
            finalize()
        elif message.structure:
            s = message.structure
            #print "MSG " + s.get_name() + ": " + s.to_string()
            if s.get_name() == 'progress' and self.progress is not None:
                if not self.progress(
                        s['percent-double'] / 100,
                        _("%(count)d utterances until %(time)s") % {
                            'count': len(self.buffer_list),
                            'time': helper.format_time(s['current'] * 1000)
                        }):
                    finalize()
        return True
Beispiel #17
0
 def set_cursor(wid, t=None, precision=None):
     if t is None:
         t=self.annotation
     if precision is None:
         precision=config.data.preferences['bookmark-snapshot-precision']
     cache=self.controller.package.imagecache
     if self.no_image_pixbuf is None:
         self.no_image_pixbuf=png_to_pixbuf(ImageCache.not_yet_available_image, width=config.data.preferences['drag-snapshot-width'])
     if not t == w._current:
         if isinstance(t, long) or isinstance(t, int):
             if cache.is_initialized(t, epsilon=precision):
                 begin.set_from_pixbuf(png_to_pixbuf (cache.get(t, epsilon=precision), width=config.data.preferences['drag-snapshot-width']))
             elif begin.get_pixbuf() != self.no_image_pixbuf:
                 begin.set_from_pixbuf(self.no_image_pixbuf)
             end.hide()
             padding.hide()
             l.set_text(helper.format_time(t))
         elif isinstance(t, Annotation):
             # It can be an annotation
             begin.set_from_pixbuf(png_to_pixbuf (cache.get(t.fragment.begin), width=config.data.preferences['drag-snapshot-width']))
             end.set_from_pixbuf(png_to_pixbuf (cache.get(t.fragment.end), width=config.data.preferences['drag-snapshot-width']))
             end.show()
             padding.show()
             if widgets:
                 l.set_text(_("Set of %s annotations") % len(widgets))
             else:
                 l.set_text(self.controller.get_title(t))
     wid._current=t
     return True
Beispiel #18
0
    def position_update(self):
        s = self.get_stream_information ()
        if s.position == 0:
            # Try again once. timestamp sometimes goes through 0 when
            # modifying the player position.
            s = self.get_stream_information()

        self.status = s.status
        self.stream_duration = s.length
        self.current_position_value = int(s.position)
        if self.caption.text and (s.position < self.caption.begin
                                  or s.position > self.caption.end):
            self.display_text('', -1, -1)
        if self.overlay.data and (s.position < self.overlay.begin
                                  or s.position > self.overlay.end):
            self.imageoverlay.props.data=None
            self.overlay.begin=-1
            self.overlay.end=-1
            self.overlay.data=None
        elif not self.overlay.data and self.imageoverlay is not None and self.is_fullscreen() and config.data.player.get('fullscreen-timestamp', False):
            t = time.time()
            # Update timestamp every half second
            if t - self.last_timestamp_update > .5 and abs(s.position - self.last_timestamp) > 10:
                self.imageoverlay.props.data = '''<svg:svg width="640pt" height="480pt" preserveAspectRatio="xMinYMin meet" version="1" viewBox="0 0 640 480" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:svg="http://www.w3.org/2000/svg">
  <text fill="white" stroke="white" style="stroke-width:1; font-family: sans-serif; font-size: 22" x="5" y="475">%s</text>
</svg:svg>''' % format_time(s.position)
                self.last_timestamp = s.position
                self.last_timestamp_update = t
Beispiel #19
0
 def refresh(self):
     """Update the display of the widget according to self._value and self.width
     """
     if self._value is None:
         v=-1
     else:
         v=self._value
     if self.width < 9:
         self.image.hide()
         self.set_size_request(6, 12)
     else:
         ic=self.controller.package.imagecache
         png = ic.get(v, epsilon=self.epsilon)
         if png == ic.not_yet_available_image and 'async-snapshot' in self.controller.player.player_capabilities:
             self.controller.queue_action(self.controller.update_snapshot, v)
         self.image.set_from_pixbuf(png_to_pixbuf(png, width=self.width))
         self.set_size_request(-1, -1)
         self.image.show()
     ts=helper.format_time(self._value)
     self.label.set_markup(self._text % { 'timestamp': ts })
     if self.visible_label and self.label.get_child_requisition()[0] <= 1.2 * self.image.get_child_requisition()[0]:
         self.label.show()
     else:
         self.label.hide()
     self.set_tooltip_text(ts)
     return True
Beispiel #20
0
    def position_update(self):
        s = self.get_stream_information()
        if s.position == 0:
            # Try again once. timestamp sometimes goes through 0 when
            # modifying the player position.
            s = self.get_stream_information()

        self.status = s.status
        self.stream_duration = s.length
        self.current_position_value = int(s.position)
        if self.caption.text and (s.position < self.caption.begin
                                  or s.position > self.caption.end):
            self.display_text('', -1, -1)
        if self.overlay.data and (s.position < self.overlay.begin
                                  or s.position > self.overlay.end):
            self.imageoverlay.props.data = None
            self.overlay.begin = -1
            self.overlay.end = -1
            self.overlay.data = None
        elif not self.overlay.data and self.imageoverlay is not None and self.is_fullscreen(
        ) and config.data.player.get('fullscreen-timestamp', False):
            t = time.time()
            # Update timestamp every half second
            if t - self.last_timestamp_update > .5 and abs(
                    s.position - self.last_timestamp) > 10:
                self.imageoverlay.props.data = '''<svg:svg width="640pt" height="480pt" preserveAspectRatio="xMinYMin meet" version="1" viewBox="0 0 640 480" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:svg="http://www.w3.org/2000/svg">
  <text fill="white" stroke="white" style="stroke-width:1; font-family: sans-serif; font-size: 22" x="5" y="475">%s</text>
</svg:svg>''' % format_time(s.position)
                self.last_timestamp = s.position
                self.last_timestamp_update = t
Beispiel #21
0
 def refresh(self):
     """Update the display of the widget according to self._value and self.width
     """
     if self._value is None:
         v = -1
     else:
         v = self._value
     if self.width < 9:
         self.image.hide()
         self.set_size_request(6, 12)
     else:
         png = self.controller.get_snapshot(position=v,
                                            media=self._media,
                                            precision=self.precision)
         self.valid_screenshot = not png.is_default
         self.image.set_from_pixbuf(
             png_to_pixbuf(bytes(png), width=self.width))
         self.set_size_request(-1, -1)
         self.image.show()
     ts = helper.format_time(self._value)
     self.label.set_markup(self._text % {'timestamp': ts})
     self.label.get_style_context().add_class("timestamp_label")
     if (self.visible_label and self.label.get_child_requisition().width <=
             1.2 * self.image.get_child_requisition().width):
         self.label.show()
     else:
         self.label.hide()
     self.set_tooltip_text(ts)
     return True
Beispiel #22
0
 def refresh(self):
     """Update the display of the widget according to self._value and self.width
     """
     if self._value is None:
         v=-1
     else:
         v=self._value
     if self.width < 9:
         self.image.hide()
         self.set_size_request(6, 12)
     else:
         ic=self.controller.gui.imagecache
         if ic is None:
             png=ImageCache.not_yet_available_image
         else:
             png=ic.get(v, epsilon=self.epsilon)
         if png == ImageCache.not_yet_available_image and 'async-snapshot' in self.controller.player.player_capabilities:
             self.controller.queue_action(self.controller.update_snapshot, v)
         self.image.set_from_pixbuf(png_to_pixbuf(png, width=self.width))
         self.set_size_request(-1, -1)
         self.image.show()
     ts=helper.format_time(self._value)
     self.label.set_markup(self._text % { 'timestamp': ts })
     if self.visible_label and self.label.get_child_requisition()[0] <= 1.2 * self.image.get_child_requisition()[0]:
         self.label.show()
     else:
         self.label.hide()
     self.set_tooltip_text(ts)
     return True
Beispiel #23
0
 def set_cursor(wid, t=None, precision=None):
     if t is None:
         t=self.annotation
     if precision is None:
         precision=config.data.preferences['bookmark-snapshot-precision']
     # FIXME not multi-media compatible
     cache=self.controller.gui.imagecache
     if self.no_image_pixbuf is None:
         self.no_image_pixbuf=png_to_pixbuf(ImageCache.not_yet_available_image, width=config.data.preferences['drag-snapshot-width'])
     if not t == w._current:
         if isinstance(t, long) or isinstance(t, int):
             if cache.is_initialized(t, epsilon=precision):
                 begin.set_from_pixbuf(png_to_pixbuf (cache.get(t, epsilon=precision), width=config.data.preferences['drag-snapshot-width']))
             elif begin.get_pixbuf() != self.no_image_pixbuf:
                 begin.set_from_pixbuf(self.no_image_pixbuf)
             end.hide()
             padding.hide()
             l.set_text(helper.format_time(t))
         elif isinstance(t, Annotation):
             cache=self.controller.imagecache[t.media.url]
             # It can be an annotation
             begin.set_from_pixbuf(png_to_pixbuf (cache.get(t.begin), width=config.data.preferences['drag-snapshot-width']))
             end.set_from_pixbuf(png_to_pixbuf (cache.get(t.end), width=config.data.preferences['drag-snapshot-width']))
             end.show()
             padding.show()
             if widgets:
                 l.set_text(_("Set of %s annotations") % len(widgets))
             else:
                 l.set_text(self.controller.get_title(t))
     wid._current=t
     return True
Beispiel #24
0
    def as_html(self):
        if self.annotation is None:
            return """<span advene:error="Non-existent annotation"></span>"""

        ctx = self.controller.build_context(self.annotation)
        d = {
            'id':
            self.annotation.id,
            'href':
            self.controller.get_urlbase() +
            ctx.evaluateValue('here/player_url'),
            'imgurl':
            self.controller.get_urlbase() +
            ctx.evaluateValue('here/snapshot_url'),
            'timestamp':
            helper.format_time(self.annotation.fragment.begin),
            'content':
            self.controller.get_title(self.annotation),
            'urlbase':
            self.controller.get_urlbase().rstrip('/'),
        }
        data = [
            """<span class="advene:annotation" advene:annotation="%s" advene:presentation="%s">"""
            % (self.annotation.id, ':'.join(self.presentation))
        ]

        if 'link' in self.presentation:
            data.append(
                """<a title="Click to play the movie in Advene" tal:attributes="href package/annotations/%(id)s/player_url" href="%(href)s">"""
                % d)

        if 'overlay' in self.presentation:
            data.append(
                """<img title="Click here to play"  width="160" height="100" src="%(urlbase)s/media/overlay/advene/%(id)s"></img>"""
                % d)
        elif 'snapshot' in self.presentation:
            if 'timestamp' in self.presentation:
                data.append(
                    """<img title="Click here to play"  width="160" height="100" src="%(urlbase)s/media/overlay/advene/%(id)s/fragment/formatted/begin"></img>"""
                    % d)
            else:
                data.append(
                    """<img title="Click here to play" width="160" height="100" tal:attributes="src package/annotations/%(id)s/snapshot_url" src="%(imgurl)s" ></img>"""
                    % d)
        elif 'timestamp' in self.presentation:
            # timestamp without snapshot or overlay
            data.append(
                """<em tal:content="package/annotations/%(id)s/fragment/formatted/begin">%(timestamp)s</em><br>"""
                % d)
        elif 'content' in self.presentation:
            data.append(
                """<span tal:content="package/annotations/%(id)s/representation">%(content)s</span>"""
                % d)
        if 'link' in self.presentation:
            data.append('</a>')

        data.append('</span>')

        return "".join(data)
Beispiel #25
0
    def generate_transcription(self):
        last=None
        for d in self.parse_transcription(show_ignored=True,
                                          strip_blank=False):
            if d['ignored']:
                yield '[I%s]' % helper.format_time(d['begin'])
                yield d['content']
                yield '[%s]' % helper.format_time(d['end'])

            elif last != d['begin']:
                yield '[%s]' % helper.format_time(d['begin'])
                yield d['content']
                yield '[%s]' % helper.format_time(d['end'])
            else:
                yield d['content']
                yield '[%s]' % helper.format_time(d['end'])
            last=d['end']
Beispiel #26
0
 def iterator(self):
     for b in self.elements:
         yield {
             'begin': b.value,
             'end': b.value + self.duration,
             'content': b.comment or  "Bookmark %s" % helper.format_time(b.value),
             'notify': True,
             'complete': False,
             }
Beispiel #27
0
    def editor_drag_received(self, widget, context, x, y, selection, targetType, time):
        """Handle the drop from an annotation to the editor.
        """
        # FIXME: Upon DND, TextView receives the event twice. Some
        # posts from 2004 signal the same problem, some hacks can be
        # found in existing code :
        #   widget.emit_stop_by_name ("drag-data-received")
        #   context.finish(False, False, time)
        #   widget.stop_emission("drag-data-received")
        # but none of them seems to work here. Just use a basic approach,
        # imagining that nobody is fast enough to really do two DNDs
        # at the same time.
        # But on win32, timestamp is always 0. So we must use x and y information as well.
        if time == self.last_dndtime and x == self.last_x and y == self.last_y:
            return True
        self.last_dndtime=time
        self.last_x=x
        self.last_y=y

        x, y = self.editor.window_to_buffer_coords(gtk.TEXT_WINDOW_TEXT,
                                                   *widget.get_pointer())
        it = self.editor.get_iter_at_location(x, y)
        self.editor.get_buffer().place_cursor(it)

        if targetType == config.data.target_type['annotation']:
            for uri in unicode(selection.data, 'utf8').split('\n'):
                source=self.controller.package.annotations.get(uri)
                if source is None:
                    return True
                m=gtk.Menu()
                for (title, choice) in (
                    (_("Snapshot only"), ['link', 'snapshot', ]),
                    (_("Overlayed snapshot only"), ['link', 'overlay', ]),
                    (_("Timestamp only"), ['link', 'timestamp', ]),
                    (_("Snapshot+timestamp"), ['link', 'snapshot', 'timestamp']),
                    ):
                    i=gtk.MenuItem(title)
                    i.connect('activate', (lambda it, ann, data: self.insert_annotation_content(data, ann, focus=True)), source, choice)
                    m.append(i)
                m.show_all()
                m.popup(None, None, None, 0, gtk.get_current_event_time())
            return True
        elif targetType == config.data.target_type['annotation-type']:
            # FIXME: use splitlines()
            source=self.controller.package.get(unicode(selection.data, 'utf8'))
            # FIXME: propose various choices (insert all annotations, insert title, etc)
            self.editor.get_buffer().insert_at_cursor(source.title)
            return True
        elif targetType == config.data.target_type['timestamp']:
            data=decode_drop_parameters(selection.data)
            t=long(data['timestamp'])
            # FIXME: propose various choices (insert timestamp, insert snapshot, etc)
            self.editor.get_buffer().insert_at_cursor(helper.format_time(t))
            return True
        else:
            print "Unknown target type for drop: %d" % targetType
        return False
Beispiel #28
0
 def iterator(self):
     for b in self.elements:
         yield {
             'begin': b.value,
             'end': b.value + self.duration,
             'content': b.comment or  "Bookmark %s" % helper.format_time(b.value),
             'notify': True,
             'complete': False,
             }
Beispiel #29
0
 def popup_modify(win, t):
     timestamp=child.value + t
     child.set_tooltip_text("%s" % helper.format_time(timestamp))
     # FIXME: find a way to do this in the new Gtk.Tooltip API?
     #if self.tooltips.active_tips_data is None:
     #    button.emit('show-help', Gtk.WIDGET_HELP_TOOLTIP)
     child.value=timestamp
     if self.options['play-on-scroll']:
         popup_goto(child, timestamp)
     return True
 def popup_modify(win, t):
     timestamp=child.value + t
     child.set_tooltip_text("%s" % helper.format_time(timestamp))
     # FIXME: find a way to do this in the new Gtk.Tooltip API?
     #if self.tooltips.active_tips_data is None:
     #    button.emit('show-help', Gtk.WIDGET_HELP_TOOLTIP)
     child.value=timestamp
     if self.options['play-on-scroll']:
         popup_goto(child, timestamp)
     return True
Beispiel #31
0
    def on_bus_message(self, bus, message):
        def finalize():
            GObject.idle_add(
                lambda: self.pipeline.set_state(Gst.State.NULL) and False)
            # Add last buffer data
            if self.buffer:
                # There is some data left.
                self.buffer_list.append(
                    (self.first_item_time,
                     self.first_item_time + len(self.buffer) * self.interval,
                     list(self.buffer)))
            self.generate_normalized_annotations()
            self.end_callback()
            return True

        s = message.get_structure()
        if message.type == Gst.MessageType.EOS:
            finalize()
        elif message.type == Gst.MessageType.ERROR:
            title, message = message.parse_error()
            logger.error("%s: %s", title, message)
        elif message.type == Gst.MessageType.WARNING:
            title, message = message.parse_warning()
            logger.warn("%s: %s", title, message)
        elif s:
            if s.get_name() == 'progress' and self.progress is not None:
                if not self.progress(
                        s['percent-double'] / 100,
                        _("At %s") % helper.format_time(s['current'] * 1000)):
                    finalize()
            elif s.get_name() == 'level':
                if not self.buffer:
                    self.first_item_time = s['stream-time'] / Gst.MSECOND
                rms = s['rms']
                v = rms[0]
                if len(rms) > 1:
                    if self.channel == 'right':
                        v = rms[1]
                    elif self.channel == 'both':
                        v = (rms[0] + rms[1]) / 2
                if isinf(v) or isnan(v) or v < self.lower_db_limit:
                    v = self.lastval
                if v < self.min:
                    self.min = v
                elif v > self.max:
                    self.max = v
                self.lastval = v
                self.buffer.append(v)
                if len(self.buffer) >= self.count:
                    self.buffer_list.append(
                        (self.first_item_time, s['endtime'] / Gst.MSECOND,
                         list(self.buffer)))
                    self.buffer = []
        return True
Beispiel #32
0
 def as_html(self, with_timestamp=True):
     """Return a HTML representation of the widget.
     """
     data={ 'image_url': 'http:/media/snapshot/advene/%d' % self._value,
            'player_url': 'http:/media/play/%d' % self._value,
            'timestamp': helper.format_time(self._value)
            }
     ret="""<a href="%(player_url)s"><img width="120" border="0" src="%(image_url)s" alt="" /></a>""" % data
     if with_timestamp:
         ret = ''.join( (ret, """<br /><em><a href="%(player_url)s">%(timestamp)s</a></em>""" % data) )
     return ret
Beispiel #33
0
 def as_html(self, with_timestamp=True):
     """Return a HTML representation of the widget.
     """
     data={ 'image_url': 'http:/media/snapshot/advene/%d' % self._value,
            'player_url': 'http:/media/play/%d' % self._value,
            'timestamp': helper.format_time(self._value)
            }
     ret="""<a href="%(player_url)s"><img width="120" border="0" src="%(image_url)s" alt="" /></a>""" % data
     if with_timestamp:
         ret = ''.join( (ret, """<br /><em><a href="%(player_url)s">%(timestamp)s</a></em>""" % data) )
     return ret
Beispiel #34
0
 def title (self, node):
     title=None
     if self.controller:
         title=self.controller.get_title(node)
     if not title:
         title = "???"
         try:
             title=node.id
         except AttributeError:
             pass
     # FIXME: bad hardcoded value
     #if len(title) > 50:
     #    title=title[:50]
     if isinstance(node, Annotation):
         title="%s (%s, %s)" % (title,
                                helper.format_time(node.fragment.begin),
                                helper.format_time(node.fragment.end))
     if ((hasattr(node, 'isImported') and node.isImported())
         or (hasattr(node, 'schema') and node.schema.isImported())):
         title += " (*)"
     return title
Beispiel #35
0
 def drag_sent(self, widget, context, selection, targetType, eventTime):
     """Handle the drag-sent event.
     """
     if targetType == config.data.target_type['timestamp']:
         selection.set(selection.target, 8, encode_drop_parameters(timestamp=self.value))
         return True
     elif targetType in ( config.data.target_type['text-plain'],
                          config.data.target_type['TEXT'],
                          config.data.target_type['STRING'] ):
         selection.set(selection.target, 8, helper.format_time(self.value))
         return True
     return False
Beispiel #36
0
 def title(self, node):
     title = None
     if self.controller:
         title = self.controller.get_title(node)
     if not title:
         title = "???"
         try:
             title = node.id
         except AttributeError:
             pass
     # FIXME: bad hardcoded value
     #if len(title) > 50:
     #    title=title[:50]
     if isinstance(node, Annotation):
         title = "%s (%s, %s)" % (title,
                                  helper.format_time(node.fragment.begin),
                                  helper.format_time(node.fragment.end))
     if ((hasattr(node, 'isImported') and node.isImported())
             or (hasattr(node, 'schema') and node.schema.isImported())):
         title += " (*)"
     return title
Beispiel #37
0
    def generate_buffer_content(self):
        b = self.textview.get_buffer()
        # Clear the buffer
        begin, end = b.get_bounds()
        b.delete(begin, end)

        def insert_at_cursor_with_tags_by_name(text, *tags):
            b.insert_with_tags_by_name(b.get_iter_at_mark(b.get_insert()),
                                       text, *tags)

        l = list(self.model)
        l.sort(key=lambda a: a.fragment.begin)
        for a in l:
            if self.options['display-time']:
                insert_at_cursor_with_tags_by_name(
                    "[%s]" % helper.format_time(a.fragment.begin), "bound")

            mark = b.create_mark("b_%s" % a.id,
                                 b.get_iter_at_mark(b.get_insert()),
                                 left_gravity=True)
            mark.set_visible(self.options['display-bounds'])

            # Put a 0-width char to make it easier to edit annotations
            insert_at_cursor_with_tags_by_name(ZERO_WIDTH_NOBREAK_SPACE,
                                               "bound")
            b.insert_at_cursor(str(self.representation(a)))
            insert_at_cursor_with_tags_by_name(ZERO_WIDTH_NOBREAK_SPACE,
                                               "bound")
            mark = b.create_mark("e_%s" % a.id,
                                 b.get_iter_at_mark(b.get_insert()),
                                 left_gravity=True)
            mark.set_visible(self.options['display-bounds'])

            if self.options['display-time']:
                insert_at_cursor_with_tags_by_name(
                    "[%s]" % helper.format_time(a.fragment.end), "bound")

            insert_at_cursor_with_tags_by_name(self.options['separator'],
                                               "bound")
        return
Beispiel #38
0
    def refresh(self, *p):
        self.mainbox.foreach(self.mainbox.remove)
        self.append_dropzone(0)
        duration = 0
        for i, a in enumerate(self.contents):
            self.append_repr(a)
            self.append_dropzone(i + 1)
            duration += a.annotation.fragment.duration
        self.mainbox.show_all()

        self.duration = duration
        self.duration_label.set_text(helper.format_time(duration))
        return True
Beispiel #39
0
    def refresh(self, *p):
        self.mainbox.foreach(self.mainbox.remove)
        self.append_dropzone(0)
        duration=0
        for i, a in enumerate(self.contents):
            self.append_repr(a)
            self.append_dropzone(i+1)
            duration += a.annotation.fragment.duration
        self.mainbox.show_all()

        self.duration=duration
        self.duration_label.set_text(helper.format_time(duration))
        return True
Beispiel #40
0
 def drag_sent(self, widget, context, selection, targetType, eventTime):
     """Handle the drag-sent event.
     """
     if targetType == config.data.target_type['timestamp']:
         selection.set(selection.target, 8,
                       encode_drop_parameters(timestamp=self.value))
         return True
     elif targetType in (config.data.target_type['text-plain'],
                         config.data.target_type['TEXT'],
                         config.data.target_type['STRING']):
         selection.set(selection.target, 8, helper.format_time(self.value))
         return True
     return False
Beispiel #41
0
    def build_model(self, elements):
        """Build the ListStore containing the data.

        """
        l=gtk.ListStore(object, str, str, str, long, long, str, str, str, gtk.gdk.Pixbuf, str)
        if not elements:
            return l
        for a in elements:
            if isinstance(a, Annotation):
                l.append( (a,
                           self.controller.get_title(a),
                           self.controller.get_title(a.type),
                           a.id,
                           a.begin,
                           a.end,
                           helper.format_time(a.duration),
                           helper.format_time(a.begin),
                           helper.format_time(a.end),
                           png_to_pixbuf(self.controller.imagecache[a.media.url][a.begin],
                                         height=32),
                           self.controller.get_element_color(a),
                           ) )
        return l
Beispiel #42
0
    def build_pixbuf(self):
        if self.annotation is None:
            pixbuf=png_to_pixbuf(self.controller.gui.imagecache.not_yet_available_image,
                                 width=self.width)
        elif 'overlay' in self.presentation:
            pixbuf=overlay_svg_as_pixbuf(self.controller.imagecache[self.annotation.media.url][self.annotation.begin],
                                         self.annotation.content.data,
                                         width=self.width)
        elif 'snapshot' in self.presentation:
            if 'timestamp' in self.presentation:
                pixbuf=overlay_svg_as_pixbuf(self.controller.imagecache[self.annotation.media.url][self.annotation.begin],
                                             helper.format_time(self.annotation.begin),
                                             width=self.width)
            else:
                pixbuf=png_to_pixbuf(self.controller.imagecache[self.annotation.media.url][self.annotation.begin],
                                     width=self.width)
        elif 'timestamp' in self.presentation:
            # Generate only a timestamp 
            # FIXME: hardcoded value in viewBox is bad... We should find out the appropriate size.
            loader = gtk.gdk.PixbufLoader('svg')
            loader.write("""<svg version='1'> preserveAspectRatio="xMinYMin meet" viewBox="0 0 220 20">
<text x='0' y='10' fill="black" font-size="12" stroke="black" font-family="sans-serif">
%s
  </text>
</svg>
""" % helper.format_time(self.annotation.begin))
            loader.close ()
            pixbuf = loader.get_pixbuf ()
        else:
            pixbuf=png_to_pixbuf(self.controller.gui.imagecache.not_yet_available_image,
                                 width=self.width)
        pixbuf.as_html=self.as_html
        pixbuf._placeholder=self
        pixbuf._tag='span'
        pixbuf._attr=[]
        return pixbuf
Beispiel #43
0
    def generate_buffer_content(self):
        b=self.textview.get_buffer()
        # Clear the buffer
        begin, end = b.get_bounds()
        b.delete(begin, end)

        def insert_at_cursor_with_tags_by_name(text, *tags):
            b.insert_with_tags_by_name(b.get_iter_at_mark(b.get_insert()),
                                       text, *tags)

        l=list(self.model)
        l.sort(key=lambda a: a.fragment.begin)
        for a in l:
            if self.options['display-time']:
                insert_at_cursor_with_tags_by_name("[%s]" % helper.format_time(a.fragment.begin),
                                                     "bound")

            mark = b.create_mark("b_%s" % a.id,
                                 b.get_iter_at_mark(b.get_insert()),
                                 left_gravity=True)
            mark.set_visible(self.options['display-bounds'])

            # Put a 0-width char to make it easier to edit annotations
            insert_at_cursor_with_tags_by_name(ZERO_WIDTH_NOBREAK_SPACE, "bound")
            b.insert_at_cursor(str(self.representation(a)))
            insert_at_cursor_with_tags_by_name(ZERO_WIDTH_NOBREAK_SPACE, "bound")
            mark = b.create_mark("e_%s" % a.id,
                                 b.get_iter_at_mark(b.get_insert()),
                                 left_gravity=True)
            mark.set_visible(self.options['display-bounds'])

            if self.options['display-time']:
                insert_at_cursor_with_tags_by_name("[%s]" % helper.format_time(a.fragment.end), "bound")

            insert_at_cursor_with_tags_by_name(self.options['separator'], "bound")
        return
Beispiel #44
0
    def on_bus_message(self, bus, message):
        def finalize():
            pos = self.pipeline.query_position(
                gst.FORMAT_TIME)[0] / gst.MSECOND
            gobject.idle_add(
                lambda: self.pipeline.set_state(gst.STATE_NULL) and False)
            self.convert({
                'begin': begin,
                'end': end,
                'content': 'sound',
            } for begin, end in self.buffer)
            self.end_callback()
            return True

        if message.type == gst.MESSAGE_EOS:
            finalize()
        ##elif message.type == gst.MESSAGE_STATE_CHANGED:
        ##    old, new, pending = message.parse_state_changed()
        ##    if old == gst.STATE_READY and new == gst.STATE_PAUSED:
        ##        # There has been a problem. Cancel.
        ##        self.progress(1.0, _("Problem when running detection"))
        ##        print "Undetermined problem when running silence detection."
        ##        self.end_callback()
        ##        gobject.idle_add(lambda: self.pipeline.set_state(gst.STATE_NULL) and False)
        ##    #if new == gst.STATE_NULL:
        ##    #    self.end_callback()
        elif message.structure:
            s = message.structure
            #print "MSG " + bus.get_name() + ": " + s.to_string()
            if s.get_name() == 'progress' and self.progress is not None:
                if not self.progress(
                        s['percent-double'] / 100,
                        _("Detected %(count)d segments until %(time)s") % {
                            'count': len(self.buffer),
                            'time': helper.format_time(s['current'] * 1000)
                        }):
                    finalize()
            elif s.get_name() == 'cutter':
                t = s['timestamp'] / gst.MSECOND
                if s['above']:
                    self.last_above = t
                else:
                    if self.last_above is not None:
                        self.buffer.append((self.last_above, t))
                    else:
                        print "Error: not above without matching above"
                    self.last_above = t
        return True
Beispiel #45
0
    def on_bus_message(self, bus, message):
        def finalize():
            GObject.idle_add(lambda: self.pipeline.set_state(Gst.State.NULL) and False)
            # Add last buffer data
            if self.buffer:
                # There is some data left.
                self.buffer_list.append((self.first_item_time,
                                         self.first_item_time + len(self.buffer) * self.interval,
                                         list(self.buffer)))
            self.generate_normalized_annotations()
            self.end_callback()
            return True

        s = message.get_structure()
        if message.type == Gst.MessageType.EOS:
            finalize()
        elif message.type == Gst.MessageType.ERROR:
            title, message = message.parse_error()
            logger.error("%s: %s", title, message)
        elif message.type == Gst.MessageType.WARNING:
            title, message = message.parse_warning()
            logger.warn("%s: %s", title, message)
        elif s:
            if s.get_name() == 'progress' and self.progress is not None:
                if not self.progress(s['percent-double'] / 100, _("At %s") % helper.format_time(s['current'] * 1000)):
                    finalize()
            elif s.get_name() == 'level':
                if not self.buffer:
                    self.first_item_time = s['stream-time'] / Gst.MSECOND
                rms = s['rms']
                v = rms[0]
                if len(rms) > 1:
                    if self.channel == 'right':
                        v = rms[1]
                    elif self.channel == 'both':
                        v = (rms[0] + rms[1]) / 2
                if isinf(v) or isnan(v) or v < self.lower_db_limit:
                    v = self.lastval
                if v < self.min:
                    self.min = v
                elif v > self.max:
                    self.max = v
                self.lastval = v
                self.buffer.append(v)
                if len(self.buffer) >= self.count:
                    self.buffer_list.append((self.first_item_time, s['endtime'] / Gst.MSECOND, list(self.buffer)))
                    self.buffer = []
        return True
Beispiel #46
0
    def on_bus_message(self, bus, message):
        def finalize():
            pos = self.pipeline.query_position(
                gst.FORMAT_TIME)[0] / gst.MSECOND
            gobject.idle_add(
                lambda: self.pipeline.set_state(gst.STATE_NULL) and False)
            # Add last buffer data
            self.buffer_list.append(
                (self.first_item_time, pos, list(self.buffer)))
            self.generate_normalized_annotations()
            self.end_callback()
            return True

        if message.type == gst.MESSAGE_EOS:
            finalize()
        elif message.structure:
            s = message.structure
            #print "MSG " + bus.get_name() + ": " + s.to_string()
            if s.get_name() == 'progress' and self.progress is not None:
                if not self.progress(
                        s['percent-double'] / 100,
                        _("At %s") % helper.format_time(s['current'] * 1000)):
                    finalize()
            elif s.get_name() == 'level':
                if not self.buffer:
                    self.first_item_time = s['stream-time'] / gst.MSECOND
                rms = s['rms']
                v = rms[0]
                if len(rms) > 1:
                    if self.channel == 'right':
                        v = rms[1]
                    elif self.channel == 'both':
                        v = (rms[0] + rms[1]) / 2
                if isinf(v) or isnan(v):
                    v = self.lastval
                if v < self.min:
                    self.min = v
                elif v > self.max:
                    self.max = v
                self.lastval = v
                self.buffer.append(v)
                if len(self.buffer) >= self.count:
                    self.buffer_list.append(
                        (self.first_item_time, s['endtime'] / gst.MSECOND,
                         list(self.buffer)))
                    self.buffer = []
        return True
Beispiel #47
0
    def validate_and_next(self, new):
        """Validate the current annotation and display the next one.
        """
        i = self.index
        annotation = self.annotations[i]
        batch=object()

        event = Gtk.get_current_event()
        if event.get_state().state & Gdk.ModifierType.CONTROL_MASK:
            # Control-key is held. Split the annotation.
            if new > annotation.fragment.begin and new < annotation.fragment.end:
                self.controller.split_annotation(annotation, new)
                self.message(_("Split annotation #%(current)d into #%(current)d and #%(next)d") % {
                        'current': i + 1,
                        'next': i + 2
                        })
            else:
                self.message(_("Cannot split annotation #%(current)d: out of bounds.") % {
                        'current': i + 1,
                        })
            return True

        if new != annotation.fragment.begin:
            logger.debug("Updating annotation begin from %s to %s", helper.format_time(annotation.fragment.begin), helper.format_time_reference(new))
            self.controller.notify('EditSessionStart', element=annotation, immediate=True)
            annotation.fragment.begin = new
            self.controller.notify('AnnotationEditEnd', annotation=annotation, batch=batch)
            self.controller.notify('EditSessionEnd', element=annotation)
            self.undo_button.set_sensitive(True)

        # Update previous annotation end.
        if i > 0:
            annotation = self.annotations[i - 1]
            if new != annotation.fragment.end:
                self.controller.notify('EditSessionStart', element=annotation, immediate=True)
                annotation.fragment.end = new
                self.controller.notify('AnnotationEditEnd', annotation=annotation, batch=batch)
                self.controller.notify('EditSessionEnd', element=annotation)
            self.message(_("Changed cut between #%(first)d and %(second)d") % { 'first': i + 1,
                                                                                  'second': i + 2 })
        else:
            self.message(_("Changed begin time for first annotation"))
        self.set_index(i + 1)
        return True
Beispiel #48
0
 def set_time(self, attr):
     """Sets the time of the current annotation to the current player time.
     """
     an, an_path = self.get_selected_node(with_path=True)
     if an is None:
         return
     current_time = self.controller.player.current_position_value
     confirm = True
     if self.options['confirm-time-update']:
         confirm = dialog.message_dialog(_("Set %(attr)s time to %(time)s") % {
             'attr': _(attr),
             'time': helper.format_time(current_time)
             }, icon=Gtk.MessageType.QUESTION)
     if confirm:
         self.last_edited_path = an_path
         self.controller.notify('EditSessionStart', element=an, immediate=True)
         setattr(an.fragment, attr, current_time)
         self.controller.notify("AnnotationEditEnd", annotation=an)
         self.controller.notify('EditSessionEnd', element=an)
        def handle_scroll_event(button, event):
            if not (event.get_state() & Gdk.ModifierType.CONTROL_MASK):
                return False
            if event.get_state() & Gdk.ModifierType.SHIFT_MASK:
                i='second-scroll-increment'
            else:
                i='scroll-increment'

            if event.direction == Gdk.ScrollDirection.DOWN or event.direction == Gdk.ScrollDirection.RIGHT:
                button.value -= config.data.preferences[i]
            elif event.direction == Gdk.ScrollDirection.UP or event.direction == Gdk.ScrollDirection.LEFT:
                button.value += config.data.preferences[i]

                button.set_tooltip_text("%s" % helper.format_time(button.value))
            # FIXME: find a way to do this in the new Gtk.Tooltip API?
            #if self.tooltips.active_tips_data is None:
            #    button.emit('show-help', Gtk.WIDGET_HELP_TOOLTIP)
            self.timestamp_play = button.value
            button.grab_focus()
            return True
Beispiel #50
0
        def handle_scroll_event(button, event):
            if not (event.get_state() & Gdk.ModifierType.CONTROL_MASK):
                return False
            if event.get_state() & Gdk.ModifierType.SHIFT_MASK:
                i='second-scroll-increment'
            else:
                i='scroll-increment'

            if event.direction == Gdk.ScrollDirection.DOWN or event.direction == Gdk.ScrollDirection.RIGHT:
                button.value -= config.data.preferences[i]
            elif event.direction == Gdk.ScrollDirection.UP or event.direction == Gdk.ScrollDirection.LEFT:
                button.value += config.data.preferences[i]

                button.set_tooltip_text("%s" % helper.format_time(button.value))
            # FIXME: find a way to do this in the new Gtk.Tooltip API?
            #if self.tooltips.active_tips_data is None:
            #    button.emit('show-help', Gtk.WIDGET_HELP_TOOLTIP)
            self.timestamp_play = button.value
            button.grab_focus()
            return True
Beispiel #51
0
    def on_bus_message(self, bus, message):
        def finalize():
            """Finalize data creation.
            """
            gobject.idle_add(lambda: self.pipeline.set_state(gst.STATE_NULL) and False)
            self.generate_annotations()
            if self.end_callback:
                self.end_callback()
            return False

        if message.type == gst.MESSAGE_EOS:
            finalize()
        elif message.structure:
            s = message.structure
            #print "MSG " + s.get_name() + ": " + s.to_string()
            if s.get_name() == 'progress' and self.progress is not None:
                if not self.progress(s['percent-double'] / 100, _("%(count)d utterances until %(time)s") % {
                        'count': len(self.buffer_list),
                        'time': helper.format_time(s['current'] * 1000) }):
                    finalize()
        return True
Beispiel #52
0
    def on_bus_message(self, bus, message):
        def finalize():
            """Finalize data creation.
            """
            GObject.idle_add(lambda: self.pipeline.set_state(Gst.State.NULL) and False)
            self.generate_annotations()
            if self.end_callback:
                self.end_callback()
            return False

        s = message.get_structure()
        if message.type == Gst.MessageType.EOS:
            finalize()
        elif s:
            logger.debug("MSG ", s.get_name(), s.to_string())
            if s.get_name() == 'progress' and self.progress is not None:
                if not self.progress(s['percent-double'] / 100, _("%(count)d utterances until %(time)s") % {
                        'count': len(self.buffer_list),
                        'time': helper.format_time(s['current'] * 1000) }):
                    finalize()
        return True
Beispiel #53
0
    def on_bus_message(self, bus, message):
        def finalize():
            pos = self.pipeline.query_position(gst.FORMAT_TIME)[0] / gst.MSECOND
            gobject.idle_add(lambda: self.pipeline.set_state(gst.STATE_NULL) and False)
            # Add last buffer data
            self.buffer_list.append((self.first_item_time, pos, list(self.buffer)))
            self.generate_normalized_annotations()
            self.end_callback()
            return True

        if message.type == gst.MESSAGE_EOS:
            finalize()
        elif message.structure:
            s=message.structure
            #print "MSG " + bus.get_name() + ": " + s.to_string()
            if s.get_name() == 'progress' and self.progress is not None:
                if not self.progress(s['percent-double'] / 100, _("At %s") % helper.format_time(s['current'] * 1000)):
                    finalize()
            elif s.get_name() == 'level':
                if not self.buffer:
                    self.first_item_time = s['stream-time'] / gst.MSECOND
                rms = s['rms']
                v = rms[0]
                if len(rms) > 1:
                    if self.channel == 'right':
                        v = rms[1]
                    elif self.channel == 'both':
                        v = (rms[0] + rms[1]) / 2
                if isinf(v) or isnan(v):
                    v = self.lastval
                if v < self.min:
                    self.min = v
                elif v > self.max:
                    self.max = v
                self.lastval = v
                self.buffer.append(v)
                if len(self.buffer) >= self.count:
                    self.buffer_list.append((self.first_item_time, s['endtime'] / gst.MSECOND, list(self.buffer)))
                    self.buffer = []
        return True
Beispiel #54
0
 def set_time(self, attr):
     """Sets the time of the current annotation to the current player time.
     """
     an, an_path = self.get_selected_node(with_path=True)
     if an is None:
         return
     current_time = self.controller.player.current_position_value
     confirm = True
     if self.options['confirm-time-update']:
         confirm = dialog.message_dialog(
             _("Set %(attr)s time to %(time)s") % {
                 'attr': _(attr),
                 'time': helper.format_time(current_time)
             },
             icon=Gtk.MessageType.QUESTION)
     if confirm:
         self.last_edited_path = an_path
         self.controller.notify('EditSessionStart',
                                element=an,
                                immediate=True)
         setattr(an.fragment, attr, current_time)
         self.controller.notify("AnnotationEditEnd", annotation=an)
         self.controller.notify('EditSessionEnd', element=an)
Beispiel #55
0
    def get_view(self, compact=False):
        """Generate a view widget for editing SVG."""
        vbox = Gtk.VBox()

        if self.parent is not None and hasattr(self.parent, 'fragment'):
            i = image_from_position(self.controller,
                                    position=self.parent.fragment.begin,
                                    media=self.parent.media)
            vi = self.controller.package.imagecache.video_info
            self.view = ShapeEditor(background=i,
                                    icon_dir=config.data.advenefile('pixmaps'),
                                    default_size=(vi.get('width', 320),
                                                  vi.get('height', 200)))

            def snapshot_update_cb(context, target):
                if context.globals['media'] != self.parent.media:
                    return True
                pos = self.get_background_position()
                if context.globals['position'] == pos:
                    # Refresh image
                    i = image_from_position(self.controller,
                                            position=pos,
                                            media=self.parent.media)
                    self.view.set_background(i)
                return True

            self.rules.append(
                self.controller.event_handler.internal_rule(
                    event='SnapshotUpdate', method=snapshot_update_cb))

            def annotation_update_cb(context, target):
                self.view.background_adj.set_value(0)
                return True

            self.rules.append(
                self.controller.event_handler.internal_rule(
                    event='AnnotationEditEnd', method=annotation_update_cb))

        else:
            self.view = ShapeEditor(icon_dir=config.data.advenefile('pixmaps'))

        self.parse_svg()

        self.view.drawer.widget.connect('drag-data-received',
                                        self.drawer_drag_received)
        self.view.drawer.widget.drag_dest_set(
            Gtk.DestDefaults.MOTION | Gtk.DestDefaults.HIGHLIGHT
            | Gtk.DestDefaults.ALL,
            config.data.get_target_types('view', 'annotation', 'uri-list'),
            Gdk.DragAction.COPY | Gdk.DragAction.LINK)

        def edit_svg(b=None):
            vbox.foreach(vbox.remove)
            vbox.add(self.view.widget)
            self.editing_source = False
            vbox.show_all()
            return True

        def edit_xml(b=None):
            if self.sourceview is None:
                self.sourceview = TextContentHandler(
                    element=self.element,
                    controller=self.controller,
                    parent=self.parent)
                self.sourceview.widget = self.sourceview.get_view()
                b = get_pixmap_toolbutton('xml.png', edit_svg)
                b.set_tooltip_text(_("Graphical editor"))
                self.sourceview.toolbar.insert(b, 0)

            vbox.foreach(vbox.remove)
            vbox.add(self.sourceview.widget)
            self.editing_source = True
            vbox.show_all()
            return True

        # Insert "View source" button in Shapewidget toolbar
        b = get_pixmap_toolbutton('xml.png', edit_xml)
        b.set_tooltip_text(_("Edit XML"))
        self.view.toolbar.insert(b, 0)

        def update_background(adj):
            pos = self.get_background_position()
            i = image_from_position(self.controller,
                                    position=pos,
                                    media=self.parent.media)
            self.view.set_background(i)
            return True

        self.view.background_adj = Gtk.Adjustment.new(value=0,
                                                      lower=0,
                                                      upper=1.0,
                                                      step_increment=0.1,
                                                      page_increment=0.2,
                                                      page_size=0.2)
        slider = Gtk.HScale.new(self.view.background_adj)
        slider.connect(
            "format-value",
            lambda s, v: helper.format_time(self.parent.fragment.begin + int(
                v * self.parent.fragment.duration)))
        ti = Gtk.ToolItem()
        ti.add(slider)
        ti.set_expand(True)
        self.view.toolbar.insert(ti, -1)
        self.view.background_adj.connect('value-changed', update_background)

        if config.data.preferences['prefer-wysiwyg']:
            edit_svg()
        else:
            edit_xml()
        return vbox
Beispiel #56
0
 def update_display(self):
     """Updates the value displayed in the entry according to the current value."""
     self.entry.set_text(helper.format_time(self.value))
     self.image.value = self.value
Beispiel #57
0
    def make_widget(self):
        def refresh_snapshot(item):
            self.image.refresh_snapshot()
            return True

        def image_button_clicked(button):
            event = Gtk.get_current_event()
            if event.get_state().state & Gdk.ModifierType.CONTROL_MASK:
                self.use_current_position(button)
                return True
            else:
                self.play_from_here(button)
                return True

        def image_button_press(button, event):
            if event.button == 3 and event.type == Gdk.EventType.BUTTON_PRESS:
                # Display the popup menu
                menu = Gtk.Menu()
                item = Gtk.MenuItem(_("Refresh snapshot"))
                item.connect('activate', refresh_snapshot)
                menu.append(item)
                menu.show_all()
                menu.popup_at_pointer(None)
                return True
            return False

        def make_button(incr_value, pixmap):
            """Helper function to build the buttons."""
            b = Gtk.Button()
            i = Gtk.Image()
            i.set_from_file(config.data.advenefile(('pixmaps', pixmap)))
            b.set_image(i)

            def increment_value_cb(widget, increment):
                self.set_value(self.value + increment)
                return True

            b.connect('clicked', increment_value_cb, incr_value)
            if incr_value < 0:
                tip = _("Decrement value by %.2f s") % (incr_value / 1000.0)
            else:
                tip = _("Increment value by %.2f s") % (incr_value / 1000.0)
            b.set_tooltip_text(tip)
            return b

        vbox = Gtk.VBox()

        hbox = Gtk.HBox()
        hbox.set_homogeneous(False)

        if self.editable:
            vb = Gtk.VBox()
            b = make_button(-self.large_increment, "2leftarrow.png")
            vb.pack_start(b, False, True, 0)
            b = make_button(-self.small_increment, "1leftarrow.png")
            vb.pack_start(b, False, True, 0)
            hbox.pack_start(vb, False, True, 0)

        if self.compact:
            width = 50
        else:
            width = 100
        self.image = TimestampRepresentation(self.value,
                                             None,
                                             self.controller,
                                             width,
                                             visible_label=False,
                                             callback=self.set_value)
        self.image.connect('button-press-event', image_button_press)
        self.image.connect('clicked', image_button_clicked)
        self.image.set_tooltip_text(
            _("Click to play\nControl+click to set to current time\nScroll to modify value (with control/shift)\nRight-click to invalidate screenshot"
              ))
        hbox.pack_start(self.image, False, True, 0)

        if self.editable:
            vb = Gtk.VBox()
            b = make_button(self.large_increment, "2rightarrow.png")
            vb.pack_start(b, False, True, 0)
            b = make_button(self.small_increment, "1rightarrow.png")
            vb.pack_start(b, False, True, 0)
            hbox.pack_start(vb, False, True, 0)

        hb = Gtk.HBox()

        if self.editable:
            self.entry = Gtk.Entry()
            self.entry.set_tooltip_text(
                _("Enter a timecode.\nAn integer value will be considered as milliseconds.\nA float value (12.2) will be considered as seconds.\nHH:MM:SS.sss values are possible."
                  ))
            # Default width of the entry field
            self.entry.set_width_chars(len(helper.format_time(0.0)))
            self.entry.connect('activate', self.convert_entered_value)
            self.entry.connect('focus-out-event', self.convert_entered_value)
            self.entry.set_editable(self.editable)
            hb.pack_start(self.entry, False, True, 0)
        else:
            self.entry = None

        if self.editable:
            current_pos = Gtk.Button()
            i = Gtk.Image()
            i.set_from_file(
                config.data.advenefile(('pixmaps', 'set-to-now.png')))
            current_pos.set_tooltip_text(_("Set to current player position"))
            current_pos.add(i)
            current_pos.connect('clicked', self.use_current_position)
            hb.pack_start(current_pos, False, True, 0)

        vbox.pack_start(hbox, False, True, 0)
        vbox.pack_start(hb, False, True, 0)
        hb.set_style(self.image.box.get_style())
        #self.entry.set_style(self.image.box.get_style())
        vbox.set_style(self.image.box.get_style())
        vbox.show_all()

        hb.set_no_show_all(True)
        hbox.set_no_show_all(True)
        self.image.label.hide()
        hb.show()

        def handle_scroll_event(button, event):
            if event.get_state() & Gdk.ModifierType.CONTROL_MASK:
                i = config.data.preferences['scroll-increment']
            elif event.get_state() & Gdk.ModifierType.SHIFT_MASK:
                i = config.data.preferences['second-scroll-increment']
            else:
                # 1 frame
                i = self.controller.frame2time(1)

            if event.direction == Gdk.ScrollDirection.DOWN or event.direction == Gdk.ScrollDirection.LEFT:
                incr = -i
            elif event.direction == Gdk.ScrollDirection.UP or event.direction == Gdk.ScrollDirection.RIGHT:
                incr = i

            if not self.set_value(self.value + incr):
                return True
            return True

        if self.editable:
            # The widget can receive drops from annotations
            vbox.connect('drag-data-received', self.drag_received)
            vbox.drag_dest_set(
                Gtk.DestDefaults.MOTION | Gtk.DestDefaults.HIGHLIGHT
                | Gtk.DestDefaults.ALL,
                config.data.get_target_types('annotation',
                                             'timestamp'), Gdk.DragAction.LINK)

            vbox.connect('scroll-event', handle_scroll_event)

        vbox.show_all()
        return vbox
Beispiel #58
0
    def make_annotation_menu(self, element, menu):
        def add_item(*p, **kw):
            self.add_menuitem(menu, *p, **kw)

        def loop_on_annotation(menu, ann):
            self.controller.gui.loop_on_annotation_gui(ann, goto=True)
            return True

        def save_snapshot(menu, ann):
            self.controller.gui.save_snapshot_as(ann.fragment.begin)
            return True

        add_item(_("Go to..."), self.goto_annotation, element)
        add_item(_("Loop"), loop_on_annotation, element)
        add_item(_("Duplicate"), self.duplicate_annotation, element)
        item = gtk.MenuItem(_("Highlight"), use_underline=False)
        item.set_submenu(self.activate_submenu(element))
        menu.append(item)
        add_item(_("Save snapshot..."), save_snapshot, element)
        if 'montagerenderer' in self.controller.generic_features:
            add_item(_("Extract video fragment"), self.extract_fragment,
                     element)

        def build_submenu(submenu, el, items):
            """Build the submenu for the given element.
            """
            if submenu.get_children():
                # The submenu was already populated.
                return False
            if len(items) == 1:
                # Only 1 elements, do not use an intermediary menu
                m = Menu(element=items[0], controller=self.controller)
                for c in m.menu.get_children():
                    m.menu.remove(c)
                    submenu.append(c)
            else:
                for i in items:
                    item = gtk.MenuItem(self.get_title(i), use_underline=False)
                    m = Menu(element=i, controller=self.controller)
                    item.set_submenu(m.menu)
                    submenu.append(item)
            submenu.show_all()
            return False

        def build_related(submenu, el):
            """Build the related annotations submenu for the given element.
            """
            if submenu.get_children():
                # The submenu was already populated.
                return False
            if el.incomingRelations:
                i = gtk.MenuItem(_("Incoming"))
                submenu.append(i)
                i = gtk.SeparatorMenuItem()
                submenu.append(i)
                for t, l in el.typedRelatedIn.iteritems():
                    at = self.controller.package.get_element_by_id(t)
                    m = gtk.MenuItem(self.get_title(at), use_underline=False)
                    amenu = gtk.Menu()
                    m.set_submenu(amenu)
                    amenu.connect('map', build_submenu, at, l)
                    submenu.append(m)
            if submenu.get_children():
                # There were incoming annotations. Use a separator
                i = gtk.SeparatorMenuItem()
                submenu.append(i)
            if el.outgoingRelations:
                i = gtk.MenuItem(_("Outgoing"))
                submenu.append(i)
                i = gtk.SeparatorMenuItem()
                submenu.append(i)
                for t, l in el.typedRelatedOut.iteritems():
                    at = self.controller.package.get_element_by_id(t)
                    m = gtk.MenuItem(self.get_title(at), use_underline=False)
                    amenu = gtk.Menu()
                    m.set_submenu(amenu)
                    amenu.connect('map', build_submenu, at, l)
                    submenu.append(m)
            submenu.show_all()
            return False

        if element.relations:
            i = gtk.MenuItem(_("Related annotations"), use_underline=False)
            submenu = gtk.Menu()
            i.set_submenu(submenu)
            submenu.connect('map', build_related, element)
            menu.append(i)

            if element.incomingRelations:
                i = gtk.MenuItem(_("Incoming relations"), use_underline=False)
                submenu = gtk.Menu()
                i.set_submenu(submenu)
                submenu.connect('map', build_submenu, element,
                                element.incomingRelations)
                menu.append(i)

            if element.outgoingRelations:
                i = gtk.MenuItem(_("Outgoing relations"), use_underline=False)
                submenu = gtk.Menu()
                i.set_submenu(submenu)
                submenu.connect('map', build_submenu, element,
                                element.outgoingRelations)
                menu.append(i)

        add_item("")

        item = gtk.MenuItem()
        item.add(
            image_from_position(self.controller,
                                position=element.fragment.begin,
                                height=60))
        item.connect('activate', self.goto_annotation, element)
        menu.append(item)

        #add_item(element.content.data[:40])
        add_item(
            _('Begin: %s') % helper.format_time(element.fragment.begin),
            lambda i: self.controller.gui.adjust_annotation_bound(
                element, 'begin'))
        add_item(
            _('End: %s') % helper.format_time(element.fragment.end),
            lambda i: self.controller.gui.adjust_annotation_bound(
                element, 'end'))
        add_item(
            _('Duration: %s') % helper.format_time(element.fragment.duration))
        return
Beispiel #59
0
    def on_bus_message(self, bus, message):
        def finalize():
            GObject.idle_add(lambda: self.pipeline.set_state(Gst.State.NULL) and False)
            self.convert( {
                    'begin': begin,
                    'end': end,
                    'content': 'sound',
                    }
                          for begin, end in self.buffer )
            self.end_callback()
            return True

        s = message.get_structure()
        if message.type == Gst.MessageType.EOS:
            finalize()
        ##elif message.type == Gst.MessageType.STATE_CHANGED:
        ##    old, new, pending = message.parse_state_changed()
        ##    if old == Gst.State.READY and new == Gst.State.PAUSED:
        ##        # There has been a problem. Cancel.
        ##        self.progress(1.0, _("Problem when running detection"))
        ##        print "Undetermined problem when running silence detection."
        ##        self.end_callback()
        ##        GObject.idle_add(lambda: self.pipeline.set_state(Gst.State.NULL) and False)
        ##    #if new == Gst.State.NULL:
        ##    #    self.end_callback()
        elif s:
            logger.debug("MSG %s: %s", bus.get_name(), s.to_string())
            if s.get_name() == 'progress' and self.progress is not None:
                if not self.progress(s['percent-double'] / 100, _("Detected %(count)d segments until %(time)s") % { 'count': len(self.buffer),
                                                                                                                    'time': helper.format_time(s['current'] * 1000) }):
                    finalize()
            elif s.get_name() == 'cutter':
                t = s['timestamp'] / Gst.MSECOND
                if s['above']:
                    self.last_above = t
                else:
                    if self.last_above is not None:
                        self.buffer.append( (self.last_above, t) )
                    else:
                        logger.error("Error: not above without matching above")
                    self.last_above = t
        return True