예제 #1
0
 def __init__(self):
     plugin.MenuItem.__init__(self)
     self.config = Config()
     self.pluginConfig = parsePluginConfig(self.config)
     self.loggingTerminals = {}
     self.scrollbackLines = self.config['scrollback_lines']
     dbg("using config: %s" % self.pluginConfig)
예제 #2
0
    def configure(self, widget):

        store_factory = StoreFactory()
        gen_store = store_factory.create_gen_store(self.config)

        action_stores = {}
        for pattern in self.config.keys():
            action_stores[pattern] = store_factory.create_action_store(
                self.config[pattern]['actions'])

        dialog = RunWithDialog(gen_store,
                               action_stores,
                               widget,
                               title='RunWith configuration')

        icon_theme = Gtk.IconTheme.get_default()
        if icon_theme.lookup_icon('terminator-run-with', 48, 0):
            dialog.set_icon_name('terminator-run-with')
        else:
            dbg('Cannot load Terminator RunWith icon')
            icon = dialog.render_icon(Gtk.STOCK_DIALOG_INFO,
                                      Gtk.IconSize.BUTTON)
            dialog.set_icon(icon)

        while True:
            result = dialog.run()
            if result == Gtk.ResponseType.OK:
                if dialog.is_gen_store_valid():
                    self.save_config(dialog)
                    break
            else:
                break

        dialog.destroy()
        return
예제 #3
0
 def __init__(self):
     super(TerminalExporter, self).__init__()
     self.config = Config()
     self.plugin_config = parse_plugin_config(self.config)
     self.logging_terminals = {}
     self.scrollback_lines = self.config['scrollback_lines']
     dbg('using config: %s' % self.plugin_config)
예제 #4
0
 def group_emit(self, terminal, group, type, event):
     """Emit to each terminal in a group"""
     dbg('Terminator::group_emit: emitting a keystroke for group %s' %
         group)
     for term in self.terminals:
         if term != terminal and term.group == group:
             term.vte.emit(type, eventkey2gdkevent(event))
 def __init__(self):
     super(TerminalExporter, self).__init__()
     self.config = Config()
     self.plugin_config = parse_plugin_config(self.config)
     self.logging_terminals = {}
     self.scrollback_lines = self.config['scrollback_lines']
     dbg('using config: %s' % self.plugin_config)
예제 #6
0
    def __init__(self):
        self.terminator = Terminator()
        self.terminator.register_launcher_window(self)

        self.config = config.Config()
        self.config.base.reload()
        self.builder = Gtk.Builder()
        try:
            # Figure out where our library is on-disk so we can open our UI
            (head, _tail) = os.path.split(config.__file__)
            librarypath = os.path.join(head, 'layoutlauncher.glade')
            with open(librarypath, mode='rt') as f:
                gladedata = f.read()
        except Exception as ex:
            print("Failed to find layoutlauncher.glade")
            print(ex)
            return

        self.builder.add_from_string(gladedata)
        self.window = self.builder.get_object('layoutlauncherwin')

        icon_theme = Gtk.IconTheme.get_default()
        if icon_theme.lookup_icon('terminator-layout', 48, 0):
            self.window.set_icon_name('terminator-layout')
        else:
            dbg('Unable to load Terminator layout launcher icon')
            icon = self.window.render_icon(Gtk.STOCK_DIALOG_INFO, Gtk.IconSize.BUTTON)
            self.window.set_icon(icon)

        self.builder.connect_signals(self)
        self.window.connect('destroy', self.on_destroy_event)
        self.window.show_all()
        self.layouttreeview = self.builder.get_object('layoutlist')
        self.layouttreestore = self.builder.get_object('layoutstore')
        self.update_layouts()
 def __init__(self):
     plugin.MenuItem.__init__(self)
     self.config = Config()
     self.pluginConfig = parsePluginConfig(self.config)
     self.loggingTerminals = {}
     self.scrollbackLines = self.config['scrollback_lines']
     dbg("using config: %s" % self.pluginConfig)
예제 #8
0
    def tab_change(self, widget, num=None):
        """Change to a specific tab"""
        if num is None:
            err('must specify a tab to change to')

        maker = Factory()
        child = self.get_child()

        if not maker.isinstance(child, 'Notebook'):
            dbg('child is not a notebook, nothing to change to')
            return

        if num == -1:
            # Go to the next tab
            cur = child.get_current_page()
            pages = child.get_n_pages()
            if cur == pages - 1:
                num = 0
            else:
                num = cur + 1
        elif num == -2:
            # Go to the previous tab
            cur = child.get_current_page()
            if cur > 0:
                num = cur - 1
            else:
                num = child.get_n_pages() - 1

        child.set_current_page(num)
        # Work around strange bug in gtk-2.12.11 and pygtk-2.12.1
        # Without it, the selection changes, but the displayed page doesn't
        # change
        child.set_current_page(child.get_current_page())
