Ejemplo n.º 1
0
    def build_widget(self):
        vb = Gtk.VBox()

        l = Gtk.Label(label=self.label)
        vb.pack_start(l, False, True, 0)

        hb = Gtk.HBox()

        eb = Gtk.EventBox()
        ar = Gtk.Arrow(Gtk.ArrowType.LEFT, Gtk.ShadowType.IN)
        ar.set_tooltip_text(
            _("Click to see more frames or scroll with the mouse wheel"))
        eb.connect('button-press-event', lambda b, e: self.update_offset(-1))
        eb.add(ar)
        hb.pack_start(eb, False, True, 0)

        r = None
        for i in range(self.count):

            r = TimestampRepresentation(0,
                                        None,
                                        self.controller,
                                        width=self.frame_width,
                                        visible_label=True,
                                        precision=0)
            r.add_class("frameselector_frame")
            r.add_class("frameselector_frame_%s" % self.border_mode)
            self.frames.append(r)
            r.connect("clicked", self.select_time)

            def enter_bookmark(widget, event):
                widget.add_class('frameselector_selected')
                return False

            def leave_bookmark(widget, event):
                widget.remove_class('frameselector_selected')
                return False

            r.connect('enter-notify-event', enter_bookmark)
            r.connect('leave-notify-event', leave_bookmark)

            hb.pack_start(r, False, True, 0)

        hb.connect("draw", self.check_size)
        eb = Gtk.EventBox()
        ar = Gtk.Arrow(Gtk.ArrowType.RIGHT, Gtk.ShadowType.IN)
        ar.set_tooltip_text(
            _("Click to see more frames or scroll with the mouse wheel"))
        eb.connect('button-press-event', lambda b, e: self.update_offset(+1))
        eb.add(ar)
        hb.pack_start(eb, False, True, 0)

        vb.add(hb)

        vb.set_events(Gdk.EventMask.SCROLL_MASK | Gdk.EventMask.KEY_PRESS_MASK)
        vb.connect('scroll-event', self.handle_scroll_event)
        vb.connect('key-press-event', self.handle_key_press)

        self.update_timestamp(self.timestamp)
        return vb
Ejemplo n.º 2
0
    def build_widget(self):
        self.image = TimestampRepresentation(
            self.value,
            None,
            self.controller,
            comment_getter=lambda: self.comment,
            width=self.width,
            precision=config.data.preferences['bookmark-snapshot-precision'])

        self.image.connect('clicked', self.image.goto_and_refresh)

        if self.display_comments:
            hbox = Gtk.HBox()
            self.comment_entry = Gtk.TextView()
            # Hook the completer component
            completer = Completer(textview=self.comment_entry,
                                  controller=self.controller,
                                  element=self.comment_entry.get_buffer(),
                                  indexer=self.controller.package._indexer)
            self.comment_entry.set_wrap_mode(Gtk.WrapMode.WORD)
            fd = Pango.FontDescription(
                'sans %d' % config.data.preferences['timeline']['font-size'])
            self.comment_entry.modify_font(fd)
            b = self.comment_entry.get_buffer()
            b.set_text(self.comment)

            def focus_in_event(wid, event):
                if b.get_text(*b.get_bounds() +
                              (False, )) == self.default_comment:
                    b.set_text('')
                return False

            self.comment_entry.connect('focus-in-event', focus_in_event)

            def focus_out_event(wid, event):
                if b.get_text(*b.get_bounds() + (False, )) == '':
                    b.set_text(self.default_comment)
                return False

            self.comment_entry.connect('focus-out-event', focus_out_event)

            def update_comment(buf):
                self.comment = buf.get_text(*buf.get_bounds() + (False, ))
                return True

            b.connect('changed', update_comment)

            #self.comment_entry.set_size_request(config.data.preferences['bookmark-snapshot-width'], -1)

            sw = Gtk.ScrolledWindow()
            sw.add(self.comment_entry)
            sw.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.NEVER)
            hbox.pack_start(self.image, False, True, 0)
            hbox.pack_start(sw, True, True, 0)
            hbox.show_all()
            return hbox
        else:
            return self.image
Ejemplo n.º 3
0
    def build_widget(self):
        vb=gtk.VBox()

        buttons = gtk.HBox()

        b=gtk.Button(stock=gtk.STOCK_REFRESH)
        b.set_tooltip_text(_("Refresh missing snapshots"))
        b.connect("clicked", lambda b: self.refresh_snapshots())
        buttons.pack_start(b, expand=True)

        vb.pack_start(buttons, expand=False)

        l = gtk.Label(_("Click on a frame to select its time."))
        vb.pack_start(l, expand=False)

        hb=gtk.HBox()

        ar = gtk.Arrow(gtk.ARROW_LEFT, gtk.SHADOW_IN)
        ar.set_tooltip_text(_("Scroll to see more frames"))
        hb.pack_start(ar, expand=False)

        r = None
        for i in xrange(self.count):

            border = GenericColorButtonWidget('border')
            border.default_size=(3, 110)
            border.local_color=self.black_color

            if r is not None:
                # Previous TimestampRepresentation -> right border
                r.right_border = border

            r = TimestampRepresentation(0, self.controller, width=100, visible_label=True, epsilon=30)
            self.frames.append(r)
            r.connect("clicked", self.select_time)
            r.left_border = border
            
            hb.pack_start(border, expand=False)
            hb.pack_start(r, expand=False)

        # Last right border
        border = GenericColorButtonWidget('border')
        border.default_size=(3, 110)
        border.local_color=self.black_color
        r.right_border = border
        hb.pack_start(border, expand=False)

        ar = gtk.Arrow(gtk.ARROW_RIGHT, gtk.SHADOW_IN)
        ar.set_tooltip_text(_("Scroll to see more frames"))
        hb.pack_start(ar, expand=False)

        hb.set_style(get_color_style(hb, 'black', 'black'))
        hb.connect('scroll-event', self.handle_scroll_event)
        hb.connect('key-press-event', self.handle_key_press)
        vb.add(hb)

        self.update_timestamp(self.timestamp)
        return vb
