~ubuntu-branches/ubuntu/saucy/terminator/saucy

« back to all changes in this revision

Viewing changes to terminatorlib/plugins/custom_commands.py

  • Committer: Bazaar Package Importer
  • Author(s): Nicolas Valcárcel Scerpella (Canonical)
  • Date: 2010-04-07 17:10:31 UTC
  • mfrom: (1.1.7 upstream)
  • Revision ID: james.westby@ubuntu.com-20100407171031-35nsuj0tmbub0bj5
Tags: 0.92-0ubuntu1
* New upstream release
* Remove python-xdg from Recommends. (Closes: #567967)
* Downgrade python-gnome2 to Recommends.
* Update python-gtk2 dependency to (>= 2.14.0)
* Add python-keybinder to Recommends

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#!/usr/bin/python
 
2
# Terminator by Chris Jones <cmsj@tenshu.net>
 
3
# GPL v2 only
 
4
"""custom_commands.py - Terminator Plugin to add custom command menu entries"""
 
5
import sys
 
6
import os
 
7
 
 
8
# Fix imports when testing this file directly
 
9
if __name__ == '__main__':
 
10
  sys.path.append( os.path.join(os.path.dirname(__file__), "../.."))
 
11
 
 
12
import gtk
 
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
 
17
 
 
18
(CC_COL_ENABLED, CC_COL_NAME, CC_COL_COMMAND) = range(0,3)
 
19
 
 
20
# Every plugin you want Terminator to load *must* be listed in 'available'
 
21
available = ['CustomCommandsMenu']
 
22
 
 
23
class CustomCommandsMenu(plugin.MenuItem):
 
24
    """Add custom commands to the terminal menu"""
 
25
    capabilities = ['terminal_menu']
 
26
    cmd_list = []
 
27
    conf_file = os.path.join(get_config_dir(),"custom_commands")
 
28
 
 
29
    def __init__( self):
 
30
      config = Config()
 
31
      sections = config.plugin_get_config(self.__class__.__name__)
 
32
      if not isinstance(sections, dict):
 
33
          return
 
34
      for part in sections:
 
35
        s = sections[part]
 
36
        if not (s.has_key("name") and s.has_key("command")):
 
37
          print "CustomCommandsMenu: Ignoring section %s" % s
 
38
          continue
 
39
        name = s["name"]
 
40
        command = s["command"]
 
41
        enabled = s["enabled"] and s["enabled"] or False
 
42
        self.cmd_list.append(
 
43
                              {'enabled' : enabled,
 
44
                                'name' : name,
 
45
                                'command' : command
 
46
                              }
 
47
                            )
 
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)
 
52
 
 
53
        submenu = gtk.Menu()
 
54
        item.set_submenu(submenu)
 
55
 
 
56
        menuitem = gtk.ImageMenuItem(gtk.STOCK_PREFERENCES)
 
57
        menuitem.connect("activate", self.configure)
 
58
        submenu.append(menuitem)
 
59
 
 
60
        menuitem = gtk.SeparatorMenuItem()
 
61
        submenu.append(menuitem)
 
62
 
 
63
        theme = gtk.IconTheme()
 
64
        for command in self.cmd_list:
 
65
          if not command['enabled']:
 
66
            continue
 
67
          exe = command['command'].split(' ')[0]
 
68
          iconinfo = theme.choose_icon([exe], gtk.ICON_SIZE_MENU, gtk.ICON_LOOKUP_USE_BUILTIN)
 
69
          if iconinfo:
 
70
            image = gtk.Image()
 
71
            image.set_from_icon_name(exe, gtk.ICON_SIZE_MENU)
 
72
            menuitem = gtk.ImageMenuItem(command['name'])
 
73
            menuitem.set_image(image)
 
74
          else:
 
75
            menuitem = gtk.MenuItem(command["name"])
 
76
          menuitem.connect("activate", self._execute, {'terminal' : terminal, 'command' : command['command'] })
 
77
          submenu.append(menuitem)
 
78
        
 
79
    def _save_config(self):
 
80
      config = Config()
 
81
      i = 0
 
82
      length = len(self.cmd_list)
 
83
      while i < length:
 
84
        enabled = self.cmd_list[i]['enabled']
 
85
        name = self.cmd_list[i]['name']
 
86
        command = self.cmd_list[i]['command']
 
87
       
 
88
        item = {}
 
89
        item['enabled'] = enabled
 
90
        item['name'] = name
 
91
        item['command'] = command
 
92
 
 
93
        config.plugin_set(self.__class__.__name__, name, item)
 
94
        config.save()
 
95
        i = i + 1
 
96
 
 
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)
 
