clicompanion-devs team mailing list archive
-
clicompanion-devs team
-
Mailing list archive
-
Message #00314
[Merge] lp:~dcaro/clicompanion/fix-614789 into lp:clicompanion
David Caro has proposed merging lp:~dcaro/clicompanion/fix-614789 into lp:clicompanion.
Requested reviews:
CLI Companion Development Team (clicompanion-devs)
For more details, see:
https://code.launchpad.net/~dcaro/clicompanion/fix-614789/+merge/88269
Fixed the copy-paste problem, now it is configured in the keybindings section.
--
https://code.launchpad.net/~dcaro/clicompanion/fix-614789/+merge/88269
Your team CLI Companion Development Team is requested to review the proposed merge of lp:~dcaro/clicompanion/fix-614789 into lp:clicompanion.
=== modified file 'clicompanionlib/config.py'
--- clicompanionlib/config.py 2012-01-09 09:17:27 +0000
+++ clicompanionlib/config.py 2012-01-11 20:43:15 +0000
@@ -78,9 +78,13 @@
'edit_command': 'unused',
'add_tab': 'F7',
'close_tab': 'unused',
+ 'next_tab': 'unused',
+ 'previous_tab': 'unused',
'toggle_fullscreen': 'F12',
'toggle_maximize': 'F11',
'toggle_hide_ui': 'F9',
+ 'copy': 'shift+ctrl+C',
+ 'paste': 'shift+ctrl+C',
}
### funcname : labelname
@@ -94,9 +98,13 @@
'edit_command': 'Edit command',
'add_tab': 'Add tab',
'close_tab': 'Close tab',
+ 'next_tab': 'Go to the next tab',
+ 'previous_tab': 'Go to the previous tab',
'toggle_fullscreen': 'Toggle fullscreen',
'toggle_maximize': 'Maximize',
'toggle_hide_ui': 'Hide UI',
+ 'copy': 'Copy the selected text',
+ 'paste': 'Paste the text in the terminal',
}
=== modified file 'clicompanionlib/helpers.py'
--- clicompanionlib/helpers.py 2012-01-08 14:43:50 +0000
+++ clicompanionlib/helpers.py 2012-01-11 20:43:15 +0000
@@ -2,23 +2,23 @@
# -*- coding: utf-8 -*-
#
# helpers.py - Helper dialogs for clicompanion
-#
+#
# Copyright 2012 Duane Hinnen, Kenny Meyer, Marcos Vanetta, Marek Bardoński,
# David Caro
-#
-# This program is free software: you can redistribute it and/or modify it
-# under the terms of the GNU General Public License version 3, as published
-# by the Free Software Foundation.
-#
-# This program is distributed in the hope that it will be useful, but
-# WITHOUT ANY WARRANTY; without even the implied warranties of
-# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
-# PURPOSE. See the GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License along
-# with this program. If not, see <http://www.gnu.org/licenses/>.
-#
-#
+#
+# This program is free software: you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 3, as published
+# by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranties of
+# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
+# PURPOSE. See the GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+#
####
## This file keeps some popups that are shown across the program execution,
## that aren't directly related with a class, like the edit comand popup or the
=== modified file 'clicompanionlib/plugins.py'
--- clicompanionlib/plugins.py 2012-01-08 00:48:43 +0000
+++ clicompanionlib/plugins.py 2012-01-11 20:43:15 +0000
@@ -2,21 +2,21 @@
# -*- coding: utf-8 -*-
#
# plugins.py - Plugin related clases for the clicompanion
-#
+#
# Copyright 2012 David Caro <david.caro.estevez@xxxxxxxxx>
-#
-# This program is free software: you can redistribute it and/or modify it
-# under the terms of the GNU General Public License version 3, as published
-# by the Free Software Foundation.
-#
-# This program is distributed in the hope that it will be useful, but
-# WITHOUT ANY WARRANTY; without even the implied warranties of
-# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
-# PURPOSE. See the GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License along
-# with this program. If not, see <http://www.gnu.org/licenses/>.
-#
+#
+# This program is free software: you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 3, as published
+# by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranties of
+# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
+# PURPOSE. See the GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program. If not, see <http://www.gnu.org/licenses/>.
+#
#################################################
## The plugins
##
=== modified file 'clicompanionlib/preferences.py'
--- clicompanionlib/preferences.py 2012-01-08 00:48:43 +0000
+++ clicompanionlib/preferences.py 2012-01-11 20:43:15 +0000
@@ -2,22 +2,22 @@
# -*- coding: utf-8 -*-
#
# preferences.py - Preferences dialogs for clicompanion
-#
+#
# Copyright 2012 Duane Hinnen, Kenny Meyer, Marcos Vanettai, Marek Bardoński,
# David Caro <david.caro.estevez@xxxxxxxxx>
-#
-# This program is free software: you can redistribute it and/or modify it
-# under the terms of the GNU General Public License version 3, as published
-# by the Free Software Foundation.
-#
-# This program is distributed in the hope that it will be useful, but
-# WITHOUT ANY WARRANTY; without even the implied warranties of
-# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
-# PURPOSE. See the GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License along
-# with this program. If not, see <http://www.gnu.org/licenses/>.
-#
+#
+# This program is free software: you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 3, as published
+# by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranties of
+# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
+# PURPOSE. See the GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program. If not, see <http://www.gnu.org/licenses/>.
+#
############################################
## The preferences window is a popup that shows all the configuration options
## allowing the user to change them, also handles the profiles creatin and
=== modified file 'clicompanionlib/tabs.py'
--- clicompanionlib/tabs.py 2012-01-08 00:48:43 +0000
+++ clicompanionlib/tabs.py 2012-01-11 20:43:15 +0000
@@ -56,7 +56,7 @@
()),
}
- def __init__(self, title, config, profile='default'):
+ def __init__(self, title, config, profile='default', directory=None):
gtk.ScrolledWindow.__init__(self)
self.config = config
self.title = title
@@ -67,10 +67,17 @@
self.update_records = self.config.getboolean(self.profile,
'update_login_records')
dbg('Updating login records: ' + self.update_records.__repr__())
- self.vte.fork_command(cc_utils.shell_lookup(),
- logutmp=self.update_records,
- logwtmp=self.update_records,
- loglastlog=self.update_records)
+ if directory:
+ self.pid = self.vte.fork_command(cc_utils.shell_lookup(),
+ logutmp=self.update_records,
+ logwtmp=self.update_records,
+ loglastlog=self.update_records,
+ directory=directory)
+ else:
+ self.pid = self.vte.fork_command(cc_utils.shell_lookup(),
+ logutmp=self.update_records,
+ logwtmp=self.update_records,
+ loglastlog=self.update_records)
self.vte.connect("button_press_event", self.copy_paste_menu)
self.update_config()
self.show_all()
@@ -332,11 +339,16 @@
if title == None:
title = 'Tab %d' % self.gcp
- newtab = TerminalTab(title, self.global_config)
-
+ cwd = None
if self.get_n_pages() > 1:
dbg('More than one tab, showing them.')
self.set_show_tabs(True)
+ current_page = self.get_nth_page(self.get_current_page())
+ cwd = cc_utils.get_pid_cwd(current_page.pid)
+ if cwd:
+ newtab = TerminalTab(title, self.global_config, directory=cwd)
+ else:
+ newtab = TerminalTab(title, self.global_config)
label = self.create_tab_label(title, newtab)
self.insert_page(newtab, label, self.get_n_pages() - 1)
self.set_current_page(self.get_n_pages() - 2)
@@ -391,6 +403,18 @@
if self.get_n_pages() != 1:
self.focus()
+ def next_tab(self):
+ if self.get_current_page() == self.get_n_pages() - 2:
+ self.set_current_page(0)
+ else:
+ self.next_page()
+
+ def prev_tab(self):
+ if self.get_current_page() == 0:
+ self.set_current_page(self.get_n_pages() - 2)
+ else:
+ self.prev_page()
+
def quit_tab(self, tab=None):
if not tab:
tab = self.get_nth_page(self.get_current_page())
@@ -418,3 +442,13 @@
if not config:
config = self.global_config
tab.update_config(config)
+
+ def copy(self):
+ page = self.get_current_page()
+ term = self.get_nth_page(page)
+ term.vte.copy_clipboard()
+
+ def paste(self, text):
+ page = self.get_current_page()
+ term = self.get_nth_page(page)
+ term.vte.feed_child(text)
=== modified file 'clicompanionlib/utils.py'
--- clicompanionlib/utils.py 2012-01-08 00:48:43 +0000
+++ clicompanionlib/utils.py 2012-01-11 20:43:15 +0000
@@ -253,3 +253,14 @@
def __init__(self):
self.__dict__ = self.__shared_state
+
+
+def get_pid_cwd(pid):
+ """Extract the cwd of a PID from proc, given the PID and the /proc path to
+ insert it into, e.g. /proc/%s/cwd"""
+ try:
+ cwd = os.path.realpath('/proc/%s/cwd' % pid)
+ except Exception, ex:
+ dbg('Unable to get cwd for PID %s: %s' % (pid, ex))
+ cwd = '/'
+ return cwd
=== modified file 'clicompanionlib/view.py'
--- clicompanionlib/view.py 2012-01-08 00:48:43 +0000
+++ clicompanionlib/view.py 2012-01-11 20:43:15 +0000
@@ -184,7 +184,7 @@
self.config = config
newplugins = self.pluginloader.get_plugins('CommandTab')
for plugin in self.loaded_plugins.keys():
- if plugin not in [ name for name, cl in newplugins]:
+ if plugin not in [name for name, cl in newplugins]:
dbg('Disabling plugin %s' % plugin)
self.remove_page(self.page_num(self.loaded_plugins[plugin]))
self.loaded_plugins.pop(plugin)
@@ -212,6 +212,8 @@
self.filtered = False
self.fullscr = False
+ self.clipboard = gtk.clipboard_get(gtk.gdk.SELECTION_CLIPBOARD)
+
self.config = config
self.load_plugins()
@@ -332,20 +334,6 @@
self.cmd_notebook.get_command()[0]).run())
self.button_box.connect('add_tab',
lambda *x: self.term_notebook.add_tab())
- ## right click menu event capture
- # Allow enable drag and drop of rows including row move
-# self.treeview.enable_model_drag_source( gtk.gdk.BUTTON1_MASK,
-# TARGETS,
-# gtk.gdk.ACTION_DEFAULT |
-# gtk.gdk.ACTION_COPY)
-# self.treeview.enable_model_drag_dest(TARGETS,
-# gtk.gdk.ACTION_DEFAULT)
-#
-# self.treeview.connect ("drag_data_get", self.drag_data_get_event)
-# self.treeview.connect ("drag_data_received",
-# self.drag_data_received_event)
-# self.treeview.connect("drag_drop", self.on_drag_drop )
-
## show everything
self.show_all()
## set the focus on the terminal
@@ -468,6 +456,19 @@
def close_tab(self):
self.term_notebook.quit_tab()
+ def next_tab(self):
+ self.term_notebook.next_tab()
+
+ def previous_tab(self):
+ self.term_notebook.prev_tab()
+
+ def copy(self):
+ self.term_notebook.copy()
+
+ def paste(self):
+ text = self.clipboard.wait_for_text() or ''
+ self.term_notebook.paste(text)
+
def toggle_hide_ui(self):
if self.hiddenui:
self.show_ui()
@@ -478,15 +479,19 @@
if self.hiddenui:
return
dbg('Hide UI')
+ self.set_border_width(0)
self.l_vbox.remove(self.term_notebook)
self.remove(self.vpane)
self.add(self.term_notebook)
self.hiddenui = True
+ ## set the focus on the terminal
+ self.term_notebook.focus()
def show_ui(self):
if not self.hiddenui:
return
dbg('Show UI')
+ self.set_border_width(5)
self.remove(self.term_notebook)
btns = self.l_vbox.get_children()[0]
self.l_vbox.remove(btns)
@@ -494,12 +499,16 @@
self.l_vbox.pack_start(btns, False, False, 0)
self.add(self.vpane)
self.hiddenui = False
+ ## set the focus on the terminal
+ self.term_notebook.focus()
def toggle_maximize(self):
if not self.maximized:
self.maximize()
else:
self.unmaximize()
+ ## set the focus on the terminal
+ self.term_notebook.focus()
self.maximized = not self.maximized
def toggle_fullscreen(self):
@@ -516,70 +525,8 @@
self.unfullscreen()
self.set_border_width(5)
self.fullscr = not self.fullscr
-
- ### TODO: pass these functions to the LocalCommandList class
- def on_drag_drop(self, treeview, *x):
- '''
- Stop the signal when in search mode
- '''
- if self.FILTER:
- treeview.stop_emission('drag_drop')
-
- def drag_data_get_event(self, treeview, context, selection, target_id,
- etime):
- """
- Executed on dragging
- """
- treeselection = treeview.get_selection()
- model, iter = treeselection.get_selected()
- data = model.get(iter, 0, 1, 2)
- selection.set(selection.target, 8, '\t'.join(data))
-
- def drag_data_received_event(self, treeview, context, x, y, selection,
- info, etime):
- """
- Executed when dropping.
- """
- global CMNDS
- ## if we are in a search, do nothing
- if self.FILTER == 1:
- return
- model = treeview.get_model()
- ## get the destination
- drop_info = treeview.get_dest_row_at_pos(x, y)
- if drop_info:
- path, position = drop_info
- iter = model.get_iter(path)
- dest = list(model.get(iter, 0, 1, 2))
-
- ## parse all the incoming commands
- for data in selection.data.split('\n'):
- # if we got an empty line skip it
- if not data.replace('\r', ''):
- continue
- # format the incoming string
- orig = data.replace('\r', '').split('\t', 2)
- orig = [fld.strip() for fld in orig]
- # fill the empty fields
- if len(orig) < 3:
- orig = orig + ('', ) * (3 - len(orig))
- dbg('Got drop of command %s' % '_\t_'.join(orig))
-
- if drop_info:
- if (position == gtk.TREE_VIEW_DROP_BEFORE
- or position == gtk.TREE_VIEW_DROP_INTO_OR_BEFORE):
- dbg('\t to before dest %s' % '_\t_'.join(dest))
- CMNDS.drag_n_drop(orig, dest, before=True)
- else:
- dbg('\t to after dest %s' % '_\t_'.join(dest))
- CMNDS.drag_n_drop(orig, dest, before=False)
- else:
- dbg('\t to the end')
- CMNDS[len(CMNDS)] = orig
- if context.action == gtk.gdk.ACTION_MOVE:
- context.finish(True, True, etime)
- self.sync_cmnds()
- CMNDS.save()
+ ## set the focus on the terminal
+ self.term_notebook.focus()
def main(self):
try: