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

« back to all changes in this revision

Viewing changes to terminatorlib/prefs_profile.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
 
 
3
 
from terminatorlib.config import dbg,err,DEFAULTS,TerminatorConfValuestoreRC
4
 
from terminatorlib.keybindings import TerminatorKeybindings, KeymapError
5
 
from terminatorlib.version import APP_NAME, APP_VERSION
6
 
from terminatorlib import translation
7
 
 
8
 
import gtk, gobject
9
 
 
10
 
class ProfileEditor:
11
 
  # lists of which settings to put in which tabs
12
 
  appearance = ['titlebars', 'zoomedtitlebar', 'titletips', 'allow_bold', 'audible_bell', 'visible_bell', 'urgent_bell', 'force_no_bell', 'background_darkness', 'background_type', 'background_image', 'cursor_blink', 'cursor_shape', 'font', 'scrollbar_position', 'scroll_background', 'use_system_font', 'use_theme_colors', 'enable_real_transparency']
13
 
  colours = ['foreground_color','background_color', 'cursor_color', 'palette', 'title_tx_txt_color', 'title_tx_bg_color', 'title_rx_txt_color', 'title_rx_bg_color', 'title_ia_txt_color', 'title_ia_bg_color']
14
 
  behaviour = ['backspace_binding', 'delete_binding', 'emulation', 'scroll_on_keystroke', 'scroll_on_output', 'alternate_screen_scroll', 'scrollback_lines', 'focus', 'focus_on_close', 'exit_action', 'word_chars', 'mouse_autohide', 'use_custom_command', 'custom_command', 'http_proxy', 'encoding']
15
 
  globals = ['fullscreen', 'maximise', 'borderless', 'handle_size', 'cycle_term_tab', 'close_button_on_tab', 'tab_position', 'copy_on_selection', 'extreme_tabs', 'try_posix_regexp']
16
 
 
17
 
  # metadata about the settings
18
 
  data = {'titlebars': ['Show titlebars', 'This places a bar above each terminal which displays its title.'],
19
 
          'zoomedtitlebar': ['Show titlebar when zoomed', 'This places an informative bar above a zoomed terminal to indicate there are hidden terminals.'],
20
 
          'titletips': ['Show title tooltips', 'This adds a tooltip to each terminal which contains its title'],
21
 
          'allow_bold': ['Allow bold text', 'Controls whether or not the terminals will honour requests for bold text'],
22
 
          'silent_bell': ['', 'When enabled, bell events will generate a flash. When disabled, they will generate a beep'],
23
 
          'background_darkness': ['', 'Controls how much the background will be tinted'],
24
 
          'scroll_background': ['', 'When enabled the background image will scroll with the text'],
25
 
          'force_no_bell': ['', 'Disable both the visual and audible bells'],
26
 
          'tab_position': ['', 'Controls the placement of the tab bar'],
27
 
          'use_theme_colors': ['', 'Take the foreground and background colours from the current GTK theme'],
28
 
          'enable_real_transparency': ['', 'If you are running a composited desktop (e.g. compiz), enabling this option will enable "true" transpraency'],
29
 
          'handle_size': ['', 'This controls the size of the border between terminals. Values 0 to 5 are in pixels, while -1 means the value will be decided by your normal GTK theme.'],
30
 
          'close_window': ['Quit Terminator', ''],
31
 
          'toggle_zoom': ['Toggle maximise terminal', ''],
32
 
          'scaled_zoom': ['Toggle zoomed terminal', ''],
33
 
          'prev_tab': ['Previous tab', ''],
34
 
          'split_vert': ['Split vertically', ''],
35
 
          'split_horiz': ['Split horizontally', ''],
36
 
          'go_prev': ['Focus previous terminal', ''],
37
 
          'go_next': ['Focus next terminal', ''],
38
 
          'close_term': ['Close terminal', ''],
39
 
          'new_root_tab': ['New root tab', ''],
40
 
          'zoom_normal': ['Zoom reset', ''],
41
 
          'reset': ['Reset terminal state', ''],
42
 
          'reset_clear': ['Reset and clear terminal', ''],
43
 
          'hide_window': ['Toggle visibility of the window', ''],
44
 
          'title_tx_txt_color': ['Tx Title Foreground Color', ''],
45
 
          'title_tx_bg_color': ['Tx Title Background Color', ''],
46
 
          'title_rx_txt_color': ['Rx Title Foreground Color', ''],
47
 
          'title_rx_bg_color': ['Rx Title Background Color', ''],
48
 
          'title_ia_txt_color': ['Inactive Title Foreground Color', ''],
49
 
          'title_ia_bg_color': ['Inactive Title Background Color', ''],
50
 
         }
