Example #1
0
    def edit(self, element):
        e = get_edit_popup(element, self.controller)
        if e._widget:
            # The edit popup is already open
            return True
        w = e.compact()

        # Buttons hbox
        hbox = Gtk.HBox()

        def handle_ok(b, w):
            e.apply_cb()
            #self.undisplay_cb(b, w)
            return True

        # OK button
        b = get_pixmap_button('small_ok.png', handle_ok, w)
        b.set_relief(Gtk.ReliefStyle.NONE)
        b.set_tooltip_text(_("Validate"))
        hbox.pack_start(b, False, True, 0)

        # Close button
        b = get_pixmap_button('small_close.png', self.undisplay_cb, w)
        b.set_relief(Gtk.ReliefStyle.NONE)
        b.set_tooltip_text(_("Close"))
        hbox.pack_start(b, False, True, 0)

        t = self.get_short_title(element)
        l = Gtk.Label()
        l.set_markup('<b>%s</b>' % t.replace('<', '&lt;'))
        hbox.pack_start(l, True, True, 0)

        self.edited_elements[element] = w
        w._title_label = l
        self.display(w, title=hbox)

        def handle_destroy(*p):
            if self.controller and self.controller.gui:
                self.controller.gui.unregister_edit_popup(e)
            self.undisplay_cb(None, w)
            return True

        w.connect('destroy', handle_destroy)

        self.controller.gui.make_pane_visible(
            getattr(self, '_destination', None))

        if self.controller and self.controller.gui:
            self.controller.gui.register_edit_popup(e)
Example #2
0
    def edit(self, element):
        e=get_edit_popup(element, self.controller)
        if e._widget:
            # The edit popup is already open
            return True
        w=e.compact()

        # Buttons hbox
        hbox=Gtk.HBox()

        def handle_ok(b, w):
            e.apply_cb()
            #self.undisplay_cb(b, w)
            return True

        # OK button
        b=get_pixmap_button('small_ok.png', handle_ok, w)
        b.set_relief(Gtk.ReliefStyle.NONE)
        b.set_tooltip_text(_("Validate"))
        hbox.pack_start(b, False, True, 0)

        # Close button
        b=get_pixmap_button('small_close.png', self.undisplay_cb, w)
        b.set_relief(Gtk.ReliefStyle.NONE)
        b.set_tooltip_text(_("Close"))
        hbox.pack_start(b, False, True, 0)

        t=self.get_short_title(element)
        l=Gtk.Label()
        l.set_markup('<b>%s</b>' % t.replace('<', '&lt;'))
        hbox.pack_start(l, True, True, 0)

        self.edited_elements[element]=w
        w._title_label=l
        self.display(w, title=hbox)

        def handle_destroy(*p):
            if self.controller and self.controller.gui:
                self.controller.gui.unregister_edit_popup(e)
            self.undisplay_cb(None, w)
            return True

        w.connect('destroy', handle_destroy)

        self.controller.gui.make_pane_visible(getattr(self, '_destination', None))

        if self.controller and self.controller.gui:
            self.controller.gui.register_edit_popup(e)
Example #3
0
    def display(self, widget=None, timeout=None, title=None):
        """Display the given widget.

        timeout is in ms.
        title is either a string (that will be converted to a label), or a gtk widget.
        """
        if title is None:
            title="X"
        if self.size and len(self.widgets) >= self.size:
            # Remove the last one
            self.undisplay(self.widgets[0][0])
        if timeout is not None and timeout != 0:
            hidetime=time.time() * 1000 + long(timeout)
        else:
            hidetime=None

        # Build a titled frame around the widget
        f=gtk.Frame()
        if isinstance(title, basestring):
            hb=gtk.HBox()

            l=gtk.Label(title)
            hb.pack_start(l, expand=False)

            b=get_pixmap_button('small_close.png')
            b.set_relief(gtk.RELIEF_NONE)
            b.connect('clicked', self.undisplay_cb, widget)
            hb.pack_start(b, expand=False, fill=False)

            f.set_label_widget(hb)
        else:
            # Hopefully it is a gtk widget
            f.set_label_widget(title)
        f.set_label_align(0.1, 0.5)
        f.set_shadow_type(gtk.SHADOW_ETCHED_OUT)
        f.add(widget)

        self.lock.acquire()
        for t in self.widgets:
            self.set_color(t[2].get_label_widget(), self.old_color)
        self.widgets.append( (widget, hidetime, f) )
        if hidetime:
            self.controller.register_usertime_action( hidetime,
                                                      lambda c, time: self.undisplay(widget))
        self.widgets.sort(key=operator.itemgetter(1))
        self.lock.release()
        self.contentbox.pack_start(f, expand=False, padding=2)

        f.show_all()
        self.show()
        nb=self.widget.get_parent()
        if isinstance(nb, gtk.Notebook):
            # Ensure that the view is visible
            nb.set_current_page(nb.page_num(self.widget))

        self.controller.notify('PopupDisplay', view=self)
        return True
Example #4
0
    def display(self, widget=None, timeout=None, title=None):
        """Display the given widget.

        timeout is in ms.
        title is either a string (that will be converted to a label), or a gtk widget.
        """
        if title is None:
            title = "X"
        if self.size and len(self.widgets) >= self.size:
            # Remove the last one
            self.undisplay(self.widgets[0][0])
        if timeout is not None and timeout != 0:
            hidetime = time.time() * 1000 + long(timeout)
        else:
            hidetime = None

        # Build a titled frame around the widget
        f = gtk.Frame()
        if isinstance(title, basestring):
            hb = gtk.HBox()

            l = gtk.Label(title)
            hb.pack_start(l, expand=False)

            b = get_pixmap_button('small_close.png')
            b.set_relief(gtk.RELIEF_NONE)
            b.connect('clicked', self.undisplay_cb, widget)
            hb.pack_start(b, expand=False, fill=False)

            f.set_label_widget(hb)
        else:
            # Hopefully it is a gtk widget
            f.set_label_widget(title)
        f.set_label_align(0.1, 0.5)
        f.set_shadow_type(gtk.SHADOW_ETCHED_OUT)
        f.add(widget)

        self.lock.acquire()
        for t in self.widgets:
            self.set_color(t[2].get_label_widget(), self.old_color)
        self.widgets.append((widget, hidetime, f))
        if hidetime:
            self.controller.register_usertime_action(
                hidetime, lambda c, time: self.undisplay(widget))
        self.widgets.sort(key=operator.itemgetter(1))
        self.lock.release()
        self.contentbox.pack_start(f, expand=False, padding=2)

        f.show_all()
        self.show()
        nb = self.widget.get_parent()
        if isinstance(nb, gtk.Notebook):
            # Ensure that the view is visible
            nb.set_current_page(nb.page_num(self.widget))

        self.controller.notify('PopupDisplay', view=self)
        return True