102
 
 
103
    def configure(self, widget, data = None):
 
104
      ui = {}
 
105
      dbox = gtk.Dialog(
 
106
                      _("Custom Commands Configuration"),
 
107
                      None,
 
108
                      gtk.DIALOG_MODAL,
 
109
                      (
 
110
                        gtk.STOCK_CANCEL, gtk.RESPONSE_REJECT,
 
111
                        gtk.STOCK_OK, gtk.RESPONSE_ACCEPT
 
112
                      )
 
113
                    )
 
114
      store = gtk.ListStore(bool, str, str)
 
115
 
 
116
      for command in self.cmd_list:
 
117
        store.append([command['enabled'], command['name'], command['command']])
 
118
 
 
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
 
125
 
 
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)
 
130
 
 
131
      renderer = gtk.CellRendererText()
 
132
      column = gtk.TreeViewColumn("Name", renderer, text=CC_COL_NAME)
 
133
      treeview.append_column(column)
 
134
 
 
135
      renderer = gtk.CellRendererText()
 
136
      column = gtk.TreeViewColumn("Command", renderer, text=CC_COL_COMMAND)
 
137
      treeview.append_column(column)
 
138
 
 
139
      hbox = gtk.HBox()
 
140
      hbox.pack_start(treeview)
 
141
      dbox.vbox.pack_start(hbox)
 
142
 
 
143
      button_box = gtk.VBox()
 
144
 
 
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
 
150
 
 
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
 
156
 
 
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
 
162
 
 
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
 
168
 
 
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
 
173
 
 
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
 
179
 
 
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
 
185
 
 
186
 
 
187
 
 
188
      hbox.pack_start(button_box)
 
189
      dbox.show_all()
 
190
      res = dbox.run()
 
191
      if res == gtk.RESPONSE_ACCEPT:
 
192
        #we save the config
 
193
        iter = store.get_iter_first()
 
194
        self.cmd_list = []
 
195
        while iter:
 
196
          (enabled, name, command) = store.get(iter,
 
197
                                              CC_COL_ENABLED,
 
198
                                              CC_COL_NAME,
 
199
                                              CC_COL_COMMAND)
 
200
          self.cmd_list.append(
 
201
                            {'enabled' : enabled,
 
202
                            'name': name,
 
203
                            'command' : command}
 
204
                              )
 
205
          iter = store.iter_next(iter)
 
206
        self._save_config()
 
207
      
 
208
      dbox.destroy()
 
209
      return
 
210
 
 
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,
 
216
                                    CC_COL_ENABLED,
 
217
                                    CC_COL_NAME,
 
218
                                    CC_COL_COMMAND
 
219
                                        )
 
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
 
224
          break
 
225
 
 
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)
 
235
 
 
236
    def _create_command_dialog(self, enabled_var = False, name_var = "", command_var = ""):
 
237
      dialog = gtk.Dialog(
 
238
                        _("New Command"),
 
239
                        None,
 
240
                        gtk.DIALOG_MODAL,
 
241
                        (
 
242
                          gtk.STOCK_CANCEL, gtk.RESPONSE_REJECT,
 
243
                          gtk.STOCK_OK, gtk.RESPONSE_ACCEPT
 
244
                        )
 
245
                      )
 
246
      table = gtk.Table(3, 2)
 
247
 
 
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)
 
253
 
 
254
      label = gtk.Label(_("Name:"))
 
255
      table.attach(label, 0, 1, 1, 2)
 
256
      name = gtk.Entry()
 
257
      name.set_text(name_var)
 
258
      table.attach(name, 1, 2, 1, 2)
 
259
      
 
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)
 
265
 
 
266
      dialog.vbox.pack_start(table)
 
267
      dialog.show_all()
 
268
      return (dialog,enabled,name,command)
 
269
 
 
270
    def _error(self, msg):
 
271
      err = gtk.MessageDialog(dialog,
 
272
                              gtk.DIALOG_MODAL,
 
273
                              gtk.MESSAGE_ERROR,
 
274
                              gtk.BUTTONS_CLOSE,
 
275
                              msg
 
276
                            )
 
277
      err.run()
 
278
      err.destroy()
 
279
 
 
280
      
 
281
 
 
282
 
 
283
    def on_new(self, button, data):
 
284
      (dialog,enabled,name,command) = self._create_command_dialog()
 
285
      res = dialog.run()
 
286
      item = {}
 
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,
 
293
                                  gtk.DIALOG_MODAL,
 
294
                                  gtk.MESSAGE_ERROR,
 
295
                                  gtk.BUTTONS_CLOSE,
 
296
                                  _("You need to define a name and command")
 
297
                                )
 
