1
from gettext import gettext as _
2
from os.path import join, isdir
5
import gtk, gtk.gdk, gtk.glade, gobject, gconf
6
import colorblind, colorblind.Utils, colorblind.ColorblindApplet
8
MAXINT = 2 ** ((8 * struct.calcsize('i')) - 1) - 1
10
class AccelEntry( gobject.GObject ):
13
'accel-edited': (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE,
14
[gobject.TYPE_STRING, gobject.TYPE_UINT, gobject.TYPE_UINT, gobject.TYPE_UINT]),
15
'keyboard-shortcut' : (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, [gobject.TYPE_STRING, gobject.TYPE_UINT]),
18
'accel_key': ( gobject.TYPE_UINT, "Accelerator key", "Accelerator key", 0, MAXINT, 0, gobject.PARAM_READWRITE ),
19
'accel_mods': ( gobject.TYPE_FLAGS, "Accelerator modifiers", "Accelerator modifiers", 0, gobject.PARAM_READWRITE ),
20
'keycode': ( gobject.TYPE_UINT, "Accelerator keycode", "Accelerator keycode", 0, MAXINT, 0, gobject.PARAM_READWRITE ),
23
FORBIDDEN_KEYS = (gtk.keysyms.BackSpace, gtk.keysyms.Begin, gtk.keysyms.Delete, gtk.keysyms.End, gtk.keysyms.Down,
24
gtk.keysyms.Home, gtk.keysyms.Insert, gtk.keysyms.Left, gtk.keysyms.Page_Down, gtk.keysyms.Page_Up,
25
gtk.keysyms.Right, gtk.keysyms.Tab, gtk.keysyms.Up, gtk.keysyms.bar, gtk.keysyms.braceleft,
26
gtk.keysyms.braceright, gtk.keysyms.colon, gtk.keysyms.comma, gtk.keysyms.dollar, gtk.keysyms.equal,
27
gtk.keysyms.exclam, gtk.keysyms.hyphen, gtk.keysyms.period, gtk.keysyms.percent, gtk.keysyms.question,
28
gtk.keysyms.quotedbl, gtk.keysyms.semicolon, gtk.keysyms.slash, gtk.keysyms.space, gtk.keysyms.underscore)
30
def __init__(self, accel_name='', cb_pref_ui = None):
31
self.__old_value = None
32
self._attributes = {'accel_key': 0, 'accel_mods': 0, 'keycode': 0}
33
self._cb_pref_ui = cb_pref_ui
34
gobject.GObject.__init__(self)
36
self.entry = gtk.Entry()
37
self.entry.set_property('editable', False)
38
self.entry.connect('button-press-event', self.__on_button_press_event)
39
self.entry.connect('key-press-event', self.__on_key_press_event)
40
self.entry.connect('focus-out-event', self.__on_focus_out_event)
42
self.set_accelerator_name(accel_name)
44
def do_get_property(self, pspec):
45
if pspec.name in ('accel_key', 'accel_mods', 'keycode'):
46
return self._attributes[pspec.name]
48
def do_set_property(self, pspec, value):
49
if pspec.name == 'accel_key':
50
self.set_accelerator(int(value), self.get_property('keycode'), self.get_property('accel_mask'))
51
elif pspec.name == 'accel_mods':
52
self.set_accelerator(self.get_property('accel_key'), self.get_property('keycode'), int(value))
53
elif pspec.name == 'keycode':
54
self.set_accelerator(self.get_property('accel_key'), int(value), self.get_property('accel_mask'))
56
def get_accelerator_name(self):
57
return self.entry.get_text()
59
def set_accelerator_name(self, value):
63
(keyval, mods) = gtk.accelerator_parse(value)
64
if gtk.accelerator_valid(keyval, mods):
65
self.entry.set_text(value)
68
def get_accelerator(self):
69
return ( self.get_property('accel_key'), self.get_property('keycode'), self.get_property('accel_mods') )
71
def set_accelerator(self, keyval, mods, keycode):
74
if keyval != self._attributes['accel_key']:
75
self._attributes['accel_key'] = keyval
76
self.notify('accel_key')
79
if mods != self._attributes['accel_mods']:
80
self._attributes['accel_mods'] = mods
81
self.notify('accel_mods')
84
if keycode != self._attributes['keycode']:
85
self._attributes['keycode'] = keycode
86
self.notify('keycode')
91
text = self.__convert_keysym_state_to_string (keyval, keycode, mods)
92
self.entry.set_text(text)
94
def __convert_keysym_state_to_string(self, keysym, keycode, mask):
95
name = gtk.accelerator_name(keysym, mask)
97
name = "%s0x%02x" % (name, keycode)
100
def get_widget(self):
103
def __on_button_press_event(self, entry, event):
104
self.__old_value = self.entry.get_text()
105
entry.set_text( _('New accelerator...') )
109
def __on_key_press_event(self, entry, event):
113
keymap = gtk.gdk.keymap_get_default()
114
translation = keymap.translate_keyboard_state(event.hardware_keycode, event.state, event.group)
115
if translation == None:
116
consumed_modifiers = 0
118
(keyval, egroup, level, consumed_modifiers) = translation
120
accel_keyval = gtk.gdk.keyval_to_lower(event.keyval)
121
if (accel_keyval == gtk.keysyms.ISO_Left_Tab):
122
accel_keyval = gtk.keysyms.Tab
124
accel_mods = event.state & gtk.accelerator_get_default_mod_mask()
126
# Filter consumed modifiers
127
accel_mods &= ~consumed_modifiers
129
# Put shift back if it changed the case of the key, not otherwise.
130
if (accel_keyval != event.keyval):
131
accel_mods |= gtk.gdk.SHIFT_MASK
134
if accel_keyval == gtk.keysyms.Escape:
138
# Do not make keyboard unusable
139
if ( ((accel_mods == 0 or accel_mods == gtk.gdk.SHIFT_MASK) and accel_keyval >= gtk.keysyms.a and accel_keyval <= gtk.keysyms.z) # alphabet
140
or (accel_mods == 0 and (
141
(accel_keyval >= 48 and accel_keyval <= 57) # number keys
142
or (accel_keyval >= gtk.keysyms.kana_fullstop and accel_keyval <= gtk.keysyms.semivoicedsound)
143
or (accel_keyval >= gtk.keysyms.Arabic_comma and accel_keyval <= gtk.keysyms.Arabic_sukun)
144
or (accel_keyval >= gtk.keysyms.Serbian_dje and accel_keyval <= gtk.keysyms.Cyrillic_HARDSIGN)
145
or (accel_keyval >= gtk.keysyms.Greek_ALPHAaccent and accel_keyval <= gtk.keysyms.Greek_omega)
146
or (accel_keyval >= gtk.keysyms.hebrew_doublelowline and accel_keyval <= gtk.keysyms.hebrew_taf)
147
or (accel_keyval >= gtk.keysyms.Thai_kokai and accel_keyval <= gtk.keysyms.Thai_lekkao)
148
or (accel_keyval >= gtk.keysyms.Hangul and accel_keyval <= gtk.keysyms.Hangul_Special)
149
or (accel_keyval >= gtk.keysyms.Hangul_Kiyeog and accel_keyval <= gtk.keysyms.Hangul_J_YeorinHieuh)
151
or (accel_keyval in self.FORBIDDEN_KEYS)
152
or (accel_keyval == 0 and accel_mods != 0) ):
153
dialog = gtk.MessageDialog (self.entry.get_toplevel(),
154
gtk.DIALOG_DESTROY_WITH_PARENT | gtk.DIALOG_MODAL,
157
_("The shortcut \"%s\" cannot be used because it will become unusable to type using this key.\nPlease try with a key such as Control, Alt or Shift at the same time.\n")
158
% gtk.accelerator_name(accel_keyval, accel_mods)
165
if not gtk.accelerator_valid(accel_keyval, accel_mods):
169
accel_name = self.__convert_keysym_state_to_string(accel_keyval, event.hardware_keycode, accel_mods)
171
# Yeah, I know, this is very ugly code, but I don't know how do
172
# it better for now... patches are welcome :-)
173
if entry == self._cb_pref_ui.get_on_off_entry().entry:
174
keybinding_switch_string = colorblind.GCONF_CLIENT.get_string(colorblind.GCONF_KEYBINDING_SWITCH)
175
if accel_name == keybinding_switch_string:
177
elif entry == self._cb_pref_ui.get_switch_entry().entry:
178
keybinding_on_off_string = colorblind.GCONF_CLIENT.get_string(colorblind.GCONF_KEYBINDING_ONOFF)
179
if accel_name == keybinding_on_off_string:
182
self.set_accelerator(accel_keyval, accel_mods, event.hardware_keycode)
183
self.__old_value = None
184
self.emit('accel-edited', accel_name, accel_keyval, accel_mods, event.hardware_keycode)
187
def __on_focus_out_event(self, entry, event):
188
if self.__old_value != None:
192
self.set_accelerator_name(self.__old_value)
194
class ColorblindPreferencesUI:
195
CB_FILTER_NO_FILTER, CB_FILTER_SELECTIVE_SATURATE_RED, CB_FILTER_SELECTIVE_SATURATE_GREEN, CB_FILTER_SELECTIVE_SATURATE_BLUE, CB_FILTER_SELECTIVE_DESSATURATE_RED, CB_FILTER_SELECTIVE_DESSATURATE_GREEN, CB_FILTER_SELECTIVE_DESSATURATE_BLUE, CB_FILTER_POSITIVE_HUE_SHIFT, CB_FILTER_NEGATIVE_HUE_SHIFT = range (9)
197
def __init__(self, applet):
198
self.glade = gtk.glade.XML(join(colorblind.SHARED_DATA_DIR, "colorblind-prefs.glade"))
200
self.dialog = self.glade.get_widget("window_preferences")
201
self.radio1 = self.glade.get_widget("radio_filter_red_saturate")
202
self.radio2 = self.glade.get_widget("radio_filter_green_saturate")
203
self.radio3 = self.glade.get_widget("radio_filter_blue_saturate")
204
self.radio4 = self.glade.get_widget("radio_filter_red_dessaturate")
205
self.radio5 = self.glade.get_widget("radio_filter_green_dessaturate")
206
self.radio6 = self.glade.get_widget("radio_filter_blue_dessaturate")
207
self.radio7 = self.glade.get_widget("radio_filter_positive_hue_shift")
208
self.radio8 = self.glade.get_widget("radio_filter_negative_hue_shift")
209
self.hbox_default = self.glade.get_widget("hbox_default")
210
self.combofilters = gtk.combo_box_new_text ()
211
self.hbox_default.add (self.combofilters)
212
self.combofilters.append_text (_("Selective Red Saturation"))
213
self.combofilters.append_text (_("Selective Green Saturation"))
214
self.combofilters.append_text (_("Selective Blue Saturation"))
215
self.combofilters.append_text (_("Selective Red Dessaturation"))
216
self.combofilters.append_text (_("Selective Green Dessaturation"))
217
self.combofilters.append_text (_("Selective Blue Dessaturation"))
218
self.combofilters.append_text (_("Positive Hue Shift"))
219
self.combofilters.append_text (_("Negative Hue Shift"))
220
self.check_default_filter = self.glade.get_widget("check_default_filter")
221
self.button_close = self.glade.get_widget("button_close")
223
# Retreive current values
224
self.keybinding_on_off = colorblind.GCONF_CLIENT.get_string(applet.prefs.GCONF_KEYBINDING_ONOFF)
225
self.keyboard_shortcut_entry_on_off = AccelEntry("<Shift><Control>c", self)
226
self.keyboard_shortcut_entry_on_off.connect('accel-edited', self.on_keyboard_shortcut_entry_changed, colorblind.GCONF_KEYBINDING_ONOFF)
227
self.glade.get_widget("table_shortcut").attach(self.keyboard_shortcut_entry_on_off.get_widget(), 1, 2, 0, 1)
229
self.keybinding_switch = colorblind.GCONF_CLIENT.get_string(applet.prefs.GCONF_KEYBINDING_SWITCH)
230
self.keyboard_shortcut_entry_switch = AccelEntry("<Shift><Control>n", self)
231
self.keyboard_shortcut_entry_switch.connect('accel-edited', self.on_keyboard_shortcut_entry_changed, colorblind.GCONF_KEYBINDING_SWITCH)
232
self.glade.get_widget("table_shortcut").attach(self.keyboard_shortcut_entry_switch.get_widget(), 1, 2, 1, 2)
234
self.colorblind_filter = colorblind.GCONF_CLIENT.get_int(colorblind.GCONF_COLORBLIND_FILTER)
235
if self.colorblind_filter == None:
236
self.colorblind_filter = self.CB_FILTER_POSITIVE_HUE_SHIFT
237
self.default_filter = colorblind.GCONF_CLIENT.get_int(colorblind.GCONF_DEFAULT_FILTER)
238
if self.colorblind_filter == None:
239
self.colorblind_filter = self.CB_FILTER_POSITIVE_HUE_SHIFT
240
self.check_default = colorblind.GCONF_CLIENT.get_bool(colorblind.GCONF_CHECK_DEFAULT)
241
if self.check_default == None:
242
self.check_default = False
246
self.set_ui_signals ()
248
def __on_radio_toggled_event (self, entry):
249
if entry == self.radio1:
250
colorblind.GCONF_CLIENT.set_int(colorblind.GCONF_COLORBLIND_FILTER, self.CB_FILTER_SELECTIVE_SATURATE_RED)
251
elif entry == self.radio2:
252
colorblind.GCONF_CLIENT.set_int(colorblind.GCONF_COLORBLIND_FILTER, self.CB_FILTER_SELECTIVE_SATURATE_GREEN)
253
elif entry == self.radio3:
254
colorblind.GCONF_CLIENT.set_int(colorblind.GCONF_COLORBLIND_FILTER, self.CB_FILTER_SELECTIVE_SATURATE_BLUE)
255
elif entry == self.radio4:
256
colorblind.GCONF_CLIENT.set_int(colorblind.GCONF_COLORBLIND_FILTER, self.CB_FILTER_SELECTIVE_DESSATURATE_RED)
257
elif entry == self.radio5:
258
colorblind.GCONF_CLIENT.set_int(colorblind.GCONF_COLORBLIND_FILTER, self.CB_FILTER_SELECTIVE_DESSATURATE_GREEN)
259
elif entry == self.radio6:
260
colorblind.GCONF_CLIENT.set_int(colorblind.GCONF_COLORBLIND_FILTER, self.CB_FILTER_SELECTIVE_DESSATURATE_BLUE)
261
elif entry == self.radio7:
262
colorblind.GCONF_CLIENT.set_int(colorblind.GCONF_COLORBLIND_FILTER, self.CB_FILTER_POSITIVE_HUE_SHIFT)
263
elif entry == self.radio8:
264
colorblind.GCONF_CLIENT.set_int(colorblind.GCONF_COLORBLIND_FILTER, self.CB_FILTER_NEGATIVE_HUE_SHIFT)
265
colorblind.ColorblindApplet.active_actual_filter ()
267
def __on_changed_event (self, entry):
268
i = entry.get_active () + 1
269
if i == self.CB_FILTER_SELECTIVE_SATURATE_RED:
270
colorblind.GCONF_CLIENT.set_int(colorblind.GCONF_DEFAULT_FILTER, self.CB_FILTER_SELECTIVE_SATURATE_RED)
271
elif i == self.CB_FILTER_SELECTIVE_SATURATE_GREEN:
272
colorblind.GCONF_CLIENT.set_int(colorblind.GCONF_DEFAULT_FILTER, self.CB_FILTER_SELECTIVE_SATURATE_GREEN)
273
elif i == self.CB_FILTER_SELECTIVE_SATURATE_BLUE:
274
colorblind.GCONF_CLIENT.set_int(colorblind.GCONF_DEFAULT_FILTER, self.CB_FILTER_SELECTIVE_SATURATE_BLUE)
275
elif i == self.CB_FILTER_SELECTIVE_DESSATURATE_RED:
276
colorblind.GCONF_CLIENT.set_int(colorblind.GCONF_DEFAULT_FILTER, self.CB_FILTER_SELECTIVE_DESSATURATE_RED)
277
elif i == self.CB_FILTER_SELECTIVE_DESSATURATE_GREEN:
278
colorblind.GCONF_CLIENT.set_int(colorblind.GCONF_DEFAULT_FILTER, self.CB_FILTER_SELECTIVE_DESSATURATE_GREEN)
279
elif i == self.CB_FILTER_SELECTIVE_DESSATURATE_BLUE:
280
colorblind.GCONF_CLIENT.set_int(colorblind.GCONF_DEFAULT_FILTER, self.CB_FILTER_SELECTIVE_DESSATURATE_BLUE)
281
elif i == self.CB_FILTER_POSITIVE_HUE_SHIFT:
282
colorblind.GCONF_CLIENT.set_int(colorblind.GCONF_DEFAULT_FILTER, self.CB_FILTER_POSITIVE_HUE_SHIFT)
283
elif i == self.CB_FILTER_NEGATIVE_HUE_SHIFT:
284
colorblind.GCONF_CLIENT.set_int(colorblind.GCONF_DEFAULT_FILTER, self.CB_FILTER_NEGATIVE_HUE_SHIFT)
286
def __on_check_toggled_event (self, entry):
287
state = entry.get_active ()
288
colorblind.GCONF_CLIENT.set_bool(colorblind.GCONF_CHECK_DEFAULT, state)
290
def __on_click_button_close_event (self, entry):
291
self.dialog.destroy ()
293
def set_ui_signals (self):
294
self.radio1.connect('toggled', self.__on_radio_toggled_event)
295
self.radio2.connect('toggled', self.__on_radio_toggled_event)
296
self.radio3.connect('toggled', self.__on_radio_toggled_event)
297
self.radio4.connect('toggled', self.__on_radio_toggled_event)
298
self.radio5.connect('toggled', self.__on_radio_toggled_event)
299
self.radio6.connect('toggled', self.__on_radio_toggled_event)
300
self.radio7.connect('toggled', self.__on_radio_toggled_event)
301
self.radio8.connect('toggled', self.__on_radio_toggled_event)
303
self.combofilters.connect('changed', self.__on_changed_event)
305
self.check_default_filter.connect('toggled', self.__on_check_toggled_event)
306
self.button_close.connect ('clicked', self.__on_click_button_close_event)
308
def show_run_hide(self, parent):
310
self.dialog.set_screen(parent.get_screen())
311
self.dialog.show_all ()
313
def get_on_off_entry (self):
314
return self.keyboard_shortcut_entry_on_off
316
def get_switch_entry (self):
317
return self.keyboard_shortcut_entry_switch
320
if self.keybinding_on_off != None:
321
self.keyboard_shortcut_entry_on_off.set_accelerator_name(self.keybinding_on_off)
323
self.keyboard_shortcut_entry_on_off.set_accelerator_name("<Shift><Control>c")
324
if self.keybinding_switch != None:
325
self.keyboard_shortcut_entry_switch.set_accelerator_name(self.keybinding_switch)
327
self.keyboard_shortcut_entry_switch.set_accelerator_name("<Shift><Control>n")
329
self.colorblind_filter = colorblind.GCONF_CLIENT.get_int(colorblind.GCONF_COLORBLIND_FILTER)
331
if self.colorblind_filter == 1:
332
self.radio1.set_active (True)
333
elif self.colorblind_filter == 2:
334
self.radio2.set_active (True)
335
elif self.colorblind_filter == 3:
336
self.radio3.set_active (True)
337
elif self.colorblind_filter == 4:
338
self.radio4.set_active (True)
339
elif self.colorblind_filter == 5:
340
self.radio5.set_active (True)
341
elif self.colorblind_filter == 6:
342
self.radio6.set_active (True)
343
elif self.colorblind_filter == 7:
344
self.radio7.set_active (True)
345
elif self.colorblind_filter == 8:
346
self.radio8.set_active (True)
348
self.radio7.set_active (True)
350
if self.default_filter == 1:
351
self.combofilters.set_active (0)
352
elif self.default_filter == 2:
353
self.combofilters.set_active (1)
354
elif self.default_filter == 3:
355
self.combofilters.set_active (2)
356
elif self.default_filter == 4:
357
self.combofilters.set_active (3)
358
elif self.default_filter == 5:
359
self.combofilters.set_active (4)
360
elif self.default_filter == 6:
361
self.combofilters.set_active (5)
362
elif self.default_filter == 7:
363
self.combofilters.set_active (6)
364
elif self.default_filter == 8:
365
self.combofilters.set_active (7)
367
self.combofilters.set_active (6)
369
if self.check_default == True:
370
self.check_default_filter.set_active (True)
372
self.check_default_filter.set_active (False)
374
def on_keyboard_shortcut_entry_changed(self, entry, accel_name, keyval, mods, keycode, keybinding):
376
colorblind.GCONF_CLIENT.set_string(keybinding, accel_name)
379
def show_preferences(applet):
380
ColorblindPreferencesUI (applet).show_run_hide(applet.applet)