Ejemplo n.º 4
0
    def build_widget(self):
        vb=Gtk.VBox()

        l = Gtk.Label(label=self.label)
        vb.pack_start(l, False, True, 0)

        hb=Gtk.HBox()

        eb = Gtk.EventBox()
        ar = Gtk.Arrow(Gtk.ArrowType.LEFT, Gtk.ShadowType.IN)
        ar.set_tooltip_text(_("Click to see more frames or scroll with the mouse wheel"))
        eb.connect('button-press-event', lambda b,e: self.update_offset(-1))
        eb.add(ar)
        hb.pack_start(eb, False, True, 0)

        r = None
        for i in range(self.count):

            r = TimestampRepresentation(0, None,
                                        self.controller,
                                        width=self.frame_width,
                                        visible_label=True,
                                        precision=0)
            r.add_class("frameselector_frame")
            r.add_class("frameselector_frame_%s" % self.border_mode)
            self.frames.append(r)
            r.connect("clicked", self.select_time)

            def enter_bookmark(widget, event):
                widget.add_class('frameselector_selected')
                return False
            def leave_bookmark(widget, event):
                widget.remove_class('frameselector_selected')
                return False
            r.connect('enter-notify-event', enter_bookmark)
            r.connect('leave-notify-event', leave_bookmark)

            hb.pack_start(r, False, True, 0)

        hb.connect("draw", self.check_size)
        eb = Gtk.EventBox()
        ar = Gtk.Arrow(Gtk.ArrowType.RIGHT, Gtk.ShadowType.IN)
        ar.set_tooltip_text(_("Click to see more frames or scroll with the mouse wheel"))
        eb.connect('button-press-event', lambda b,e: self.update_offset(+1))
        eb.add(ar)
        hb.pack_start(eb, False, True, 0)

        vb.add(hb)

        vb.set_events(Gdk.EventMask.SCROLL_MASK | Gdk.EventMask.KEY_PRESS_MASK)
        vb.connect('scroll-event', self.handle_scroll_event)
        vb.connect('key-press-event', self.handle_key_press)

        self.update_timestamp(self.timestamp)
        return vb
Ejemplo n.º 5
0
 def build_event_box(self, obj_evt):
     # build the widget to present an event :
     # tooltip with event infos
     # image containing snapshot of the event
     # label with the time of the event
     corpsstr = ''
     entetestr = ''
     if obj_evt.content is not None:
         corpsstr = urllib.unquote(obj_evt.content.encode('utf-8'))
     ev_time = time.strftime("%H:%M:%S", time.localtime(obj_evt.time))
     if self.options['time'] == 'activity':
         ev_time = helper.format_time_reference(obj_evt.activity_time)
     if obj_evt.name in self.events_names or obj_evt.name in self.operations_names:
         if ECACatalog.event_names[obj_evt.name]:
             entetestr = "%s : %s" % (ev_time, ECACatalog.event_names[obj_evt.name])
         else:
             entetestr = "%s : %s" % (ev_time, "Event not described")
         if obj_evt.concerned_object['id']:
             entetestr = entetestr + ' (%s)' % obj_evt.concerned_object['id']
     elif obj_evt.name in self.incomplete_operations_names.keys():
         comp = ''
         ob = self.controller.package.get_element_by_id(obj_evt.concerned_object['id'])
         #print "%s %s %s" % (self.controller.package, obj_evt.concerned_object['id'], ob)
         if isinstance(ob, advene.model.annotation.Annotation):
             comp = _('of an annotation (%s)') % obj_evt.concerned_object['id']
         elif isinstance(ob,advene.model.annotation.Relation):
             comp = _('of a relation (%s)') % obj_evt.concerned_object['id']
         elif isinstance(ob,advene.model.schema.AnnotationType):
             comp = _('of an annotation type (%s)') % obj_evt.concerned_object['id']
         elif isinstance(ob,advene.model.schema.RelationType):
             comp = _('of a relation type (%s)') % obj_evt.concerned_object['id']
         elif isinstance(ob,advene.model.schema.Schema):
             comp = _('of a schema (%s)') % obj_evt.concerned_object['id']
         elif isinstance(ob,advene.model.view.View):
             comp = _('of a view (%s)') % obj_evt.concerned_object['id']
         elif isinstance(ob,advene.model.package.Package):
             comp = _('of a package (%s)') % obj_evt.concerned_object['id']
         else:
             comp = _('of an unknown item (%s)') % obj_evt.concerned_object['id']
             #print "%s" % ob
         entetestr = "%s : %s %s" % (ev_time, self.incomplete_operations_names[obj_evt.name], comp)
     else:
         print "unlabelled event : %s" % obj_evt.name
         entetestr = "%s : %s" % (ev_time, obj_evt.name)
     entete = gtk.Label(entetestr.encode("UTF-8"))
     hb = gtk.HBox()
     tr = TimestampRepresentation(obj_evt.movietime, self.controller, 50, 0, None , False)
     if tr is not None:
         hb.pack_start(tr, expand=False)
         hb.pack_start(gtk.VSeparator(), expand=False)
     hb.pack_start(entete, expand=False)
     if corpsstr != "":
         hb.set_tooltip_text(corpsstr)
     return hb
Ejemplo n.º 6
0
    def build_action_box(self, obj_evt):
        # build the widget to present an event :
        # tooltip with event infos
        # image containing snapshot of the event
        # label with the time of the event
        act = obj_evt.name
        act_begin = time.strftime("%H:%M:%S", time.localtime(obj_evt.time[0]))
        if self.options['time'] == 'activity':
            act_begin = helper.format_time_reference(obj_evt.activity_time[0])
        entetestr = "%s : %s" % (act_begin, act)
        corpsstr = ""
        for op in obj_evt.operations:
            op_time = time.strftime("%H:%M:%S", time.localtime(op.time))
            if self.options['time'] == 'activity':
                op_time = helper.format_time_reference(op.activity_time)
            if op.concerned_object['name'] is None:
                corpsstr += urllib.parse.unquote(op_time + " : " + op.name +
                                                 "\n")
            else:
                corpsstr += urllib.parse.unquote(op_time + " : " + op.name +
                                                 " ( " +
                                                 op.concerned_object['name'] +
                                                 " : " +
                                                 op.concerned_object['id'] +
                                                 " )\n")
        entete = Gtk.Label(label=entetestr.encode("UTF-8"))
        hb = Gtk.HBox()
        box = Gtk.EventBox()
        tr = TimestampRepresentation(obj_evt.movietime, None, self.controller,
                                     50, 0, None, False)
        if tr is not None:
            hb.pack_start(tr, False, True, 0)
            hb.pack_start(Gtk.VSeparator(), False, False, 0)
        if corpsstr != "":
            hb.set_tooltip_text(corpsstr)

        def box_pressed(w, event, ops):
            if event.button == 1 and event.type == Gdk.EventType._2BUTTON_PRESS:
                #FIXME : need to change details in another way
                self.filters['objects'] = []
                self.filters['objects'].extend(ops)
                self.options['detail'] = 'operations'
                self.DetB.set_label('operations')
                #FIXME color change of the reset button when applying a filter
                self.filter_active(True)
                self.receive(self.tracer.trace)
            return

        box.add(entete)
        box.connect('button-press-event', box_pressed, obj_evt.operations)
        hb.pack_start(box, False, True, 0)
        return hb