51
 
 
52
 
  # dictionary for results after setting
53
 
  widgets = {}
54
 
 
55
 
  # combobox settings
56
 
  scrollbar_position = ['left', 'right', 'disabled']
57
 
  backspace_del_binding = ['ascii-del', 'control-h', 'escape-sequence', 'delete-sequence']
58
 
  focus = ['click', 'sloppy', 'mouse']
59
 
  background_type = ['solid', 'image', 'transparent']
60
 
  tab_position = ['top', 'bottom', 'left', 'right']
61
 
  tab_position_gtk = {'top' : gtk.POS_TOP, 'bottom' : gtk.POS_BOTTOM, 'left' : gtk.POS_LEFT, 'right' : gtk.POS_RIGHT}
62
 
  cursor_shape = ['block', 'ibeam', 'underline']
63
 
 
64
 
  def __init__ (self, term):
65
 
    self.term = term
66
 
    self.window = gtk.Window ()
67
 
    self.notebook = gtk.Notebook()
68
 
    self.box = gtk.VBox()
69
 
    self.warning = gtk.Label()
70
 
 
71
 
    self.warning.set_use_markup (True)
72
 
    self.warning.set_line_wrap (True)
73
 
    self.warning.set_markup ("<i><b>NOTE:</b> These settings will not be saved. See:</i> <tt>man terminator_config</tt>")
74
 
 
75
 
    self.butbox = gtk.HButtonBox()
76
 
    self.applybut = gtk.Button(stock=gtk.STOCK_APPLY)
77
 
    self.applybut.connect ("clicked", self.apply)
78
 
    self.cancelbut = gtk.Button(stock=gtk.STOCK_CLOSE)
79
 
    self.cancelbut.connect ("clicked", self.cancel)
80
 
 
81
 
    self.box.pack_start(self.warning, False, False)
82
 
    self.box.pack_start(self.notebook, False, False)
83
 
    self.box.pack_end(self.butbox, False, False)
84
 
 
85
 
    self.butbox.set_layout(gtk.BUTTONBOX_END)
86
 
    self.butbox.pack_start(self.applybut, False, False)
87
 
    self.butbox.pack_start(self.cancelbut, False, False)
88
 
    self.window.add (self.box)
89
 
 
90
 
    self.notebook.append_page (self.auto_add (gtk.Table (), self.globals), gtk.Label ("Global Settings"))
91
 
    self.notebook.append_page (self.prepare_keybindings (), gtk.Label ("Keybindings"))
92
 
    self.notebook.append_page (self.auto_add (gtk.Table (), self.appearance), gtk.Label ("Appearance"))
93
 
    self.notebook.append_page (self.auto_add (gtk.Table (), self.colours), gtk.Label ("Colours"))
94
 
    self.notebook.append_page (self.auto_add (gtk.Table (), self.behaviour), gtk.Label ("Behaviour"))
95
 
 
96
 
  def go (self):
97
 
    self.window.show_all ()
98
 
 
99
 
  def source_get_type (self, key):
100
 
    if DEFAULTS.has_key (key):
101
 
      return DEFAULTS[key].__class__.__name__
102
 
    elif DEFAULTS['keybindings'].has_key (key):
103
 
      return DEFAULTS['keybindings'][key].__class__.__name__