예제 #9
0
def get_pid_cwd():
    """Determine an appropriate cwd function for the OS we are running on"""

    func = lambda pid: None
    system = platform.system()

    if system == 'Linux':
        dbg('Using Linux get_pid_cwd')
        func = linux_get_pid_cwd
    elif system == 'FreeBSD':
        try:
            import freebsd
            func = freebsd.get_process_cwd
            dbg('Using FreeBSD get_pid_cwd')
        except (OSError, NotImplementedError, ImportError):
            dbg('FreeBSD version too old for get_pid_cwd')
    elif system == 'SunOS':
        dbg('Using SunOS get_pid_cwd')
        func = sunos_get_pid_cwd
    elif psutil_avail:
        func = psutil_cwd
    else:
        dbg('Unable to determine a get_pid_cwd for OS: %s' % system)

    return (func)
예제 #10
0
    def __init__(self):
        config = Config()
        sections = config.plugin_get_config(self.__class__.__name__)
        if not isinstance(sections, dict):
            return
        noord_cmds = []
        for part in sections:
            s = sections[part]
            if not ("regexp" in s and "command" in s):
                dbg("Ignoring section %s" % s)
                continue
            regexp = s["regexp"]
            command = s["command"]
            enabled = s["enabled"] and s["enabled"] or False
            if "position" in s:
                self.cmd_list[int(s["position"])] = {
                    'enabled': enabled,
                    'regexp': regexp,
                    'command': command
                }
            else:
                noord_cmds.append({
                    'enabled': enabled,
                    'regexp': regexp,
                    'command': command
                })
            for cmd in noord_cmds:
                self.cmd_list[len(self.cmd_list)] = cmd

            self._load_configured_handlers()
예제 #11
0
    def _load_configured_handlers(self):
        """Forge an URLhandler plugin and hide it in the available ones."""
        me = sys.modules[__name__]  # Current module.
        config = Config()

        for key, handler in [(key, self.cmd_list[key])
                             for key in sorted(self.cmd_list.keys())]:
            # Forge a hidden/managed plugin
            # (names starting with an underscore will not be displayed in the preference/plugins window).
            rcom_name = "_RunCmdOnMatch_{}".format(
                key)  # key is just the index
            # Make a handler class.
            RCOM = MetaRCOM(rcom_name, handler["regexp"], handler["command"])
            # Instanciate the class.
            setattr(me, rcom_name, RCOM)

            if rcom_name not in AVAILABLE:
                AVAILABLE.append(rcom_name)
                dbg("add {} to the list of URL handlers: '{}' -> '{}'".format(
                    rcom_name, RCOM.match, RCOM.cmd))

            if handler['enabled'] and rcom_name not in config[
                    "enabled_plugins"]:
                config["enabled_plugins"].append(rcom_name)

        config.save()
예제 #12
0
    def move_tab(self, widget, direction):
        """Handle a keyboard shortcut for moving tab positions"""
        maker = Factory()
        notebook = self.get_child()

        if not maker.isinstance(notebook, 'Notebook'):
            dbg('not in a notebook, refusing to move tab %s' % direction)
            return

        dbg('moving tab %s' % direction)
        numpages = notebook.get_n_pages()
        page = notebook.get_current_page()
        child = notebook.get_nth_page(page)

        if direction == 'left':
            if page == 0:
                page = numpages
            else:
                page = page - 1
        elif direction == 'right':
            if page == numpages - 1:
                page = 0
            else:
                page = page + 1
        else:
            err('unknown direction: %s' % direction)
            return

        notebook.reorder_child(child, page)
예제 #13
0
    def save(self):
        """Save the config to a file"""
        dbg('ConfigBase::save: saving config')
        parser = ConfigObj()
        parser.indent_type = '  '

        for section_name in ['global_config', 'keybindings']:
            dbg('ConfigBase::save: Processing section: %s' % section_name)
            section = getattr(self, section_name)
            parser[section_name] = dict_diff(DEFAULTS[section_name], section)

        parser['profiles'] = {}
        for profile in self.profiles:
            dbg('ConfigBase::save: Processing profile: %s' % profile)
            parser['profiles'][profile] = dict_diff(
                DEFAULTS['profiles']['default'], self.profiles[profile])

        parser['layouts'] = {}
        for layout in self.layouts:
            dbg('ConfigBase::save: Processing layout: %s' % layout)
            parser['layouts'][layout] = self.layouts[layout]

        parser['plugins'] = {}
        for plugin in self.plugins:
            dbg('ConfigBase::save: Processing plugin: %s' % plugin)
            parser['plugins'][plugin] = self.plugins[plugin]

        config_dir = get_config_dir()
        if not os.path.isdir(config_dir):
            os.makedirs(config_dir)
        try:
            parser.write(open(self.command_line_options.config, 'w'))
        except Exception as ex:
            err('ConfigBase::save: Unable to save config: %s' % ex)