Ejemplo n.º 7
0
    def build_widget(self):
        self.image=TimestampRepresentation(self.value, None, self.controller, comment_getter=lambda: self.comment, width=self.width, precision=config.data.preferences['bookmark-snapshot-precision'])

        self.image.connect('clicked', self.image.goto_and_refresh)

        if self.display_comments:
            hbox=Gtk.HBox()
            self.comment_entry=Gtk.TextView()
            # Hook the completer component
            completer=Completer(textview=self.comment_entry,
                                controller=self.controller,
                                element=self.comment_entry.get_buffer(),
                                indexer=self.controller.package._indexer)
            self.comment_entry.set_wrap_mode(Gtk.WrapMode.WORD)
            fd=Pango.FontDescription('sans %d' % config.data.preferences['timeline']['font-size'])
            self.comment_entry.modify_font(fd)
            b=self.comment_entry.get_buffer()
            b.set_text(self.comment)

            def focus_in_event(wid, event):
                if b.get_text(*b.get_bounds() + (False,)) == self.default_comment:
                    b.set_text('')
                return False
            self.comment_entry.connect('focus-in-event', focus_in_event)

            def focus_out_event(wid, event):
                if b.get_text(*b.get_bounds() + (False,)) == '':
                    b.set_text(self.default_comment)
                return False
            self.comment_entry.connect('focus-out-event', focus_out_event)

            def update_comment(buf):
                self.comment=buf.get_text(*buf.get_bounds() + (False,))
                return True
            b.connect('changed', update_comment)

            #self.comment_entry.set_size_request(config.data.preferences['bookmark-snapshot-width'], -1)

            sw=Gtk.ScrolledWindow()
            sw.add(self.comment_entry)
            sw.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.NEVER)
            hbox.pack_start(self.image, False, True, 0)
            hbox.pack_start(sw, True, True, 0)
            hbox.show_all()
            return hbox
        else:
            return self.image
Ejemplo n.º 8
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
Ejemplo n.º 9
0
class TimeAdjustment:
    """TimeAdjustment widget.

    Note: time values are integers in milliseconds.
    """
    def __init__(self,
                 value=0,
                 controller=None,
                 videosync=False,
                 editable=True,
                 compact=False,
                 callback=None):
        self.value = value
        self.controller = controller
        self.sync_video = videosync
        # Small increment
        self.small_increment = config.data.preferences['scroll-increment']
        # Large increment
        self.large_increment = config.data.preferences[
            'second-scroll-increment']
        self.image = None
        self.editable = editable
        self.compact = compact
        # Callback is a method which will be called *before* setting
        # the new value. If it returns False, then the new value will
        # not be used.
        self.callback = callback
        self.widget = self.make_widget()
        self.update_display()

    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

    def drag_received(self, widget, context, x, y, selection, targetType,
                      time):
        if targetType == config.data.target_type['annotation']:
            source_uri = str(selection.get_data(), 'utf8').split('\n')[0]
            source = self.controller.package.annotations.get(source_uri)
            self.set_value(source.fragment.begin)
        elif targetType == config.data.target_type['timestamp']:
            data = decode_drop_parameters(selection.get_data().decode('utf-8'))
            v = int(float(data['timestamp']))
            self.set_value(v)
        else:
            logger.warning("Unknown target type for drop: %d", targetType)
        return True

    def drag_sent(self, widget, context, selection, targetType, eventTime):
        """Handle the drag-sent event.
        """
        if targetType == config.data.target_type['timestamp']:
            selection.set(selection.get_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.get_target(), 8,
                          helper.format_time(self.value))
            return True
        return False

    def play_from_here(self, button):
        self.controller.update_status("seek", self.value)
        return True

    def use_current_position(self, button):
        self.set_value(self.controller.player.current_position_value)
        return True

    def update_snapshot(self, button):
        # FIXME: to implement
        logger.warning("Not implemented yet.")
        pass

    def convert_entered_value(self, *p):
        t = self.entry.get_text()
        v = helper.parse_time(t)
        if v is not None and v != self.value:
            if not self.set_value(v):
                return False
        return False

    def check_bound_value(self, value):
        if value < 0 or value is None:
            value = 0
        elif (self.controller.cached_duration > 0
              and value > self.controller.cached_duration):
            value = self.controller.cached_duration
        return value

    def update(self):
        self.update_display()

    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

    def get_widget(self):
        return self.widget

    def get_value(self):
        return self.value

    def set_value(self, v):
        """Set the new value.

        The method does various consistency checks, and can leave the
        value unset if a callback is defined and returns False.
        """
        if self.value == v:
            return True
        v = self.check_bound_value(v)
        if self.callback and not self.callback(v):
            return False
        self.value = v
        self.update_display()
        if self.sync_video:
            self.controller.update_status("seek", self.value)
        return True
