def get_tab_title(self, uuid=None): """Return the title of a parent tab of a given terminal""" maker = Factory() terminal = self.terminator.find_terminal_by_uuid(uuid) window = terminal.get_toplevel() root_widget = window.get_children()[0] if maker.isinstance(root_widget, "Notebook"): for tab_child in root_widget.get_children(): terms = [tab_child] if not maker.isinstance(terms[0], "Terminal"): terms = enumerate_descendants(tab_child)[1] if terminal in terms: return root_widget.get_tab_label(tab_child).get_label()
def closetab(self, widget, label): """Close a tab""" tabnum = None try: nb = widget.notebook except AttributeError: err('TabLabel::closetab: called on non-Notebook: %s' % widget) return for i in range(0, nb.get_n_pages() + 1): if label == nb.get_tab_label(nb.get_nth_page(i)): tabnum = i break if tabnum is None: err('TabLabel::closetab: %s not in %s. Bailing.' % (label, nb)) return maker = Factory() child = nb.get_nth_page(tabnum) if maker.isinstance(child, 'Terminal'): dbg('Notebook::closetab: child is a single Terminal') del nb.last_active_term[child] child.close() # FIXME: We only do this del and return here to avoid removing the # page below, which child.close() implicitly does del(label) return elif maker.isinstance(child, 'Container'): dbg('Notebook::closetab: child is a Container') result = self.construct_confirm_close(self.window, _('tab')) if result == Gtk.ResponseType.ACCEPT: containers = None objects = None containers, objects = enumerate_descendants(child) while len(objects) > 0: descendant = objects.pop() descendant.close() while Gtk.events_pending(): Gtk.main_iteration() return else: dbg('Notebook::closetab: user cancelled request') return else: err('Notebook::closetab: child is unknown type %s' % child) return
def do_enumerate(self, widget, pad): """Insert the number of each terminal in a group, into that terminal""" if pad: numstr = '%0' + str(len(str(len(self.terminals)))) + 'd' else: numstr = '%d' terminals = [] for window in self.windows: containers, win_terminals = enumerate_descendants(window) terminals.extend(win_terminals) for term in self.get_target_terms(widget): idx = terminals.index(term) term.feed(numstr % (idx + 1))
def get_tab(self, uuid=None): """Return the UUID of the parent tab of a given terminal""" maker = Factory() terminal = self.terminator.find_terminal_by_uuid(uuid) window = terminal.get_toplevel() root_widget = window.get_children()[0] if maker.isinstance(root_widget, 'Notebook'): #return root_widget.uuid.urn for tab_child in root_widget.get_children(): terms = [tab_child] if not maker.isinstance(terms[0], "Terminal"): terms = enumerate_descendants(tab_child)[1] if terminal in terms: # FIXME: There are no uuid's assigned to the the notebook, or the actual tabs! # This would fail: return root_widget.uuid.urn return ""
def wrapcloseterm(self, widget): """A child terminal has closed, so this container must die""" dbg('Paned::wrapcloseterm: Called on %s' % widget) if self.closeterm(widget): # At this point we only have one child, which is the surviving term sibling = self.children[0] first_term_sibling = sibling cur_tabnum = None focus_sibling = True if self.get_toplevel().is_child_notebook(): notebook = self.get_toplevel().get_children()[0] cur_tabnum = notebook.get_current_page() tabnum = notebook.page_num_descendant(self) nth_page = notebook.get_nth_page(tabnum) exiting_term_was_last_active = ( notebook.last_active_term[nth_page] == widget.uuid) if exiting_term_was_last_active: first_term_sibling = enumerate_descendants(self)[1][0] notebook.set_last_active_term(first_term_sibling.uuid) notebook.clean_last_active_term() self.get_toplevel().last_active_term = None if cur_tabnum != tabnum: focus_sibling = False elif self.get_toplevel().last_active_term != widget.uuid: focus_sibling = False self.remove(sibling) metadata = None parent = self.get_parent() metadata = parent.get_child_metadata(self) dbg('metadata obtained for %s: %s' % (self, metadata)) parent.remove(self) self.cnxids.remove_all() parent.add(sibling, metadata) if cur_tabnum: notebook.set_current_page(cur_tabnum) if focus_sibling: first_term_sibling.grab_focus() elif not sibling.get_toplevel().is_child_notebook(): Terminator().find_terminal_by_uuid( sibling.get_toplevel().last_active_term.urn).grab_focus() else: dbg("Paned::wrapcloseterm: self.closeterm failed")
def navigate_terminal(self, terminal, direction): """Navigate around terminals""" _containers, terminals = enumerate_descendants(self) visibles = self.get_visible_terminals() current = terminals.index(terminal) length = len(terminals) next = None if length <= 1 or len(visibles) <= 1: return if direction in ['next', 'prev']: tmpterms = copy.copy(terminals) tmpterms = tmpterms[current + 1:] tmpterms.extend(terminals[0:current]) if direction == 'next': tmpterms.reverse() next = 0 while len(tmpterms) > 0: tmpitem = tmpterms.pop() if tmpitem in visibles: next = terminals.index(tmpitem) break elif direction in ['left', 'right', 'up', 'down']: layout = self.get_visible_terminals() allocation = terminal.get_allocation() possibles = [] # Get the co-ordinate of the appropriate edge for this direction edge, p1, p2 = get_edge(allocation, direction) # Find all visible terminals which are, in their entirity, in the # direction we want to move, and are at least partially spanning # p1 to p2 for term in layout: rect = layout[term] if get_nav_possible(edge, rect, direction, p1, p2): possibles.append(term) if len(possibles) == 0: return # Find out how far away each of the possible terminals is, then # find the smallest distance. The winning terminals are all of # those who are that distance away. offsets = {} for term in possibles: rect = layout[term] offsets[term] = get_nav_offset(edge, rect, direction) keys = offsets.values() keys.sort() winners = [k for k, v in offsets.iteritems() if v == keys[0]] next = terminals.index(winners[0]) if len(winners) > 1: # Break an n-way tie using the cursor position term_alloc = terminal.get_allocation() cursor_x = term_alloc.x + term_alloc.width / 2 cursor_y = term_alloc.y + term_alloc.height / 2 for term in winners: rect = layout[term] if get_nav_tiebreak(direction, cursor_x, cursor_y, rect): next = terminals.index(term) break else: err('Unknown navigation direction: %s' % direction) if next is not None: terminals[next].grab_focus()
def newtab(self, debugtab=False, widget=None, cwd=None, metadata=None, profile=None): """Add a new tab, optionally supplying a child widget""" dbg('making a new tab') maker = Factory() top_window = self.get_toplevel() if not widget: widget = maker.make('Terminal') if cwd: widget.set_cwd(cwd) if profile and self.config['always_split_with_profile']: widget.force_set_profile(None, profile) widget.spawn_child(debugserver=debugtab) elif profile and self.config['always_split_with_profile']: widget.force_set_profile(None, profile) signals = {'close-term': self.wrapcloseterm, 'split-horiz': self.split_horiz, 'split-vert': self.split_vert, 'title-change': self.propagate_title_change, 'unzoom': self.unzoom, 'tab-change': top_window.tab_change, 'group-all': top_window.group_all, 'group-all-toggle': top_window.group_all_toggle, 'ungroup-all': top_window.ungroup_all, 'group-tab': top_window.group_tab, 'group-tab-toggle': top_window.group_tab_toggle, 'ungroup-tab': top_window.ungroup_tab, 'move-tab': top_window.move_tab, 'tab-new': [top_window.tab_new, widget], 'navigate': top_window.navigate_terminal} if maker.isinstance(widget, 'Terminal'): for signal in signals: args = [] handler = signals[signal] if isinstance(handler, list): args = handler[1:] handler = handler[0] self.connect_child(widget, signal, handler, *args) if metadata and metadata.has_key('tabnum'): tabpos = metadata['tabnum'] else: tabpos = -1 label = TabLabel(self.window.get_title(), self) if metadata and metadata.has_key('label'): dbg('creating TabLabel with text: %s' % metadata['label']) label.set_custom_label(metadata['label']) label.connect('close-clicked', self.closetab) label.show_all() widget.show_all() dbg('inserting page at position: %s' % tabpos) self.insert_page(widget, None, tabpos) if maker.isinstance(widget, 'Terminal'): containers, objects = ([], [widget]) else: containers, objects = enumerate_descendants(widget) term_widget = None for term_widget in objects: if maker.isinstance(term_widget, 'Terminal'): self.set_last_active_term(term_widget.uuid) break self.set_tab_label(widget, label) self.child_set_property(widget, 'tab-expand', True) self.child_set_property(widget, 'tab-fill', True) self.set_tab_reorderable(widget, True) self.set_current_page(tabpos) self.show_all() if maker.isinstance(term_widget, 'Terminal'): widget.grab_focus()