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('<', '<')) 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)
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('<', '<')) 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)
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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