Ejemplo n.º 10
0
 def build_operation_box(self, obj_evt):
     # build the widget to present an event :
     # tooltip with event infos
     # image containing snapshot of the event
     # label with the time of the event
     corpsstr = ''
     if obj_evt.content is not None:
         corpsstr = urllib.unquote(obj_evt.content.encode('utf-8'))
     ev_time = time.strftime("%H:%M:%S", time.localtime(obj_evt.time))
     if self.options['time'] == 'activity':
         ev_time = helper.format_time_reference(obj_evt.activity_time)
     if obj_evt.name in self.operations_names:
         if ECACatalog.event_names[obj_evt.name]:
             entetestr = "%s : %s" % (ev_time, ECACatalog.event_names[obj_evt.name])
         else:
             entetestr = "%s : %s" % (ev_time, "Operation not described")
         if obj_evt.concerned_object['id']:
             entetestr = entetestr + ' (%s)' % obj_evt.concerned_object['id']
     elif obj_evt.name in self.incomplete_operations_names.keys():
         comp = ''
         # store type of item in the trace
         ob = self.controller.package.get_element_by_id(obj_evt.concerned_object['id'])
         #print "%s %s %s" % (self.controller.package, obj_evt.concerned_object['id'], ob)
         if isinstance(ob, advene.model.annotation.Annotation):
             comp = _('of an annotation (%s)') % obj_evt.concerned_object['id']
         elif isinstance(ob,advene.model.annotation.Relation):
             comp = _('of a relation (%s)') % obj_evt.concerned_object['id']
         elif isinstance(ob,advene.model.schema.AnnotationType):
             comp = _('of an annotation type (%s)') % obj_evt.concerned_object['id']
         elif isinstance(ob,advene.model.schema.RelationType):
             comp = _('of a relation type (%s)') % obj_evt.concerned_object['id']
         elif isinstance(ob,advene.model.schema.Schema):
             comp = _('of a schema (%s)') % obj_evt.concerned_object['id']
         elif isinstance(ob,advene.model.view.View):
             comp = _('of a view (%s)') % obj_evt.concerned_object['id']
         elif isinstance(ob,advene.model.package.Package):
             comp = _('of a package (%s)') % obj_evt.concerned_object['id']
         else:
             comp = _('of an unknown item (%s)') % obj_evt.concerned_object['id']
         entetestr = "%s : %s %s" % (ev_time, self.incomplete_operations_names[obj_evt.name], comp)
     else:
         print "unlabelled event : %s" % obj_evt.name
         entetestr = "%s : %s" % (ev_time, obj_evt.name)
     entete = gtk.Label(entetestr.encode("UTF-8"))
     hb = gtk.HBox()
     box = gtk.EventBox()
     tr = TimestampRepresentation(obj_evt.movietime, self.controller, 50, 0, None , False)
     if tr is not None:
         hb.pack_start(tr, expand=False)
         hb.pack_start(gtk.VSeparator(), expand=False)
     if corpsstr != "":
         box.set_tooltip_text(corpsstr)
     def box_pressed(w, event, id):
         #print "%s %s" % (id, mtime)
         if event.button == 1 and event.type == gtk.gdk._2BUTTON_PRESS:
             if id is not None:
                 obj = self.controller.package.get_element_by_id(id)
                 if obj is not None:
                     #Need to edit the item
                     #print obj
                     self.controller.gui.edit_element(obj)
                 else:
                     print "item %s no longuer exists" % id
         return
     box.add(entete)
     box.connect('button-press-event', box_pressed, obj_evt.concerned_object['id'])
     hb.pack_start(box, expand=False)
     return hb
Ejemplo n.º 11
0
class TimeAdjustment:
    """TimeAdjustment widget.

    Note: time values are integers in milliseconds.
    """
    def __init__(self, value=0, controller=None, videosync=False, editable=True, compact=False, callback=None):
        self.value=value
        self.controller=controller
        self.sync_video=videosync
        # Small increment
        self.small_increment=config.data.preferences['scroll-increment']
        # Large increment
        self.large_increment=config.data.preferences['second-scroll-increment']
        self.image=None
        self.editable=editable
        self.compact=compact
        # Callback is a method which will be called *before* setting
        # the new value. If it returns False, then the new value will
        # not be used.
        self.callback=callback
        self.widget=self.make_widget()
        self.update_display()

    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.state & gtk.gdk.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 == gtk.gdk.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(None, None, None, 0, gtk.get_current_event_time())
                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) ))
            # FIXME: to re-enable
            # The proper way is to do
            #b.set_image(i)
            # but it works only on linux, gtk 2.10
            # and is broken on windows and mac
            al=gtk.Alignment()
            al.set_padding(0, 0, 0, 0)
            al.add(i)
            b.add(al)

            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, expand=False)
            b=make_button(-self.small_increment, "1leftarrow.png")
            vb.pack_start(b, expand=False)
            hbox.pack_start(vb, expand=False)

        if self.compact:
            width=50
        else:
            width=100
        self.image=TimestampRepresentation(self.value, self.controller, width,
                                           epsilon=1000/config.data.preferences['default-fps'],
                                           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, expand=False)

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

        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, expand=False)
        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, expand=False)

        vbox.pack_start(hbox, expand=False)
        vbox.pack_start(hb, expand=False)
        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.state & gtk.gdk.CONTROL_MASK:
                i=config.data.preferences['scroll-increment']
            elif event.state & gtk.gdk.SHIFT_MASK:
                i=config.data.preferences['second-scroll-increment']
            else:
                # 1 frame
                i=1000 / config.data.preferences['default-fps']

            if event.direction == gtk.gdk.SCROLL_DOWN or event.direction == gtk.gdk.SCROLL_LEFT:
                incr=-i
            elif event.direction == gtk.gdk.SCROLL_UP or event.direction == gtk.gdk.SCROLL_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.DEST_DEFAULT_MOTION |
                               gtk.DEST_DEFAULT_HIGHLIGHT |
                               gtk.DEST_DEFAULT_ALL,
                               config.data.drag_type['annotation']
                               + config.data.drag_type['timestamp'],
                               gtk.gdk.ACTION_LINK)

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

        vbox.show_all()
        return vbox

    def drag_received(self, widget, context, x, y, selection, targetType, time):
        if targetType == config.data.target_type['annotation']:
            source_uri=unicode(selection.data, 'utf8').split('\n')[0]
            source=self.controller.package.annotations.get(source_uri)
            self.set_value(source.fragment.begin)
        elif targetType == config.data.target_type['timestamp']:
            data=decode_drop_parameters(selection.data)
            v=long(float(data['timestamp']))
            self.set_value(v)
        else:
            print "Unknown target type for drop: %d" % targetType
        return True

    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

    def play_from_here(self, button):
        self.controller.update_status("set", self.value)
        return True

    def use_current_position(self, button):
        self.set_value(self.controller.player.current_position_value)
        return True

    def update_snapshot(self, button):
        # FIXME: to implement
        print "Not implemented yet."
        pass

    def convert_entered_value(self, *p):
        t=unicode(self.entry.get_text())
        v=helper.parse_time(t)
        if v is not None and v != self.value:
            if not self.set_value(v):
                return False
        return False

    def check_bound_value(self, value):
        if value < 0 or value is None:
            value = 0
        elif (self.controller.cached_duration > 0
              and value > self.controller.cached_duration):
            value = self.controller.cached_duration
        return value

    def update(self):
        self.update_display()

    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

    def get_widget(self):
        return self.widget

    def get_value(self):
        return self.value

    def set_value(self, v):
        """Set the new value.

        The method does various consistency checks, and can leave the
        value unset if a callback is defined and returns False.
        """
        if self.value == v:
            return True
        v = self.check_bound_value(v)
        if self.callback and not self.callback(v):
            return False
        self.value=v
        self.update_display()
        if self.sync_video:
            self.controller.move_position(self.value, relative=False)
        return True