Example #5
0
    def add_view(self, v, name=None, permanent=False):
        """Add a new view to the notebook.

        Each view is an Advene view, and must have a .widget attribute
        """
        if name is None:
            try:
                name=v.view_name
            except AttributeError:
                name="FIXME"
        self.controller.gui.register_view (v)
        self.views.append(v)
        v._destination=self.location
        v.set_label(name)
        if permanent:
            self.permanent_widgets.append(v)

        def close_view(item, view):
            self.remove_view(view)
            return True

        def detach_view(item, view):
            self.detach_view(view)
            return True

        def relocate_view(item, v, d):
            # Reference the widget so that it is not destroyed
            wid=v.widget
            if not self.detach_view(v):
                return True
            if d == 'popup':
                v.popup(label=v._label)
            elif d in ('south', 'east', 'west', 'fareast'):
                v._destination=d
                self.controller.gui.viewbook[d].add_view(v, name=v._label)
            return True

        def popup_menu(button, event, view):
            if event.button == 3:
                menu = gtk.Menu()
                if not permanent:
                    # Relocation submenu
                    submenu=gtk.Menu()

                    for (label, destination) in (
                        (_("...in its own window"), 'popup'),
                        (_("...embedded east of the video"), 'east'),
                        (_("...embedded west of the video"), 'west'),
                        (_("...embedded south of the video"), 'south'),
                        (_("...embedded at the right of the window"), 'fareast')):
                        if destination == self.location:
                            continue
                        item = gtk.MenuItem(label)
                        item.connect('activate', relocate_view,  view, destination)
                        submenu.append(item)

                    item=gtk.MenuItem(_("Detach"))
                    item.set_submenu(submenu)
                    menu.append(item)

                    item = gtk.MenuItem(_("Close"))
                    item.connect('activate', close_view, view)
                    menu.append(item)

                try:
                    for label, action in view.contextual_actions:
                        item = gtk.MenuItem(label, use_underline=False)
                        item.connect('activate', action, view)
                        menu.append(item)
                except AttributeError:
                    pass

                menu.show_all()
                menu.popup(None, None, None, 0, gtk.get_current_event_time())
                return True
            elif event.button == 1 and event.type == gtk.gdk._2BUTTON_PRESS:
                # Double click: propose to rename the view
                label_widget=button.get_children()[0]
                lab=dialog.entry_dialog(title=_("Rename the view"),
                                        text=_("Please enter the new name of the view"),
                                        default=view._label)
                if lab is not None:
                    view.set_label(lab)
                return True
            return False

        def label_drag_sent(widget, context, selection, targetType, eventTime, v):
            if targetType == config.data.target_type['adhoc-view-instance']:
                # This is not very robust, but allows to transmit a view instance reference
                selection.set(selection.target, 8, self.controller.gui.get_adhoc_view_instance_id(v))
                self.detach_view(v)
                return True
            return False

        e=gtk.EventBox()
        e.set_visible_window(False)
        e.set_above_child(True)
        if len(name) > 13:
            shortname=unicode(name)[:12] + u'\u2026'
        else:
            shortname=name
        l=gtk.Label()
        l.set_markup("<small>%s</small>" % shortname)
        if self.controller.gui:
            e.set_tooltip_text(name)
        e.add(l)
        e.connect('button-press-event', popup_menu, v)

        if not permanent:
            e.connect('drag-data-get', label_drag_sent, v)
            # The widget can generate drags
            e.drag_source_set(gtk.gdk.BUTTON1_MASK,
                              config.data.drag_type['adhoc-view-instance'],
                              gtk.gdk.ACTION_COPY | gtk.gdk.ACTION_LINK)
        hb=gtk.HBox()

        if not permanent:
            b=get_pixmap_button('small_detach.png')
            b.set_tooltip_text(_("Detach view in its own window, or drag-and-drop to another zone"))
            b.set_relief(gtk.RELIEF_NONE)
            b.connect('clicked', relocate_view, v, 'popup')
            b.connect('drag-data-get', label_drag_sent, v)
            # The widget can generate drags
            b.drag_source_set(gtk.gdk.BUTTON1_MASK,
                              config.data.drag_type['adhoc-view-instance'],
                              gtk.gdk.ACTION_COPY | gtk.gdk.ACTION_LINK)
            hb.pack_start(b, expand=False, fill=False)

        hb.pack_start(e, expand=False, fill=False)

        if not permanent:
            b=get_pixmap_button('small_close.png')
            b.set_tooltip_text(_("Close view"))
            b.set_relief(gtk.RELIEF_NONE)
            b.connect('clicked', close_view, v)
            hb.pack_start(b, expand=False, fill=False)
        hb.show_all()

        self.widget.append_page(v.widget, hb)
        v.widget.show_all()
        # Hide the player toolbar when the view is embedded
        try:
            v.player_toolbar.hide()
        except AttributeError:
            pass

        num=self.widget.page_num(v.widget)
        self.widget.set_current_page(num)

        return True
Example #6
0
    def popup(self, label=None):
        if label is None:
            label = self.view_name
        window = gtk.Window(gtk.WINDOW_TOPLEVEL)
        window.set_title(label)

        def close_popup(*p):
            window.destroy()
            return True

        # Close the popup window when the widget is destroyed
        self.widget.connect('destroy', close_popup)

        # Buttons specific to the window, that should be removed from
        # the buttonbox on window close (esp. when reparenting to the
        # application)
        window.own_buttons = []

        # If the widget defines a buttonbox, we can use it and do not
        # have to define a enclosing VBox (which also solves a problem
        # with the timeline view not being embedable inside a VBox()
        if hasattr(self.widget,
                   'buttonbox') and self.widget.buttonbox is not None:
            window.add(self.widget)
            window.buttonbox = self.widget.buttonbox
        else:
            vbox = gtk.VBox()
            window.add(vbox)
            window.buttonbox = gtk.HBox()
            vbox.pack_start(window.buttonbox, expand=False)
            vbox.add(self.widget)

        # Insert contextual_actions in buttonbox
        if hasattr(self, 'contextual_actions') and self.contextual_actions:
            menubar = gtk.MenuBar()
            root = gtk.MenuItem(_("Actions"))
            menubar.append(root)
            menu = gtk.Menu()
            root.set_submenu(menu)
            for label, action in self.contextual_actions:
                b = gtk.MenuItem(label, use_underline=False)
                b.connect('activate', action)
                menu.append(b)
            window.buttonbox.pack_start(menubar, expand=False)
            window.own_buttons.append(menubar)

        def drag_sent(widget_, context, selection, targetType, eventTime):
            if targetType == config.data.target_type['adhoc-view-instance']:
                # This is not very robust, but allows to transmit a view instance reference
                selection.set(selection.target, 8, repr(self).encode('utf8'))
                if hasattr(self, 'reparent_prepare'):
                    self.reparent_prepare()
                self.widget.get_parent().remove(self.widget)
                # Do not trigger the close_view_cb handler
                window.disconnect(window.cleanup_id)
                window.destroy()
                return True
            return False

        b = get_pixmap_button('small_attach.png', self.attach_view, window)
        b.set_tooltip_text(_("Click or drag-and-drop to reattach view"))
        b.connect('drag-data-get', drag_sent)
        # The widget can generate drags
        b.drag_source_set(gtk.gdk.BUTTON1_MASK,
                          config.data.drag_type['adhoc-view-instance'],
                          gtk.gdk.ACTION_LINK)

        window.own_buttons.append(b)
        window.buttonbox.pack_start(b, expand=False)

        b = get_pixmap_button('small_close.png')
        if self.controller and self.controller.gui:
            b.connect('clicked', self.controller.gui.close_view_cb, window,
                      self)
        else:
            b.connect('clicked', lambda w: window.destroy())
        window.own_buttons.append(b)
        window.buttonbox.pack_start(b, expand=False)

        def remove_own_buttons(w):
            for b in window.own_buttons:
                b.destroy()
            return False

        window.connect('destroy', remove_own_buttons)

        window.buttonbox.show_all()
        window.show_all()

        if hasattr(self, 'reparent_done'):
            self.reparent_done()

        if self.controller and self.controller.gui:
            self.controller.gui.register_view(self)
            window.cleanup_id = window.connect(
                'destroy', self.controller.gui.close_view_cb, window, self)
            self.controller.gui.init_window_size(window, self.view_id)
            window.set_icon_list(*self.controller.gui.get_icon_list())

        if config.data.os == 'win32':
            # Force resize for win32
            oldmode = window.get_resize_mode()
            window.set_resize_mode(gtk.RESIZE_IMMEDIATE)
            window.resize_children()
            window.set_resize_mode(oldmode)
        return window
