1''' 2Defines the preferences dialog. 3 4@author: Eitan Isaacson 5@organization: Mozilla Foundation 6@copyright: Copyright (c) 2006, 2007 Mozilla Foundation 7@license: BSD 8 9All rights reserved. This program and the accompanying materials are made 10available under the terms of the BSD which accompanies this distribution, and 11is available at U{http://www.opensource.org/licenses/bsd-license.php} 12''' 13 14import gi 15 16from gi.repository import Gtk as gtk 17from gi.repository import Gdk as gdk 18from gi.repository import Atk as atk 19from gi.repository.Gio import Settings as GSettings 20 21from .i18n import _ 22from . import node 23from .tools import parseColorString 24 25class AccerciserPreferencesDialog(gtk.Dialog): 26 ''' 27 Class that creates a preferences dialog. 28 ''' 29 def __init__(self, plugins_view=None, hotkeys_view=None): 30 ''' 31 Initialize a preferences dialog. 32 33 @param plugins_view: Treeview of plugins. 34 @type plugins_view: L{PluginManager._View} 35 @param hotkeys_view: Treeview of global hotkeys. 36 @type hotkeys_view: L{HotkeyTreeView} 37 ''' 38 gtk.Dialog.__init__(self, title=_('accerciser Preferences')) 39 self.add_buttons(gtk.STOCK_CLOSE, gtk.ResponseType.CLOSE) 40 self.connect('response', self._onResponse) 41 self.set_default_size(500, 250) 42 notebook = gtk.Notebook() 43 vbox = self.get_children()[0] 44 vbox.pack_start(notebook, True, True, 2) 45 for view, section in [(plugins_view, _('Plugins')), 46 (hotkeys_view, _('Global Hotkeys'))]: 47 if view is not None: 48 sw = gtk.ScrolledWindow() 49 sw.set_shadow_type(gtk.ShadowType.IN) 50 sw.set_policy(gtk.PolicyType.AUTOMATIC, gtk.PolicyType.AUTOMATIC) 51 sw.set_size_request(500, 150) 52 sw.add(view) 53 notebook.append_page(sw, gtk.Label.new(section)) 54 55 notebook.append_page(_HighlighterView(), gtk.Label.new(_('Highlighting'))) 56 57 def _onResponse(self, dialog, response_id): 58 ''' 59 Callback for dialog responses, always destroy it. 60 61 @param dialog: This dialog. 62 @type dialog: L{AccerciserPreferencesDialog} 63 @param response_id: Response ID recieved. 64 @type response_id: integer 65 ''' 66 dialog.destroy() 67 68class _HighlighterView(gtk.Alignment): 69 ''' 70 A container widget with the settings for the highlighter. 71 ''' 72 def __init__(self): 73 gtk.Alignment.__init__(self) 74 self.set_padding(12, 12, 18, 12) 75 self.gsettings = GSettings.new('org.a11y.Accerciser') 76 self._buildUI() 77 78 def _buildUI(self): 79 ''' 80 Programatically build the UI. 81 ''' 82 table = gtk.Table.new(3, 2, True) 83 table.set_col_spacings(6) 84 self.add(table) 85 labels = [None, None, None] 86 controls = [None, None, None] 87 labels[0] = gtk.Label.new(_('Highlight duration:')) 88 controls[0] = gtk.SpinButton() 89 controls[0].set_range(0.01, 5) 90 controls[0].set_digits(2) 91 controls[0].set_value(self.gsettings.get_double('highlight-duration')) 92 controls[0].set_increments(0.01, 0.1) 93 controls[0].connect('value-changed', self._onDurationChanged) 94 labels[1] = gtk.Label.new(_('Border color:')) 95 controls[1] = self._ColorButton(node.BORDER_COLOR, node.BORDER_ALPHA) 96 controls[1].connect('color-set', self._onColorSet, 'highlight-border') 97 controls[1].set_tooltip_text(_('The border color of the highlight box')) 98 labels[2] = gtk.Label.new(_('Fill color:')) 99 controls[2] = self._ColorButton(node.FILL_COLOR, node.FILL_ALPHA) 100 controls[2].connect('color-set', self._onColorSet, 'highlight-fill') 101 controls[2].set_tooltip_text(_('The fill color of the highlight box')) 102 103 for label, control, row in zip(labels, controls, range(3)): 104 label.set_alignment(0, 0.5) 105 table.attach(label, 0, 1, row, row + 1, gtk.AttachOptions.FILL) 106 table.attach(control, 1, 2, row, row + 1, gtk.AttachOptions.FILL) 107 108 for label, control in zip([x.get_accessible() for x in labels], 109 [x.get_accessible() for x in controls]): 110 label.add_relationship(atk.RelationType.LABEL_FOR, control) 111 control.add_relationship(atk.RelationType.LABELLED_BY, label) 112 113 def _onDurationChanged(self, spin_button): 114 ''' 115 Callback for the duration spin button. Update key and the global variable 116 in the L{node} module. 117 118 @param spin_button: The spin button that emitted the value-changed signal. 119 @type spin_button: gtk.SpinButton 120 ''' 121 node.HL_DURATION = int(spin_button.get_value()*1000) 122 self.gsettings.set_double('highlight-duration', 123 spin_button.get_value()) 124 125 126 def _onColorSet(self, color_button, key): 127 ''' 128 Callback for a color button. Update gsettings and the global variables 129 in the L{node} module. 130 131 @param color_button: The color button that emitted the color-set signal. 132 @type color_button: l{_HighlighterView._ColorButton} 133 @param key: the key name suffix for this color setting. 134 @type key: string 135 ''' 136 if 'fill' in key: 137 node.FILL_COLOR = color_button.get_rgb_string() 138 node.FILL_ALPHA = color_button.get_alpha_float() 139 else: 140 node.BORDER_COLOR = color_button.get_rgb_string() 141 node.BORDER_ALPHA = color_button.get_alpha_float() 142 143 self.gsettings.set_string(key, color_button.get_rgba_string()) 144 145 class _ColorButton(gtk.ColorButton): 146 ''' 147 ColorButton derivative with useful methods for us. 148 ''' 149 def __init__(self, color, alpha): 150 color = gdk.color_parse(color) 151 gtk.ColorButton.__init__(self) 152 self.set_use_alpha(True) 153 self.set_alpha(int(alpha*0xffff)) 154 self.set_color(color) 155 156 def get_rgba_string(self): 157 ''' 158 Get the current color and alpha in string format. 159 160 @return: String in the format of #rrggbbaa. 161 @rtype: string. 162 ''' 163 color = self.get_color() 164 color_val = 0 165 color_val |= color.red >> 8 << 24 166 color_val |= color.green >> 8 << 16 167 color_val |= color.blue >> 8 << 8 168 color_val |= self.get_alpha() >> 8 169 return \ 170 '#' + hex(color_val).replace('0x', '').replace('L', '').rjust(8, '0') 171 172 def get_rgb_string(self): 173 ''' 174 Get the current color in string format. 175 176 @return: String in the format of #rrggbb. 177 @rtype: string. 178 ''' 179 color = self.get_color() 180 color_val = 0 181 color_val |= color.red >> 8 << 16 182 color_val |= color.green >> 8 << 8 183 color_val |= color.blue >> 8 184 return \ 185 '#' + hex(color_val).replace('0x', '').replace('L', '').rjust(6, '0') 186 187 def get_alpha_float(self): 188 ''' 189 Get the current alpha as a value from 0.0 to 1.0. 190 ''' 191 return self.get_alpha()/float(0xffff) 192