Ejemplo n.º 12
0
    def build_widget(self):
        v = gtk.VBox()

        self.label = {}
        self.sw = {}

        h = gtk.HBox()
        self.label['title'] = gtk.Label()
        h.pack_start(self.label['title'], expand=False)
        v.pack_start(h, expand=False)

        h = gtk.HBox()
        self.label['begin'] = gtk.Label()
        h.pack_start(self.label['begin'], expand=False)
        l = gtk.Label(' - ')
        h.pack_start(l, expand=False)
        self.label['end'] = gtk.Label()
        h.pack_start(self.label['end'], expand=False)
        v.pack_start(h, expand=False)

        def handle_motion(widget, event):
            if isinstance(self.annotation, Annotation):
                i = self.label['image']
                i.epsilon = self.annotation.fragment.duration / widget.allocation.width
                v = self.annotation.fragment.begin + i.epsilon * 20 * int(
                    event.x / 20)
                i.set_value(v)
            return True

        def handle_leave(widget, event):
            if isinstance(self.annotation, Annotation):
                i = self.label['image']
                i.epsilon = config.data.preferences[
                    'bookmark-snapshot-precision']
                i.set_value(self.annotation.fragment.begin)
            return True

        fr = gtk.Expander()
        fr.set_label(_("Screenshot"))
        self.label['image'] = TimestampRepresentation(
            -1,
            self.controller,
            width=config.data.preferences['drag-snapshot-width'],
            epsilon=config.data.preferences['bookmark-snapshot-precision'],
            visible_label=False)
        self.label['image'].add_events(gtk.gdk.POINTER_MOTION_MASK
                                       | gtk.gdk.LEAVE_NOTIFY_MASK)
        self.label['image'].connect('motion-notify-event', handle_motion)
        self.label['image'].connect('leave-notify-event', handle_leave)

        fr.add(self.label['image'])
        fr.set_expanded(True)
        v.pack_start(fr, expand=False)

        # Contents frame
        def handle_ok(b):
            b.hide()
            if isinstance(self.annotation, Annotation):
                self.controller.notify('EditSessionStart',
                                       element=self.annotation,
                                       immediate=True)
                self.annotation.content.data = self.label['contents'].get_text(
                )
                self.controller.notify("AnnotationEditEnd",
                                       annotation=self.annotation)
                self.controller.notify('EditSessionEnd',
                                       element=self.annotation)
            return True

        hbox = gtk.HBox()
        hbox.pack_start(gtk.Label(_("Contents")), expand=False)
        ok_button = get_pixmap_button('small_ok.png', handle_ok)
        ok_button.set_relief(gtk.RELIEF_NONE)
        ok_button.set_tooltip_text(_("Validate"))
        ok_button.set_no_show_all(True)
        hbox.pack_start(ok_button, expand=False)

        f = gtk.Frame()
        f.set_label_widget(hbox)

        def contents_modified(buf):
            if buf.get_modified():
                if not buf.ignore_modified:
                    ok_button.show()
            else:
                ok_button.hide()
            return True

        c = self.label['contents'] = gtk.TextView()
        c.set_wrap_mode(gtk.WRAP_WORD_CHAR)
        c.get_buffer().ignore_modified = False
        c.get_buffer().connect('modified-changed', contents_modified)
        sw = gtk.ScrolledWindow()
        sw.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
        sw.add(c)

        def set_text(widget, t):
            b = widget.get_buffer()
            b.ignore_modified = True
            b.delete(*b.get_bounds())
            b.set_text(t)
            b.set_modified(False)
            b.ignore_modified = False
            return True

        c.set_text = set_text.__get__(c)

        def get_text(widget):
            b = widget.get_buffer()
            return b.get_text(*b.get_bounds())

        c.get_text = get_text.__get__(c)
        self.sw['contents'] = sw

        def handle_keypress(widget, event):
            if (event.keyval == gtk.keysyms.Return
                    and event.state & gtk.gdk.CONTROL_MASK
                    and widget.get_buffer().get_modified()):
                handle_ok(ok_button)
                return True
            return False

        c.connect('key-press-event', handle_keypress)

        # Hook the completer component
        if hasattr(self.controller.package, '_indexer'):
            self.completer = Completer(
                textview=c,
                controller=self.controller,
                element=self.annotation,
                indexer=self.controller.package._indexer)

        image = self.label['imagecontents'] = gtk.Image()

        swi = gtk.ScrolledWindow()
        swi.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
        swi.add_with_viewport(image)
        self.sw['imagecontents'] = swi

        vb = gtk.VBox()
        vb.add(sw)
        vb.add(swi)

        f.add(vb)
        v.add(f)

        v.show_all()
        image.hide()
        v.set_no_show_all(True)

        def annotation_drag_received_cb(widget, context, x, y, selection,
                                        targetType, time):
            """Handle the drop of an annotation.
            """
            if targetType == config.data.target_type['annotation']:
                sources = [
                    self.controller.package.annotations.get(uri)
                    for uri in unicode(selection.data, 'utf8').split('\n')
                ]
                if sources:
                    self.set_annotation(sources[0])
                return True
            return False

        # The button can receive drops (to display annotations)
        v.connect('drag-data-received', annotation_drag_received_cb)
        v.drag_dest_set(
            gtk.DEST_DEFAULT_MOTION | gtk.DEST_DEFAULT_HIGHLIGHT
            | gtk.DEST_DEFAULT_ALL, config.data.drag_type['annotation'],
            gtk.gdk.ACTION_COPY | gtk.gdk.ACTION_LINK | gtk.gdk.ACTION_MOVE)

        return v
Ejemplo n.º 13
0
    def create_timestamp_mark(self, timestamp, it):
        def popup_goto (b):
            self.controller.update_status(status="seek", position=b.value)
            return True

        b=self.textview.get_buffer()
        b.begin_user_action()
        anchor=b.create_child_anchor(it)
        # Create the mark representation
        child=TimestampRepresentation(timestamp, None, self.controller, width=self.options['snapshot-size'], visible_label=False)
        child.anchor=anchor
        child.connect('clicked', popup_goto)
        child.popup_menu=None
        child.connect('button-press-event', self.mark_button_press_cb, anchor, child)
        b.end_user_action()

        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

        def mark_key_release_cb(button, event, anchor=None, child=None):
            """Handler for key release on timestamp mark.
            """
            # Control key released. Goto the position if we were scrolling a mark
            if self.timestamp_play is not None and (event.get_state() & Gdk.ModifierType.CONTROL_MASK):
                # self.timestamp_play contains the new value, but child.timestamp
                # as well. So we can use popup_goto
                self.timestamp_play = None
                popup_goto(child)
                return True
            return False

        child.connect('scroll-event', handle_scroll_event)
        child.connect('key-release-event', mark_key_release_cb, anchor, child)
        child.set_tooltip_text("%s" % helper.format_time(timestamp))
        child.value=timestamp
        child.ignore=False
        self.update_mark(child)
        child.show_all()
        child.label.set_no_show_all(True)
        child.label.hide()
        self.textview.add_child_at_anchor(child, anchor)

        self.marks.append(child)
        self.marks.sort(key=lambda a: a.value)
        return child