예제 #14
0
    def create_layout(self, layout):
        """Apply layout configuration"""
        if 'children' not in layout:
            err('layout specifies no children: %s' % layout)
            return

        children = layout['children']
        if len(children) != 2:
            # Paned widgets can only have two children
            err('incorrect number of children for Paned: %s' % layout)
            return

        keys = []

        # FIXME: This seems kinda ugly. All we want here is to know the order
        # of children based on child['order']
        try:
            child_order_map = {}
            for child in children:
                key = children[child]['order']
                child_order_map[key] = child
            map_keys = child_order_map.keys()
            map_keys.sort()
            for map_key in map_keys:
                keys.append(child_order_map[map_key])
        except KeyError:
            # We've failed to figure out the order. At least give the terminals
            # in the wrong order
            keys = children.keys()

        num = 0
        for child_key in keys:
            child = children[child_key]
            dbg('Making a child of type: %s' % child['type'])
            if child['type'] == 'Terminal':
                pass
            elif child['type'] == 'VPaned':
                if num == 0:
                    terminal = self.get_child1()
                else:
                    terminal = self.get_child2()
                self.split_axis(terminal, True)
            elif child['type'] == 'HPaned':
                if num == 0:
                    terminal = self.get_child1()
                else:
                    terminal = self.get_child2()
                self.split_axis(terminal, False)
            else:
                err('unknown child type: %s' % child['type'])
            num = num + 1

        self.get_child1().create_layout(children[keys[0]])
        self.get_child2().create_layout(children[keys[1]])

        # Set the position with ratio. For some reason more reliable than by pos.
        if 'ratio' in layout:
            self.ratio = float(layout['ratio'])
            self.set_position_by_ratio()
예제 #15
0
    def get_last_line(self, terminal):
        """Retrieve last line of terminal (contains 'user@hostname')"""
        ret=None
        vte = terminal.get_vte()

        cursor = vte.get_cursor_position()
        column_count = vte.get_column_count()
        row_position = cursor[1]
        
        start_row = row_position
        start_col = 0
        end_row = row_position
        end_col = column_count
        is_interesting_char = lambda a, b, c, d: True

        """ manage text wrapping :
        usecases :
        - PS1 too long
        - componant of PS1 forcing display on several lines (e.g working directory)
        - window resizing
        - ...
        So, very ugly algorithm
        if current line too short, we assume prompt is wrapped
        we the search for 1st line of prompt, that is : first line following the
        last line containing LF
        we iterate back until LF found (means : end of output of last command), 
        then forward one line
        """
        lines= vte.get_text_range(start_row, start_col, end_row, end_col, is_interesting_char)

        if lines and lines[0]:
            # line too short, iterate back
            if len(lines)<=self.prompt_minlen:
                dbg("line below prompt min size of "+str(self.prompt_minlen)+ " chars : must iterate back '"+lines+"'")
                start_row=start_row-1
                end_row=start_row
                lines = vte.get_text_range(start_row, start_col, end_row, end_col, is_interesting_char)
                prev_lines=lines
                # we iterate back to first line of terminal, including history...
                while lines != None and start_row>=0:
                    # LF found, PS1 first line is next line... eeeer previous pushed line
                    if lines[len(lines)-1] == '\n':
                        lines=prev_lines
                        break
                    
                    lines = vte.get_text_range(start_row, start_col, end_row, end_col, is_interesting_char)
                    start_row=start_row-1
                    end_row=start_row                        
                    prev_lines=lines
                    
        lines=lines.splitlines()
        if lines and lines[0]:
            if len(lines[0])>=self.line_minlen:
                ret=lines[0]
            else:
                # should never happen since we browse back in history
                dbg("line '"+lines[0]+"' too short, won't use : "+str(len(lines[0])))
        
        return ret
예제 #16
0
 def find_window_by_uuid(self, uuid):
     """Search our terminals for one matching the supplied UUID"""
     dbg(f'searching self.terminals for: {uuid}')
     for window in self.windows:
         dbg(f'checking: {window.uuid.urn} ({window})')
         if window.uuid.urn == uuid:
             return window
     return None
예제 #17
0
 def set_cwd(self, cwd=None):
     if cwd is None:
         cwd = self.terminal.get_cwd()
     if cwd == self.cwd:
         return
     self.cwd = cwd
     cwd = self.clisnips.SetWorkingDirectory(cwd)
     dbg('clisnips.SetWorkingDirectory "%s"' % cwd)
예제 #18
0
 def watch(self, _widget, terminal):
     """Watch a terminal"""
     vte = terminal.get_vte()
     self.watches[terminal] = vte.connect('contents-changed',
                                          self.reset_timer, terminal)
     timeout_id = gobject.timeout_add(5000, self.check_times, terminal)
     self.timers[terminal] = timeout_id
     dbg('timer %s added for %s' % (timeout_id, terminal))
예제 #19
0
 def find_terminal_by_uuid(self, uuid):
     """Search our terminals for one matching the supplied UUID"""
     dbg(f'searching self.terminals for: {uuid}')
     for terminal in self.terminals:
         dbg(f'checking: {terminal.uuid.urn} ({terminal})')
         if terminal.uuid.urn == uuid:
             return terminal
     return None
예제 #20
0
 def watch(self, _widget, terminal):
     """Watch a terminal"""
     vte = terminal.get_vte()
     self.watches[terminal] = vte.connect('contents-changed',
                                          self.reset_timer, terminal)
     timeout_id = gobject.timeout_add(5000, self.check_times, terminal)
     self.timers[terminal] = timeout_id
     dbg('timer %s added for %s' %(timeout_id, terminal))