Example #7
0
    def build_widget(self):
        vbox = Gtk.VBox()

        self.player = self.controller.playerfactory.get_player()

        self.player.sound_mute()

        self.drawable = get_drawable()

        black = Gdk.Color(0, 0, 0)
        for state in (Gtk.StateType.ACTIVE, Gtk.StateType.NORMAL,
                      Gtk.StateType.SELECTED, Gtk.StateType.INSENSITIVE,
                      Gtk.StateType.PRELIGHT):
            self.drawable.modify_bg(state, black)

        self.drawable.set_size_request(320, 200)

        self.toolbar = Gtk.Toolbar()
        self.toolbar.set_style(Gtk.ToolbarStyle.ICONS)

        # Append the volume control to the toolbar
        def volume_change(scale, value):
            if self.player.sound_get_volume() != int(value * 100):
                self.player.sound_set_volume(int(value * 100))
            return True

        self.audio_volume = Gtk.VolumeButton()
        self.audio_volume.set_value(self.player.sound_get_volume() / 100.0)
        ti = Gtk.ToolItem()
        ti.add(self.audio_volume)
        self.audio_volume.connect('value-changed', volume_change)
        self.toolbar.insert(ti, -1)

        sync_button = Gtk.ToolButton(Gtk.STOCK_CONNECT)
        sync_button.set_tooltip_text(_("Synchronize"))
        sync_button.connect('clicked', self.synchronize)
        self.toolbar.insert(sync_button, -1)

        def offset_changed(spin):
            self.offset = int(spin.get_value())
            return True

        ti = Gtk.ToolItem()
        self.offset_spin = Gtk.SpinButton.new(
            Gtk.Adjustment.new(self.offset, -24 * 60 * 60 * 1000,
                               24 * 60 * 60 * 1000,
                               self.controller.frame2time(1), 1000, 500), 1000,
            0)
        self.offset_spin.get_adjustment().connect('value-changed',
                                                  offset_changed)
        ti.add(self.offset_spin)
        self.offset_spin.set_tooltip_text(_("Offset in ms"))
        self.toolbar.insert(ti, -1)

        self.label = Gtk.Label()
        self.label.set_alignment(0, 0)
        self.label.modify_font(Pango.FontDescription("sans 10"))

        timestamp_button = get_pixmap_button('set-to-now.png')
        timestamp_button.set_tooltip_text(
            _("Drag and drop to get player time"))
        enable_drag_source(
            timestamp_button,
            lambda: int(self.player.get_stream_information().position),
            self.controller)
        # Cannot use a Gtk.ToolButton since it cannot be drag_source
        ti = Gtk.ToolItem()
        ti.add(timestamp_button)
        self.toolbar.insert(ti, -1)

        black = Gdk.color_parse('black')
        white = Gdk.color_parse('white')
        eb = Gtk.EventBox()
        eb.add(self.label)
        for state in (Gtk.StateType.ACTIVE, Gtk.StateType.NORMAL,
                      Gtk.StateType.SELECTED, Gtk.StateType.INSENSITIVE,
                      Gtk.StateType.PRELIGHT):
            self.label.modify_bg(state, black)
            eb.modify_bg(state, black)
            self.label.modify_fg(state, white)

        vbox.add(self.drawable)
        vbox.pack_start(eb, False, True, 0)
        vbox.pack_start(self.toolbar, False, True, 0)

        self.drawable.connect_after('realize', self.register_drawable)

        # Accept annotation/timestamp drop, to adjust time offset
        vbox.connect('drag-data-received', self.drag_received_cb)
        vbox.drag_dest_set(
            Gtk.DestDefaults.MOTION | Gtk.DestDefaults.HIGHLIGHT
            | Gtk.DestDefaults.ALL,
            config.data.get_target_types('annotation', 'timestamp'),
            Gdk.DragAction.COPY | Gdk.DragAction.LINK | Gdk.DragAction.MOVE)

        vbox.show_all()
        return vbox