Ejemplo n.º 14
0
    def build_widget(self):
        vb=gtk.VBox()

        l = gtk.Label(self.label)
        vb.pack_start(l, expand=False)

        hb=gtk.HBox()

        eb = gtk.EventBox()
        ar = gtk.Arrow(gtk.ARROW_LEFT, gtk.SHADOW_IN)
        ar.set_tooltip_text(_("Click to see more frames or scroll with the mouse wheel"))
        eb.connect('button-press-event', lambda b,e: self.update_offset(-1))
        eb.add(ar)
        hb.pack_start(eb, expand=False)

        r = None
        for i in xrange(self.count):

            border = GenericColorButtonWidget('border')
            border.default_size=(3, 110)
            border.local_color=self.black_color

            if r is not None:
                # Previous TimestampRepresentation -> right border
                r.right_border = border

            r = TimestampRepresentation(0, self.controller, width=100, visible_label=True,
                                        epsilon=(1000 / config.data.preferences['default-fps'] - 10))
            self.frames.append(r)
            r.connect("clicked", self.select_time)
            r.left_border = border

            def enter_bookmark(widget, event):
                if self.border_mode == 'left':
                    b=widget.left_border
                elif self.border_mode == 'right':
                    b=widget.right_border
                b.old_color = b.local_color
                b.set_color(self.mouseover_color)
                return False
            def leave_bookmark(widget, event):
                if self.border_mode == 'left':
                    b=widget.left_border
                elif self.border_mode == 'right':
                    b=widget.right_border
                b.set_color(b.old_color)
                return False
            if self.border_mode in ('left', 'right'):
                r.connect('enter-notify-event', enter_bookmark)
                r.connect('leave-notify-event', leave_bookmark)

            hb.pack_start(border, expand=False)
            hb.pack_start(r, expand=False)

        # Last right border
        border = GenericColorButtonWidget('border')
        border.default_size=(3, 110)
        border.local_color=self.black_color
        r.right_border = border
        hb.pack_start(border, expand=False)

        eb = gtk.EventBox()
        ar = gtk.Arrow(gtk.ARROW_RIGHT, gtk.SHADOW_IN)
        ar.set_tooltip_text(_("Click to see more frames or scroll with the mouse wheel"))
        eb.connect('button-press-event', lambda b,e: self.update_offset(+1))
        eb.add(ar)
        hb.pack_start(eb, expand=False)

        hb.set_style(get_color_style(hb, 'black', 'black'))
        hb.connect('scroll-event', self.handle_scroll_event)
        hb.connect('key-press-event', self.handle_key_press)
        vb.add(hb)

        self.update_timestamp(self.timestamp)
        return vb
Ejemplo n.º 15
0
class TimeAdjustment:
    """TimeAdjustment widget.

    Note: time values are integers in milliseconds.
    """
    def __init__(self, value=0, controller=None, videosync=False, editable=True, compact=False, callback=None):
        self.value=value
        self.controller=controller
        self.sync_video=videosync
        # Small increment
        self.small_increment=config.data.preferences['scroll-increment']
        # Large increment
        self.large_increment=config.data.preferences['second-scroll-increment']
        self.image=None
        self.editable=editable
        self.compact=compact
        # Callback is a method which will be called *before* setting
        # the new value. If it returns False, then the new value will
        # not be used.
        self.callback=callback
        self.widget=self.make_widget()
        self.update_display()

    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.state & gtk.gdk.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 == gtk.gdk.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(None, None, None, 0, gtk.get_current_event_time())
                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) ))
            # FIXME: to re-enable
            # The proper way is to do
            #b.set_image(i)
            # but it works only on linux, gtk 2.10
            # and is broken on windows and mac
            al=gtk.Alignment()
            al.set_padding(0, 0, 0, 0)
            al.add(i)
            b.add(al)

            b.connect('clicked', self.update_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, expand=False)
            b=make_button(-self.small_increment, "1leftarrow.png")
            vb.pack_start(b, expand=False)
            hbox.pack_start(vb, expand=False)

        if self.compact:
            width=50
        else:
            width=100
        self.image=TimestampRepresentation(self.value, self.controller, width, epsilon=1000/25, visible_label=False)
        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\Scroll to modify value (with control/shift)\nRight-click to invalidate screenshot"))
        hbox.pack_start(self.image, expand=False)

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

        hb = gtk.HBox()

        if self.editable:
            self.entry=gtk.Entry()
            # 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, expand=False)
        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, expand=False)

        vbox.pack_start(hbox, expand=False)
        vbox.pack_start(hb, expand=False)
        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.state & gtk.gdk.CONTROL_MASK:
                i=config.data.preferences['scroll-increment']
            elif event.state & gtk.gdk.SHIFT_MASK:
                i=config.data.preferences['second-scroll-increment']
            else:
                # 1 frame
                i=1000/25

            if event.direction == gtk.gdk.SCROLL_DOWN or event.direction == gtk.gdk.SCROLL_LEFT:
                incr=-i
            elif event.direction == gtk.gdk.SCROLL_UP or event.direction == gtk.gdk.SCROLL_RIGHT:
                incr=i

            v=self.value
            v += incr
            if self.callback and not self.callback(v):
                return True
            self.value=v
            self.update_display()
            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.DEST_DEFAULT_MOTION |
                               gtk.DEST_DEFAULT_HIGHLIGHT |
                               gtk.DEST_DEFAULT_ALL,
                               config.data.drag_type['annotation']
                               + config.data.drag_type['timestamp'],
                               gtk.gdk.ACTION_LINK)

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

        vbox.show_all()
        return vbox

    def drag_received(self, widget, context, x, y, selection, targetType, time):
        if targetType == config.data.target_type['annotation']:
            source_uri=unicode(selection.data, 'utf8').split('\n')[0]
            source=self.controller.package.get(source_uri)
            if self.callback and not self.callback(source.begin):
                return True
            self.value = source.begin
            self.update_display()
        elif targetType == config.data.target_type['timestamp']:
            data=decode_drop_parameters(selection.data)
            v=long(float(data['timestamp']))
            if self.callback and not self.callback(v):
                return True
            self.value=v
            self.update_display()
        else:
            print "Unknown target type for drop: %d" % targetType
        return True

    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

    def play_from_here(self, button):
        if self.controller.player.status == self.controller.player.PauseStatus:
            self.controller.update_status("set", self.value)
        elif self.controller.player.status != self.controller.player.PlayingStatus:
            self.controller.update_status("start", self.value)
        self.controller.update_status("set", self.value)
        return True

    def use_current_position(self, button):
        v=self.controller.player.current_position_value
        if self.callback and not self.callback(v):
            return True
        self.value=v
        self.update_display()
        return True

    def update_snapshot(self, button):
        # FIXME: to implement
        print "Not implemented yet."
        pass

    # Static values used in numericTime
    _hour = r'(?P<hour>\d+)'
    _minute = r'(?P<minute>\d+)'
    _second = r'(?P<second>\d+(\.\d+))'
    _time = _hour + r':' + _minute + r'(:' + _second + r')?'
    _timeRE = re.compile(_time, re.I)

    def numericTime(self, s):
        """Converts a time string into a long value.

        This function is inspired from the numdate.py example script from the
        egenix mxDateTime package.

        If the input string s is a valid time expression of the
        form hh:mm:ss.sss or hh:mm:ss or hh:mm, return
        the corresponding value in milliseconds (float), else None
        """

        if s is None:
            return None
        dt = None
        match = TimeAdjustment._timeRE.search(s)
        if match is not None:
            hh = int(match.group('hour'))
            mm = int(match.group('minute'))
            second = match.group('second')
            if second:
                ss = float(second)
            else:
                ss = 0.0
            dt=int(1000 * (ss + (60 * mm) + (3600 * hh)))
        return dt

    def convert_entered_value(self, *p):
        t=self.entry.get_text()
        v=self.numericTime(t)
        if v is not None and v != self.value:
            v=self.check_bound_value(v)
            if self.callback and not self.callback(v):
                return False
            self.value = v
            if self.sync_video:
                self.controller.move_position(self.value, relative=False)
            self.update_display()
        return False

    def check_bound_value(self, value):
        if value < 0:
            value = 0
        elif (self.controller.cached_duration > 0
              and value > self.controller.cached_duration):
            value = self.controller.cached_duration
        return value

    def update(self):
        self.update_display()

    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

    def update_value_cb(self, widget, increment):
        if not self.editable:
            return True
        v=self.check_bound_value(self.value + increment)
        if self.callback and not self.callback(v):
            return True
        self.value=v
        if self.sync_video:
            self.controller.move_position(self.value, relative=False)
        self.update_display()
        return True

    def get_widget(self):
        return self.widget

    def get_value(self):
        return self.value
