2
# Terminator by Chris Jones <cmsj@tenshu.net>
4
"""custom_commands.py - Terminator Plugin to add custom command menu entries"""
8
# Fix imports when testing this file directly
9
if __name__ == '__main__':
10
sys.path.append( os.path.join(os.path.dirname(__file__), "../.."))
13
import terminatorlib.plugin as plugin
14
from terminatorlib.config import Config
15
from terminatorlib.translation import _
16
from terminatorlib.util import get_config_dir
18
(CC_COL_ENABLED, CC_COL_NAME, CC_COL_COMMAND) = range(0,3)
20
# Every plugin you want Terminator to load *must* be listed in 'available'
21
available = ['CustomCommandsMenu']
23
class CustomCommandsMenu(plugin.MenuItem):
24
"""Add custom commands to the terminal menu"""
25
capabilities = ['terminal_menu']
27
conf_file = os.path.join(get_config_dir(),"custom_commands")
31
sections = config.plugin_get_config(self.__class__.__name__)
32
if not isinstance(sections, dict):
36
if not (s.has_key("name") and s.has_key("command")):
37
print "CustomCommandsMenu: Ignoring section %s" % s
40
command = s["command"]
41
enabled = s["enabled"] and s["enabled"] or False
48
def callback(self, menuitems, menu, terminal):
49
"""Add our menu items to the menu"""
50
item = gtk.MenuItem(_('Custom Commands'))
51
menuitems.append(item)
54
item.set_submenu(submenu)
56
menuitem = gtk.ImageMenuItem(gtk.STOCK_PREFERENCES)
57
menuitem.connect("activate", self.configure)
58
submenu.append(menuitem)
60
menuitem = gtk.SeparatorMenuItem()
61
submenu.append(menuitem)
63
theme = gtk.IconTheme()
64
for command in self.cmd_list:
65
if not command['enabled']:
67
exe = command['command'].split(' ')[0]
68
iconinfo = theme.choose_icon([exe], gtk.ICON_SIZE_MENU, gtk.ICON_LOOKUP_USE_BUILTIN)
71
image.set_from_icon_name(exe, gtk.ICON_SIZE_MENU)
72
menuitem = gtk.ImageMenuItem(command['name'])
73
menuitem.set_image(image)
75
menuitem = gtk.MenuItem(command["name"])
76
menuitem.connect("activate", self._execute, {'terminal' : terminal, 'command' : command['command'] })
77
submenu.append(menuitem)
79
def _save_config(self):
82
length = len(self.cmd_list)
84
enabled = self.cmd_list[i]['enabled']
85
name = self.cmd_list[i]['name']
86
command = self.cmd_list[i]['command']
89
item['enabled'] = enabled
91
item['command'] = command
93
config.plugin_set(self.__class__.__name__, name, item)
97
def _execute(self, widget, data):
98
command = data['command']
99
if command[len(command)-1] != '\n':
100
command = command + '\n'
101
data['terminal'].vte.feed_child(command)
103
def configure(self, widget, data = None):
106
_("Custom Commands Configuration"),
110
gtk.STOCK_CANCEL, gtk.RESPONSE_REJECT,
111
gtk.STOCK_OK, gtk.RESPONSE_ACCEPT
114
store = gtk.ListStore(bool, str, str)
116
for command in self.cmd_list:
117
store.append([command['enabled'], command['name'], command['command']])
119
treeview = gtk.TreeView(store)
120
#treeview.connect("cursor-changed", self.on_cursor_changed, ui)
121
selection = treeview.get_selection()
122
selection.set_mode(gtk.SELECTION_SINGLE)
123
selection.connect("changed", self.on_selection_changed, ui)
124
ui['treeview'] = treeview
126
renderer = gtk.CellRendererToggle()
127
renderer.connect('toggled', self.on_toggled, ui)
128
column = gtk.TreeViewColumn("Enabled", renderer, active=CC_COL_ENABLED)
129
treeview.append_column(column)
131
renderer = gtk.CellRendererText()
132
column = gtk.TreeViewColumn("Name", renderer, text=CC_COL_NAME)
133
treeview.append_column(column)
135
renderer = gtk.CellRendererText()
136
column = gtk.TreeViewColumn("Command", renderer, text=CC_COL_COMMAND)
137
treeview.append_column(column)
140
hbox.pack_start(treeview)
141
dbox.vbox.pack_start(hbox)
143
button_box = gtk.VBox()
145
button = gtk.Button(stock=gtk.STOCK_GOTO_TOP)
146
button_box.pack_start(button, False, True)
147
button.connect("clicked", self.on_goto_top, ui)
148
button.set_sensitive(False)
149
ui['button_top'] = button
151
button = gtk.Button(stock=gtk.STOCK_GO_UP)
152
button_box.pack_start(button, False, True)
153
button.connect("clicked", self.on_go_up, ui)
154
button.set_sensitive(False)
155
ui['button_up'] = button
157
button = gtk.Button(stock=gtk.STOCK_GO_DOWN)
158
button_box.pack_start(button, False, True)
159
button.connect("clicked", self.on_go_down, ui)
160
button.set_sensitive(False)
161
ui['button_down'] = button
163
button = gtk.Button(stock=gtk.STOCK_GOTO_LAST)
164
button_box.pack_start(button, False, True)
165
button.connect("clicked", self.on_goto_last, ui)
166
button.set_sensitive(False)
167
ui['button_last'] = button
169
button = gtk.Button(stock=gtk.STOCK_NEW)
170
button_box.pack_start(button, False, True)
171
button.connect("clicked", self.on_new, ui)
172
ui['button_new'] = button
174
button = gtk.Button(stock=gtk.STOCK_EDIT)
175
button_box.pack_start(button, False, True)
176
button.set_sensitive(False)
177
button.connect("clicked", self.on_edit, ui)
178
ui['button_edit'] = button
180
button = gtk.Button(stock=gtk.STOCK_DELETE)
181
button_box.pack_start(button, False, True)
182
button.connect("clicked", self.on_delete, ui)
183
button.set_sensitive(False)
184
ui['button_delete'] = button
188
hbox.pack_start(button_box)
191
if res == gtk.RESPONSE_ACCEPT:
193
iter = store.get_iter_first()
196
(enabled, name, command) = store.get(iter,
200
self.cmd_list.append(
201
{'enabled' : enabled,
205
iter = store.iter_next(iter)
211
def on_toggled(self, widget, path, data):
212
treeview = data['treeview']
213
store = treeview.get_model()
214
iter = store.get_iter(path)
215
(enabled, name, command) = store.get(iter,
220
store.set_value(iter, CC_COL_ENABLED, not enabled)
221
for cmd in self.cmd_list:
222
if cmd['name'] == name:
223
cmd['enabled'] = not enabled
226
def on_selection_changed(self,selection, data=None):
227
treeview = selection.get_tree_view()
228
(model, iter) = selection.get_selected()
229
data['button_top'].set_sensitive(iter is not None)
230
data['button_up'].set_sensitive(iter is not None)
231
data['button_down'].set_sensitive(iter is not None)
232
data['button_last'].set_sensitive(iter is not None)
233
data['button_edit'].set_sensitive(iter is not None)
234
data['button_delete'].set_sensitive(iter is not None)
236
def _create_command_dialog(self, enabled_var = False, name_var = "", command_var = ""):
242
gtk.STOCK_CANCEL, gtk.RESPONSE_REJECT,
243
gtk.STOCK_OK, gtk.RESPONSE_ACCEPT
246
table = gtk.Table(3, 2)
248
label = gtk.Label(_("Enabled:"))
249
table.attach(label, 0, 1, 0, 1)
250
enabled = gtk.CheckButton()
251
enabled.set_active(enabled_var)
252
table.attach(enabled, 1, 2, 0, 1)
254
label = gtk.Label(_("Name:"))
255
table.attach(label, 0, 1, 1, 2)
257
name.set_text(name_var)
258
table.attach(name, 1, 2, 1, 2)
260
label = gtk.Label(_("Command:"))
261
table.attach(label, 0, 1, 2, 3)
262
command = gtk.Entry()
263
command.set_text(command_var)
264
table.attach(command, 1, 2, 2, 3)
266
dialog.vbox.pack_start(table)
268
return (dialog,enabled,name,command)
270
def _error(self, msg):
271
err = gtk.MessageDialog(dialog,
283
def on_new(self, button, data):
284
(dialog,enabled,name,command) = self._create_command_dialog()
287
if res == gtk.RESPONSE_ACCEPT:
288
item['enabled'] = enabled.get_active()
289
item['name'] = name.get_text()
290
item['command'] = command.get_text()
291
if item['name'] == '' or item['command'] == '':
292
err = gtk.MessageDialog(dialog,
296
_("You need to define a name and command")
301
# we have a new command
302
store = data['treeview'].get_model()
303
iter = store.get_iter_first()
306
if store.get_value(iter,CC_COL_NAME) == item['name']:
309
iter = store.iter_next(iter)
311
store.append((item['enabled'], item['name'], item['command']))
313
self._err(_("Name *%s* already exist") % item['name'])
316
def on_goto_top(self, button, data):
317
treeview = data['treeview']
318
selection = treeview.get_selection()
319
(store, iter) = selection.get_selected()
323
firstiter = store.get_iter_first()
324
store.move_before(iter, firstiter)
326
def on_go_up(self, button, data):
327
treeview = data['treeview']
328
selection = treeview.get_selection()
329
(store, iter) = selection.get_selected()
334
tmpiter = store.get_iter_first()
336
if(store.get_path(tmpiter) == store.get_path(iter)):
340
next = store.iter_next(tmpiter)
341
if(store.get_path(next) == store.get_path(iter)):
342
store.swap(iter, tmpiter)
346
def on_go_down(self, button, data):
347
treeview = data['treeview']
348
selection = treeview.get_selection()
349
(store, iter) = selection.get_selected()
353
next = store.iter_next(iter)
355
store.swap(iter, next)
357
def on_goto_last(self, button, data):
358
treeview = data['treeview']
359
selection = treeview.get_selection()
360
(store, iter) = selection.get_selected()
365
tmpiter = store.get_iter_first()
368
tmpiter = store.iter_next(tmpiter)
370
store.move_after(iter, lastiter)
373
def on_delete(self, button, data):
374
treeview = data['treeview']
375
selection = treeview.get_selection()
376
(store, iter) = selection.get_selected()
382
def on_edit(self, button, data):
383
treeview = data['treeview']
384
selection = treeview.get_selection()
385
(store, iter) = selection.get_selected()
390
(dialog,enabled,name,command) = self._create_command_dialog(
391
enabled_var = store.get_value(iter, CC_COL_ENABLED),
392
name_var = store.get_value(iter, CC_COL_NAME),
393
command_var = store.get_value(iter, CC_COL_COMMAND)
397
if res == gtk.RESPONSE_ACCEPT:
398
item['enabled'] = enabled.get_active()
399
item['name'] = name.get_text()
400
item['command'] = command.get_text()
401
if item['name'] == '' or item['command'] == '':
402
err = gtk.MessageDialog(dialog,
406
_("You need to define a name and command")
411
tmpiter = store.get_iter_first()
413
while tmpiter != None:
414
if store.get_path(tmpiter) != store.get_path(iter) and store.get_value(tmpiter,CC_COL_NAME) == item['name']:
417
tmpiter = store.iter_next(tmpiter)
420
CC_COL_ENABLED,item['enabled'],
421
CC_COL_NAME, item['name'],
422
CC_COL_COMMAND, item['command']
425
self._err(_("Name *%s* already exist") % item['name'])
430
if __name__ == '__main__':
431
c = CustomCommandsMenu()
432
c.configure(None, None)