Example #8
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
Example #9
0
    def build_widget(self):
        vbox = gtk.VBox()

        if gtksourceview2 is not None:
            self.textview=gtksourceview2.View()
            self.textview.set_buffer(gtksourceview2.Buffer())
        else:
            self.textview = gtk.TextView()

        # We could make it editable and modify the annotation
        self.textview.set_editable(True)
        self.textview.set_wrap_mode (gtk.WRAP_WORD)

        hb=gtk.HBox()
        vbox.pack_start(hb, expand=False)
        if self.controller.gui:
            self.player_toolbar=self.controller.gui.get_player_control_toolbar()
            hb.add(self.player_toolbar)
        hb.add(self.get_toolbar())

        sw = gtk.ScrolledWindow()
        sw.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
        vbox.add (sw)


        # 0-mark at the beginning
        zero=self.create_timestamp_mark(0, self.textview.get_buffer().get_start_iter())
        self.current_mark=zero

        # Memorize the last keypress time
        self.last_keypress_time = 0

        self.textview.connect('button-press-event', self.button_press_event_cb)
        self.textview.connect('key-press-event', self.key_pressed_cb)
        self.textview.get_buffer().create_tag("past", background="#dddddd")
        self.textview.get_buffer().create_tag("ignored", strikethrough=True)

        self.textview.drag_dest_set(gtk.DEST_DEFAULT_MOTION |
                                    gtk.DEST_DEFAULT_HIGHLIGHT |
                                    gtk.DEST_DEFAULT_ALL,
                                    config.data.drag_type['timestamp']
                                    ,
                                    gtk.gdk.ACTION_COPY | gtk.gdk.ACTION_MOVE)
        self.textview.connect('drag-data-received', self.textview_drag_received)

        # Hook the completer component
        completer=Completer(textview=self.textview,
                            controller=self.controller,
                            element=self.textview.get_buffer(),
                            indexer=self.controller.package._indexer)

        sw.add(self.textview)

        # Search box
        b=self.textview.get_buffer()

        # Create useful tags
        b.create_tag("activated", background="skyblue")
        b.create_tag("current", background="lightblue")
        b.create_tag("searched_string", background="green")

        self.searchbox=gtk.HBox()

        def hide_searchbox(*p):
            # Clear the searched_string tags
            b=self.textview.get_buffer()
            b.remove_tag_by_name("searched_string", *b.get_bounds())
            self.searchbox.hide()
            return True

        close_button=get_pixmap_button('small_close.png', hide_searchbox)
        close_button.set_relief(gtk.RELIEF_NONE)
        self.searchbox.pack_start(close_button, expand=False, fill=False)

        def search_entry_cb(e):
            self.highlight_search_forward(e.get_text())
            return True

        def search_entry_key_press_cb(e, event):
            if event.keyval == gtk.keysyms.Escape:
                hide_searchbox()
                return True
            return False

        self.searchbox.entry=gtk.Entry()
        self.searchbox.entry.connect('activate', search_entry_cb)
        self.searchbox.pack_start(self.searchbox.entry, expand=False, fill=False)
        self.searchbox.entry.connect('key-press-event', search_entry_key_press_cb)

        b=get_small_stock_button(gtk.STOCK_FIND)
        b.connect('clicked', lambda b: self.highlight_search_forward(self.searchbox.entry.get_text()))
        self.searchbox.pack_start(b, expand=False)

        fill=gtk.HBox()
        self.searchbox.pack_start(fill, expand=True, fill=True)
        self.searchbox.show_all()
        self.searchbox.hide()

        self.searchbox.set_no_show_all(True)
        vbox.pack_start(self.searchbox, expand=False)

        self.statusbar=gtk.Statusbar()
        self.statusbar.set_has_resize_grip(False)
        vbox.pack_start(self.statusbar, expand=False)
        vbox.show_all()

        return vbox
Example #10
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
Example #11
0
    def build_widget(self):
        mainbox = Gtk.VBox()

        tb = Gtk.Toolbar()
        tb.set_style(Gtk.ToolbarStyle.ICONS)

        for icon, action, tip in (
            (Gtk.STOCK_SAVE, self.save_transcription,
             _("Save transcription to a text file")),
            (Gtk.STOCK_APPLY, self.validate, _("Apply the modifications")),
            (Gtk.STOCK_FIND, self.show_searchbox, _("Find text")),
            (Gtk.STOCK_REDO, self.quick_options_toggle,
             _("Quickly switch display options")),
            (Gtk.STOCK_REFRESH, self.refresh, _("Refresh the transcription")),
            (Gtk.STOCK_PREFERENCES, self.edit_options, _("Edit preferences")),
        ):
            b = Gtk.ToolButton(stock_id=icon)
            b.set_tooltip_text(tip)
            b.connect('clicked', action)
            tb.insert(b, -1)
        mainbox.pack_start(tb, False, True, 0)

        sw = Gtk.ScrolledWindow()
        sw.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC)
        sw.set_resize_mode(Gtk.ResizeMode.PARENT)
        mainbox.add(sw)

        self.textview = Gtk.TextView()
        # We could make it editable and modify the annotation
        self.textview.set_editable(True)
        self.textview.set_wrap_mode(Gtk.WrapMode.WORD)
        b = self.textview.get_buffer()

        # Create useful tags
        b.create_tag("activated", weight=Pango.Weight.BOLD)
        b.create_tag("current", background="lightblue")
        b.create_tag("searched_string", background="green")
        b.create_tag("bound", editable=False)

        self.generate_buffer_content()

        self.textview.connect('button-press-event', self.button_press_event_cb)
        self.textview.connect_after('move-cursor', self.move_cursor_cb)
        self.textview.connect('populate-popup', self.populate_popup_cb)

        self.update_current_annotation(self.textview, None)

        sw.add(self.textview)

        self.searchbox = Gtk.HBox()

        def hide_searchbox(*p):
            # Clear the searched_string tags
            b = self.textview.get_buffer()
            b.remove_tag_by_name("searched_string", *b.get_bounds())
            self.searchbox.hide()
            return True

        close_button = get_pixmap_button('small_close.png', hide_searchbox)
        close_button.set_relief(Gtk.ReliefStyle.NONE)
        self.searchbox.pack_start(close_button, False, False, 0)

        def search_entry_cb(e):
            self.highlight_search_forward(e.get_text())
            return True

        def search_entry_key_press_cb(e, event):
            if event.keyval == Gdk.KEY_Escape:
                hide_searchbox()
                return True
            return False

        self.searchbox.entry = Gtk.Entry()
        self.searchbox.entry.connect('activate', search_entry_cb)
        self.searchbox.pack_start(self.searchbox.entry, False, False, 0)
        self.searchbox.entry.connect('key-press-event',
                                     search_entry_key_press_cb)

        #        def find_next(b):
        #            # FIXME
        #            return True
        #
        #        b=get_small_stock_button(Gtk.STOCK_GO_FORWARD, find_next)
        #        b.set_relief(Gtk.ReliefStyle.NONE)
        #        b.set_tooltip_text(_("Find next occurrence"))
        #        self.searchbox.pack_start(b, False, False, 0)

        fill = Gtk.HBox()
        self.searchbox.pack_start(fill, True, True, 0)

        mainbox.pack_start(self.searchbox, False, True, 0)

        self.statusbar = Gtk.Statusbar()
        mainbox.pack_start(self.statusbar, False, True, 0)

        mainbox.show_all()

        hide_searchbox()

        # Ignore show_all method to keep the searchbar hidden, and
        # we already did it anyway.
        mainbox.set_no_show_all(True)

        mainbox.connect('key-press-event', self.key_press_event_cb)
        self.textview.connect('key-press-event', self.key_press_event_cb)

        return mainbox