Ejemplo n.º 16
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
Ejemplo n.º 17
0
    def create_timestamp_mark(self, timestamp, it):
        def popup_goto (b):
            self.controller.update_status(status="seek", position=b.value)
            return True

        b=self.textview.get_buffer()
        b.begin_user_action()
        if self.options['mark-prefix']:
            b.insert(it, unescape_string(self.options['mark-prefix']))
        anchor=b.create_child_anchor(it)
        if self.options['mark-suffix']:
            b.insert(it, unescape_string(self.options['mark-suffix']))
        # Create the mark representation
        child=TimestampRepresentation(timestamp, None, self.controller, width=self.options['snapshot-size'], visible_label=False)
        child.anchor=anchor
        child.connect('clicked', popup_goto)
        child.popup_menu=None
        child.connect('button-press-event', self.mark_button_press_cb, anchor, child)
        b.end_user_action()

        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

        def mark_key_release_cb(button, event, anchor=None, child=None):
            """Handler for key release on timestamp mark.
            """
            # Control key released. Goto the position if we were scrolling a mark
            if self.timestamp_play is not None and (event.get_state() & Gdk.ModifierType.CONTROL_MASK):
                # self.timestamp_play contains the new value, but child.timestamp
                # as well. So we can use popup_goto
                self.timestamp_play = None
                popup_goto(child)
                return True
            return False

        child.connect('scroll-event', handle_scroll_event)
        child.connect('key-release-event', mark_key_release_cb, anchor, child)
        child.set_tooltip_text("%s" % helper.format_time(timestamp))
        child.value=timestamp
        child.ignore=False
        self.update_mark(child)
        child.show_all()
        child.label.set_no_show_all(True)
        child.label.hide()
        self.textview.add_child_at_anchor(child, anchor)

        self.marks.append(child)
        self.marks.sort(key=lambda a: a.value)
        return child
Ejemplo n.º 18
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.state & gtk.gdk.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 == gtk.gdk.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(None, None, None, 0, gtk.get_current_event_time())
                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)))
            # FIXME: to re-enable
            # The proper way is to do
            #b.set_image(i)
            # but it works only on linux, gtk 2.10
            # and is broken on windows and mac
            al = gtk.Alignment()
            al.set_padding(0, 0, 0, 0)
            al.add(i)
            b.add(al)

            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, expand=False)
            b = make_button(-self.small_increment, "1leftarrow.png")
            vb.pack_start(b, expand=False)
            hbox.pack_start(vb, expand=False)

        if self.compact:
            width = 50
        else:
            width = 100
        self.image = TimestampRepresentation(
            self.value,
            self.controller,
            width,
            epsilon=1000 / config.data.preferences['default-fps'],
            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, expand=False)

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

        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, expand=False)
        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, expand=False)

        vbox.pack_start(hbox, expand=False)
        vbox.pack_start(hb, expand=False)
        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.state & gtk.gdk.CONTROL_MASK:
                i = config.data.preferences['scroll-increment']
            elif event.state & gtk.gdk.SHIFT_MASK:
                i = config.data.preferences['second-scroll-increment']
            else:
                # 1 frame
                i = 1000 / config.data.preferences['default-fps']

            if event.direction == gtk.gdk.SCROLL_DOWN or event.direction == gtk.gdk.SCROLL_LEFT:
                incr = -i
            elif event.direction == gtk.gdk.SCROLL_UP or event.direction == gtk.gdk.SCROLL_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.DEST_DEFAULT_MOTION | gtk.DEST_DEFAULT_HIGHLIGHT
                | gtk.DEST_DEFAULT_ALL, config.data.drag_type['annotation'] +
                config.data.drag_type['timestamp'], gtk.gdk.ACTION_LINK)

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

        vbox.show_all()
        return vbox