298
          err.run()
 
299
          err.destroy()
 
300
        else:
 
301
          # we have a new command
 
302
          store = data['treeview'].get_model()
 
303
          iter = store.get_iter_first()
 
304
          name_exist = False
 
305
          while iter != None:
 
306
            if store.get_value(iter,CC_COL_NAME) == item['name']:
 
307
              name_exist = True
 
308
              break
 
309
            iter = store.iter_next(iter)
 
310
          if not name_exist:
 
311
            store.append((item['enabled'], item['name'], item['command']))
 
312
          else:
 
313
            self._err(_("Name *%s* already exist") % item['name'])
 
314
      dialog.destroy()
 
315
 
 
316
    def on_goto_top(self, button, data):
 
317
      treeview = data['treeview']
 
318
      selection = treeview.get_selection()
 
319
      (store, iter) = selection.get_selected()
 
320
      
 
321
      if not iter:
 
322
        return
 
323
      firstiter = store.get_iter_first()
 
324
      store.move_before(iter, firstiter)
 
325
 
 
326
    def on_go_up(self, button, data):
 
327
      treeview = data['treeview']
 
328
      selection = treeview.get_selection()
 
329
      (store, iter) = selection.get_selected()
 
330
       
 
331
      if not iter:
 
332
        return
 
333
 
 
334
      tmpiter = store.get_iter_first()
 
335
 
 
336
      if(store.get_path(tmpiter) == store.get_path(iter)):
 
337
        return
 
338
 
 
339
      while tmpiter:
 
340
        next = store.iter_next(tmpiter)
 
341
        if(store.get_path(next) == store.get_path(iter)):
 
342
          store.swap(iter, tmpiter)
 
343
          break
 
344
        tmpiter = next
 
345
 
 
346
    def on_go_down(self, button, data):
 
347
      treeview = data['treeview']
 
348
      selection = treeview.get_selection()
 
349
      (store, iter) = selection.get_selected()
 
350
      
 
351
      if not iter:
 
352
        return
 
353
      next = store.iter_next(iter)
 
354
      if next:
 
355
        store.swap(iter, next)
 
356
 
 
357
    def on_goto_last(self, button, data):
 
358
      treeview = data['treeview']
 
359
      selection = treeview.get_selection()
 
360
      (store, iter) = selection.get_selected()
 
361
      
 
362
      if not iter:
 
363
        return
 
364
      lastiter = iter
 
365
      tmpiter = store.get_iter_first()
 
366
      while tmpiter:
 
367
        lastiter = tmpiter
 
368
        tmpiter = store.iter_next(tmpiter)
 
369
      
 
370
      store.move_after(iter, lastiter)
 
371
 
 
372
 
 
373
    def on_delete(self, button, data):
 
374
      treeview = data['treeview']
 
375
      selection = treeview.get_selection()
 
376
      (store, iter) = selection.get_selected()
 
377
      if iter:
 
378
        store.remove(iter)
 
379
      
 
380
      return
 
381
 
 
382
    def on_edit(self, button, data):
 
383
      treeview = data['treeview']
 
384
      selection = treeview.get_selection()
 
385
      (store, iter) = selection.get_selected()
 
386
      
 
387
      if not iter:
 
388
        return
 
389
       
 
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)
 
394
                                                                  )
 
395
      res = dialog.run()
 
396
      item = {}
 
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,
 
403
                                  gtk.DIALOG_MODAL,
 
404
                                  gtk.MESSAGE_ERROR,
 
405
                                  gtk.BUTTONS_CLOSE,
 
406
                                  _("You need to define a name and command")
 
407
                                )
 
408
          err.run()
 
409
          err.destroy()
 
410
        else:
 
411
          tmpiter = store.get_iter_first()
 
412
          name_exist = False
 
413
          while tmpiter != None:
 
414
            if store.get_path(tmpiter) != store.get_path(iter) and store.get_value(tmpiter,CC_COL_NAME) == item['name']:
 
415
              name_exist = True
 
416
              break
 
417
            tmpiter = store.iter_next(tmpiter)
 
418
          if not name_exist:
 
419
            store.set(iter,
 
420
                      CC_COL_ENABLED,item['enabled'],
 
421
                      CC_COL_NAME, item['name'],
 
422
                      CC_COL_COMMAND, item['command']
 
423
                      )
 
424
          else:
 
425
            self._err(_("Name *%s* already exist") % item['name'])
 
426
 
 
427
      dialog.destroy()
 
428
 
 
429
      
 
430
if __name__ == '__main__':
 
431
  c = CustomCommandsMenu()
 
432
  c.configure(None, None)
 
433
  gtk.main()
 
434