Example #12
0
    def add_view(self, v, name=None, permanent=False):
        """Add a new view to the notebook.

        Each view is an Advene view, and must have a .widget attribute
        """
        if name is None:
            try:
                name = v.view_name
            except AttributeError:
                name = "FIXME"
        self.controller.gui.register_view(v)
        self.views.append(v)
        v._destination = self.location
        v.set_label(name)
        if permanent:
            self.permanent_widgets.append(v)

        def close_view(item, view):
            self.remove_view(view)
            return True

        def detach_view(item, view):
            self.detach_view(view)
            return True

        def relocate_view(item, v, d):
            # Reference the widget so that it is not destroyed
            wid = v.widget
            if not self.detach_view(v):
                return True
            if d == 'popup':
                v.popup(label=v._label)
            elif d in ('south', 'east', 'west', 'fareast'):
                v._destination = d
                self.controller.gui.viewbook[d].add_view(v, name=v._label)
            return True

        def popup_menu(button, event, view):
            if event.button == 3:
                menu = gtk.Menu()
                if not permanent:
                    # Relocation submenu
                    submenu = gtk.Menu()

                    for (label, destination) in (
                        (_("...in its own window"), 'popup'),
                        (_("...embedded east of the video"),
                         'east'), (_("...embedded west of the video"), 'west'),
                        (_("...embedded south of the video"), 'south'),
                        (_("...embedded at the right of the window"),
                         'fareast')):
                        if destination == self.location:
                            continue
                        item = gtk.MenuItem(label)
                        item.connect('activate', relocate_view, view,
                                     destination)
                        submenu.append(item)

                    item = gtk.MenuItem(_("Detach"))
                    item.set_submenu(submenu)
                    menu.append(item)

                    item = gtk.MenuItem(_("Close"))
                    item.connect('activate', close_view, view)
                    menu.append(item)

                try:
                    for label, action in view.contextual_actions:
                        item = gtk.MenuItem(label, use_underline=False)
                        item.connect('activate', action, view)
                        menu.append(item)
                except AttributeError:
                    pass

                menu.show_all()
                menu.popup(None, None, None, 0, gtk.get_current_event_time())
                return True
            elif event.button == 1 and event.type == gtk.gdk._2BUTTON_PRESS:
                # Double click: propose to rename the view
                label_widget = button.get_children()[0]
                lab = dialog.entry_dialog(
                    title=_("Rename the view"),
                    text=_("Please enter the new name of the view"),
                    default=view._label)
                if lab is not None:
                    view.set_label(lab)
                return True
            return False

        def label_drag_sent(widget, context, selection, targetType, eventTime,
                            v):
            if targetType == config.data.target_type['adhoc-view-instance']:
                # This is not very robust, but allows to transmit a view instance reference
                selection.set(
                    selection.target, 8,
                    self.controller.gui.get_adhoc_view_instance_id(v))
                self.detach_view(v)
                return True
            return False

        e = gtk.EventBox()
        e.set_visible_window(False)
        e.set_above_child(True)
        if len(name) > 13:
            shortname = unicode(name)[:12] + u'\u2026'
        else:
            shortname = name
        l = gtk.Label()
        l.set_markup("<small>%s</small>" % shortname)
        if self.controller.gui:
            e.set_tooltip_text(name)
        e.add(l)
        e.connect('button-press-event', popup_menu, v)

        if not permanent:
            e.connect('drag-data-get', label_drag_sent, v)
            # The widget can generate drags
            e.drag_source_set(gtk.gdk.BUTTON1_MASK,
                              config.data.drag_type['adhoc-view-instance'],
                              gtk.gdk.ACTION_COPY | gtk.gdk.ACTION_LINK)
        hb = gtk.HBox()

        if not permanent:
            b = get_pixmap_button('small_detach.png')
            b.set_tooltip_text(
                _("Detach view in its own window, or drag-and-drop to another zone"
                  ))
            b.set_relief(gtk.RELIEF_NONE)
            b.connect('clicked', relocate_view, v, 'popup')
            b.connect('drag-data-get', label_drag_sent, v)
            # The widget can generate drags
            b.drag_source_set(gtk.gdk.BUTTON1_MASK,
                              config.data.drag_type['adhoc-view-instance'],
                              gtk.gdk.ACTION_COPY | gtk.gdk.ACTION_LINK)
            hb.pack_start(b, expand=False, fill=False)

        hb.pack_start(e, expand=False, fill=False)

        if not permanent:
            b = get_pixmap_button('small_close.png')
            b.set_tooltip_text(_("Close view"))
            b.set_relief(gtk.RELIEF_NONE)
            b.connect('clicked', close_view, v)
            hb.pack_start(b, expand=False, fill=False)
        hb.show_all()

        self.widget.append_page(v.widget, hb)
        v.widget.show_all()
        # Hide the player toolbar when the view is embedded
        try:
            v.player_toolbar.hide()
        except AttributeError:
            pass

        num = self.widget.page_num(v.widget)
        self.widget.set_current_page(num)

        return True
Example #13
0
    def build_widget(self):
        vbox = gtk.VBox()

        self.player = self.controller.playerfactory.get_player()

        self.player.sound_mute()

        self.drawable = gtk.Socket()

        def handle_remove(socket):
            # Do not kill the widget if the application exits
            return True

        self.drawable.connect('plug-removed', handle_remove)

        black = gtk.gdk.Color(0, 0, 0)
        for state in (gtk.STATE_ACTIVE, gtk.STATE_NORMAL, gtk.STATE_SELECTED,
                      gtk.STATE_INSENSITIVE, gtk.STATE_PRELIGHT):
            self.drawable.modify_bg(state, black)

        self.drawable.set_size_request(320, 200)

        self.toolbar = gtk.Toolbar()
        self.toolbar.set_style(gtk.TOOLBAR_ICONS)

        # Append the volume control to the toolbar
        def volume_change(scale, value):
            if self.player.sound_get_volume() != int(value * 100):
                self.player.sound_set_volume(int(value * 100))
            return True

        self.audio_volume = gtk.VolumeButton()
        self.audio_volume.set_value(self.player.sound_get_volume() / 100.0)
        ti = gtk.ToolItem()
        ti.add(self.audio_volume)
        self.audio_volume.connect('value-changed', volume_change)
        self.toolbar.insert(ti, -1)

        sync_button = gtk.ToolButton(gtk.STOCK_CONNECT)
        sync_button.set_tooltip_text(_("Synchronize"))
        sync_button.connect('clicked', self.synchronize)
        self.toolbar.insert(sync_button, -1)

        def offset_changed(spin):
            self.offset = long(spin.get_value())
            return True

        ti = gtk.ToolItem()
        self.offset_spin = gtk.SpinButton(
            gtk.Adjustment(value=self.offset,
                           lower=-24 * 60 * 60 * 1000,
                           upper=24 * 60 * 60 * 1000,
                           step_incr=1000 /
                           config.data.preferences['default-fps'],
                           page_incr=1000))
        self.offset_spin.get_adjustment().connect('value-changed',
                                                  offset_changed)
        ti.add(self.offset_spin)
        self.offset_spin.set_tooltip_text(_("Offset in ms"))
        self.toolbar.insert(ti, -1)

        self.label = gtk.Label()
        self.label.set_alignment(0, 0)
        self.label.modify_font(pango.FontDescription("sans 10"))

        timestamp_button = get_pixmap_button('set-to-now.png')
        timestamp_button.set_tooltip_text(
            _("Drag and drop to get player time"))
        enable_drag_source(
            timestamp_button,
            lambda: long(self.player.get_stream_information().position),
            self.controller)
        # Cannot use a gtk.ToolButton since it cannot be drag_source
        ti = gtk.ToolItem()
        ti.add(timestamp_button)
        self.toolbar.insert(ti, -1)

        black = gtk.gdk.color_parse('black')
        white = gtk.gdk.color_parse('white')
        eb = gtk.EventBox()
        eb.add(self.label)
        for state in (gtk.STATE_ACTIVE, gtk.STATE_NORMAL, gtk.STATE_SELECTED,
                      gtk.STATE_INSENSITIVE, gtk.STATE_PRELIGHT):
            self.label.modify_bg(state, black)
            eb.modify_bg(state, black)
            self.label.modify_fg(state, white)

        vbox.add(self.drawable)
        vbox.pack_start(eb, expand=False)
        vbox.pack_start(self.toolbar, expand=False)

        self.drawable.connect_after('realize', self.register_drawable)

        # Accept annotation/timestamp drop, to adjust time offset
        vbox.connect('drag-data-received', self.drag_received_cb)
        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_COPY | gtk.gdk.ACTION_LINK | gtk.gdk.ACTION_MOVE)

        vbox.show_all()
        return vbox