예제 #21
0
 def find_window_by_uuid(self, uuid):
     """Search our terminals for one matching the supplied UUID"""
     dbg('searching self.terminals for: %s' % uuid)
     for window in self.windows:
         dbg('checking: %s (%s)' % (window.uuid.urn, window))
         if window.uuid.urn == uuid:
             return window
     return None
예제 #22
0
 def set_cwd(self, cwd=None):
     if cwd is None:
         cwd = self.terminal.get_cwd()
     if cwd == self.cwd:
         return
     self.cwd = cwd
     cwd = self.clisnips.SetWorkingDirectory(cwd)
     dbg('clisnips.SetWorkingDirectory "%s"' % cwd)
예제 #23
0
 def remove_widget(self, widget):
     """Remove all signal handlers for a widget"""
     if widget not in self.cnxids:
         dbg(f'{widget} not registered')
         return
     signals = tuple(self.cnxids[widget].keys())
     for signal in signals:
         self.remove_signal(widget, signal)
예제 #24
0
 def remove_widget(self, widget):
     """Remove all signal handlers for a widget"""
     if widget not in self.cnxids:
         dbg('%s not registered' % widget)
         return
     signals = self.cnxids[widget].keys()
     for signal in list(signals):
         self.remove_signal(widget, signal)
예제 #25
0
def spawn(env):
  PythonConsoleServer.env = env
  tcpserver = socketserver.TCPServer(('127.0.0.1', 0), PythonConsoleServer)
  dbg("debugserver: listening on %s" % str(tcpserver.server_address))
  debugserver = threading.Thread(target=tcpserver.serve_forever, name="DebugServer")
  debugserver.setDaemon(True)
  debugserver.start()
  return(debugserver, tcpserver)
예제 #26
0
 def new_window_cmdline(self, options=dbus.Dictionary()):
     """Create a new Window"""
     dbg('dbus method called: new_window with parameters %s' % (options))
     oldopts = self.terminator.config.options_get()
     oldopts.__dict__ = options
     self.terminator.config.options_set(oldopts)
     self.terminator.create_layout(oldopts.layout)
     self.terminator.layout_done()
예제 #27
0
 def new_tab_cmdline(self, options=dbus.Dictionary()):
     """Create a new tab"""
     dbg('dbus method called: new_tab with parameters %s' % (options))
     oldopts = self.terminator.config.options_get()
     oldopts.__dict__ = options
     self.terminator.config.options_set(oldopts)
     window = self.terminator.get_windows()[0]
     window.tab_new()
예제 #28
0
 def find_terminal_by_uuid(self, uuid):
     """Search our terminals for one matching the supplied UUID"""
     dbg('searching self.terminals for: %s' % uuid)
     for terminal in self.terminals:
         dbg('checking: %s (%s)' % (terminal.uuid.urn, terminal))
         if terminal.uuid.urn == uuid:
             return terminal
     return None
예제 #29
0
def spawn(env):
  PythonConsoleServer.env = env
  tcpserver = SocketServer.TCPServer(('127.0.0.1', 0), PythonConsoleServer)
  dbg("debugserver: listening on %s" % str(tcpserver.server_address))
  debugserver = threading.Thread(target=tcpserver.serve_forever, name="DebugServer")
  debugserver.setDaemon(True)
  debugserver.start()
  return(debugserver, tcpserver)
예제 #30
0
    def split_axis(self,
                   widget,
                   vertical=True,
                   cwd=None,
                   sibling=None,
                   widgetfirst=True):
        """Split the axis of a terminal inside us"""
        dbg('called for widget: %s' % widget)
        order = None
        page_num = self.page_num(widget)
        if page_num == -1:
            err('Notebook::split_axis: %s not found in Notebook' % widget)
            return

        label = self.get_tab_label(widget)
        self.remove(widget)

        maker = Factory()
        if vertical:
            container = maker.make('vpaned')
        else:
            container = maker.make('hpaned')

        self.get_toplevel().set_pos_by_ratio = True

        if not sibling:
            sibling = maker.make('terminal')
            sibling.set_cwd(cwd)
            if self.config['always_split_with_profile']:
                sibling.force_set_profile(None, widget.get_profile())
            sibling.spawn_child()
            if widget.group and self.config['split_to_group']:
                sibling.set_group(None, widget.group)
        elif self.config['always_split_with_profile']:
            sibling.force_set_profile(None, widget.get_profile())

        self.insert_page(container, None, page_num)
        self.child_set_property(container, 'tab-expand', True)
        self.child_set_property(container, 'tab-fill', True)
        self.set_tab_reorderable(container, True)
        self.set_tab_label(container, label)
        self.show_all()

        order = [widget, sibling]
        if widgetfirst is False:
            order.reverse()

        for terminal in order:
            container.add(terminal)
        self.set_current_page(page_num)

        self.show_all()

        while Gtk.events_pending():
            Gtk.main_iteration_do(False)
        self.get_toplevel().set_pos_by_ratio = False

        GLib.idle_add(terminal.ensure_visible_and_focussed)