104
 
    else:
105
 
      raise KeyError
106
 
 
107
 
  def source_get_value (self, key):
108
 
    try:
109
 
      return self.term.conf.__getattr__(key)
110
 
    except AttributeError:
111
 
      try:
112
 
        return self.term.conf.keybindings[key]
113
 
      except AttributeError:
114
 
        pass
115
 
 
116
 
  def source_get_keyname (self, key):
117
 
    if self.data.has_key (key) and self.data[key][0] != '':
118
 
      label_text = self.data[key][0]
119
 
    else:
120
 
      label_text = key.replace ('_', ' ').capitalize ()
121
 
    return label_text
122
 
 
123
 
  def auto_add (self, table, list):
124
 
    row = 0
125
 
    for key in list:
126
 
      table.resize (row + 1, 2)
127
 
      label = gtk.Label (self.source_get_keyname (key))
128
 
      wrapperbox = gtk.HBox()
129
 
      wrapperbox.pack_start(label, False, True)  
130
 
 
131
 
      type = self.source_get_type (key)
132
 
      value = self.source_get_value (key)
133
 
      widget = None
134
 
 
135
 
      if key == 'font':
136
 
        widget = gtk.FontButton(value)
137
 
      elif key == 'scrollback_lines':
138
 
        # estimated byte size per line according to g-t:
139
 
        # sizeof(void *) + sizeof(char *) + sizeof(int) + (80 * (sizeof(int32) + 4)
140
 
        widget = gtk.SpinButton()
141
 
        widget.set_digits(0)
142
 
        widget.set_increments(100, 1000)
143
 
        widget.set_range(0, 100000)
144
 
        widget.set_value(value)
145
 
      elif key == 'scrollbar_position':
146
 
        if value == 'hidden':
147
 
          value = 'disabled'
148
 
        widget = gtk.combo_box_new_text()
149
 
        for item in self.scrollbar_position:
150
 
          widget.append_text (item)
151
 
        if value in self.scrollbar_position:
152
 
          widget.set_active (self.scrollbar_position.index(value))
153
 
      elif key == 'backspace_binding':
154
 
        widget = gtk.combo_box_new_text()
155
 
        for item in self.backspace_del_binding:
156
 
          widget.append_text (item)
157
 
        if value in self.backspace_del_binding:
158
 
          widget.set_active (self.backspace_del_binding.index(value))
159
 
      elif key == 'delete_binding':
160
 
        widget = gtk.combo_box_new_text()
161
 
        for item in self.backspace_del_binding:
162
 
          widget.append_text (item)
163
 
        if value in self.backspace_del_binding:
164
 
          widget.set_active (self.backspace_del_binding.index(value))
165
 
      elif key == 'focus':
166
 
        widget = gtk.combo_box_new_text()
167
 
        for item in self.focus:
168
 
          widget.append_text (item)
169
 
        if value in self.focus:
170
 
          widget.set_active (self.focus.index(value))
171
 
      elif key == 'background_type':
172
 
        widget = gtk.combo_box_new_text()
173
 
        for item in self.background_type:
174
 
          widget.append_text (item)
175
 
        if value in self.background_type:
176
 
          widget.set_active (self.background_type.index(value))
177
 
      elif key == 'background_darkness':
178
 
        widget = gtk.HScale ()
179
 
        widget.set_digits (1)
180
 
        widget.set_draw_value (True)
181
 
        widget.set_value_pos (gtk.POS_LEFT)
182
 
        widget.set_range (0, 1)
183
 
        widget.set_value (value)
184
 
      elif key == 'handle_size':
185
 
        widget = gtk.HScale ()
186
 
        widget.set_digits (0)
187
 
        widget.set_draw_value (True)
188
 
        widget.set_value_pos (gtk.POS_LEFT)
189
 
        widget.set_range (-1, 5)
190
 
        widget.set_value (value)
191
 
      elif key == 'foreground_color':
192
 
        widget = gtk.ColorButton (gtk.gdk.color_parse (value))