Example #14
0
    def build_widget(self):
        vbox = Gtk.VBox()

        if GtkSource is not None:
            self.textview=GtkSource.View()
            self.textview.set_buffer(GtkSource.Buffer())
        else:
            self.textview = Gtk.TextView()

        # We could make it editable and modify the annotation
        self.textview.set_editable(True)
        self.textview.set_wrap_mode (Gtk.WrapMode.WORD)

        hb=Gtk.HBox()
        vbox.pack_start(hb, False, True, 0)
        if self.controller.gui:
            self.player_toolbar=self.controller.gui.get_player_control_toolbar()
            hb.add(self.player_toolbar)
        hb.add(self.get_toolbar())

        sw = Gtk.ScrolledWindow()
        sw.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC)
        vbox.add (sw)


        # 0-mark at the beginning
        zero=self.create_timestamp_mark(0, self.textview.get_buffer().get_start_iter())
        self.current_mark=zero

        # Memorize the last keypress time
        self.last_keypress_time = 0

        self.textview.connect('button-press-event', self.button_press_event_cb)
        self.textview.connect('key-press-event', self.key_pressed_cb)
        self.textview.get_buffer().create_tag("past", background="#dddddd")
        self.textview.get_buffer().create_tag("ignored", strikethrough=True)

        self.textview.drag_dest_set(Gtk.DestDefaults.MOTION |
                                    Gtk.DestDefaults.HIGHLIGHT |
                                    Gtk.DestDefaults.ALL,
                                    config.data.get_target_types('timestamp'),
                                    Gdk.DragAction.COPY | Gdk.DragAction.MOVE)
        self.textview.connect('drag-data-received', self.textview_drag_received)

        # Hook the completer component
        self.completer=Completer(textview=self.textview,
                                 controller=self.controller,
                                 element=self.textview.get_buffer(),
                                 indexer=self.controller.package._indexer)
        sw.add(self.textview)

        # Search box
        b=self.textview.get_buffer()

        # Create useful tags
        b.create_tag("activated", background="skyblue")
        b.create_tag("current", background="lightblue")
        b.create_tag("searched_string", background="green")

        self.searchbox=Gtk.HBox()

        def hide_searchbox(*p):
            # Clear the searched_string tags
            b=self.textview.get_buffer()
            b.remove_tag_by_name("searched_string", *b.get_bounds())
            self.searchbox.hide()
            return True

        close_button=get_pixmap_button('small_close.png', hide_searchbox)
        close_button.set_relief(Gtk.ReliefStyle.NONE)
        self.searchbox.pack_start(close_button, False, False, 0)

        def search_entry_cb(e):
            self.highlight_search_forward(e.get_text())
            return True

        def search_entry_key_press_cb(e, event):
            if event.keyval == Gdk.KEY_Escape:
                hide_searchbox()
                return True
            return False

        self.searchbox.entry=Gtk.Entry()
        self.searchbox.entry.connect('activate', search_entry_cb)
        self.searchbox.pack_start(self.searchbox.entry, False, False, 0)
        self.searchbox.entry.connect('key-press-event', search_entry_key_press_cb)

        b=get_small_stock_button(Gtk.STOCK_FIND)
        b.connect('clicked', lambda b: self.highlight_search_forward(self.searchbox.entry.get_text()))
        self.searchbox.pack_start(b, False, True, 0)

        fill=Gtk.HBox()
        self.searchbox.pack_start(fill, True, True, 0)
        self.searchbox.show_all()
        self.searchbox.hide()

        self.searchbox.set_no_show_all(True)
        vbox.pack_start(self.searchbox, False, True, 0)

        self.statusbar=Gtk.Statusbar()
        vbox.pack_start(self.statusbar, False, True, 0)
        vbox.show_all()

        return vbox