예제 #31
0
 def on_destroy_event(self, widget, data=None):
     """Handle window destruction"""
     dbg('destroying self')
     for terminal in self.get_visible_terminals():
         terminal.close()
     self.cnxids.remove_all()
     self.terminator.deregister_window(self)
     self.destroy()
     del (self)
예제 #32
0
 def on_terminal_key_pressed(self, vt, event):
     kv = event.keyval
     if kv in (gtk.keysyms.Return, gtk.keysyms.KP_Enter):
         # Although we registered the emission hook on vte.Terminal,
         # the event is also fired by terminatorlib.window.Window ...
         if isinstance(vt, vte.Terminal):
             dbg('CliSnipsMenu :: Enter pressed %s' % vt)
             self.on_keypress_enter()
     return True
예제 #33
0
 def hoover(self):
     """Check that we still have a reason to exist"""
     if len(self.children) == 1:
         dbg('Paned::hoover: We only have one child, die')
         parent = self.get_parent()
         child = self.children[0]
         self.remove(child)
         parent.replace(self, child)
         del self
예제 #34
0
    def get_plugins_by_capability(self, capability):
        """Return a list of plugins with a particular capability"""
        result = []
        dbg('PluginRegistry::get_plugins_by_capability: searching %d plugins \
for %s' % (len(self.instances), capability))
        for plugin in self.instances:
            if capability in self.instances[plugin].capabilities:
                result.append(self.instances[plugin])
        return result
예제 #35
0
 def page_num_descendant(self, widget):
     """Find the tabnum of the tab containing a widget at any level"""
     tabnum = self.page_num(widget)
     dbg("widget is direct child if not equal -1 - tabnum: %d" % tabnum)
     while tabnum == -1 and widget.get_parent():
         widget = widget.get_parent()
         tabnum = self.page_num(widget)
     dbg("found tabnum containing widget: %d" % tabnum)
     return tabnum
예제 #36
0
 def on_terminal_key_pressed(self, vt, event):
     kv = event.keyval
     if kv in (gtk.keysyms.Return, gtk.keysyms.KP_Enter):
         # Although we registered the emission hook on vte.Terminal,
         # the event is also fired by terminatorlib.window.Window ...
         if isinstance(vt, vte.Terminal):
             dbg('CliSnipsMenu :: Enter pressed %s' % vt)
             self.on_keypress_enter()
     return True
예제 #37
0
 def on_resize(self, widget, allocation):
     # current = self.term.vte.get_font()
     config = pango.FontDescription(self.term.config['font'])
     # dbg(current.get_size())
     dbg(config.get_size())
     dbg(allocation)
     if allocation.width < 600 or allocation.height < 400:
         config.set_size(int(config.get_size() * 0.85))
     self.term.set_font(config)
예제 #38
0
 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'])
예제 #39
0
 def callback(self, menuitems, menu, terminal):
     """Add our menu items to the menu"""
     if not self.watches.has_key(terminal):
         item = gtk.MenuItem(_("Watch for silence"))
         item.connect("activate", self.watch, terminal)
     else:
         item = gtk.MenuItem(_("Stop watching for silence"))
         item.connect("activate", self.unwatch, terminal)
     menuitems.append(item)
     dbg('Menu items appended')
예제 #40
0
 def tryAddLayoutMenuItem(self, name, terminal, menu):
     (isLayout, shortname) = self.tryGetLayoutShortName(name)
     if isLayout:
         layoutItem = gtk.MenuItem(_(shortname))
         layoutItem.connect(EVENT_ACTIVATE, self.loadCallback, terminal)
         menu.append(layoutItem)
         return True
     else:
         dbg("ignoring [%s] : %s" % (name, shortname))
         return False               
예제 #41
0
 def callback(self, menuitems, menu, terminal):
     """Add our menu item to the menu"""
     item = gtk.CheckMenuItem(_("Watch for _silence"))
     item.set_active(self.watches.has_key(terminal))
     if item.get_active():
         item.connect("activate", self.unwatch, terminal)
     else:
         item.connect("activate", self.watch, terminal)
     menuitems.append(item)
     dbg('Menu items appended')
예제 #42
0
 def callback(self, menuitems, menu, terminal):
     """Add our menu item to the menu"""
     item = Gtk.CheckMenuItem.new_with_mnemonic(_('Watch for _activity'))
     item.set_active(self.watches.has_key(terminal))
     if item.get_active():
         item.connect("activate", self.unwatch, terminal)
     else:
         item.connect("activate", self.watch, terminal)
     menuitems.append(item)
     dbg('Menu item appended')
예제 #43
0
 def writeXmlToFile (self, element, filename = None):
     if filename is None:
         newFilename = inputBox(title=SAVE_BOX_TITLE, message=SAVE_BOX_MESSAGE, default_text="")
         if not (newFilename is None or newFilename == ""):
             self.writeXmlToFile(element, newFilename)
         else:
             dbg("no filename provided; abort saving")
     else:           
         targetFileName = join(self.configDir,filename)
         targetFileName = targetFileName + LAYOUT_EXTENSION
         ET.ElementTree(element).write(targetFileName)