Ejemplo n.º 19
0
class BookmarkWidget(object):

    default_comment=_("Comment here")

    def __init__(self, controller=None, timestamp=0, comment=None, display_comments=False, width=None):
        self.controller=controller
        self.value=timestamp
        if comment is None:
            comment=self.default_comment
        self.comment=comment
        self.comment_entry=None
        self.display_comments=display_comments
        self.width=width
        self.widget=self.build_widget()

    def update(self):
        self.image.value=self.value
        if self.comment_entry is not None:
            self.comment_entry.get_buffer().set_text(self.comment)
        return True

    def build_widget(self):
        self.image=TimestampRepresentation(self.value, self.controller, comment_getter=lambda: self.comment, width=self.width, epsilon=config.data.preferences['bookmark-snapshot-precision'])

        self.image.connect('clicked', self.image.goto_and_refresh)

        if self.display_comments:
            hbox=gtk.HBox()
            self.comment_entry=gtk.TextView()
            # Hook the completer component
            completer=Completer(textview=self.comment_entry,
                                controller=self.controller,
                                element=self.comment_entry.get_buffer(),
                                indexer=self.controller.package._indexer)
            self.comment_entry.set_wrap_mode(gtk.WRAP_WORD)
            fd=pango.FontDescription('sans %d' % config.data.preferences['timeline']['font-size'])
            self.comment_entry.modify_font(fd)
            b=self.comment_entry.get_buffer()
            b.set_text(self.comment)

            def focus_in_event(wid, event):
                if unicode(b.get_text(*b.get_bounds())) == self.default_comment:
                    b.set_text('')
                return False
            self.comment_entry.connect('focus-in-event', focus_in_event)

            def focus_out_event(wid, event):
                if b.get_text(*b.get_bounds()) == '':
                    b.set_text(self.default_comment)
                return False
            self.comment_entry.connect('focus-out-event', focus_out_event)

            def update_comment(buf):
                self.comment=unicode(buf.get_text(*buf.get_bounds()))
                return True
            b.connect('changed', update_comment)

            #self.comment_entry.set_size_request(config.data.preferences['bookmark-snapshot-width'], -1)

            sw=gtk.ScrolledWindow()
            sw.add(self.comment_entry)
            sw.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_NEVER)
            hbox.pack_start(self.image, expand=False)
            hbox.pack_start(sw, expand=True)
            hbox.show_all()
            return hbox
        else:
            return self.image
Ejemplo n.º 20
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.state & gtk.gdk.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 == gtk.gdk.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(None, None, None, 0, gtk.get_current_event_time())
                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) ))
            # FIXME: to re-enable
            # The proper way is to do
            #b.set_image(i)
            # but it works only on linux, gtk 2.10
            # and is broken on windows and mac
            al=gtk.Alignment()
            al.set_padding(0, 0, 0, 0)
            al.add(i)
            b.add(al)

            b.connect('clicked', self.update_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, expand=False)
            b=make_button(-self.small_increment, "1leftarrow.png")
            vb.pack_start(b, expand=False)
            hbox.pack_start(vb, expand=False)

        if self.compact:
            width=50
        else:
            width=100
        self.image=TimestampRepresentation(self.value, self.controller, width, epsilon=1000/25, visible_label=False)
        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\Scroll to modify value (with control/shift)\nRight-click to invalidate screenshot"))
        hbox.pack_start(self.image, expand=False)

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

        hb = gtk.HBox()

        if self.editable:
            self.entry=gtk.Entry()
            # 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, expand=False)
        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, expand=False)

        vbox.pack_start(hbox, expand=False)
        vbox.pack_start(hb, expand=False)
        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.state & gtk.gdk.CONTROL_MASK:
                i=config.data.preferences['scroll-increment']
            elif event.state & gtk.gdk.SHIFT_MASK:
                i=config.data.preferences['second-scroll-increment']
            else:
                # 1 frame
                i=1000/25

            if event.direction == gtk.gdk.SCROLL_DOWN or event.direction == gtk.gdk.SCROLL_LEFT:
                incr=-i
            elif event.direction == gtk.gdk.SCROLL_UP or event.direction == gtk.gdk.SCROLL_RIGHT:
                incr=i

            v=self.value
            v += incr
            if self.callback and not self.callback(v):
                return True
            self.value=v
            self.update_display()
            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.DEST_DEFAULT_MOTION |
                               gtk.DEST_DEFAULT_HIGHLIGHT |
                               gtk.DEST_DEFAULT_ALL,
                               config.data.drag_type['annotation']
                               + config.data.drag_type['timestamp'],
                               gtk.gdk.ACTION_LINK)

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

        vbox.show_all()
        return vbox
Ejemplo n.º 21
0
class BookmarkWidget(object):

    default_comment = _("Comment here")

    def __init__(self,
                 controller=None,
                 timestamp=0,
                 comment=None,
                 display_comments=False,
                 width=None):
        self.controller = controller
        self.value = timestamp
        if comment is None:
            comment = self.default_comment
        self.comment = comment
        self.comment_entry = None
        self.display_comments = display_comments
        self.width = width
        self.widget = self.build_widget()

    def update(self):
        self.image.value = self.value
        if self.comment_entry is not None:
            self.comment_entry.get_buffer().set_text(self.comment)
        return True

    def build_widget(self):
        self.image = TimestampRepresentation(
            self.value,
            self.controller,
            comment_getter=lambda: self.comment,
            width=self.width,
            epsilon=config.data.preferences['bookmark-snapshot-precision'])

        self.image.connect('clicked', self.image.goto_and_refresh)

        if self.display_comments:
            hbox = gtk.HBox()
            self.comment_entry = gtk.TextView()
            # Hook the completer component
            completer = Completer(textview=self.comment_entry,
                                  controller=self.controller,
                                  element=self.comment_entry.get_buffer(),
                                  indexer=self.controller.package._indexer)
            self.comment_entry.set_wrap_mode(gtk.WRAP_WORD)
            fd = pango.FontDescription(
                'sans %d' % config.data.preferences['timeline']['font-size'])
            self.comment_entry.modify_font(fd)
            b = self.comment_entry.get_buffer()
            b.set_text(self.comment)

            def focus_in_event(wid, event):
                if unicode(
                        b.get_text(*b.get_bounds())) == self.default_comment:
                    b.set_text('')
                return False

            self.comment_entry.connect('focus-in-event', focus_in_event)

            def focus_out_event(wid, event):
                if b.get_text(*b.get_bounds()) == '':
                    b.set_text(self.default_comment)
                return False

            self.comment_entry.connect('focus-out-event', focus_out_event)

            def update_comment(buf):
                self.comment = unicode(buf.get_text(*buf.get_bounds()))
                return True

            b.connect('changed', update_comment)

            #self.comment_entry.set_size_request(config.data.preferences['bookmark-snapshot-width'], -1)

            sw = gtk.ScrolledWindow()
            sw.add(self.comment_entry)
            sw.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_NEVER)
            hbox.pack_start(self.image, expand=False)
            hbox.pack_start(sw, expand=True)
            hbox.show_all()
            return hbox
        else:
            return self.image