Example #15
0
    def popup(self, label=None):
        if label is None:
            label = self.view_name
        window = gtk.Window(gtk.WINDOW_TOPLEVEL)
        window.set_title(label)

        def close_popup(*p):
            window.destroy()
            return True

        # Close the popup window when the widget is destroyed
        self.widget.connect("destroy", close_popup)

        # Buttons specific to the window, that should be removed from
        # the buttonbox on window close (esp. when reparenting to the
        # application)
        window.own_buttons = []

        # If the widget defines a buttonbox, we can use it and do not
        # have to define a enclosing VBox (which also solves a problem
        # with the timeline view not being embedable inside a VBox()
        if hasattr(self.widget, "buttonbox") and self.widget.buttonbox is not None:
            window.add(self.widget)
            window.buttonbox = self.widget.buttonbox
        else:
            vbox = gtk.VBox()
            window.add(vbox)
            window.buttonbox = gtk.HBox()
            vbox.pack_start(window.buttonbox, expand=False)
            vbox.add(self.widget)

        # Insert contextual_actions in buttonbox
        if hasattr(self, "contextual_actions") and self.contextual_actions:
            menubar = gtk.MenuBar()
            root = gtk.MenuItem(_("Actions"))
            menubar.append(root)
            menu = gtk.Menu()
            root.set_submenu(menu)
            for label, action in self.contextual_actions:
                b = gtk.MenuItem(label, use_underline=False)
                b.connect("activate", action)
                menu.append(b)
            window.buttonbox.pack_start(menubar, expand=False)
            window.own_buttons.append(menubar)

        def drag_sent(widget_, context, selection, targetType, eventTime):
            if targetType == config.data.target_type["adhoc-view-instance"]:
                # This is not very robust, but allows to transmit a view instance reference
                selection.set(selection.target, 8, repr(self).encode("utf8"))
                if hasattr(self, "reparent_prepare"):
                    self.reparent_prepare()
                self.widget.get_parent().remove(self.widget)
                # Do not trigger the close_view_cb handler
                window.disconnect(window.cleanup_id)
                window.destroy()
                return True
            return False

        b = get_pixmap_button("small_attach.png", self.attach_view, window)
        b.set_tooltip_text(_("Click or drag-and-drop to reattach view"))
        b.connect("drag-data-get", drag_sent)
        # The widget can generate drags
        b.drag_source_set(gtk.gdk.BUTTON1_MASK, config.data.drag_type["adhoc-view-instance"], gtk.gdk.ACTION_LINK)

        window.own_buttons.append(b)
        window.buttonbox.pack_start(b, expand=False)

        b = get_pixmap_button("small_close.png")
        if self.controller and self.controller.gui:
            b.connect("clicked", self.controller.gui.close_view_cb, window, self)
        else:
            b.connect("clicked", lambda w: window.destroy())
        window.own_buttons.append(b)
        window.buttonbox.pack_start(b, expand=False)

        def remove_own_buttons(w):
            for b in window.own_buttons:
                b.destroy()
            return False

        window.connect("destroy", remove_own_buttons)

        window.buttonbox.show_all()
        window.show_all()

        if hasattr(self, "reparent_done"):
            self.reparent_done()

        if self.controller and self.controller.gui:
            self.controller.gui.register_view(self)
            window.cleanup_id = window.connect("destroy", self.controller.gui.close_view_cb, window, self)
            self.controller.gui.init_window_size(window, self.view_id)
            window.set_icon_list(*self.controller.gui.get_icon_list())

        if config.data.os == "win32":
            # Force resize for win32
            oldmode = window.get_resize_mode()
            window.set_resize_mode(gtk.RESIZE_IMMEDIATE)
            window.resize_children()
            window.set_resize_mode(oldmode)
        return window
Example #16
0
    def build_widget(self):
        vbox = Gtk.VBox()

        if GtkSource is not None:
            self.textview=GtkSource.View()
            self.textview.set_buffer(GtkSource.Buffer())
        else:
            self.textview = Gtk.TextView()

        # We could make it editable and modify the annotation
        self.textview.set_editable(True)
        self.textview.set_wrap_mode (Gtk.WrapMode.WORD)

        hb=Gtk.HBox()
        vbox.pack_start(hb, False, True, 0)
        if self.controller.gui:
            self.player_toolbar=self.controller.gui.get_player_control_toolbar()
            hb.add(self.player_toolbar)
        hb.add(self.get_toolbar())

        sw = Gtk.ScrolledWindow()
        sw.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC)
        vbox.add (sw)


        # 0-mark at the beginning
        zero=self.create_timestamp_mark(0, self.textview.get_buffer().get_start_iter())
        self.current_mark=zero

        # Memorize the last keypress time
        self.last_keypress_time = 0

        self.textview.connect('button-press-event', self.button_press_event_cb)
        self.textview.connect('key-press-event', self.key_pressed_cb)
        self.textview.get_buffer().create_tag("past", background="#dddddd")
        self.textview.get_buffer().create_tag("ignored", strikethrough=True)

        self.textview.drag_dest_set(Gtk.DestDefaults.MOTION |
                                    Gtk.DestDefaults.HIGHLIGHT |
                                    Gtk.DestDefaults.ALL,
                                    config.data.get_target_types('timestamp'),
                                    Gdk.DragAction.COPY | Gdk.DragAction.MOVE)
        self.textview.connect('drag-data-received', self.textview_drag_received)

        # Hook the completer component
        completer=Completer(textview=self.textview,
                            controller=self.controller,
                            element=self.textview.get_buffer(),
                            indexer=self.controller.package._indexer)

        sw.add(self.textview)

        # Search box
        b=self.textview.get_buffer()

        # Create useful tags
        b.create_tag("activated", background="skyblue")
        b.create_tag("current", background="lightblue")
        b.create_tag("searched_string", background="green")

        self.searchbox=Gtk.HBox()

        def hide_searchbox(*p):
            # Clear the searched_string tags
            b=self.textview.get_buffer()
            b.remove_tag_by_name("searched_string", *b.get_bounds())
            self.searchbox.hide()
            return True

        close_button=get_pixmap_button('small_close.png', hide_searchbox)
        close_button.set_relief(Gtk.ReliefStyle.NONE)
        self.searchbox.pack_start(close_button, False, False, 0)

        def search_entry_cb(e):
            self.highlight_search_forward(e.get_text())
            return True

        def search_entry_key_press_cb(e, event):
            if event.keyval == Gdk.KEY_Escape:
                hide_searchbox()
                return True
            return False

        self.searchbox.entry=Gtk.Entry()
        self.searchbox.entry.connect('activate', search_entry_cb)
        self.searchbox.pack_start(self.searchbox.entry, False, False, 0)
        self.searchbox.entry.connect('key-press-event', search_entry_key_press_cb)

        b=get_small_stock_button(Gtk.STOCK_FIND)
        b.connect('clicked', lambda b: self.highlight_search_forward(self.searchbox.entry.get_text()))
        self.searchbox.pack_start(b, False, True, 0)

        fill=Gtk.HBox()
        self.searchbox.pack_start(fill, True, True, 0)
        self.searchbox.show_all()
        self.searchbox.hide()

        self.searchbox.set_no_show_all(True)
        vbox.pack_start(self.searchbox, False, True, 0)

        self.statusbar=Gtk.Statusbar()
        vbox.pack_start(self.statusbar, False, True, 0)
        vbox.show_all()

        return vbox