193
 
      elif key == 'background_color':
194
 
        widget = gtk.ColorButton (gtk.gdk.color_parse (value))
195
 
      elif key == 'cursor_color':
196
 
        if not value:
197
 
          value = self.source_get_value ('foreground_color')
198
 
        widget = gtk.ColorButton (gtk.gdk.color_parse (value))
199
 
      elif key == 'palette':
200
 
        colours = value.split (':')
201
 
        numcolours = len (colours)
202
 
        widget = gtk.Table (2, numcolours / 2)
203
 
        x = 0
204
 
        y = 0
205
 
        for thing in colours:
206
 
          if x == numcolours / 2:
207
 
            y += 1
208
 
            x = 0
209
 
          widget.attach (gtk.ColorButton (gtk.gdk.color_parse (thing)), x, x + 1, y, y + 1)
210
 
          x += 1
211
 
      elif key in ['title_tx_txt_color', 'title_tx_bg_color', 'title_rx_txt_color', 'title_rx_bg_color', 'title_ia_txt_color', 'title_ia_bg_color']:
212
 
        widget = gtk.ColorButton (gtk.gdk.color_parse (value))
213
 
      elif key == 'background_image':
214
 
        widget = gtk.FileChooserButton('Select a File')
215
 
        filter = gtk.FileFilter()
216
 
        filter.add_mime_type ('image/*')
217
 
        widget.add_filter (filter)
218
 
        widget.set_local_only (True)
219
 
        if value:
220
 
          widget.set_filename (value)
221
 
      elif key == 'tab_position':
222
 
        widget = gtk.combo_box_new_text()
223
 
        for item in self.tab_position:
224
 
          widget.append_text (item)
225
 
        if value in self.tab_position:
226
 
          widget.set_active (self.tab_position.index(value))
227
 
      elif key == 'cursor_shape':
228
 
        widget = gtk.combo_box_new_text()
229
 
        for item in self.cursor_shape:
230
 
          widget.append_text (item)
231
 
        if value in self.cursor_shape:
232
 
          widget.set_active (self.cursor_shape.index (value))
233
 
      else:
234
 
        if type == "bool":
235
 
          widget = gtk.CheckButton ()
236
 
          widget.set_active (value)
237
 
        elif type in ["str", "int", "float"]:
238
 
          widget = gtk.Entry ()
239
 
          widget.set_text (str(value))
240
 
        elif type == "list":
241
 
          continue
242
 
        else:
243
 
          err("Unknown type: %s for key: %s" % (type, key))
244
 
          continue
245
 
 
246
 
      if hasattr(widget, 'set_tooltip_text') and self.data.has_key (key):
247
 
        widget.set_tooltip_text (self.data[key][1])
248
 
  
249
 
      widget.set_name(key)
250
 
      self.widgets[key] = widget
251
 
      table.attach (wrapperbox, 0, 1, row, row + 1, gtk.EXPAND|gtk.FILL, gtk.FILL)
252
 
      table.attach (widget, 1, 2, row, row + 1,  gtk.EXPAND|gtk.FILL, gtk.FILL)
253
 
      row += 1
254
 
 
255
 
    return (table)
256
 
 
257
 
  def apply (self, data):
258
 
    values = {}
259
 
    for page in [self.appearance, self.behaviour, self.globals, self.colours]:
260
 
      for property in page:
261
 
        widget = self.widgets[property]
262
 
 
263
 
        if isinstance (widget, gtk.SpinButton):
264
 
          value = widget.get_value ()
265
 
        elif isinstance (widget, gtk.Entry):
266
 
          value = widget.get_text()
267
 
        elif isinstance (widget, gtk.CheckButton):
268
 
          value = widget.get_active()
269
 
        elif isinstance (widget, gtk.ComboBox):
270
 
          if widget.name == 'scrollbar_position':
271
 
            bucket = self.scrollbar_position
272
 
          elif widget.name == 'backspace_binding' or widget.name == 'delete_binding':
