def add_new_label(self, instance): button_parent = self.info_panel button_parent.remove_widget(self.info_panel.button_layout) self.info_panel.button_layout.clear_widgets() attr_layout = RelativeLayout(size=(100, 30), size_hint=(1, None)) edit_label = EditableLabel(text="", size=(300, 30), size_hint=(None, None), pos_hint={ "center_x": .5, "center_y": .5 }, color=(1, 1, 1, 1), font_size=14) attr_layout.add_widget(edit_label) button_parent.add_widget(attr_layout) edit_label.toggle_edit(edit_label) self.info_panel.button_layout.add_widget( HoverButton(font_size=20, text='New Attribute', size=(500, 30), size_hint=(None, None), pos_hint={"center_x": .5}, button_up=DD_LCHRC[0], button_down=DD_LCHRC[1], on_press=self.add_new_label)) self.info_panel.add_widget(self.info_panel.button_layout)
def create_attr_label(self, attr, editable, group=False): attr_layout = RelativeLayout(size=(100, 30), size_hint=(1, None)) color = (1, 1, 1, 1) bold = manager.menu.get_search_mode( ) != 'name' and manager.menu.get_search_term() != "" if self.color_dark(attr.name, attr.value): color = (1, 1, 1, .6) bold = False label = EditableLabel(text=("" + attr.name + " " + attr.operator + " " + attr.value), attr_category=attr.category, color=color, size=(300, 30), group=group, bold=bold, editable=editable, size_hint=(None, None), pos_hint={ "center_x": .5, "center_y": .5 }, font_size=14) label.name = attr.name label.val = attr.value attr_layout.add_widget(label) self.attribute_labels.append(label) self.layout.add_widget(attr_layout)
def __init__(self, terminal): """Class initialiser""" GObject.GObject.__init__(self) self.terminator = Terminator() self.terminal = terminal self.config = self.terminal.config self.label = EditableLabel() self.label.connect('edit-done', self.on_edit_done) self.ebox = Gtk.EventBox() grouphbox = Gtk.HBox() self.grouplabel = Gtk.Label(ellipsize='end') self.groupicon = Gtk.Image() self.bellicon = Gtk.Image() self.bellicon.set_no_show_all(True) self.groupentry = Gtk.Entry() self.groupentry.set_no_show_all(True) self.groupentry.connect('focus-out-event', self.groupentry_cancel) self.groupentry.connect('activate', self.groupentry_activate) self.groupentry.connect('key-press-event', self.groupentry_keypress) groupsend_type = self.terminator.groupsend_type if self.terminator.groupsend == groupsend_type['all']: icon_name = 'all' elif self.terminator.groupsend == groupsend_type['group']: icon_name = 'group' elif self.terminator.groupsend == groupsend_type['off']: icon_name = 'off' self.set_from_icon_name('_active_broadcast_%s' % icon_name, Gtk.IconSize.MENU) grouphbox.pack_start(self.groupicon, False, True, 2) grouphbox.pack_start(self.grouplabel, False, True, 2) grouphbox.pack_start(self.groupentry, False, True, 2) self.ebox.add(grouphbox) self.ebox.show_all() self.bellicon.set_from_icon_name('terminal-bell', Gtk.IconSize.MENU) viewport = Gtk.Viewport(hscroll_policy='natural') viewport.add(self.label) hbox = Gtk.HBox() hbox.pack_start(self.ebox, False, True, 0) hbox.pack_start(Gtk.VSeparator(), False, True, 0) hbox.pack_start(viewport, True, True, 0) hbox.pack_end(self.bellicon, False, False, 2) self.add(hbox) hbox.show_all() self.set_no_show_all(True) self.show() self.connect('button-press-event', self.on_clicked)
def __init__(self, terminal): """Class initialiser""" gtk.EventBox.__init__(self) self.__gobject_init__() self.terminator = Terminator() self.terminal = terminal self.config = self.terminal.config self.label = EditableLabel() self.label.connect('edit-done', self.on_edit_done) self.ebox = gtk.EventBox() grouphbox = gtk.HBox() self.grouplabel = gtk.Label() self.groupicon = gtk.Image() self.bellicon = gtk.Image() self.bellicon.set_no_show_all(True) self.groupentry = gtk.Entry() self.groupentry.set_no_show_all(True) self.groupentry.connect('focus-out-event', self.groupentry_cancel) self.groupentry.connect('activate', self.groupentry_activate) self.groupentry.connect('key-press-event', self.groupentry_keypress) groupsend_type = self.terminator.groupsend_type if self.terminator.groupsend == groupsend_type['all']: icon_name = 'all' elif self.terminator.groupsend == groupsend_type['group']: icon_name = 'group' elif self.terminator.groupsend == groupsend_type['off']: icon_name = 'off' self.set_from_icon_name('_active_broadcast_%s' % icon_name, gtk.ICON_SIZE_MENU) grouphbox.pack_start(self.groupicon, False, True, 2) grouphbox.pack_start(self.grouplabel, False, True, 2) grouphbox.pack_start(self.groupentry, False, True, 2) self.ebox.add(grouphbox) self.ebox.show_all() self.bellicon.set_from_icon_name('terminal-bell', gtk.ICON_SIZE_MENU) hbox = gtk.HBox() hbox.pack_start(self.ebox, False, True, 0) hbox.pack_start(gtk.VSeparator(), False, True, 0) hbox.pack_start(self.label, True, True) hbox.pack_end(self.bellicon, False, False, 2) self.add(hbox) hbox.show_all() self.set_no_show_all(True) self.show() self.connect('button-press-event', self.on_clicked)
def __init__(self, title, notebook): gtk.HBox.__init__(self) self.notebook = notebook self.config = Config() self.terminal = None self.label = EditableLabel(title) self.update_angle() self.broadcast_image = None self.prefix_box = gtk.HBox() self.pack_start(self.prefix_box, False, False) self.pack_start(self.label, True, True) self.update_button() self.connect('button-press-event', self.show_popupmenu) self.show_all()
def __init__(self, title, notebook): """Class initialiser""" GObject.GObject.__init__(self) self.notebook = notebook self.terminator = Terminator() self.config = Config() self.label = EditableLabel(title) self.update_angle() self.pack_start(self.label, True, True, 0) self.update_button() self.show_all()
def add_new_label(self, group=False): for child in self.layout.children: if type(child) == EditableLabel: if child.text == '': self.layout.remove_widget(child) else: pass if manager.CURRENT_USER != None or manager.CURRENT_GROUP != None: attr_layout = RelativeLayout(size=(100, 30), size_hint=(1, None)) edit_label = EditableLabel(text=(''), pos_hint={ "center_x": .5, "center_y": .5 }, size_hint=(None, None), size=(300, 30), group=group, color=(1, 1, 1, 1), font_size=14) edit_label.name = None edit_label.val = None self.attribute_labels.append(edit_label) attr_layout.add_widget(edit_label) self.layout.add_widget(attr_layout) edit_label.toggle_edit(edit_label)
def __init__(self, title, notebook): """Class initialiser""" GObject.GObject.__init__(self) self.notebook = notebook self.terminator = Terminator() self.config = Config() self.label = EditableLabel(title) self.label.add_events(2097152) # SCROLL self.label.add_events(4194304) # TOUCH self.label.connect('scroll-event', notebook.on_scroll_event) self.update_angle() self.pack_start(self.label, True, True, 0) self.update_button() if self.button: self.button.add_events(2097152) # SCROLL self.button.add_events(4194304) # TOUCH self.button.connect('scroll-event', notebook.on_scroll_event) self.show_all()
def display_preset_info(self, preset): self.info_panel.clear_widgets() if preset == None: return manager.CURRENT_PRESET = preset.name self.show_presets() self.info_panel.add_widget( Label(text=(preset.name), color=(1, 1, 1, 1), font_size=25)) for key in preset.attributes: attr_layout = RelativeLayout(size=(100, 30), size_hint=(1, None)) attr_layout.add_widget( EditableLabel(text=('' + key[0] + ' ' + key[1] + ' ' + preset.attributes[key]), size=(300, 30), attr_category=key[2], size_hint=(None, None), pos_hint={ "center_x": .5, "center_y": .5 }, color=(1, 1, 1, 1), font_size=14)) self.info_panel.add_widget(attr_layout) self.info_panel.button_layout = RelativeLayout(size=(100, 30), size_hint=(1, None)) self.info_panel.button_layout.add_widget( HoverButton(font_size=20, text='New Attribute', size=(500, 30), size_hint=(None, None), pos_hint={"center_x": .5}, button_up=DD_LCHRC[0], button_down=DD_LCHRC[1], on_press=self.add_new_label)) self.info_panel.add_widget(self.info_panel.button_layout)
class Titlebar(Gtk.EventBox): """Class implementing the Titlebar widget""" terminator = None terminal = None config = None oldtitle = None termtext = None sizetext = None label = None ebox = None groupicon = None grouplabel = None groupentry = None bellicon = None __gsignals__ = { 'clicked': (GObject.SignalFlags.RUN_LAST, None, ()), 'edit-done': (GObject.SignalFlags.RUN_LAST, None, ()), 'create-group': (GObject.SignalFlags.RUN_LAST, None, (GObject.TYPE_STRING, )), } def __init__(self, terminal): """Class initialiser""" GObject.GObject.__init__(self) self.terminator = Terminator() self.terminal = terminal self.config = self.terminal.config self.label = EditableLabel() self.label.connect('edit-done', self.on_edit_done) self.ebox = Gtk.EventBox() grouphbox = Gtk.HBox() self.grouplabel = Gtk.Label(ellipsize='end') self.groupicon = Gtk.Image() self.bellicon = Gtk.Image() self.bellicon.set_no_show_all(True) self.groupentry = Gtk.Entry() self.groupentry.set_no_show_all(True) self.groupentry.connect('focus-out-event', self.groupentry_cancel) self.groupentry.connect('activate', self.groupentry_activate) self.groupentry.connect('key-press-event', self.groupentry_keypress) groupsend_type = self.terminator.groupsend_type if self.terminator.groupsend == groupsend_type['all']: icon_name = 'all' elif self.terminator.groupsend == groupsend_type['group']: icon_name = 'group' elif self.terminator.groupsend == groupsend_type['off']: icon_name = 'off' self.set_from_icon_name('_active_broadcast_%s' % icon_name, Gtk.IconSize.MENU) grouphbox.pack_start(self.groupicon, False, True, 2) grouphbox.pack_start(self.grouplabel, False, True, 2) grouphbox.pack_start(self.groupentry, False, True, 2) self.ebox.add(grouphbox) self.ebox.show_all() self.bellicon.set_from_icon_name('terminal-bell', Gtk.IconSize.MENU) viewport = Gtk.Viewport(hscroll_policy='natural') viewport.add(self.label) hbox = Gtk.HBox() hbox.pack_start(self.ebox, False, True, 0) hbox.pack_start(Gtk.VSeparator(), False, True, 0) hbox.pack_start(viewport, True, True, 0) hbox.pack_end(self.bellicon, False, False, 2) self.add(hbox) hbox.show_all() self.set_no_show_all(True) self.show() self.connect('button-press-event', self.on_clicked) def connect_icon(self, func): """Connect the supplied function to clicking on the group icon""" self.ebox.connect('button-press-event', func) def update(self, other=None): """Update our contents""" default_bg = False if self.config['title_hide_sizetext']: self.label.set_text("%s" % self.termtext) else: self.label.set_text("%s %s" % (self.termtext, self.sizetext)) if (not self.config['title_use_system_font'] ) and self.config['title_font']: title_font = Pango.FontDescription(self.config['title_font']) else: title_font = Pango.FontDescription( self.config.get_system_prop_font()) self.label.modify_font(title_font) self.grouplabel.modify_font(title_font) if other: term = self.terminal terminator = self.terminator if other == 'window-focus-out': title_fg = self.config['title_inactive_fg_color'] title_bg = self.config['title_inactive_bg_color'] icon = '_receive_off' default_bg = True group_fg = self.config['title_inactive_fg_color'] group_bg = self.config['title_inactive_bg_color'] elif term != other and term.group and term.group == other.group: if terminator.groupsend == terminator.groupsend_type['off']: title_fg = self.config['title_inactive_fg_color'] title_bg = self.config['title_inactive_bg_color'] icon = '_receive_off' default_bg = True else: title_fg = self.config['title_receive_fg_color'] title_bg = self.config['title_receive_bg_color'] icon = '_receive_on' group_fg = self.config['title_receive_fg_color'] group_bg = self.config['title_receive_bg_color'] elif term != other and not term.group or term.group != other.group: if terminator.groupsend == terminator.groupsend_type['all']: title_fg = self.config['title_receive_fg_color'] title_bg = self.config['title_receive_bg_color'] icon = '_receive_on' else: title_fg = self.config['title_inactive_fg_color'] title_bg = self.config['title_inactive_bg_color'] icon = '_receive_off' default_bg = True group_fg = self.config['title_inactive_fg_color'] group_bg = self.config['title_inactive_bg_color'] else: # We're the active terminal title_fg = self.config['title_transmit_fg_color'] title_bg = self.config['title_transmit_bg_color'] if terminator.groupsend == terminator.groupsend_type['all']: icon = '_active_broadcast_all' elif terminator.groupsend == terminator.groupsend_type[ 'group']: icon = '_active_broadcast_group' else: icon = '_active_broadcast_off' group_fg = self.config['title_transmit_fg_color'] group_bg = self.config['title_transmit_bg_color'] self.label.modify_fg(Gtk.StateType.NORMAL, Gdk.color_parse(title_fg)) self.grouplabel.modify_fg(Gtk.StateType.NORMAL, Gdk.color_parse(group_fg)) self.modify_bg(Gtk.StateType.NORMAL, Gdk.color_parse(title_bg)) if not self.get_desired_visibility(): if default_bg == True: color = term.get_style_context().get_background_color( Gtk.StateType.NORMAL) # VERIFY FOR GTK3 else: color = Gdk.color_parse(title_bg) self.update_visibility() self.ebox.modify_bg(Gtk.StateType.NORMAL, Gdk.color_parse(group_bg)) self.set_from_icon_name(icon, Gtk.IconSize.MENU) def update_visibility(self): """Make the titlebar be visible or not""" if not self.get_desired_visibility(): dbg('hiding titlebar') self.hide() self.label.hide() else: dbg('showing titlebar') self.show() self.label.show() def get_desired_visibility(self): """Returns True if the titlebar is supposed to be visible. False if not""" if self.editing() == True or self.terminal.group: dbg('implicit desired visibility') return (True) else: dbg('configured visibility: %s' % self.config['show_titlebar']) return (self.config['show_titlebar']) def set_from_icon_name(self, name, size=Gtk.IconSize.MENU): """Set an icon for the group label""" if not name: self.groupicon.hide() return self.groupicon.set_from_icon_name(APP_NAME + name, size) self.groupicon.show() def update_terminal_size(self, width, height): """Update the displayed terminal size""" self.sizetext = "%sx%s" % (width, height) self.update() def set_terminal_title(self, widget, title): """Update the terminal title""" self.termtext = title self.update() # Return False so we don't interrupt any chains of signal handling return False def set_group_label(self, name): """Set the name of the group""" if name: self.grouplabel.set_text(name) self.grouplabel.show() else: self.grouplabel.set_text('') self.grouplabel.hide() self.update_visibility() def on_clicked(self, widget, event): """Handle a click on the label""" self.show() self.label.show() self.emit('clicked') def on_edit_done(self, widget): """Re-emit an edit-done signal from an EditableLabel""" self.emit('edit-done') def editing(self): """Determine if we're currently editing a group name or title""" return (self.groupentry.get_property('visible') or self.label.editing()) def create_group(self): """Create a new group""" if self.terminal.group: self.groupentry.set_text(self.terminal.group) else: defaultmembers = [ _('Alpha'), _('Beta'), _('Gamma'), _('Delta'), _('Epsilon'), _('Zeta'), _('Eta'), _('Theta'), _('Iota'), _('Kappa'), _('Lambda'), _('Mu'), _('Nu'), _('Xi'), _('Omicron'), _('Pi'), _('Rho'), _('Sigma'), _('Tau'), _('Upsilon'), _('Phi'), _('Chi'), _('Psi'), _('Omega') ] currentgroups = set(self.terminator.groups) for i in range(1, 4): defaultgroups = set( map(''.join, list(itertools.product(defaultmembers, repeat=i)))) freegroups = list(defaultgroups - currentgroups) if freegroups: self.groupentry.set_text(random.choice(freegroups)) break else: self.groupentry.set_text('') self.groupentry.show() self.grouplabel.hide() self.groupentry.grab_focus() self.update_visibility() def groupentry_cancel(self, widget, event): """Hide the group name entry""" self.groupentry.set_text('') self.groupentry.hide() self.grouplabel.show() self.get_parent().grab_focus() def groupentry_activate(self, widget): """Actually cause a group to be created""" groupname = self.groupentry.get_text() or None dbg('Titlebar::groupentry_activate: creating group: %s' % groupname) self.groupentry_cancel(None, None) last_focused_term = self.terminator.last_focused_term if self.terminal.targets_for_new_group: [ term.titlebar.emit('create-group', groupname) for term in self.terminal.targets_for_new_group ] self.terminal.targets_for_new_group = None else: self.emit('create-group', groupname) last_focused_term.grab_focus() self.terminator.focus_changed(last_focused_term) def groupentry_keypress(self, widget, event): """Handle keypresses on the entry widget""" key = Gdk.keyval_name(event.keyval) if key == 'Escape': self.groupentry_cancel(None, None) def icon_bell(self): """A bell signal requires we display our bell icon""" self.bellicon.show() GObject.timeout_add(1000, self.icon_bell_hide) def icon_bell_hide(self): """Handle a timeout which means we now hide the bell icon""" self.bellicon.hide() return (False) def get_custom_string(self): """If we have a custom string set, return it, otherwise None""" if self.label.is_custom(): return (self.label.get_text()) else: return (None) def set_custom_string(self, string): """Set a custom string""" self.label.set_text(string) self.label.set_custom()
class GshellTabLabel(gtk.HBox): __gsignals__ = { 'close-clicked': (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, (gobject.TYPE_OBJECT, )), } def __init__(self, title, notebook): gtk.HBox.__init__(self) self.notebook = notebook self.config = Config() self.terminal = None self.label = EditableLabel(title) self.update_angle() self.broadcast_image = None self.prefix_box = gtk.HBox() self.pack_start(self.prefix_box, False, False) self.pack_start(self.label, True, True) self.update_button() self.connect('button-press-event', self.show_popupmenu) self.show_all() def show_popupmenu(self, widget, event): if event.type == gtk.gdk.BUTTON_PRESS and event.button == 3 and self.terminal: popupmenu = GshellTabPopupMenu(tablabel=self, notebook=self.notebook) popupmenu.popup(None, None, None, event.button, event.time) return False def on_enable_broadcast(self, widget, *args): if self.terminal: self.terminal.emit('enable-broadcast', self) def enable_log(self, widget, *args): if self.terminal and self.terminal.logger: if self.terminal.logger.logging: self.terminal.logger.stop_logger() else: if self.terminal.host and self.terminal.host['log']: self.terminal.logger.start_logger( self.terminal.host['log']) else: self.terminal.logger.start_logger() def update_button(self): self.button = gtk.Button() self.icon = gtk.Image() self.icon.set_from_stock(gtk.STOCK_CLOSE, gtk.ICON_SIZE_MENU) self.button.set_focus_on_click(False) self.button.set_relief(gtk.RELIEF_NONE) style = gtk.RcStyle() style.xthickness = 0 style.ythickness = 0 self.button.modify_style(style) self.button.add(self.icon) self.button.connect('clicked', self.on_close) self.button.set_name('tab-close-button') if hasattr(self.button, 'set_tooltip_text'): self.button.set_tooltip_text('Close Tab') self.pack_start(self.button, False, False) self.show_all() def update_angle(self): """Update the angle of a label""" position = self.notebook.get_tab_pos() if position == gtk.POS_LEFT: if hasattr(self, 'set_orientation'): self.set_orientation(gtk.ORIENTATION_VERTICAL) self.label.set_angle(90) elif position == gtk.POS_RIGHT: if hasattr(self, 'set_orientation'): self.set_orientation(gtk.ORIENTATION_VERTICAL) self.label.set_angle(270) else: if hasattr(self, 'set_orientation'): self.set_orientation(gtk.ORIENTATION_HORIZONTAL) self.label.set_angle(0) def on_close(self, widget, data=None): print 'GshellTabLabel::on_close called' self.emit('close-clicked', self) def mark_close(self): text = self.label._label.get_text() self.label._label.set_markup( "<span color='darkgray' strikethrough='true'>%s</span>" % text) def unmark_close(self): text = self.label._label.get_text() self.label.set_text(text)
class GshellTabLabel(gtk.HBox): __gsignals__ = { 'close-clicked': (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE,(gobject.TYPE_OBJECT,)), } def __init__(self, title, notebook): gtk.HBox.__init__(self) self.notebook = notebook self.config = Config() self.terminal = None self.label = EditableLabel(title) self.update_angle() self.broadcast_image = None self.prefix_box = gtk.HBox() self.pack_start(self.prefix_box, False, False) self.pack_start(self.label, True, True) self.update_button() self.connect('button-press-event', self.show_popupmenu) self.show_all() def show_popupmenu(self, widget, event): if event.type == gtk.gdk.BUTTON_PRESS and event.button == 3 and self.terminal: popupmenu = GshellTabPopupMenu(tablabel=self, notebook=self.notebook) popupmenu.popup(None, None, None, event.button, event.time) return False def on_enable_broadcast(self, widget, *args): if self.terminal: self.terminal.emit('enable-broadcast', self) def enable_log(self, widget, *args): if self.terminal and self.terminal.logger: if self.terminal.logger.logging: self.terminal.logger.stop_logger() else: if self.terminal.host and self.terminal.host['log']: self.terminal.logger.start_logger(self.terminal.host['log']) else: self.terminal.logger.start_logger() def update_button(self): self.button = gtk.Button() self.icon = gtk.Image() self.icon.set_from_stock(gtk.STOCK_CLOSE, gtk.ICON_SIZE_MENU) self.button.set_focus_on_click(False) self.button.set_relief(gtk.RELIEF_NONE) style = gtk.RcStyle() style.xthickness = 0 style.ythickness = 0 self.button.modify_style(style) self.button.add(self.icon) self.button.connect('clicked', self.on_close) self.button.set_name('tab-close-button') if hasattr(self.button, 'set_tooltip_text'): self.button.set_tooltip_text('Close Tab') self.pack_start(self.button, False, False) self.show_all() def update_angle(self): """Update the angle of a label""" position = self.notebook.get_tab_pos() if position == gtk.POS_LEFT: if hasattr(self, 'set_orientation'): self.set_orientation(gtk.ORIENTATION_VERTICAL) self.label.set_angle(90) elif position == gtk.POS_RIGHT: if hasattr(self, 'set_orientation'): self.set_orientation(gtk.ORIENTATION_VERTICAL) self.label.set_angle(270) else: if hasattr(self, 'set_orientation'): self.set_orientation(gtk.ORIENTATION_HORIZONTAL) self.label.set_angle(0) def on_close(self, widget, data=None): print 'GshellTabLabel::on_close called' self.emit('close-clicked', self) def mark_close(self): text = self.label._label.get_text() self.label._label.set_markup("<span color='darkgray' strikethrough='true'>%s</span>" % text) def unmark_close(self): text = self.label._label.get_text() self.label.set_text(text)
class TabLabel(gtk.HBox): """Class implementing a label widget for Notebook tabs""" notebook = None terminator = None config = None label = None icon = None button = None __gsignals__ = { 'close-clicked': (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, (gobject.TYPE_OBJECT, )), } def __init__(self, title, notebook): """Class initialiser""" gtk.HBox.__init__(self) self.__gobject_init__() self.notebook = notebook self.terminator = Terminator() self.config = Config() self.label = EditableLabel(title) self.update_angle() self.pack_start(self.label, True, True) self.update_button() self.show_all() def set_label(self, text): """Update the text of our label""" self.label.set_text(text) def get_label(self): return self.label.get_text() def set_custom_label(self, text): """Set a permanent label as if the user had edited it""" self.label.set_text(text) self.label.set_custom() def get_custom_label(self): """Return a custom label if we have one, otherwise None""" if self.label.is_custom(): return (self.label.get_text()) else: return (None) def update_button(self): """Update the state of our close button""" if not self.config['close_button_on_tab']: if self.button: self.button.remove(self.icon) self.remove(self.button) del (self.button) del (self.icon) self.button = None self.icon = None return if not self.button: self.button = gtk.Button() if not self.icon: self.icon = gtk.Image() self.icon.set_from_stock(gtk.STOCK_CLOSE, gtk.ICON_SIZE_MENU) self.button.set_focus_on_click(False) self.button.set_relief(gtk.RELIEF_NONE) style = gtk.RcStyle() style.xthickness = 0 style.ythickness = 0 self.button.modify_style(style) self.button.add(self.icon) self.button.connect('clicked', self.on_close) self.button.set_name('terminator-tab-close-button') if hasattr(self.button, 'set_tooltip_text'): self.button.set_tooltip_text(_('Close Tab')) self.pack_start(self.button, False, False) self.show_all() def update_angle(self): """Update the angle of a label""" position = self.notebook.get_tab_pos() if position == gtk.POS_LEFT: if hasattr(self, 'set_orientation'): self.set_orientation(gtk.ORIENTATION_VERTICAL) self.label.set_angle(90) elif position == gtk.POS_RIGHT: if hasattr(self, 'set_orientation'): self.set_orientation(gtk.ORIENTATION_VERTICAL) self.label.set_angle(270) else: if hasattr(self, 'set_orientation'): self.set_orientation(gtk.ORIENTATION_HORIZONTAL) self.label.set_angle(0) def on_close(self, _widget): """The close button has been clicked. Destroy the tab""" self.emit('close-clicked', self)
class TabLabel(Gtk.HBox): """Class implementing a label widget for Notebook tabs""" notebook = None terminator = None config = None label = None icon = None button = None __gsignals__ = { 'close-clicked': (GObject.SignalFlags.RUN_LAST, None, (GObject.TYPE_OBJECT, )), } def __init__(self, title, notebook): """Class initialiser""" GObject.GObject.__init__(self) self.notebook = notebook self.terminator = Terminator() self.config = Config() self.label = EditableLabel(title) self.label.connect("button-press-event", self.on_title_click) self.update_angle() self.pack_start(self.label, True, True, 0) self.update_button() self.show_all() def set_label(self, text): """Update the text of our label""" self.label.set_text(text) def get_label(self): return self.label.get_text() def set_custom_label(self, text): """Set a permanent label as if the user had edited it""" self.label.set_text(text) self.label.set_custom() def get_custom_label(self): """Return a custom label if we have one, otherwise None""" if self.label.is_custom(): return (self.label.get_text()) else: return (None) def edit(self): self.label.edit() def update_button(self): """Update the state of our close button""" if not self.config['close_button_on_tab']: if self.button: self.button.remove(self.icon) self.remove(self.button) del (self.button) del (self.icon) self.button = None self.icon = None return if not self.button: self.button = Gtk.Button() if not self.icon: self.icon = Gio.ThemedIcon.new_with_default_fallbacks( "window-close-symbolic") self.icon = Gtk.Image.new_from_gicon(self.icon, Gtk.IconSize.MENU) self.button.set_focus_on_click(False) self.button.set_relief(Gtk.ReliefStyle.NONE) # style = Gtk.RcStyle() # FIXME FOR GTK3 how to do it there? actually do we really want to override the theme? # style.xthickness = 0 # style.ythickness = 0 # self.button.modify_style(style) self.button.add(self.icon) self.button.connect('clicked', self.on_close) self.button.set_name('terminator-tab-close-button') if hasattr(self.button, 'set_tooltip_text'): self.button.set_tooltip_text(_('Close Tab')) self.pack_start(self.button, False, False, 0) self.show_all() def update_angle(self): """Update the angle of a label""" position = self.notebook.get_tab_pos() if position == Gtk.PositionType.LEFT: if hasattr(self, 'set_orientation'): self.set_orientation(Gtk.Orientation.VERTICAL) self.label.set_angle(90) elif position == Gtk.PositionType.RIGHT: if hasattr(self, 'set_orientation'): self.set_orientation(Gtk.Orientation.VERTICAL) self.label.set_angle(270) else: if hasattr(self, 'set_orientation'): self.set_orientation(Gtk.Orientation.HORIZONTAL) self.label.set_angle(0) def on_close(self, _widget): """The close button has been clicked. Destroy the tab""" self.emit('close-clicked', self) def on_title_click(self, widget, event): """The tab label was clicked. This is probably not the best way to do it, but it works.""" if event.button == 2: self.emit('close-clicked', self)
class Titlebar(Gtk.EventBox): """Class implementing the Titlebar widget""" terminator = None terminal = None config = None oldtitle = None termtext = None sizetext = None label = None ebox = None groupicon = None grouplabel = None groupentry = None bellicon = None __gsignals__ = { 'clicked': (GObject.SignalFlags.RUN_LAST, None, ()), 'edit-done': (GObject.SignalFlags.RUN_LAST, None, ()), 'create-group': (GObject.SignalFlags.RUN_LAST, None, (GObject.TYPE_STRING,)), } def __init__(self, terminal): """Class initialiser""" GObject.GObject.__init__(self) self.terminator = Terminator() self.terminal = terminal self.config = self.terminal.config self.label = EditableLabel() self.label.connect('edit-done', self.on_edit_done) self.ebox = Gtk.EventBox() grouphbox = Gtk.HBox() self.grouplabel = Gtk.Label(ellipsize='end') self.groupicon = Gtk.Image() self.bellicon = Gtk.Image() self.bellicon.set_no_show_all(True) self.groupentry = Gtk.Entry() self.groupentry.set_no_show_all(True) self.groupentry.connect('focus-out-event', self.groupentry_cancel) self.groupentry.connect('activate', self.groupentry_activate) self.groupentry.connect('key-press-event', self.groupentry_keypress) groupsend_type = self.terminator.groupsend_type if self.terminator.groupsend == groupsend_type['all']: icon_name = 'all' elif self.terminator.groupsend == groupsend_type['group']: icon_name = 'group' elif self.terminator.groupsend == groupsend_type['off']: icon_name = 'off' self.set_from_icon_name('_active_broadcast_%s' % icon_name, Gtk.IconSize.MENU) grouphbox.pack_start(self.groupicon, False, True, 2) grouphbox.pack_start(self.grouplabel, False, True, 2) grouphbox.pack_start(self.groupentry, False, True, 2) self.ebox.add(grouphbox) self.ebox.show_all() self.bellicon.set_from_icon_name('terminal-bell', Gtk.IconSize.MENU) viewport = Gtk.Viewport(hscroll_policy='natural') viewport.add(self.label) hbox = Gtk.HBox() hbox.pack_start(self.ebox, False, True, 0) hbox.pack_start(Gtk.VSeparator(), False, True, 0) hbox.pack_start(viewport, True, True, 0) hbox.pack_end(self.bellicon, False, False, 2) self.add(hbox) hbox.show_all() self.set_no_show_all(True) self.show() self.connect('button-press-event', self.on_clicked) def connect_icon(self, func): """Connect the supplied function to clicking on the group icon""" self.ebox.connect('button-press-event', func) def update(self, other=None): """Update our contents""" default_bg = False if self.config['title_hide_sizetext']: self.label.set_text("%s" % self.termtext) else: self.label.set_text("%s %s" % (self.termtext, self.sizetext)) if (not self.config['title_use_system_font']) and self.config['title_font']: title_font = Pango.FontDescription(self.config['title_font']) else: title_font = Pango.FontDescription(self.config.get_system_prop_font()) self.label.modify_font(title_font) self.grouplabel.modify_font(title_font) if other: term = self.terminal terminator = self.terminator if other == 'window-focus-out': title_fg = self.config['title_inactive_fg_color'] title_bg = self.config['title_inactive_bg_color'] icon = '_receive_off' default_bg = True group_fg = self.config['title_inactive_fg_color'] group_bg = self.config['title_inactive_bg_color'] elif term != other and term.group and term.group == other.group: if terminator.groupsend == terminator.groupsend_type['off']: title_fg = self.config['title_inactive_fg_color'] title_bg = self.config['title_inactive_bg_color'] icon = '_receive_off' default_bg = True else: title_fg = self.config['title_receive_fg_color'] title_bg = self.config['title_receive_bg_color'] icon = '_receive_on' group_fg = self.config['title_receive_fg_color'] group_bg = self.config['title_receive_bg_color'] elif term != other and not term.group or term.group != other.group: if terminator.groupsend == terminator.groupsend_type['all']: title_fg = self.config['title_receive_fg_color'] title_bg = self.config['title_receive_bg_color'] icon = '_receive_on' else: title_fg = self.config['title_inactive_fg_color'] title_bg = self.config['title_inactive_bg_color'] icon = '_receive_off' default_bg = True group_fg = self.config['title_inactive_fg_color'] group_bg = self.config['title_inactive_bg_color'] else: # We're the active terminal title_fg = self.config['title_transmit_fg_color'] title_bg = self.config['title_transmit_bg_color'] if terminator.groupsend == terminator.groupsend_type['all']: icon = '_active_broadcast_all' elif terminator.groupsend == terminator.groupsend_type['group']: icon = '_active_broadcast_group' else: icon = '_active_broadcast_off' group_fg = self.config['title_transmit_fg_color'] group_bg = self.config['title_transmit_bg_color'] self.label.modify_fg(Gtk.StateType.NORMAL, Gdk.color_parse(title_fg)) self.grouplabel.modify_fg(Gtk.StateType.NORMAL, Gdk.color_parse(group_fg)) self.modify_bg(Gtk.StateType.NORMAL, Gdk.color_parse(title_bg)) if not self.get_desired_visibility(): if default_bg == True: color = term.get_style_context().get_background_color(Gtk.StateType.NORMAL) # VERIFY FOR GTK3 else: color = Gdk.color_parse(title_bg) self.update_visibility() self.ebox.modify_bg(Gtk.StateType.NORMAL, Gdk.color_parse(group_bg)) self.set_from_icon_name(icon, Gtk.IconSize.MENU) def update_visibility(self): """Make the titlebar be visible or not""" if not self.get_desired_visibility(): dbg('hiding titlebar') self.hide() self.label.hide() else: dbg('showing titlebar') self.show() self.label.show() def get_desired_visibility(self): """Returns True if the titlebar is supposed to be visible. False if not""" if self.editing() == True or self.terminal.group: dbg('implicit desired visibility') return(True) else: dbg('configured visibility: %s' % self.config['show_titlebar']) return(self.config['show_titlebar']) def set_from_icon_name(self, name, size = Gtk.IconSize.MENU): """Set an icon for the group label""" if not name: self.groupicon.hide() return self.groupicon.set_from_icon_name(APP_NAME + name, size) self.groupicon.show() def update_terminal_size(self, width, height): """Update the displayed terminal size""" self.sizetext = "%sx%s" % (width, height) self.update() def set_terminal_title(self, widget, title): """Update the terminal title""" self.termtext = title self.update() # Return False so we don't interrupt any chains of signal handling return False def set_group_label(self, name): """Set the name of the group""" if name: self.grouplabel.set_text(name) self.grouplabel.show() else: self.grouplabel.set_text('') self.grouplabel.hide() self.update_visibility() def on_clicked(self, widget, event): """Handle a click on the label""" self.show() self.label.show() self.emit('clicked') def on_edit_done(self, widget): """Re-emit an edit-done signal from an EditableLabel""" self.emit('edit-done') def editing(self): """Determine if we're currently editing a group name or title""" return(self.groupentry.get_property('visible') or self.label.editing()) def create_group(self): """Create a new group""" if self.terminal.group: self.groupentry.set_text(self.terminal.group) else: defaultmembers=[_('Alpha'),_('Beta'),_('Gamma'),_('Delta'),_('Epsilon'),_('Zeta'),_('Eta'), _('Theta'),_('Iota'),_('Kappa'),_('Lambda'),_('Mu'),_('Nu'),_('Xi'), _('Omicron'),_('Pi'),_('Rho'),_('Sigma'),_('Tau'),_('Upsilon'),_('Phi'), _('Chi'),_('Psi'),_('Omega')] currentgroups=set(self.terminator.groups) for i in range(1,4): defaultgroups=set(map(''.join, list(itertools.product(defaultmembers,repeat=i)))) freegroups = list(defaultgroups-currentgroups) if freegroups: self.groupentry.set_text(random.choice(freegroups)) break else: self.groupentry.set_text('') self.groupentry.show() self.grouplabel.hide() self.groupentry.grab_focus() self.update_visibility() def groupentry_cancel(self, widget, event): """Hide the group name entry""" self.groupentry.set_text('') self.groupentry.hide() self.grouplabel.show() self.get_parent().grab_focus() def groupentry_activate(self, widget): """Actually cause a group to be created""" groupname = self.groupentry.get_text() or None dbg('Titlebar::groupentry_activate: creating group: %s' % groupname) self.groupentry_cancel(None, None) last_focused_term=self.terminator.last_focused_term if self.terminal.targets_for_new_group: [term.titlebar.emit('create-group', groupname) for term in self.terminal.targets_for_new_group] self.terminal.targets_for_new_group = None else: self.emit('create-group', groupname) last_focused_term.grab_focus() self.terminator.focus_changed(last_focused_term) def groupentry_keypress(self, widget, event): """Handle keypresses on the entry widget""" key = Gdk.keyval_name(event.keyval) if key == 'Escape': self.groupentry_cancel(None, None) def icon_bell(self): """A bell signal requires we display our bell icon""" self.bellicon.show() GObject.timeout_add(1000, self.icon_bell_hide) def icon_bell_hide(self): """Handle a timeout which means we now hide the bell icon""" self.bellicon.hide() return(False) def get_custom_string(self): """If we have a custom string set, return it, otherwise None""" if self.label.is_custom(): return(self.label.get_text()) else: return(None) def set_custom_string(self, string): """Set a custom string""" self.label.set_text(string) self.label.set_custom()
class Titlebar(gtk.EventBox): """Class implementing the Titlebar widget""" terminator = None terminal = None config = None oldtitle = None termtext = None sizetext = None label = None ebox = None groupicon = None grouplabel = None groupentry = None bellicon = None __gsignals__ = { 'clicked': (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, ()), 'edit-done': (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, ()), 'create-group': (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, (gobject.TYPE_STRING, )), } def __init__(self, terminal): """Class initialiser""" gtk.EventBox.__init__(self) self.__gobject_init__() self.terminator = Terminator() self.terminal = terminal self.config = self.terminal.config self.label = EditableLabel() self.label.connect('edit-done', self.on_edit_done) self.ebox = gtk.EventBox() grouphbox = gtk.HBox() self.grouplabel = gtk.Label() self.groupicon = gtk.Image() self.bellicon = gtk.Image() self.bellicon.set_no_show_all(True) self.groupentry = gtk.Entry() self.groupentry.set_no_show_all(True) self.groupentry.connect('focus-out-event', self.groupentry_cancel) self.groupentry.connect('activate', self.groupentry_activate) self.groupentry.connect('key-press-event', self.groupentry_keypress) groupsend_type = self.terminator.groupsend_type if self.terminator.groupsend == groupsend_type['all']: icon_name = 'all' elif self.terminator.groupsend == groupsend_type['group']: icon_name = 'group' elif self.terminator.groupsend == groupsend_type['off']: icon_name = 'off' self.set_from_icon_name('_active_broadcast_%s' % icon_name, gtk.ICON_SIZE_MENU) grouphbox.pack_start(self.groupicon, False, True, 2) grouphbox.pack_start(self.grouplabel, False, True, 2) grouphbox.pack_start(self.groupentry, False, True, 2) self.ebox.add(grouphbox) self.ebox.show_all() self.bellicon.set_from_icon_name('terminal-bell', gtk.ICON_SIZE_MENU) hbox = gtk.HBox() hbox.pack_start(self.ebox, False, True, 0) hbox.pack_start(gtk.VSeparator(), False, True, 0) hbox.pack_start(self.label, True, True) hbox.pack_end(self.bellicon, False, False, 2) self.add(hbox) hbox.show_all() self.set_no_show_all(True) self.show() self.connect('button-press-event', self.on_clicked) def connect_icon(self, func): """Connect the supplied function to clicking on the group icon""" self.ebox.connect('button-release-event', func) def update(self, other=None): """Update our contents""" default_bg = False if self.config['title_hide_sizetext']: self.label.set_text("%s" % self.termtext) else: self.label.set_text("%s %s" % (self.termtext, self.sizetext)) if other: term = self.terminal terminator = self.terminator if other == 'window-focus-out': title_fg = self.config['title_inactive_fg_color'] title_bg = self.config['title_inactive_bg_color'] icon = '_receive_off' default_bg = True group_fg = self.config['title_inactive_fg_color'] group_bg = self.config['title_inactive_bg_color'] elif term != other and term.group and term.group == other.group: if terminator.groupsend == terminator.groupsend_type['off']: title_fg = self.config['title_inactive_fg_color'] title_bg = self.config['title_inactive_bg_color'] icon = '_receive_off' default_bg = True else: title_fg = self.config['title_receive_fg_color'] title_bg = self.config['title_receive_bg_color'] icon = '_receive_on' group_fg = self.config['title_receive_fg_color'] group_bg = self.config['title_receive_bg_color'] elif term != other and not term.group or term.group != other.group: if terminator.groupsend == terminator.groupsend_type['all']: title_fg = self.config['title_receive_fg_color'] title_bg = self.config['title_receive_bg_color'] icon = '_receive_on' else: title_fg = self.config['title_inactive_fg_color'] title_bg = self.config['title_inactive_bg_color'] icon = '_receive_off' default_bg = True group_fg = self.config['title_inactive_fg_color'] group_bg = self.config['title_inactive_bg_color'] else: # We're the active terminal title_fg = self.config['title_transmit_fg_color'] title_bg = self.config['title_transmit_bg_color'] if terminator.groupsend == terminator.groupsend_type['all']: icon = '_active_broadcast_all' elif terminator.groupsend == terminator.groupsend_type[ 'group']: icon = '_active_broadcast_group' else: icon = '_active_broadcast_off' group_fg = self.config['title_transmit_fg_color'] group_bg = self.config['title_transmit_bg_color'] self.label.modify_fg(gtk.STATE_NORMAL, gtk.gdk.color_parse(title_fg)) self.grouplabel.modify_fg(gtk.STATE_NORMAL, gtk.gdk.color_parse(group_fg)) self.modify_bg(gtk.STATE_NORMAL, gtk.gdk.color_parse(title_bg)) if not self.get_desired_visibility(): if default_bg == True: color = term.get_style().bg[gtk.STATE_NORMAL] else: color = gtk.gdk.color_parse(title_bg) self.update_visibility() self.ebox.modify_bg(gtk.STATE_NORMAL, gtk.gdk.color_parse(group_bg)) self.set_from_icon_name(icon, gtk.ICON_SIZE_MENU) def update_visibility(self): """Make the titlebar be visible or not""" if not self.get_desired_visibility(): dbg('hiding titlebar') self.hide() self.label.hide() else: dbg('showing titlebar') self.show() self.label.show() def get_desired_visibility(self): """Returns True if the titlebar is supposed to be visible. False if not""" if self.editing() == True or self.terminal.group: dbg('implicit desired visibility') return (True) else: dbg('configured visibility: %s' % self.config['show_titlebar']) return (self.config['show_titlebar']) def set_from_icon_name(self, name, size=gtk.ICON_SIZE_MENU): """Set an icon for the group label""" if not name: self.groupicon.hide() return self.groupicon.set_from_icon_name(APP_NAME + name, size) self.groupicon.show() def update_terminal_size(self, width, height): """Update the displayed terminal size""" self.sizetext = "%sx%s" % (width, height) self.update() def set_terminal_title(self, widget, title): """Update the terminal title""" self.termtext = title self.update() # Return False so we don't interrupt any chains of signal handling return False def set_group_label(self, name): """Set the name of the group""" if name: self.grouplabel.set_text(name) self.grouplabel.show() else: self.grouplabel.hide() self.update_visibility() def on_clicked(self, widget, event): """Handle a click on the label""" self.show() self.label.show() self.emit('clicked') def on_edit_done(self, widget): """Re-emit an edit-done signal from an EditableLabel""" self.emit('edit-done') def editing(self): """Determine if we're currently editing a group name or title""" return (self.groupentry.get_property('visible') or self.label.editing()) def create_group(self): """Create a new group""" self.groupentry.show() self.groupentry.grab_focus() self.update_visibility() def groupentry_cancel(self, widget, event): """Hide the group name entry""" self.groupentry.set_text('') self.groupentry.hide() self.get_parent().grab_focus() def groupentry_activate(self, widget): """Actually cause a group to be created""" groupname = self.groupentry.get_text() dbg('Titlebar::groupentry_activate: creating group: %s' % groupname) self.groupentry_cancel(None, None) self.emit('create-group', groupname) def groupentry_keypress(self, widget, event): """Handle keypresses on the entry widget""" key = gtk.gdk.keyval_name(event.keyval) if key == 'Escape': self.groupentry_cancel(None, None) def icon_bell(self): """A bell signal requires we display our bell icon""" self.bellicon.show() gobject.timeout_add(1000, self.icon_bell_hide) def icon_bell_hide(self): """Handle a timeout which means we now hide the bell icon""" self.bellicon.hide() return (False) def get_custom_string(self): """If we have a custom string set, return it, otherwise None""" if self.label.is_custom(): return (self.label.get_text()) else: return (None) def set_custom_string(self, string): """Set a custom string""" self.label.set_text(string) self.label.set_custom()
class TabLabel(Gtk.HBox): """Class implementing a label widget for Notebook tabs""" notebook = None terminator = None config = None label = None icon = None button = None __gsignals__ = { 'close-clicked': (GObject.SignalFlags.RUN_LAST, None, (GObject.TYPE_OBJECT,)), } def __init__(self, title, notebook): """Class initialiser""" GObject.GObject.__init__(self) self.notebook = notebook self.terminator = Terminator() self.config = Config() self.label = EditableLabel(title) self.update_angle() self.pack_start(self.label, True, True, 0) self.update_button() self.show_all() def set_label(self, text): """Update the text of our label""" self.label.set_text(text) def get_label(self): return self.label.get_text() def set_custom_label(self, text): """Set a permanent label as if the user had edited it""" self.label.set_text(text) self.label.set_custom() def get_custom_label(self): """Return a custom label if we have one, otherwise None""" if self.label.is_custom(): return(self.label.get_text()) else: return(None) def edit(self): self.label.edit() def update_button(self): """Update the state of our close button""" if not self.config['close_button_on_tab']: if self.button: self.button.remove(self.icon) self.remove(self.button) del(self.button) del(self.icon) self.button = None self.icon = None return if not self.button: self.button = Gtk.Button() if not self.icon: self.icon = Gio.ThemedIcon.new_with_default_fallbacks("window-close-symbolic") self.icon = Gtk.Image.new_from_gicon(self.icon, Gtk.IconSize.MENU) self.button.set_focus_on_click(False) self.button.set_relief(Gtk.ReliefStyle.NONE) # style = Gtk.RcStyle() # FIXME FOR GTK3 how to do it there? actually do we really want to override the theme? # style.xthickness = 0 # style.ythickness = 0 # self.button.modify_style(style) self.button.add(self.icon) self.button.connect('clicked', self.on_close) self.button.set_name('terminator-tab-close-button') if hasattr(self.button, 'set_tooltip_text'): self.button.set_tooltip_text(_('Close Tab')) self.pack_start(self.button, False, False, 0) self.show_all() def update_angle(self): """Update the angle of a label""" position = self.notebook.get_tab_pos() if position == Gtk.PositionType.LEFT: if hasattr(self, 'set_orientation'): self.set_orientation(Gtk.Orientation.VERTICAL) self.label.set_angle(90) elif position == Gtk.PositionType.RIGHT: if hasattr(self, 'set_orientation'): self.set_orientation(Gtk.Orientation.VERTICAL) self.label.set_angle(270) else: if hasattr(self, 'set_orientation'): self.set_orientation(Gtk.Orientation.HORIZONTAL) self.label.set_angle(0) def on_close(self, _widget): """The close button has been clicked. Destroy the tab""" self.emit('close-clicked', self)
class Titlebar(Gtk.EventBox): """Class implementing the Titlebar widget""" terminator = None terminal = None config = None oldtitle = None termtext = None label = None ebox = None groupicon = None grouplabel = None groupentry = None bellicon = None _autotext = '' _tsize = '' _tabcapt = '' sizetext = '' titlefixed = False # True # False custom_title = '' # raw _ctitle = '' # output _ostitle = '' custom_caption = '' _tabcapt = '' custom_env = '' _custenv = '' hidesize = None __gsignals__ = { 'clicked': (GObject.SignalFlags.RUN_LAST, None, ()), 'edit-done': (GObject.SignalFlags.RUN_LAST, None, ()), 'create-group': (GObject.SignalFlags.RUN_LAST, None, (GObject.TYPE_STRING, )), } def __init__(self, terminal): """Class initialiser""" GObject.GObject.__init__(self) self.terminator = Terminator() self.terminal = terminal self.config = self.terminal.config self.label = EditableLabel() self.label.connect('edit-done', self.on_edit_done) self.ebox = Gtk.EventBox() grouphbox = Gtk.HBox() self.grouplabel = Gtk.Label(ellipsize='end') self.groupicon = Gtk.Image() self.bellicon = Gtk.Image() self.bellicon.set_no_show_all(True) self.titlefixed = False self.groupentry = Gtk.Entry() self.groupentry.set_no_show_all(True) self.groupentry.connect('focus-out-event', self.groupentry_cancel) self.groupentry.connect('activate', self.groupentry_activate) self.groupentry.connect('key-press-event', self.groupentry_keypress) groupsend_type = self.terminator.groupsend_type if self.terminator.groupsend == groupsend_type['all']: icon_name = 'all' elif self.terminator.groupsend == groupsend_type['group']: icon_name = 'group' elif self.terminator.groupsend == groupsend_type['off']: icon_name = 'off' self.set_from_icon_name('_active_broadcast_%s' % icon_name, Gtk.IconSize.MENU) grouphbox.pack_start(self.groupicon, False, True, 2) grouphbox.pack_start(self.grouplabel, False, True, 2) grouphbox.pack_start(self.groupentry, False, True, 2) self.ebox.add(grouphbox) self.ebox.show_all() self.bellicon.set_from_icon_name('terminal-bell', Gtk.IconSize.MENU) viewport = Gtk.Viewport(hscroll_policy='natural') viewport.add(self.label) hbox = Gtk.HBox() hbox.pack_start(self.ebox, False, True, 0) hbox.pack_start(Gtk.VSeparator(), False, True, 0) hbox.pack_start(viewport, True, True, 0) hbox.pack_end(self.bellicon, False, False, 2) self.add(hbox) hbox.show_all() self.set_no_show_all(True) self.show() self.connect('button-press-event', self.on_clicked) def connect_icon(self, func): """Connect the supplied function to clicking on the group icon""" self.ebox.connect('button-press-event', func) def update_visibility(self): """Make the titlebar be visible or not""" if not self.get_desired_visibility(): dbg('hiding titlebar') self.hide() self.label.hide() else: dbg('showing titlebar') self.show() self.label.show() def get_desired_visibility(self): """Returns True if the titlebar is supposed to be visible. False if not""" if self.editing() == True or self.terminal.group: dbg('implicit desired visibility') return (True) else: dbg('configured visibility: %s' % self.config['show_titlebar']) return (self.config['show_titlebar']) def set_from_icon_name(self, name, size=Gtk.IconSize.MENU): """Set an icon for the group label""" if not name: self.groupicon.hide() return self.groupicon.set_from_icon_name(APP_NAME + name, size) self.groupicon.show() def update_terminal_size(self, width, height): """Update the displayed terminal size""" self.sizetext = " %sx%s" % (width, height) self.update() def update_terminal_title(self, widget, title): """Update the terminal title from signal""" # self._tabcapt self._ctitle self._autotext self._tsize self._ostitle = title self.update() # Return False so we don't interrupt any chains of signal handling return False def get_custom_title(self): """Return custom title if it is set, otherwise return empty """ return self.custom_title def set_custom_title(self, ctitle): """Set a custom title""" if ctitle: self.custom_title = ctitle self._ctitle = "%s| " % ctitle self.label.set_edit_base("%s" % ctitle) else: self.custom_title = '' self._ctitle = '' self.label.set_edit_base('NewTitle') self.update() def set_custom_caption(self, capt): """Set tabcaption""" if capt: self.custom_caption = capt self._tabcapt = "[%s] " % capt else: self.custom_caption = '' self._tabcapt = '' self.update() def set_custom_env(self, cenv): """Set custom environment name""" if cenv: self._custenv = "env:%s " % cenv else: self._custenv = '' self.update() def make_labeltext(self): title = self._ostitle # FIXME title fiddling assumes standard linux PS1 # pobably we oughta get cwd ourselves if not title: title = 'user@host:/some/path' pathpart = self.terminal.get_cwd() homepart = get_home_dir() if pathpart.startswith(homepart): # Tilde is barely noticeable with system font on high dpi displays. #pathpart = pathpart.replace(homepart,'<HOME>',1) pathpart = pathpart.replace(homepart, '⁓', 1) if self.titlefixed: if self._ctitle: self._autotext = '' elif self.config['title_hide_userhost']: self._autotext = '@' else: # user OR remote OR R@REMOTE self._autotext = "%s" % uhoextract(title, smart=True) elif self.config['title_hide_path'] \ and self.config['title_hide_userhost']: self._autotext = r'.' elif self.config['title_hide_path']: self._autotext = "%s" % uhoextract(title) elif self.config['title_hide_userhost']: self._autotext = "%s" % pathpart else: self._autotext = "%s" % title # forcibly show at bar even if tabs are hidden if self.config['title_hide_tabcaption'] \ and not self.config['tabs_hidden']: self._tabcapt = '' elif self.custom_caption: self._tabcapt = "[%s] " % self.custom_caption else: self._tabcapt = '' if self.config['title_hide_sizetext']: self._tsize = '' else: self._tsize = self.sizetext def update(self, other=None): """Update our contents""" default_bg = False self.make_labeltext() #self.label.set_text("%s%s%s%s%s" % (self._tabcapt, self._ctitle, self._custenv, self._autotext, self._tsize), force=True) self.label.set_text("%s%s%s%s%s" % (self._custenv, self._tabcapt, self._ctitle, self._autotext, self._tsize), force=True) if (not self.config['title_use_system_font'] ) and self.config['title_font']: title_font = Pango.FontDescription(self.config['title_font']) else: title_font = Pango.FontDescription( self.config.get_system_prop_font()) self.label.modify_font(title_font) self.grouplabel.modify_font(title_font) if other: term = self.terminal terminator = self.terminator if other == 'window-focus-out': title_fg = self.config['title_inactive_fg_color'] title_bg = self.config['title_inactive_bg_color'] icon = '_receive_off' default_bg = True group_fg = self.config['title_inactive_fg_color'] group_bg = self.config['title_inactive_bg_color'] elif term != other and term.group and term.group == other.group: if terminator.groupsend == terminator.groupsend_type['off']: title_fg = self.config['title_inactive_fg_color'] title_bg = self.config['title_inactive_bg_color'] icon = '_receive_off' default_bg = True else: title_fg = self.config['title_receive_fg_color'] title_bg = self.config['title_receive_bg_color'] icon = '_receive_on' group_fg = self.config['title_receive_fg_color'] group_bg = self.config['title_receive_bg_color'] elif term != other and not term.group or term.group != other.group: if terminator.groupsend == terminator.groupsend_type['all']: title_fg = self.config['title_receive_fg_color'] title_bg = self.config['title_receive_bg_color'] icon = '_receive_on' else: title_fg = self.config['title_inactive_fg_color'] title_bg = self.config['title_inactive_bg_color'] icon = '_receive_off' default_bg = True group_fg = self.config['title_inactive_fg_color'] group_bg = self.config['title_inactive_bg_color'] else: # We're the active terminal title_fg = self.config['title_transmit_fg_color'] title_bg = self.config['title_transmit_bg_color'] if terminator.groupsend == terminator.groupsend_type['all']: icon = '_active_broadcast_all' elif terminator.groupsend == terminator.groupsend_type[ 'group']: icon = '_active_broadcast_group' else: icon = '_active_broadcast_off' group_fg = self.config['title_transmit_fg_color'] group_bg = self.config['title_transmit_bg_color'] self.label.modify_fg(Gtk.StateType.NORMAL, Gdk.color_parse(title_fg)) self.grouplabel.modify_fg(Gtk.StateType.NORMAL, Gdk.color_parse(group_fg)) self.modify_bg(Gtk.StateType.NORMAL, Gdk.color_parse(title_bg)) if not self.get_desired_visibility(): if default_bg == True: color = term.get_style_context().get_background_color( Gtk.StateType.NORMAL) # VERIFY FOR GTK3 else: color = Gdk.color_parse(title_bg) self.update_visibility() self.ebox.modify_bg(Gtk.StateType.NORMAL, Gdk.color_parse(group_bg)) self.set_from_icon_name(icon, Gtk.IconSize.MENU) def set_group_label(self, name): """Set the name of the group""" if name: self.grouplabel.set_text(name) self.grouplabel.show() else: self.grouplabel.set_text('') self.grouplabel.hide() self.update_visibility() def on_clicked(self, widget, event): """Handle a click on the label""" self.show() self.label.show() self.emit('clicked') def on_edit_done(self, widget): """Re-emit an edit-done signal from an EditableLabel""" if widget == self.label: if widget.is_custom(): self.set_custom_title(widget.get_text()) else: self.set_custom_title('') self.make_labeltext() self.emit('edit-done') def editing(self): """Determine if we're currently editing a group name or title""" return (self.groupentry.get_property('visible') or self.label.editing()) def create_group(self): """Create a new group""" if self.terminal.group: self.groupentry.set_text(self.terminal.group) else: defaultmembers = [ _('Alpha'), _('Beta'), _('Gamma'), _('Delta'), _('Epsilon'), _('Zeta'), _('Eta'), _('Theta'), _('Iota'), _('Kappa'), _('Lambda'), _('Mu'), _('Nu'), _('Xi'), _('Omicron'), _('Pi'), _('Rho'), _('Sigma'), _('Tau'), _('Upsilon'), _('Phi'), _('Chi'), _('Psi'), _('Omega') ] currentgroups = set(self.terminator.groups) for i in range(1, 4): defaultgroups = set( map(''.join, list(itertools.product(defaultmembers, repeat=i)))) freegroups = list(defaultgroups - currentgroups) if freegroups: self.groupentry.set_text(random.choice(freegroups)) break else: self.groupentry.set_text('') self.groupentry.show() self.grouplabel.hide() self.groupentry.grab_focus() self.update_visibility() def groupentry_cancel(self, widget, event): """Hide the group name entry""" self.groupentry.set_text('') self.groupentry.hide() self.grouplabel.show() self.get_parent().grab_focus() def groupentry_activate(self, widget): """Actually cause a group to be created""" groupname = self.groupentry.get_text() or None dbg('Titlebar::groupentry_activate: creating group: %s' % groupname) self.groupentry_cancel(None, None) last_focused_term = self.terminator.last_focused_term if self.terminal.targets_for_new_group: [ term.titlebar.emit('create-group', groupname) for term in self.terminal.targets_for_new_group ] self.terminal.targets_for_new_group = None else: self.emit('create-group', groupname) last_focused_term.grab_focus() self.terminator.focus_changed(last_focused_term) def groupentry_keypress(self, widget, event): """Handle keypresses on the entry widget""" key = Gdk.keyval_name(event.keyval) if key == 'Escape': self.groupentry_cancel(None, None) def icon_bell(self): """A bell signal requires we display our bell icon""" self.bellicon.show() GObject.timeout_add(1000, self.icon_bell_hide) def icon_bell_hide(self): """Handle a timeout which means we now hide the bell icon""" self.bellicon.hide() return (False)
class TabLabel(gtk.HBox): """Class implementing a label widget for Notebook tabs""" notebook = None terminator = None config = None label = None icon = None button = None __gsignals__ = { 'close-clicked': (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, (gobject.TYPE_OBJECT,)), } def __init__(self, title, notebook): """Class initialiser""" gtk.HBox.__init__(self) self.__gobject_init__() self.notebook = notebook self.terminator = Terminator() self.config = Config() self.label = EditableLabel(title) self.update_angle() self.pack_start(self.label, True, True) self.update_button() self.show_all() def set_label(self, text): """Update the text of our label""" self.label.set_text(text) def get_label(self): return self.label.get_text() def set_custom_label(self, text): """Set a permanent label as if the user had edited it""" self.label.set_text(text) self.label.set_custom() def get_custom_label(self): """Return a custom label if we have one, otherwise None""" if self.label.is_custom(): return(self.label.get_text()) else: return(None) def edit(self): self.label.edit() def update_button(self): """Update the state of our close button""" if not self.config['close_button_on_tab']: if self.button: self.button.remove(self.icon) self.remove(self.button) del(self.button) del(self.icon) self.button = None self.icon = None return if not self.button: self.button = gtk.Button() if not self.icon: self.icon = gtk.Image() self.icon.set_from_stock(gtk.STOCK_CLOSE, gtk.ICON_SIZE_MENU) self.button.set_focus_on_click(False) self.button.set_relief(gtk.RELIEF_NONE) style = gtk.RcStyle() style.xthickness = 0 style.ythickness = 0 self.button.modify_style(style) self.button.add(self.icon) self.button.connect('clicked', self.on_close) self.button.set_name('terminator-tab-close-button') if hasattr(self.button, 'set_tooltip_text'): self.button.set_tooltip_text(_('Close Tab')) self.pack_start(self.button, False, False) self.show_all() def update_angle(self): """Update the angle of a label""" position = self.notebook.get_tab_pos() if position == gtk.POS_LEFT: if hasattr(self, 'set_orientation'): self.set_orientation(gtk.ORIENTATION_VERTICAL) self.label.set_angle(90) elif position == gtk.POS_RIGHT: if hasattr(self, 'set_orientation'): self.set_orientation(gtk.ORIENTATION_VERTICAL) self.label.set_angle(270) else: if hasattr(self, 'set_orientation'): self.set_orientation(gtk.ORIENTATION_HORIZONTAL) self.label.set_angle(0) def on_close(self, _widget): """The close button has been clicked. Destroy the tab""" self.emit('close-clicked', self)
class Titlebar(gtk.EventBox): """Class implementing the Titlebar widget""" terminator = None terminal = None config = None oldtitle = None termtext = None sizetext = None label = None ebox = None groupicon = None grouplabel = None groupentry = None bellicon = None __gsignals__ = { 'clicked': (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, ()), 'edit-done': (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, ()), 'create-group': (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, (gobject.TYPE_STRING,)), } def __init__(self, terminal): """Class initialiser""" gtk.EventBox.__init__(self) self.__gobject_init__() self.terminator = Terminator() self.terminal = terminal self.config = self.terminal.config self.label = EditableLabel() self.label.connect('edit-done', self.on_edit_done) self.ebox = gtk.EventBox() grouphbox = gtk.HBox() self.grouplabel = gtk.Label() self.groupicon = gtk.Image() self.bellicon = gtk.Image() self.bellicon.set_no_show_all(True) self.groupentry = gtk.Entry() self.groupentry.set_no_show_all(True) self.groupentry.connect('focus-out-event', self.groupentry_cancel) self.groupentry.connect('activate', self.groupentry_activate) self.groupentry.connect('key-press-event', self.groupentry_keypress) groupsend_type = self.terminator.groupsend_type if self.terminator.groupsend == groupsend_type['all']: icon_name = 'all' elif self.terminator.groupsend == groupsend_type['group']: icon_name = 'group' elif self.terminator.groupsend == groupsend_type['off']: icon_name = 'off' self.set_from_icon_name('_active_broadcast_%s' % icon_name, gtk.ICON_SIZE_MENU) grouphbox.pack_start(self.groupicon, False, True, 2) grouphbox.pack_start(self.grouplabel, False, True, 2) grouphbox.pack_start(self.groupentry, False, True, 2) self.ebox.add(grouphbox) self.ebox.show_all() self.bellicon.set_from_icon_name('terminal-bell', gtk.ICON_SIZE_MENU) hbox = gtk.HBox() hbox.pack_start(self.ebox, False, True, 0) hbox.pack_start(gtk.VSeparator(), False, True, 0) hbox.pack_start(self.label, True, True) hbox.pack_end(self.bellicon, False, False, 2) self.add(hbox) hbox.show_all() self.set_no_show_all(True) self.show() self.connect('button-press-event', self.on_clicked) def connect_icon(self, func): """Connect the supplied function to clicking on the group icon""" self.ebox.connect('button-release-event', func) def update(self, other=None): """Update our contents""" default_bg = False if self.config['title_hide_sizetext']: self.label.set_text("%s" % self.termtext) else: self.label.set_text("%s %s" % (self.termtext, self.sizetext)) if other: term = self.terminal terminator = self.terminator if other == 'window-focus-out': title_fg = self.config['title_inactive_fg_color'] title_bg = self.config['title_inactive_bg_color'] icon = '_receive_off' default_bg = True group_fg = self.config['title_inactive_fg_color'] group_bg = self.config['title_inactive_bg_color'] elif term != other and term.group and term.group == other.group: if terminator.groupsend == terminator.groupsend_type['off']: title_fg = self.config['title_inactive_fg_color'] title_bg = self.config['title_inactive_bg_color'] icon = '_receive_off' default_bg = True else: title_fg = self.config['title_receive_fg_color'] title_bg = self.config['title_receive_bg_color'] icon = '_receive_on' group_fg = self.config['title_receive_fg_color'] group_bg = self.config['title_receive_bg_color'] elif term != other and not term.group or term.group != other.group: if terminator.groupsend == terminator.groupsend_type['all']: title_fg = self.config['title_receive_fg_color'] title_bg = self.config['title_receive_bg_color'] icon = '_receive_on' else: title_fg = self.config['title_inactive_fg_color'] title_bg = self.config['title_inactive_bg_color'] icon = '_receive_off' default_bg = True group_fg = self.config['title_inactive_fg_color'] group_bg = self.config['title_inactive_bg_color'] else: # We're the active terminal title_fg = self.config['title_transmit_fg_color'] title_bg = self.config['title_transmit_bg_color'] if terminator.groupsend == terminator.groupsend_type['all']: icon = '_active_broadcast_all' elif terminator.groupsend == terminator.groupsend_type['group']: icon = '_active_broadcast_group' else: icon = '_active_broadcast_off' group_fg = self.config['title_transmit_fg_color'] group_bg = self.config['title_transmit_bg_color'] self.label.modify_fg(gtk.STATE_NORMAL, gtk.gdk.color_parse(title_fg)) self.grouplabel.modify_fg(gtk.STATE_NORMAL, gtk.gdk.color_parse(group_fg)) self.modify_bg(gtk.STATE_NORMAL, gtk.gdk.color_parse(title_bg)) if not self.get_desired_visibility(): if default_bg == True: color = term.get_style().bg[gtk.STATE_NORMAL] else: color = gtk.gdk.color_parse(title_bg) self.update_visibility() self.ebox.modify_bg(gtk.STATE_NORMAL, gtk.gdk.color_parse(group_bg)) self.set_from_icon_name(icon, gtk.ICON_SIZE_MENU) def update_visibility(self): """Make the titlebar be visible or not""" if not self.get_desired_visibility(): dbg('hiding titlebar') self.hide() self.label.hide() else: dbg('showing titlebar') self.show() self.label.show() def get_desired_visibility(self): """Returns True if the titlebar is supposed to be visible. False if not""" if self.editing() == True or self.terminal.group: dbg('implicit desired visibility') return(True) else: dbg('configured visibility: %s' % self.config['show_titlebar']) return(self.config['show_titlebar']) def set_from_icon_name(self, name, size = gtk.ICON_SIZE_MENU): """Set an icon for the group label""" if not name: self.groupicon.hide() return self.groupicon.set_from_icon_name(APP_NAME + name, size) self.groupicon.show() def update_terminal_size(self, width, height): """Update the displayed terminal size""" self.sizetext = "%sx%s" % (width, height) self.update() def set_terminal_title(self, widget, title): """Update the terminal title""" self.termtext = title self.update() # Return False so we don't interrupt any chains of signal handling return False def set_group_label(self, name): """Set the name of the group""" if name: self.grouplabel.set_text(name) self.grouplabel.show() else: self.grouplabel.hide() self.update_visibility() def on_clicked(self, widget, event): """Handle a click on the label""" self.show() self.label.show() self.emit('clicked') def on_edit_done(self, widget): """Re-emit an edit-done signal from an EditableLabel""" self.emit('edit-done') def editing(self): """Determine if we're currently editing a group name or title""" return(self.groupentry.get_property('visible') or self.label.editing()) def create_group(self): """Create a new group""" self.groupentry.show() self.groupentry.grab_focus() self.update_visibility() def groupentry_cancel(self, widget, event): """Hide the group name entry""" self.groupentry.set_text('') self.groupentry.hide() self.get_parent().grab_focus() def groupentry_activate(self, widget): """Actually cause a group to be created""" groupname = self.groupentry.get_text() dbg('Titlebar::groupentry_activate: creating group: %s' % groupname) self.groupentry_cancel(None, None) self.emit('create-group', groupname) def groupentry_keypress(self, widget, event): """Handle keypresses on the entry widget""" key = gtk.gdk.keyval_name(event.keyval) if key == 'Escape': self.groupentry_cancel(None, None) def icon_bell(self): """A bell signal requires we display our bell icon""" self.bellicon.show() gobject.timeout_add(1000, self.icon_bell_hide) def icon_bell_hide(self): """Handle a timeout which means we now hide the bell icon""" self.bellicon.hide() return(False) def get_custom_string(self): """If we have a custom string set, return it, otherwise None""" if self.label.is_custom(): return(self.label.get_text()) else: return(None) def set_custom_string(self, string): """Set a custom string""" self.label.set_text(string) self.label.set_custom()