예제 #44
0
    def write_xml_to_file(self, element, filename=None):
        if filename is None:
            new_filename = input_box(title=SAVE_BOX_TITLE,
                                     message=SAVE_BOX_MESSAGE, default_text="")
            if not (new_filename is None or new_filename == ""):
                return self.write_xml_to_file(element, new_filename)
            else:
                dbg('no filename provided; abort saving')
                return

        target_filename = join(self.config_dir, filename)
        target_filename += LAYOUT_EXTENSION
        ElementTree.ElementTree(element).write(target_filename)
예제 #45
0
 def try_add_layout_menu_item(self, name, terminal, menu):
     """
     Checks if given file is a layout and add a context menu item if so.
     @param name: The file name of the possible layout.
     @param terminal: The terminal this context menu item belongs to.
     @param menu: Full gtk menu instance; not used here.
     """
     is_layout, short_name = self.try_get_layout_short_name(name)
     if is_layout:
         layout_item = gtk.MenuItem(short_name)
         layout_item.connect(EVENT_ACTIVATE, self.load_callback, terminal)
         menu.append(layout_item)
         return True
     dbg('ignoring [%s] : %s' % (name, short_name))
     return False
예제 #46
0
    def check_times(self, terminal):
        """Check if this terminal has gone silent"""
        time_now = time.mktime(time.gmtime())
        if not self.last_activities.has_key(terminal):
            dbg('Terminal %s has no last activity' % terminal)
            return True

        dbg('seconds since last activity: %f (%s)' % (time_now - self.last_activities[terminal], terminal))
        if time_now - self.last_activities[terminal] >= 10.0:
            del(self.last_activities[terminal])
            note = pynotify.Notification('Terminator', 'Silence in: %s' % 
                                         terminal.get_window_title(), 'terminator')
            note.show()

        return True
예제 #47
0
 def doExport(self, widget, terminal):
     """
     Export complete terminal content into file.
     """
     vte = terminal.get_vte()
     (startRow, endRow, endColumn) = self.getVteBufferRange(vte)
     content = vte.get_text_range(startRow, 0, endRow, endColumn, 
                                 lambda widget, col, row, junk: True)
     filename = self.getFilename()
     with open(filename, "w") as outputFile: 
         outputFile.writelines(content)
         outputFile.close()
     dbg("terminal content written to [%s]" % filename)
     if self.pluginConfig[SETTING_EXPORT_ENV] != "":
         terminal.feed('%s="%s"\n' % (self.pluginConfig[SETTING_EXPORT_ENV] ,filename))
     return filename
예제 #48
0
    def check_host(self, _vte, terminal):
        """Our host might have changed..."""
        self.update_watches()

        last_line = self.get_last_line(terminal)
        

        if last_line:
            patterns = self.get_patterns()
            for profile, pattern in patterns.iteritems():
                match = re.match(pattern, last_line)
                if match:
                    if profile in self.profiles and profile != terminal.get_profile():
                        dbg("switching to profile : "+profile)
                        terminal.set_profile(None, profile, False)
        return True
예제 #49
0
 def tryAddLayoutMenuItem(self, name, terminal, menu):
     """
     Checks if given file is a layout and add a context menu item if so.
     @param name: The file name of the possible layout.
     @param terminal: The terminal this context menu item belongs to.
     @param menu: Full gtk menu instance; not used here.
     """
     isLayout, shortname = self.tryGetLayoutShortName(name)
     if isLayout:
         layoutItem = gtk.MenuItem(_(shortname))
         layoutItem.connect(EVENT_ACTIVATE, self.loadCallback, terminal)
         menu.append(layoutItem)
         return True
     else:
         dbg("ignoring [%s] : %s" % (name, shortname))
         return False
예제 #50
0
 def do_export(self, _, terminal):
     """
     Export complete terminal content into file.
     """
     vte = terminal.get_vte()
     (start_row, end_row, end_column) = self.get_vte_buffer_range(vte)
     content = vte.get_text_range(start_row, 0, end_row, end_column,
                                  lambda widget, col, row, junk: True)
     filename = self.get_filename()
     with open(filename, "w") as output_file:
         output_file.writelines(content)
         output_file.close()
     dbg('terminal content written to [%s]' % filename)
     if self.plugin_config[SETTING_EXPORT_ENV] != '':
         terminal.feed('%s="%s"\n' % (self.plugin_config[SETTING_EXPORT_ENV], filename))
     return filename
예제 #51
0
    def check_times(self, terminal):
        """Check if this terminal has gone silent"""
        time_now = time.mktime(time.gmtime())
        if not self.last_activities.has_key(terminal):
            dbg('Terminal %s has no last activity' % terminal)
            return True

        dbg('seconds since last activity: %f (%s)' % (time_now - self.last_activities[terminal], terminal))
        if time_now - self.last_activities[terminal] >= self.timelimit:
            del(self.last_activities[terminal])
            note = pynotify.Notification('Terminator', 'Silence in: %s' % 
                                         terminal.get_window_title(), 'terminator')
            note.show()
            beeper = pyglet.media.load('/home/dave/unix_settings/install/ubuntu/terminator_beeping/doorbell.wav')
            beeper.play()    

        return True