273
 
            bucket = self.backspace_del_binding
274
 
          elif widget.name == 'focus':
275
 
            bucket = self.focus
276
 
          elif widget.name == 'background_type':
277
 
            bucket = self.background_type
278
 
          elif widget.name == 'tab_position':
279
 
            bucket = self.tab_position
280
 
          elif widget.name == 'cursor_shape':
281
 
            bucket = self.cursor_shape
282
 
          else:
283
 
            err("Unknown bucket type for %s" % widget.name)
284
 
            continue
285
 
  
286
 
          value = bucket[widget.get_active()]
287
 
        elif isinstance (widget, gtk.FontButton):
288
 
          value = widget.get_font_name()
289
 
        elif isinstance (widget, gtk.HScale):
290
 
          value = widget.get_value()
291
 
          if widget.get_digits() == 0:
292
 
            value = int(value)
293
 
        elif isinstance (widget, gtk.ColorButton):
294
 
          value = widget.get_color().to_string()
295
 
        elif isinstance (widget, gtk.FileChooserButton):
296
 
          value = widget.get_filename()
297
 
        elif widget.get_name() == 'palette':
298
 
          value = ''
299
 
          valuebits = []
300
 
          children = widget.get_children()
301
 
          children.reverse()
302
 
          for child in children:
303
 
            valuebits.append (child.get_color().to_string())
304
 
          value = ':'.join (valuebits)
305
 
        else:
306
 
          value = None
307
 
          err("skipping unknown property: %s" % property)
308
 
 
309
 
        values[property] = value
310
 
 
311
 
    has_changed = False
312
 
    changed = []
313
 
    for source in self.term.conf.sources:
314
 
      if isinstance (source, TerminatorConfValuestoreRC):
315
 
        for property in values:
316
 
          try:
317
 
            if self.source_get_value(property) != values[property]:
318
 
              dbg("%s changed from %s to %s" % (property, self.source_get_value(property), values[property]))
319
 
              source.values[property] = values[property]
320
 
              has_changed = True
321
 
              changed.append(property)
322
 
          except KeyError:
323
 
            pass
324
 
    if has_changed:
325
 
      for changer in changed:
326
 
        if changer == "fullscreen":
327
 
          self.term.fullscreen_absolute(values[changer])
328
 
        elif changer == "maximise":
329
 
          if values[changer]:
330
 
            self.term.maximize()
331
 
          else:
332
 
            self.term.unmaximize()
333
 
        elif changer == "borderless":
334
 
          self.term.window.set_decorated (not values[changer])
335
 
        elif changer == "handle_size":
336
 
          self.term.set_handle_size(values[changer])
337
 
          gtk.rc_reset_styles(gtk.settings_get_default())
338
 
        elif changer == "tab_position":
339
 
          notebook = self.term.window.get_child()
340
 
          new_pos = self.tab_position_gtk[values[changer]]
341
 
          angle = 0
342
 
          if isinstance (notebook, gtk.Notebook):
343
 
            notebook.set_tab_pos(new_pos)
344
 
            for i in xrange(0,notebook.get_n_pages()):
345
 
              notebook.get_tab_label(notebook.get_nth_page(i)).update_angle()
346
 
          pass
347
 
        elif changer == "close_button_on_tab":
348
 
          notebook = self.term.window.get_child()
349
 
          if isinstance (notebook, gtk.Notebook):
350
 
            for i in xrange(0,notebook.get_n_pages()):
351
 
              notebook.get_tab_label(notebook.get_nth_page(i)).update_closebut()
352
 
        # FIXME: which others? cycle_term_tab, copy_on_selection, extreme_tabs, try_posix_regexp
353
 
          
354
 
      self.term.reconfigure_vtes()
355
 
 
356
 
    # Check for changed keybindings
357
 
    changed_keybindings = []
358
 
    for row in self.liststore:
359
 
      accel = gtk.accelerator_name (row[2], row[3])
360
 
      value = self.term.conf.keybindings[row[0]]