Example #17
0
    def build_widget(self):
        mainbox = gtk.VBox()

        tb=gtk.Toolbar()
        tb.set_style(gtk.TOOLBAR_ICONS)

        for icon, action, tip in (
            (gtk.STOCK_SAVE, self.save_transcription, _("Save transcription to a text file")),
            (gtk.STOCK_APPLY, self.validate, _("Apply the modifications")),
            (gtk.STOCK_FIND, self.show_searchbox, _("Find text")),
            (gtk.STOCK_REDO, self.quick_options_toggle, _("Quickly switch display options")),
            (gtk.STOCK_REFRESH, self.refresh, _("Refresh the transcription")),
            (gtk.STOCK_PREFERENCES, self.edit_options, _("Edit preferences")),
            ):
            b=gtk.ToolButton(stock_id=icon)
            b.set_tooltip_text(tip)
            b.connect('clicked', action)
            tb.insert(b, -1)
        mainbox.pack_start(tb, expand=False)

        #if self.controller.gui:
        #    self.player_toolbar=self.controller.gui.get_player_control_toolbar()
        #    mainbox.pack_start(self.player_toolbar, expand=False)

        sw = gtk.ScrolledWindow()
        sw.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
        sw.set_resize_mode(gtk.RESIZE_PARENT)
        mainbox.add (sw)

        self.textview = gtk.TextView()
        # We could make it editable and modify the annotation
        self.textview.set_editable(True)
        self.textview.set_wrap_mode (gtk.WRAP_WORD)
        b=self.textview.get_buffer()

        # Create useful tags
        b.create_tag("activated", background="skyblue")
        b.create_tag("current", background="lightblue")
        b.create_tag("searched_string", background="green")

        self.generate_buffer_content()

        self.textview.connect('button-press-event', self.button_press_event_cb)
        self.textview.connect_after('move-cursor', self.move_cursor_cb)
        self.textview.connect('populate-popup', self.populate_popup_cb)

        self.update_current_annotation(self.textview, None)

        sw.add(self.textview)

        self.searchbox=gtk.HBox()

        def hide_searchbox(*p):
            # Clear the searched_string tags
            b=self.textview.get_buffer()
            b.remove_tag_by_name("searched_string", *b.get_bounds())
            self.searchbox.hide()
            return True

        close_button=get_pixmap_button('small_close.png', hide_searchbox)
        close_button.set_relief(gtk.RELIEF_NONE)
        self.searchbox.pack_start(close_button, expand=False, fill=False)

        def search_entry_cb(e):
            self.highlight_search_forward(e.get_text())
            return True

        def search_entry_key_press_cb(e, event):
            if event.keyval == gtk.keysyms.Escape:
                hide_searchbox()
                return True
            return False

        self.searchbox.entry=gtk.Entry()
        self.searchbox.entry.connect('activate', search_entry_cb)
        self.searchbox.pack_start(self.searchbox.entry, expand=False, fill=False)
        self.searchbox.entry.connect('key-press-event', search_entry_key_press_cb)

#        def find_next(b):
#            # FIXME
#            return True
#
#        b=get_small_stock_button(gtk.STOCK_GO_FORWARD, find_next)
#        b.set_relief(gtk.RELIEF_NONE)
#        b.set_tooltip_text(_("Find next occurrence"))
#        self.searchbox.pack_start(b, expand=False, fill=False)

        fill=gtk.HBox()
        self.searchbox.pack_start(fill, expand=True, fill=True)

        mainbox.pack_start(self.searchbox, expand=False)

        self.statusbar=gtk.Statusbar()
        self.statusbar.set_has_resize_grip(False)
        mainbox.pack_start(self.statusbar, expand=False)

        mainbox.show_all()

        hide_searchbox()

        # Ignore show_all method to keep the searchbar hidden, and
        # we already did it anyway.
        mainbox.set_no_show_all(True)

        mainbox.connect('key-press-event', self.key_press_event_cb)

        return mainbox
Example #18
0
    def build_widget(self):
        vbox=gtk.VBox()

        self.player = self.controller.playerfactory.get_player()

        self.player.sound_mute()

        self.drawable=gtk.Socket()
        def handle_remove(socket):
            # Do not kill the widget if the application exits
            return True
        self.drawable.connect('plug-removed', handle_remove)

        black=gtk.gdk.Color(0, 0, 0)
        for state in (gtk.STATE_ACTIVE, gtk.STATE_NORMAL,
                      gtk.STATE_SELECTED, gtk.STATE_INSENSITIVE,
                      gtk.STATE_PRELIGHT):
            self.drawable.modify_bg (state, black)

        self.drawable.set_size_request(320, 200)


        self.toolbar=gtk.Toolbar()
        self.toolbar.set_style(gtk.TOOLBAR_ICONS)

        # Append the volume control to the toolbar
        def volume_change(scale, value):
            if self.player.sound_get_volume() != int(value * 100):
                self.player.sound_set_volume(int(value * 100))
            return True

        self.audio_volume = gtk.VolumeButton()
        self.audio_volume.set_value(self.player.sound_get_volume() / 100.0)
        ti = gtk.ToolItem()
        ti.add(self.audio_volume)
        self.audio_volume.connect('value-changed', volume_change)
        self.toolbar.insert(ti, -1)

        sync_button=gtk.ToolButton(gtk.STOCK_CONNECT)
        sync_button.set_tooltip_text(_("Synchronize"))
        sync_button.connect('clicked', self.synchronize)
        self.toolbar.insert(sync_button, -1)

        def offset_changed(spin):
            self.offset = long(spin.get_value())
            return True

        ti = gtk.ToolItem()
        self.offset_spin = gtk.SpinButton(gtk.Adjustment(value = self.offset,
                                                         lower = - 24 * 60 * 60 * 1000,
                                                         upper =   24 * 60 * 60 * 1000,
                                                         step_incr = 1000 / config.data.preferences['default-fps'],
                                                         page_incr = 1000))
        self.offset_spin.get_adjustment().connect('value-changed', offset_changed)
        ti.add(self.offset_spin)
        self.offset_spin.set_tooltip_text(_("Offset in ms"))
        self.toolbar.insert(ti, -1)

        self.label = gtk.Label()
        self.label.set_alignment(0, 0)
        self.label.modify_font(pango.FontDescription("sans 10"))

        timestamp_button = get_pixmap_button('set-to-now.png')
        timestamp_button.set_tooltip_text(_("Drag and drop to get player time"))
        enable_drag_source(timestamp_button, lambda: long(self.player.get_stream_information().position), self.controller)
        # Cannot use a gtk.ToolButton since it cannot be drag_source
        ti = gtk.ToolItem()
        ti.add(timestamp_button)
        self.toolbar.insert(ti, -1)

        black=gtk.gdk.color_parse('black')
        white=gtk.gdk.color_parse('white')
        eb=gtk.EventBox()
        eb.add(self.label)
        for state in (gtk.STATE_ACTIVE, gtk.STATE_NORMAL,
                      gtk.STATE_SELECTED, gtk.STATE_INSENSITIVE,
                      gtk.STATE_PRELIGHT):
            self.label.modify_bg(state, black)
            eb.modify_bg(state, black)
            self.label.modify_fg(state, white)

        vbox.add(self.drawable)
        vbox.pack_start(eb, expand=False)
        vbox.pack_start(self.toolbar, expand=False)

        self.drawable.connect_after('realize', self.register_drawable)

        # Accept annotation/timestamp drop, to adjust time offset
        vbox.connect('drag-data-received', self.drag_received_cb)
        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_COPY | gtk.gdk.ACTION_LINK | gtk.gdk.ACTION_MOVE)

        vbox.show_all()
        return vbox