예제 #52
0
 def load_profile_mappings(self):
     """ get profile mapping as declared with profile_patterns config key
     and append profile names as patterns
     profiles are saved as compiled patterns in an ordered dictionary
     so patterns mappings are parsed prior to profiles
     """
     
     if self.config and 'profile_patterns' in self.config:
         # we have to parse and create dict since configuration doesnt allow this
         for pre in self.config['profile_patterns']:
             kv=pre.split(":")
             if len(kv)==2:
                 # config recovered as ugly string with leading and trailing quotes removed, must remove ' and "
                 dbg("profile mapping : %s -> %s"%(kv[0].replace("'","").replace('"',''),kv[1].replace("'","").replace('"','')))
                 self.profile_mappings[re.compile(kv[0].replace("'","").replace('"',''))]=kv[1].replace("'","").replace('"','')
         # we load profile name as plain regex
         for v in Terminator().config.list_profiles():
                 self.profile_mappings[re.compile(v)]=v
    def check_host(self, _vte, terminal):
        """Our host might have changed..."""

        self.update_watches()

        last_line = self.get_last_line(terminal)

        if last_line:
            profiles = Terminator().config.list_profiles()
            patterns = self.get_patterns()
            for pattern in patterns:
                match = re.match(pattern, last_line)
                if match:
                    hostname = match.group(1)
                    if hostname in profiles and hostname != terminal.get_profile():
                        dbg("switching to profile " + hostname + ", because line '" + last_line + "' matches pattern '" + pattern + "'")
                        terminal.set_profile(None, hostname, False)
                        break
                    
        return True
예제 #54
0
    def ssh_sessions(self):
        """
            SSH Connections List
            return: list
        """
        ssh_sessions_list = []
        proc_list = self.get_proc_list
       
        for proc in proc_list:
            if 'ssh' == proc['name']:
                pid = proc['pid']
                pid_cmdfile = '/proc/%s/cmdline' % pid

                with open(pid_cmdfile, 'r') as f:
                    line = f.readlines()[0].split('\x00')[1]
                f.close()

                ssh_sessions_list.append(line)

        dbg("Sessions List: %s" % list(set(ssh_sessions_list)))
        return list(set(ssh_sessions_list))
예제 #55
0
    def connect_signals(self):
        # Install DBus handlers
        dbg('CliSnipsMenu :: Connecting to Session Bus')
        self.bus = dbus.SessionBus()
        clisnips_service = self.bus.get_object(BUS_NAME, BUS_PATH)
        self.clisnips = dbus.Interface(clisnips_service, BUS_NAME)
        self.bus.add_signal_receiver(self.on_insert_snippet,
                                     dbus_interface=BUS_NAME,
                                     signal_name='InsertSnippet')

        # Connect terminal focus signal
        self.handlers['focus'] = gobject.add_emission_hook(
            Terminal,
            'focus-in',
            self.on_terminal_focus_in
        )
        self.handlers["keypress"] = gobject.add_emission_hook(
            vte.Terminal,
            'key-press-event',
            self.on_terminal_key_pressed
        )
예제 #56
0
    def check_host(self, _vte, terminal):
        """Our host might have changed..."""
        self.update_watches()
        last_line = self.get_last_line(terminal)

        if last_line:
            sel_profile=self.failback_profile
            for prompt_pattern in self.patterns:
                match = prompt_pattern.match(last_line)
                if match:
                    hostname = match.group(1)
                    dbg("match search pattern : %s (%s) ->%s"%( prompt_pattern.pattern,last_line,hostname))
                    # since dict is ordered, iterate regexp/mapping, then profiles
                    for profile_pattern,profile in self.profile_mappings.items():
                        
                        # we create a pattern based on profile name
                        #profile_pattern=re.compile(profile)
	                if hostname == profile or profile_pattern.match(hostname):
                            dbg("matching profile '" + profile + "' found : line '" + last_line + "' matches prompt pattern '" + prompt_pattern.pattern + "' and profile pattern '"+profile_pattern.pattern+"'")
                            sel_profile=profile
                            # break on first profile match
                    	    break
 
                    # avoid re-applying profile if no change
                    if sel_profile != self.last_profile:
                        dbg("setting profile "+sel_profile)
                        terminal.set_profile(None, sel_profile, False)
                        self.last_profile=sel_profile
                    # break on first pattern match
                    break
                    
        return True