361
 
      if isinstance (value, tuple):
362
 
        value = value[0]
363
 
      keyval = 0
364
 
      mask = 0
365
 
      if value is not None and value != "None":
366
 
        try:
367
 
          (keyval, mask) = self.tkbobj._parsebinding(value)
368
 
        except KeymapError:
369
 
          pass
370
 
      if (row[2], row[3]) != (keyval, mask):
371
 
        changed_keybindings.append ((row[0], accel))
372
 
        dbg("%s changed from %s to %s" % (row[0], self.term.conf.keybindings[row[0]], accel))
373
 
 
374
 
    newbindings = self.term.conf.keybindings
375
 
    for binding in changed_keybindings:
376
 
      newbindings[binding[0]] = binding[1]
377
 
    self.term.keybindings.configure (newbindings)
378
 
 
379
 
  def cancel (self, data):
380
 
    self.window.destroy()
381
 
    self.term.options = None
382
 
    del(self)
383
 
 
384
 
  def prepare_keybindings (self):
385
 
    self.liststore = gtk.ListStore (gobject.TYPE_STRING, gobject.TYPE_STRING, gobject.TYPE_UINT, gobject.TYPE_UINT, gobject.TYPE_BOOLEAN)
386
 
    self.liststore.set_sort_column_id (0, gtk.SORT_ASCENDING)
387
 
    self.tkbobj = TerminatorKeybindings()
388
 
    keyval = None
389
 
    mask = None
390
 
 
391
 
    for binding in DEFAULTS['keybindings']:
392
 
      value = self.term.conf.keybindings[binding]
393
 
      keyval = 0
394
 
      mask = 0
395
 
      if isinstance (value, tuple):
396
 
        value = value[0]
397
 
      if value is not None and value != "None":
398
 
        try:
399
 
          (keyval, mask) = self.tkbobj._parsebinding (value)
400
 
        except KeymapError:
401
 
          pass
402
 
      self.liststore.append ([binding, self.source_get_keyname (binding), keyval, mask, True])
403
 
      dbg("Appended row: %s, %s, %s" % (binding, keyval, mask))
404
 
 
405
 
    self.treeview = gtk.TreeView(self.liststore)
406
 
 
407
 
    cell = gtk.CellRendererText()
408
 
    col = gtk.TreeViewColumn(_("Name"))
409
 
    col.pack_start(cell, True)
410
 
    col.add_attribute(cell, "text", 0)
411
 
 
412
 
    self.treeview.append_column(col)
413
 
 
414
 
    cell = gtk.CellRendererText()
415
 
    col = gtk.TreeViewColumn(_("Action"))
416
 
    col.pack_start(cell, True)
417
 
    col.add_attribute(cell, "text", 1)
418
 
 
419
 
    self.treeview.append_column(col)
420
 
 
421
 
    cell = gtk.CellRendererAccel()
422
 
    col = gtk.TreeViewColumn(_("Keyboard shortcut"))
423
 
    col.pack_start(cell, True)
424
 
    col.set_attributes(cell, accel_key=2, accel_mods=3, editable=4)
425
 
 
426
 
    cell.connect ('accel-edited', self.edited)
427
 
    cell.connect ('accel-cleared', self.cleared)
428
 
 
429
 
    self.treeview.append_column(col)
430
 
 
431
 
    scrollwin = gtk.ScrolledWindow ()
432
 
    scrollwin.set_policy (gtk.POLICY_NEVER, gtk.POLICY_AUTOMATIC)
433
 
    scrollwin.add (self.treeview)
434
 
    return (scrollwin)
435
 
 
436
 
  def edited (self, obj, path, key, mods, code):
437
 
    iter = self.liststore.get_iter_from_string(path)
438
 
    self.liststore.set(iter, 2, key, 3, mods)
439
 
 
440
 
  def cleared (self, obj, path):
441
 
    iter = self.liststore.get_iter_from_string(path)
442
 
    self.liststore.set(iter, 2, 0, 3, 0)