예제 #57
0
    def configure(self, widget, data = None):
      ui = {}
      dbox = Gtk.Dialog(
                      _("Custom Commands Configuration"),
                      None,
                      Gtk.DialogFlags.MODAL,
                      (
                        Gtk.STOCK_CANCEL, Gtk.ResponseType.REJECT,
                        Gtk.STOCK_OK, Gtk.ResponseType.ACCEPT
                      )
                    )

      icon_theme = Gtk.IconTheme()
      try:
        icon = icon_theme.load_icon('terminator-custom-commands', 48, 0)
      except (NameError, GObject.GError):
        dbg('Unable to load 48px Terminator preferences icon')
        icon = dbox.render_icon(Gtk.STOCK_DIALOG_INFO, Gtk.IconSize.BUTTON)
      dbox.set_icon(icon)

      store = Gtk.ListStore(bool, str, str)

      for command in [ self.cmd_list[key] for key in sorted(self.cmd_list.keys()) ]:
        store.append([command['enabled'], command['name'], command['command']])
 
      treeview = Gtk.TreeView(store)
      #treeview.connect("cursor-changed", self.on_cursor_changed, ui)
      selection = treeview.get_selection()
      selection.set_mode(Gtk.SelectionMode.SINGLE)
      selection.connect("changed", self.on_selection_changed, ui)
      ui['treeview'] = treeview

      renderer = Gtk.CellRendererToggle()
      renderer.connect('toggled', self.on_toggled, ui)
      column = Gtk.TreeViewColumn("Enabled", renderer, active=CC_COL_ENABLED)
      treeview.append_column(column)

      renderer = Gtk.CellRendererText()
      column = Gtk.TreeViewColumn("Name", renderer, text=CC_COL_NAME)
      treeview.append_column(column)

      renderer = Gtk.CellRendererText()
      column = Gtk.TreeViewColumn("Command", renderer, text=CC_COL_COMMAND)
      treeview.append_column(column)

      scroll_window = Gtk.ScrolledWindow()
      scroll_window.set_size_request(500, 250)
      scroll_window.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC)
      scroll_window.add_with_viewport(treeview)

      hbox = Gtk.HBox()
      hbox.pack_start(scroll_window, True, True)
      dbox.vbox.pack_start(hbox, True, True, 0)

      button_box = Gtk.VBox()

      button = Gtk.Button(stock=Gtk.STOCK_GOTO_TOP)
      button_box.pack_start(button, False, True)
      button.connect("clicked", self.on_goto_top, ui) 
      button.set_sensitive(False)
      ui['button_top'] = button

      button = Gtk.Button(stock=Gtk.STOCK_GO_UP)
      button_box.pack_start(button, False, True)
      button.connect("clicked", self.on_go_up, ui)
      button.set_sensitive(False)
      ui['button_up'] = button

      button = Gtk.Button(stock=Gtk.STOCK_GO_DOWN)
      button_box.pack_start(button, False, True)
      button.connect("clicked", self.on_go_down, ui) 
      button.set_sensitive(False)
      ui['button_down'] = button

      button = Gtk.Button(stock=Gtk.STOCK_GOTO_LAST)
      button_box.pack_start(button, False, True)
      button.connect("clicked", self.on_goto_last, ui) 
      button.set_sensitive(False)
      ui['button_last'] = button

      button = Gtk.Button(stock=Gtk.STOCK_NEW)
      button_box.pack_start(button, False, True)
      button.connect("clicked", self.on_new, ui) 
      ui['button_new'] = button

      button = Gtk.Button(stock=Gtk.STOCK_EDIT)
      button_box.pack_start(button, False, True)
      button.set_sensitive(False)
      button.connect("clicked", self.on_edit, ui) 
      ui['button_edit'] = button

      button = Gtk.Button(stock=Gtk.STOCK_DELETE)
      button_box.pack_start(button, False, True)
      button.connect("clicked", self.on_delete, ui) 
      button.set_sensitive(False)
      ui['button_delete'] = button



      hbox.pack_start(button_box, False, True)
      dbox.show_all()
      res = dbox.run()
      if res == Gtk.ResponseType.ACCEPT:
        self.update_cmd_list(store)
        self._save_config()
      dbox.destroy()
      return
예제 #58
0
    def load_xml_tree(self, layout_menu_item):
        filename = layout_menu_item.props.label + LAYOUT_EXTENSION
        filename = join(self.config_dir, filename)
        dbg('loading Layout config [%s]' % filename)

        return parse(filename)
예제 #59
0
except ImportError:
    print('You need to install the python bindings for ' \
           'gobject, gtk and pango to run Terminator.')
    sys.exit(1)

import terminatorlib.optionparse
from terminatorlib.terminator import Terminator
from terminatorlib.factory import Factory
from terminatorlib.version import APP_NAME, APP_VERSION
from terminatorlib.util import dbg, err

if __name__ == '__main__':
    dbus_service = None

    dbg ("%s starting up, version %s" % (APP_NAME, APP_VERSION))
  
    OPTIONS = terminatorlib.optionparse.parse_options()

    # Attempt to import our dbus server. If one exists already we will just
    # connect to that and ask for a new window. If not, we will create one and
    # continue. Failure to import dbus, or the global config option "dbus"
    # being False will cause us to continue without the dbus server and open a
    # window.
    try:
        if OPTIONS.nodbus:
            dbg('dbus disabled by command line')
            raise ImportError
        from terminatorlib import ipc
        try:
            dbus_service = ipc.DBusService()
예제 #60
0
 def reset_timer(self, _vte, terminal):
     """Reset the last-changed time for a terminal"""
     time_now = time.mktime(time.gmtime())
     self.last_activities[terminal] = time_now
     dbg('reset activity time for %s' % terminal)