def addKeyCombo(self, component, localized_component, description, callback, keypress, modifiers): """ Adds the given key combination with the appropriate callbacks to the L{HotkeyManager}. If an identical description with the identical component already exists in the model, just reassign with the new callback. I{Note:} It is important that the component and description strings be unique. @param component: The component name, usually the plugin name, or "Core". @type component: string @param description: A description of the action performed during the given keycombo. @type description: string @param callback: The callback to call when the given key combination is pressed. @type callback: callable @param keypress: The key symbol of the keystroke that performs given operation. @type keypress: long @param modifiers: The modifiers that must be depressed for function to be perfomed. @type modifiers: int """ component_desc_pairs = list(zip([row[COL_COMPONENT] for row in self], [row[COL_DESC] for row in self])) if (component, description) in component_desc_pairs: path = component_desc_pairs.index((component, description)) self[path][COL_CALLBACK] = callback else: gspath = self._getComboGSettingsPath(component, description) gsettings = GSettings(schema=HOTKEYS_GSCHEMA, path=gspath) if gsettings.get_string("hotkey-combo"): final_keypress, final_modifiers = gtk.accelerator_parse(gsettings.get_string("hotkey-combo")) else: final_keypress, final_modifiers = keypress, modifiers self.append([component, description, callback, int(final_keypress), final_modifiers, localized_component])
def enableA11y(enable=True): """ Enables accessibility via DConf. """ from gi.repository.Gio import Settings InterfaceSettings = Settings(schema=a11yDConfKey) InterfaceSettings.set_boolean('toolkit-accessibility', enable)
def enableA11y(enable=True): """ Enables accessibility via DConf. """ from gi.repository.Gio import Settings InterfaceSettings = Settings(a11yDConfKey) InterfaceSettings.set_boolean('toolkit-accessibility', enable)
def _setPluginLayouts(self, plugin_layouts): self.plugviews = GSettings.new(PLUGVIEWS_GSCHEMA) self.plugviews.set_strv("top-panel-layout", plugin_layouts.pop("Top panel")) self.plugviews.set_strv("bottom-panel-layout", plugin_layouts.pop("Bottom panel")) for plugview in list(plugin_layouts.keys()): gspath = NEWPLUGVIEWS_PATH + plugview.lower().replace(" ", "-") + "/" newview = GSettings.new_with_path(NEWPLUGVIEWS_GSCHEMA, gspath) newview.set_strv("layout", plugin_layouts[plugview]) l = self.plugviews.get_strv("available-newviews") l.append(plugview) self.plugviews.set_strv("available-newviews", l)
def isA11yEnabled(): """ Checks if accessibility is enabled via DConf. """ from gi.repository.Gio import Settings InterfaceSettings = Settings(a11yDConfKey) dconfEnabled = InterfaceSettings.get_boolean('toolkit-accessibility') if os.environ.get('GTK_MODULES', '').find('gail:atk-bridge') == -1: envEnabled = False else: envEnabled = True # pragma: no cover return (dconfEnabled or envEnabled)
def __init__(self, *perm_views): ''' Initialize view manager. @param perm_views: List of permanent views, at least one is required. @type perm_views: list of {PluginView} ''' self._perm_views = perm_views gsettings = GSettings(schema=PLUGVIEWS_GSCHEMA) single = gsettings.get_boolean('layout-single') self._initViewModel(single) self._setupActions()
def _setPluginLayouts(self, plugin_layouts): self.plugviews = GSettings(schema=PLUGVIEWS_GSCHEMA) self.plugviews.set_strv('top-panel-layout', plugin_layouts.pop('Top panel')) self.plugviews.set_strv('bottom-panel-layout', plugin_layouts.pop('Bottom panel')) for plugview in list(plugin_layouts.keys()): gspath = NEWPLUGVIEWS_PATH + plugview.lower().replace(' ', '-') + '/' newview = GSettings(schema=NEWPLUGVIEWS_GSCHEMA, path=gspath) newview.set_strv('layout', plugin_layouts[plugview]) l = self.plugviews.get_strv('available-newviews') l.append(plugview) self.plugviews.set_strv('available-newviews', l)
def availableProfiles(self): """ List available profiles. """ profileList = self.baseSettings.get_strv('profiles') profiles = [] for profile in profileList: profileSettings = Settings(schema_id='org.gnome.orca.general', path='/org/gnome/orca/profile/%s/' % profile) profiles.append(profileSettings.get_strv('profile')) return profiles
def main(): magServiceAvailable = _initMagDbus() if magServiceAvailable: a11yAppSettings = Settings('org.gnome.desktop.a11y.applications') a11yAppSettings.connect('changed', onEnabledChanged) if a11yAppSettings.get_boolean('screen-magnifier-enabled'): startTracking() pyatspi.Registry.start() else: print 'Magnification service not available. Exiting.' return 0
def isA11yEnabled(): """ Checks if accessibility is enabled via DConf. """ from gi.repository.Gio import Settings InterfaceSettings = Settings(schema=a11yDConfKey) dconfEnabled = InterfaceSettings.get_boolean('toolkit-accessibility') if os.environ.get('GTK_MODULES', '').find('gail:atk-bridge') == -1: envEnabled = False else: envEnabled = True # pragma: no cover return (dconfEnabled or envEnabled)
def isA11yEnabled(): """ Checks if accessibility is enabled via DConf. """ from gi.repository.Gio import Settings try: InterfaceSettings = Settings(schema_id=a11yDConfKey) except TypeError: # if we have older glib that has deprecated param name InterfaceSettings = Settings(schema=a11yDConfKey) dconfEnabled = InterfaceSettings.get_boolean('toolkit-accessibility') if os.environ.get('GTK_MODULES', '').find('gail:atk-bridge') == -1: envEnabled = False else: envEnabled = True # pragma: no cover return (dconfEnabled or envEnabled)
def _onResize(self, widget, allocation): ''' Callback for window resizing. Used for persisting view sizes across sessions. @param widget: Window widget. @type widget: gtk.Widget @param allocation: The new allocation. @type allocation: gtk.gdk.Rectangle ''' view_name = self.plugin_view.view_name gspath = NEWPLUGVIEWS_PATH + view_name.lower().replace(' ', '-') + '/' gsettings = GSettings(schema=NEWPLUGVIEWS_GSCHEMA, path=gspath) gsettings.set_int('width', self.get_allocated_width()) gsettings.set_int('height', self.get_allocated_height())
def _setPluginLayouts(self, plugin_layouts): self.plugviews = GSettings.new(PLUGVIEWS_GSCHEMA) self.plugviews.set_strv('top-panel-layout', plugin_layouts.pop('Top panel')) self.plugviews.set_strv('bottom-panel-layout', plugin_layouts.pop('Bottom panel')) for plugview in list(plugin_layouts.keys()): gspath = NEWPLUGVIEWS_PATH + plugview.lower().replace(' ', '-') + '/' newview = GSettings.new_with_path(NEWPLUGVIEWS_GSCHEMA, gspath) newview.set_strv('layout', plugin_layouts[plugview]) l = self.plugviews.get_strv('available-newviews') l.append(plugview) self.plugviews.set_strv('available-newviews', l)
def __init__(self, node, hotkey_manager, *main_views): ''' Initialize the plugin manager. @param node: The application's main node. @type node: L{Node} @param hotkey_manager: Application's hot key manager. @type hotkey_manager: L{HotkeyManager} @param main_views: List of permanent plugin views. @type main_views: list of {PluginView} ''' gtk.ListStore.__init__( self, object, # Plugin instance object, # Plugin class str) # Plugin path self.node = node self.hotkey_manager = hotkey_manager self.gsettings = GSettings.new(GSCHEMA) self.view_manager = ViewManager(*main_views) self.message_manager = MessageManager() self.message_manager.connect('plugin-reload-request', self._onPluginReloadRequest) self.message_manager.connect('module-reload-request', self._onModuleReloadRequest) message_tab = self.message_manager.getMessageTab() self.view_manager.addElement(message_tab) self._row_changed_handler = \ self.connect('row_changed', self._onPluginRowChanged) self._loadPlugins()
def __init__(self, node, hotkey_manager, *main_views): ''' Initialize the plugin manager. @param node: The application's main node. @type node: L{Node} @param hotkey_manager: Application's hot key manager. @type hotkey_manager: L{HotkeyManager} @param main_views: List of permanent plugin views. @type main_views: list of {PluginView} ''' gtk.ListStore.__init__(self, object, # Plugin instance object, # Plugin class str) # Plugin path self.node = node self.hotkey_manager = hotkey_manager self.gsettings = GSettings.new(GSCHEMA) self.view_manager = ViewManager(*main_views) self.message_manager = MessageManager() self.message_manager.connect('plugin-reload-request', self._onPluginReloadRequest) self.message_manager.connect('module-reload-request', self._onModuleReloadRequest) message_tab = self.message_manager.getMessageTab() self.view_manager.addElement(message_tab) self._row_changed_handler = \ self.connect('row_changed', self._onPluginRowChanged) self._loadPlugins()
def _getPluginLayouts(self): plugin_layouts = {} self.plugviews = GSettings.new(PLUGVIEWS_GSCHEMA) plugin_layouts["Top panel"] = self.plugviews.get_strv("top-panel-layout") plugin_layouts["Bottom panel"] = self.plugviews.get_strv("bottom-panel-layout") for plugview in self.plugviews.get_strv("available-newviews"): gspath = NEWPLUGVIEWS_PATH + plugview.lower().replace(" ", "-") + "/" newview = GSettings.new_with_path(NEWPLUGVIEWS_GSCHEMA, gspath) layout = newview.get_strv("layout") if layout: plugin_layouts[plugview] = layout else: l = self.plugviews.get_strv("available-newviews") l.remove(plugview) self.plugviews.set_strv("available-newviews", l) return plugin_layouts
def _getPluginLayouts(self): plugin_layouts= {} self.plugviews = GSettings(schema=PLUGVIEWS_GSCHEMA) plugin_layouts['Top panel'] = self.plugviews.get_strv('top-panel-layout') plugin_layouts['Bottom panel'] = self.plugviews.get_strv('bottom-panel-layout') for plugview in self.plugviews.get_strv('available-newviews'): gspath = NEWPLUGVIEWS_PATH + plugview.lower().replace(' ', '-') + '/' newview = GSettings(schema=NEWPLUGVIEWS_GSCHEMA, path=gspath) layout = newview.get_strv('layout') if layout: plugin_layouts[plugview] = layout else: l = self.plugviews.get_strv('available-newviews') l.remove(plugview) self.plugviews.set_strv('available-newviews', l) return plugin_layouts
def _on_settings_changed(self, settings: Gio.Settings, key: str): uall = key == '' if key == 'dark-icons' or uall: colors = (self.icon_colors_dark if settings.get_boolean('dark-icons') else self.icon_colors) self._program_view.set_colors(colors) self._icon_view.set_colors(colors) self._program_view_search.pw_find.set_colors(colors) self._program_view_search.pw_replace.set_colors(colors)
def setSingleMode(self, single): ''' Toggle single mode on or off. @param single: True if we want single mode. @type single: boolean ''' if isinstance(self._view_model, SingleViewModel) == single: return gsettings = GSettings(schema=PLUGVIEWS_GSCHEMA) gsettings.set_boolean('layout-single', single) plugins = self._view_model.getViewedPlugins() self._view_model.close() del self._view_model for plugin in plugins: if plugin.get_parent(): plugin.get_parent().remove(plugin) self._initViewModel(single) for plugin in plugins: self._view_model.addElement(plugin)
def _getPluginLayouts(self): plugin_layouts = {} self.plugviews = GSettings.new(PLUGVIEWS_GSCHEMA) plugin_layouts['Top panel'] = self.plugviews.get_strv( 'top-panel-layout') plugin_layouts['Bottom panel'] = self.plugviews.get_strv( 'bottom-panel-layout') for plugview in self.plugviews.get_strv('available-newviews'): gspath = NEWPLUGVIEWS_PATH + plugview.lower().replace(' ', '-') + '/' newview = GSettings.new_with_path(NEWPLUGVIEWS_GSCHEMA, gspath) layout = newview.get_strv('layout') if layout: plugin_layouts[plugview] = layout else: l = self.plugviews.get_strv('available-newviews') l.remove(plugview) self.plugviews.set_strv('available-newviews', l) return plugin_layouts
def addKeyCombo(self, component, localized_component, description, callback, keypress, modifiers): ''' Adds the given key combination with the appropriate callbacks to the L{HotkeyManager}. If an identical description with the identical component already exists in the model, just reassign with the new callback. I{Note:} It is important that the component and description strings be unique. @param component: The component name, usually the plugin name, or "Core". @type component: string @param description: A description of the action performed during the given keycombo. @type description: string @param callback: The callback to call when the given key combination is pressed. @type callback: callable @param keypress: The key symbol of the keystroke that performs given operation. @type keypress: long @param modifiers: The modifiers that must be depressed for function to be perfomed. @type modifiers: int ''' component_desc_pairs = zip([row[COL_COMPONENT] for row in self], [row[COL_DESC] for row in self]) if (component, description) in component_desc_pairs: path = component_desc_pairs.index((component, description)) self[path][COL_CALLBACK] = callback else: gspath = self._getComboGSettingsPath(component, description) gsettings = GSettings(schema=HOTKEYS_GSCHEMA, path=gspath) if gsettings.get_string('hotkey-combo'): final_keypress, final_modifiers = gtk.accelerator_parse( gsettings.get_string('hotkey-combo')) else: final_keypress, final_modifiers = keypress, modifiers self.append([ component, description, callback, int(final_keypress), final_modifiers, localized_component ])
def _gsettings_set_as_background(conf, file_location): """Sets the background path to the given path in gsettings""" gsettings = Settings.new(_GSETTINGS_SCHEMA) worked = gsettings.set_string(_GSETTINGS_KEY,"file://"+file_location) # I do not think i need this sync command. gsettings.sync() if worked: _log_succsess(conf,"gsetting") else: _log_failed(conf,"gsettings") raise _exceptions.Failed("could not set gsettings key") return
def saveAppSettings(self, appName, profile, general, pronunciations, keybindings): profiles = self.baseSettings.get_strv('profiles') if profile in profiles: profileBaseSettings = Settings(schema_id='org.gnome.orca', path='/org/gnome/orca/profile/%s/' % profile) apps = profileBaseSettings.get_strv('apps') if appName not in apps: apps.append(appName) profileBaseSettings.set_strv('apps', apps) self._saveGeneralSettings(general, profile, appName) if general.__contains__('voices'): self._saveVoiceSettings(general['voices'], profile, appName) self._savePronunciations(pronunciations, profile, appName) self._saveKeybindings(keybindings, profile, appName)
def _saveGeneralSettings(self, generalSettings, profile, app=None): if app is not None and app != '': generalGSettings = Settings( schema_id='org.gnome.orca.general', path='/org/gnome/orca/profile/%s/app/%s/' % (profile, app)) speechGeneralGSettings = Settings( schema_id='org.gnome.orca.general.speech', path='/org/gnome/orca/profile/%s/app/%s/' % (profile, app)) brailleGeneralGSettings = Settings( schema_id='org.gnome.orca.general.braille', path='/org/gnome/orca/profile/%s/app/%s/' % (profile, app)) appSpecificGSettings = Settings( schema_id='org.gnome.orca.general.app', path='/org/gnome/orca/profile/%s/app/%s/' % (profile, app)) appSpecific = True else: generalGSettings = Settings(schema_id='org.gnome.orca.general', path='/org/gnome/orca/profile/%s/' % profile) speechGeneralGSettings = Settings( schema_id='org.gnome.orca.general.speech', path='/org/gnome/orca/profile/%s/' % profile) brailleGeneralGSettings = Settings( schema_id='org.gnome.orca.general.braille', path='/org/gnome/orca/profile/%s/' % profile) appSpecific = False for setting in orcaToGSettingsMapGeneral.keys(): gSetting = orcaToGSettingsMapGeneral.get(setting) gSettingName = gSetting[0] gSettingType = gSetting[1] self._setGSetting(generalGSettings, gSettingName, gSettingType, generalSettings.get(setting)) for setting in orcaToGSettingsMapGeneralSpeech.keys(): gSetting = orcaToGSettingsMapGeneralSpeech.get(setting) gSettingName = gSetting[0] gSettingType = gSetting[1] self._setGSetting(speechGeneralGSettings, gSettingName, gSettingType, generalSettings.get(setting)) for setting in orcaToGSettingsMapGeneralBraille.keys(): gSetting = orcaToGSettingsMapGeneralBraille.get(setting) gSettingName = gSetting[0] gSettingType = gSetting[1] self._setGSetting(brailleGeneralGSettings, gSettingName, gSettingType, generalSettings.get(setting)) if appSpecific == True: for setting in orcaToGSettingsMapGeneralApp.keys(): gSetting = orcaToGSettingsMapGeneralApp.get(setting) gSettingName = gSetting[0] gSettingType = gSetting[1] self._setGSetting(appSpecificGSettings, gSettingName, gSettingType, generalSettings.get(setting))
def __init__(self, view_name): ''' Initialize a new plugin view window. @param view_name: The name of the view. @type view_name: string ''' gtk.Window.__init__(self) self.plugin_view = PluginView(view_name) self.add(self.plugin_view) gspath = NEWPLUGVIEWS_PATH + view_name.lower().replace(' ', '-') + '/' gsettings = GSettings(schema=NEWPLUGVIEWS_GSCHEMA, path=gspath) width = gsettings.get_int('width') height = gsettings.get_int('height') self.set_default_size(width, height) self.connect('key_press_event', self._onKeyPress) self.plugin_view.connect_after('page_removed', self._onPluginRemoved) self.set_title(view_name) self.set_position(gtk.WindowPosition.MOUSE) self.show_all() self.connect('size-allocate', self._onResize)
def set_background(image_path, check_exist=True): if check_exist: with open(image_path, 'rb') as f: f.read(1) path_to_file = path.abspath(image_path) if isinstance(path_to_file, unicode): path_to_file = path_to_file.encode('utf-8') uri = 'file://' + quote(path_to_file) bg_setting = Settings.new('org.gnome.desktop.background') bg_setting.set_string('picture-uri', uri) bg_setting.apply()
def _onComboChanged(self, model, path, iter): """ Callback for row changes. Copies the changed key combos over to gsettings. @param model: The model that emitted the signal. Should be this class instance. @type model: L{gtk.TreeModel} @param path: The path of the row that has changed. @type path: tuple @param iter: The iter of the row that has changed. @type iter: L{gtk.TreeIter} """ if not model[iter][COL_COMPONENT] or not model[iter][COL_DESC]: return gspath = self._getComboGSettingsPath(model[iter][COL_COMPONENT], model[iter][COL_DESC]) gsettings = GSettings(schema=HOTKEYS_GSCHEMA, path=gspath) combo_name = gtk.accelerator_name(model[iter][COL_KEYPRESS], gdk.ModifierType(model[iter][COL_MOD])) key = gsettings.get_string("hotkey-combo") if key != combo_name and key != "/": gsettings.set_string("hotkey-combo", combo_name)
def getAppSettings(self, appName): prefs = {} profiles = {} availableProfiles = self.baseSettings.get_strv('profiles') for profile in availableProfiles: profileSettings = {} generalSettings = {} voiceSettings = {} pronunciationSettings = {} keybindingSettings = {} profileBaseSettings = Settings(schema_id='org.gnome.orca', path='/org/gnome/orca/profile/%s/' % profile) profileApps = profileBaseSettings.get_strv('apps') if appName in profileApps: generalSettings = self._getGeneralSettings(profile, appName) voiceSettings = self._getVoiceSettings(profile, appName) if voiceSettings != {}: generalSettings['voices'] = voiceSettings pronunciationSettings = self._getPronunciations( profile, appName) keybindingSettings = self._getKeybindings(profile, appName) profileSettings['general'] = generalSettings profileSettings['keybindings'] = keybindingSettings profileSettings['pronunciations'] = pronunciationSettings profiles[profile] = profileSettings if profiles != {}: prefs['profiles'] = profiles return prefs
def _onComboChanged(self, model, path, iter): ''' Callback for row changes. Copies the changed key combos over to gsettings. @param model: The model that emitted the signal. Should be this class instance. @type model: L{gtk.TreeModel} @param path: The path of the row that has changed. @type path: tuple @param iter: The iter of the row that has changed. @type iter: L{gtk.TreeIter} ''' if not model[iter][COL_COMPONENT] or not model[iter][COL_DESC]: return gspath = self._getComboGSettingsPath(model[iter][COL_COMPONENT], model[iter][COL_DESC]) gsettings = GSettings(schema=HOTKEYS_GSCHEMA, path=gspath) combo_name = gtk.accelerator_name( model[iter][COL_KEYPRESS], gdk.ModifierType(model[iter][COL_MOD])) key = gsettings.get_string('hotkey-combo') if key != combo_name and key != '/': gsettings.set_string('hotkey-combo', combo_name)
def _onResize(self, widget, allocation): """ Callback for window resizing. Used for persisting view sizes across sessions. @param widget: Window widget. @type widget: gtk.Widget @param allocation: The new allocation. @type allocation: gtk.gdk.Rectangle """ view_name = self.plugin_view.view_name gspath = NEWPLUGVIEWS_PATH + view_name.lower().replace(" ", "-") + "/" gsettings = GSettings.new_with_path(NEWPLUGVIEWS_GSCHEMA, gspath) gsettings.set_int("width", self.get_allocated_width()) gsettings.set_int("height", self.get_allocated_height())
def getGeneral(self, profile='default'): profiles = self.baseSettings.get_strv('profiles') startingProfile = self.baseSettings.get_strv('starting-profile') generalSettings = {} voiceSettings = {} generalSettings['startingProfile'] = startingProfile if profile in profiles: profileGeneralSettings = Settings( schema_id='org.gnome.orca.general', path='/org/gnome/orca/profile/%s/' % profile) generalSettings = self._getGeneralSettings(profile) voiceSettings = self._getVoiceSettings(profile) generalSettings['voices'] = voiceSettings generalSettings['activeProfile'] = profileGeneralSettings.get_strv( 'profile') self.baseSettings.set_strv('active-profile', generalSettings['activeProfile']) return generalSettings
def on_icon_changed(settings: Gio.Settings, key: str): icon: str = settings.get_value(ICON_KEY).get_string() try: QT5CT_CONFIG_LOCK.acquire() QT5CT_CONFIG.touch(0o644) with QT5CT_CONFIG.open('r+') as file: config = ConfigParser() config.read_file(file) config.setdefault('Appearance', {}) config['Appearance']['icon_theme'] = icon file.seek(0) config.write(file) file.truncate() except Exception as error: raise error finally: QT5CT_CONFIG_LOCK.release()
def on_theme_changed(settings: Gio.Settings, key: str): theme: str = settings.get_value(THEME_KEY).get_string() try: KVANTUM_CONFIG_LOCK.acquire() KVANTUM_CONFIG.touch(0o644) with KVANTUM_CONFIG.open('r+') as file: config = ConfigParser() config.read_file(file) config.setdefault('General', {}) config['General']['theme'] = gtk_to_kv(theme) file.seek(0) config.write(file) file.truncate() except Exception as error: raise error finally: KVANTUM_CONFIG_LOCK.release()
def __init__(self, node): ''' Initialize the window. @param node: Main application's node. @type node: L{Node} ''' gtk.Window.__init__(self) self.set_icon_name('accerciser') self.set_title(_('Accerciser Accessibility Explorer')) self.connect('key-press-event', self._onKeyPress) node.connect('blink-done', self._onBlinkDone) self.gsettings = GSettings.new(GSCHEMA) width = self.gsettings.get_int('window-width') or 640 height = self.gsettings.get_int('window-height') or 640 self.set_default_size(width, height) self.add_accel_group(ui_manager.uimanager.get_accel_group()) # Populate window self._populateUI(node) selection = self.treeview.get_selection() selection.connect('changed', self._onSelectionChanged)
def __init__(self, node): ''' Initialize the window. @param node: Main application's node. @type node: L{Node} ''' gtk.Window.__init__(self) self.set_icon_name('accerciser') self.set_title(_('Accerciser Accessibility Explorer')) self.connect('key-press-event', self._onKeyPress) node.connect('blink-done', self._onBlinkDone) self.gsettings = GSettings(schema=GSCHEMA) width = self.gsettings.get_int('window-width') or 640 height = self.gsettings.get_int('window-height') or 640 self.set_default_size(width, height) self.add_accel_group(ui_manager.uimanager.get_accel_group()) # Populate window self._populateUI(node) selection = self.treeview.get_selection() selection.connect('changed', self._onSelectionChanged)
def __init__(self, view_name): """ Initialize a new plugin view window. @param view_name: The name of the view. @type view_name: string """ gtk.Window.__init__(self) self.plugin_view = PluginView(view_name) self.add(self.plugin_view) gspath = NEWPLUGVIEWS_PATH + view_name.lower().replace(" ", "-") + "/" gsettings = GSettings.new_with_path(NEWPLUGVIEWS_GSCHEMA, gspath) width = gsettings.get_int("width") height = gsettings.get_int("height") self.set_default_size(width, height) self.connect("key_press_event", self._onKeyPress) self.plugin_view.connect_after("page_removed", self._onPluginRemoved) self.set_title(view_name) self.set_position(gtk.WindowPosition.MOUSE) self.show_all() self.connect("size-allocate", self._onResize)
def __init__(self, node): """ Initialize the window. @param node: Main application's node. @type node: L{Node} """ gtk.Window.__init__(self) self.set_icon_name("accerciser") self.set_title(_("Accerciser Accessibility Explorer")) self.connect("key-press-event", self._onKeyPress) node.connect("blink-done", self._onBlinkDone) self.gsettings = GSettings.new(GSCHEMA) width = self.gsettings.get_int("window-width") or 640 height = self.gsettings.get_int("window-height") or 640 self.set_default_size(width, height) self.add_accel_group(ui_manager.uimanager.get_accel_group()) # Populate window self._populateUI(node) selection = self.treeview.get_selection() selection.connect("changed", self._onSelectionChanged)
import gi from gi.repository import Gtk as gtk from gi.repository import Gdk as gdk from gi.repository import GLib from gi.repository import GObject from gi.repository.Gio import Settings as GSettings #from gi.repository import cairo import cairo import pyatspi import string from .tools import Tools, parseColorString MAX_BLINKS = 6 gsettings = GSettings(schema='org.a11y.Accerciser') BORDER_COLOR, BORDER_ALPHA = parseColorString( gsettings.get_string('highlight-border')) FILL_COLOR, FILL_ALPHA = parseColorString( gsettings.get_string('highlight-fill')) HL_DURATION = int(gsettings.get_double('highlight-duration')*1000) class Bag(object): ''' Bag class for converting a dicionary to an object with attributes. ''' def __init__(self, **kwargs): self.__dict__.update(kwargs)
from gi.repository.Gio import Settings _log = logging.getLogger('SafetySave') if environ.get('DEBUG', '').lower() == 'true': _log.setLevel(logging.DEBUG) # For some reason our logging won't emit correctly unless an initial message is # sent in. logging.debug("") _SETTINGS_KEY = "org.gnome.gedit.preferences.editor" _MAX_STORED_AGE_S = 86400 * 7 * 4 _DATETIME_FORMAT = '%Y-%m-%dT%H:%M:%SZ' _gedit_settings = Settings(_SETTINGS_KEY) _start_timestamp = datetime.utcnow().strftime(_DATETIME_FORMAT) _store_root = join(GLib.get_user_data_dir(), 'gedit', 'unsaved') _store_path = join(_store_root, _start_timestamp) class SafetySavePluginAppExtension(GObject.Object, Gedit.AppActivatable): __gtype_name__ = "SafetySavePluginAppExtension" app = GObject.property(type=Gedit.App) def __init__(self): GObject.Object.__init__(self) def __do_cleanup(self): """Determine if any old session backups need to be cleared."""
''' import gi from gi.repository import Gtk as gtk from gi.repository import Gdk as gdk from gi.repository import GObject from gi.repository.Gio import Settings as GSettings #from gi.repository import cairo import cairo import pyatspi import string from tools import Tools, parseColorString MAX_BLINKS = 6 gsettings = GSettings(schema='org.a11y.Accerciser') BORDER_COLOR, BORDER_ALPHA = parseColorString( gsettings.get_string('highlight-border')) FILL_COLOR, FILL_ALPHA = parseColorString( gsettings.get_string('highlight-fill')) HL_DURATION = int(gsettings.get_double('highlight-duration')*1000) class Bag(object): ''' Bag class for converting a dicionary to an object with attributes. ''' def __init__(self, **kwargs): self.__dict__.update(kwargs)
class PluginManager(gtk.ListStore, Tools): ''' @cvar COL_INSTANCE: Instance column ID. @type COL_INSTANCE: integer @cvar COL_CLASS: Class column ID. @type COL_CLASS: integer @cvar COL_PATH: Module path column ID. @type COL_PATH: integer @ivar node: Application's selected accessible node. @type node: L{Node} @ivar hotkey_manager: Application's hotkey manager. @type hotkey_manager: L{HotkeyManager} @ivar view_manager: Plugin view manager. @type view_manager: L{ViewManager} @ivar message_manager: Plugin message manager. @type message_manager: L{MessageManager} ''' COL_INSTANCE = 0 COL_CLASS = 1 COL_PATH = 2 def __init__(self, node, hotkey_manager, *main_views): ''' Initialize the plugin manager. @param node: The application's main node. @type node: L{Node} @param hotkey_manager: Application's hot key manager. @type hotkey_manager: L{HotkeyManager} @param main_views: List of permanent plugin views. @type main_views: list of {PluginView} ''' gtk.ListStore.__init__(self, object, # Plugin instance object, # Plugin class str) # Plugin path self.node = node self.hotkey_manager = hotkey_manager self.gsettings = GSettings(schema=GSCHEMA) self.view_manager = ViewManager(*main_views) self.message_manager = MessageManager() self.message_manager.connect('plugin-reload-request', self._onPluginReloadRequest) self.message_manager.connect('module-reload-request', self._onModuleReloadRequest) message_tab = self.message_manager.getMessageTab() self.view_manager.addElement(message_tab) self._row_changed_handler = \ self.connect('row_changed', self._onPluginRowChanged) self._loadPlugins() def close(self): ''' Close view manager and plugins. ''' self.view_manager.close() for row in self: plugin = row[self.COL_INSTANCE] if plugin: plugin._close() def _loadPlugins(self): ''' Load all plugins in global and local plugin paths. ''' # AQUI PETAA for plugin_dir, plugin_fn in self._getPluginFiles(): self._loadPluginFile(plugin_dir, plugin_fn) self.view_manager.initialView() def _getPluginFiles(self): ''' Get list of all modules in plugin paths. @return: List of plugin files with their paths. @rtype: tuple ''' plugin_file_list = [] plugin_dir_local = os.path.join(GLib.get_user_data_dir(), 'accerciser', 'plugins') plugin_dir_global = os.path.join(sys.prefix, 'share', 'accerciser', 'plugins') for plugin_dir in (plugin_dir_local, plugin_dir_global): if not os.path.isdir(plugin_dir): continue for fn in os.listdir(plugin_dir): if fn.endswith('.py') and not fn.startswith('.'): plugin_file_list.append((plugin_dir, fn[:-3])) return plugin_file_list def _getPluginLocals(self, plugin_dir, plugin_fn): ''' Get namespace of given module @param plugin_dir: Path. @type plugin_dir: string @param plugin_fn: Module. @type plugin_fn: string @return: Dictionary of modules symbols. @rtype: dictionary ''' sys.path.insert(0, plugin_dir) try: params = imp.find_module(plugin_fn, [plugin_dir]) plugin = imp.load_module(plugin_fn, *params) plugin_locals = plugin.__dict__ except Exception as e: self.message_manager.newModuleError(plugin_fn, plugin_dir, traceback.format_exception_only(e.__class__, e)[0].strip(), traceback.format_exc()) return {} sys.path.pop(0) return plugin_locals def _loadPluginFile(self, plugin_dir, plugin_fn): ''' Find plugin implementations in the given module, and store them. @param plugin_dir: Path. @type plugin_dir: string @param plugin_fn: Module. @type plugin_fn: string ''' plugin_locals = self._getPluginLocals(plugin_dir, plugin_fn) # use keys list to avoid size changes during iteration for symbol in list(plugin_locals.keys()): try: is_plugin = \ issubclass(plugin_locals[symbol], Plugin) and \ getattr(plugin_locals[symbol], 'plugin_name', None) except TypeError: continue if is_plugin: self.handler_block(self._row_changed_handler) iter_id = self.append([None, plugin_locals[symbol], plugin_dir]) self.handler_unblock(self._row_changed_handler) # if a plugin class is found, initialize disabled_list = self.gsettings.get_strv('disabled-plugins') enabled = plugin_locals[symbol].plugin_name not in \ disabled_list if enabled: self._enablePlugin(iter_id) self.row_changed(self.get_path(iter_id), iter_id) def _enablePlugin(self, iter): ''' Instantiate a plugin class pointed to by the given iter. @param iter: Iter of plugin class we should instantiate. @type iter: gtk.TreeIter ''' plugin_class = self[iter][self.COL_CLASS] plugin_instance = None try: plugin_instance = plugin_class(self.node, self.message_manager) plugin_instance.init() for key_combo in plugin_instance.global_hotkeys: self.hotkey_manager.addKeyCombo( plugin_class.plugin_name, plugin_class.plugin_name_localized or plugin_class.plugin_name , *key_combo) except Exception as e: self.message_manager.newPluginError( plugin_instance, plugin_class, traceback.format_exception_only(e.__class__, e)[0].strip(), traceback.format_exc()) try: plugin_instance._close() except: pass return self[iter][self.COL_INSTANCE] = plugin_instance if isinstance(plugin_instance, gtk.Widget): self.view_manager.addElement(plugin_instance) plugin_instance.onAccChanged(plugin_instance.node.acc) disabled_list = self.gsettings.get_strv('disabled-plugins') if plugin_instance.plugin_name in disabled_list: disabled_list.remove(plugin_instance.plugin_name) self.gsettings.set_strv('disabled-plugins', disabled_list) def _disablePlugin(self, iter): ''' Disable plugin pointed to by the given iter. @param iter: Iter of plugin instance to be disabled. @type iter: gtk.TreeIter ''' plugin_instance = self[iter][self.COL_INSTANCE] if not plugin_instance: return for key_combo in plugin_instance.global_hotkeys: self.hotkey_manager.removeKeyCombo( plugin_instance.plugin_name, *key_combo) if isinstance(plugin_instance, gtk.Widget): plugin_instance.destroy() plugin_instance._close() disabled_list = self.gsettings.get_strv('disabled-plugins') if not plugin_instance.plugin_name in disabled_list: disabled_list.append(plugin_instance.plugin_name) self.gsettings.set_strv('disabled-plugins', disabled_list) self[iter][self.COL_INSTANCE] = False def _reloadPlugin(self, iter): ''' Reload plugin pointed to by the given iter. @param iter: Iter of plugin to be reloaded. @type iter: gtk.TreeIter @return: New instance of plugin @rtype: L{Plugin} ''' old_class = self[iter][self.COL_CLASS] plugin_fn = old_class.__module__ plugin_dir = self[iter][self.COL_PATH] plugin_locals = self._getPluginLocals(plugin_dir, plugin_fn) self[iter][self.COL_CLASS] = plugin_locals.get(old_class.__name__) self._enablePlugin(iter) return self[iter][self.COL_INSTANCE] def _getIterWithClass(self, plugin_class): ''' Get iter with given plugin class. @param plugin_class: The plugin class to search for. @type plugin_class: type @return: The first iter with the given class. @rtype: gtk.TreeIter ''' for row in self: if row[self.COL_CLASS] == plugin_class: return row.iter return None def _onPluginReloadRequest(self, message_manager, message, plugin_class): ''' Callback for a plugin reload request from the message manager. @param message_manager: The message manager that emitted the signal. @type message_manager: L{MessageManager} @param message: The message widget. @type message: L{PluginMessage} @param plugin_class: The plugin class that should be reloaded. @type plugin_class: type ''' message.destroy() iter = self._getIterWithClass(plugin_class) if not iter: return self._disablePlugin(iter) plugin = self._reloadPlugin(iter) if plugin: self.view_manager.giveElementFocus(plugin) def _onModuleReloadRequest(self, message_manager, message, module, path): ''' Callback for a module reload request from the message manager. @param message_manager: The message manager that emitted the signal. @type message_manager: L{MessageManager} @param message: The message widget. @type message: L{PluginMessage} @param module: The module to be reloaded. @type module: string @param path: The path of the module. @type path: string ''' message.destroy() self._loadPluginFile(path, module) def togglePlugin(self, path): ''' Toggle the plugin, either enable or disable depending on current state. @param path: Tree path to plugin. @type path: tuple ''' iter = self.get_iter(path) if self[iter][self.COL_INSTANCE]: self._disablePlugin(iter) else: self._reloadPlugin(iter) def _onPluginRowChanged(self, model, path, iter): ''' Callback for model row changes. Persists plugins state (enabled/disabled) in gsettings. @param model: Current model, actually self. @type model: gtk.ListStore @param path: Tree path of changed row. @type path: tuple @param iter: Iter of changed row. @type iter: gtk.TreeIter ''' plugin_class = model[iter][self.COL_CLASS] if plugin_class is None: return plugin_instance = model[iter][self.COL_INSTANCE] disabled_list = self.gsettings.get_strv('disabled-plugins') if plugin_instance is None: if plugin_class.plugin_name not in disabled_list: disabled_list.append(plugin_class.plugin_name) else: if plugin_class.plugin_name in disabled_list: disabled_list.remove(plugin_class.plugin_name) def View(self): ''' Helps emulate a non-static inner class. These don't exist in python, I think. @return: An inner view class. @rtype: L{PluginManager._View} ''' return self._View(self) class _View(gtk.TreeView): ''' Implements a treeview of a {PluginManager} @ivar plugin_manager: Plugin manager to use as data model. @type plugin_manager: L{PluginManager} @ivar view_manager: View manager to use for plugin view data. @type view_manager: L{ViewManager} ''' def __init__(self, plugin_manager): ''' Initialize view. @param plugin_manager: Plugin manager to use as data model. @type plugin_manager: L{PluginManager} ''' gtk.TreeView.__init__(self) self.plugin_manager = plugin_manager self.view_manager = plugin_manager.view_manager self.set_model(plugin_manager) self.connect('button-press-event', self._onButtonPress) self.connect('popup-menu', self._onPopupMenu) crc = gtk.CellRendererToggle() tvc = gtk.TreeViewColumn() tvc.pack_start(crc, True) tvc.set_cell_data_func(crc, self._pluginStateDataFunc) crc.connect('toggled', self._onPluginToggled) self.append_column(tvc) crt = gtk.CellRendererText() tvc = gtk.TreeViewColumn(_('Name')) tvc.pack_start(crt, True) tvc.set_cell_data_func(crt, self._pluginNameDataFunc) self.append_column(tvc) crc = gtk.CellRendererText() # Translators: This is the viewport in which the plugin appears, # it is a noun. # tvc = gtk.TreeViewColumn(C_('viewport', 'View')) tvc.pack_start(crc, False) tvc.set_cell_data_func(crc, self._viewNameDataFunc) crc.set_property('editable', True) crc.connect('edited', self._onViewChanged) self.append_column(tvc) def _onButtonPress(self, widget, event): ''' Callback for plugin view context menus. @param widget: Widget that emitted signal. @type widget: gtk.Widget @param event: Event object. @type event: gtk.gdk.Event ''' if event.button == 3: path = self.get_path_at_pos(int(event.x), int(event.y))[0] self._showPopup(event.button, event.time, path) def _onPopupMenu(self, widget): ''' Callback for popup request event. Usually happens when keyboard context menu os pressed. @param widget: Widget that emitted signal. @type widget: gtk.Widget @return: Return true to stop event trickling. @rtype: boolean ''' path, col = self.get_cursor() rect = getTreePathBoundingBox(self, path, col) self._showPopup(0, gtk.get_current_event_time(), path, lambda m, r: (r.x, r.y, True), rect) return True def _showPopup(self, button, time, path, pos_func=None, data=None): ''' Convinience function for showing the view manager's popup menu. @param button: Mouse button that was clicked. @type button: integer @param time: Time of event. @type time: float @param path: Tree path of context menu. @type path: tuple @param pos_func: Function to use for determining menu placement. @type pos_func: callable @param data: Additional data. @type data: object ''' plugin = \ self.plugin_manager[path][self.plugin_manager.COL_INSTANCE] menu = self.view_manager.Menu(plugin, self.get_toplevel()) menu.popup(None, None, pos_func, data, button, time) def _viewNameDataFunc(self, column, cell, model, iter, foo=None): ''' Function for determining the displayed data in the tree's view column. @param column: Column number. @type column: integer @param cell: Cellrender. @type cell: gtk.CellRendererText @param model: Tree's model @type model: gtk.ListStore @param iter: Tree iter of current row, @type iter: gtk.TreeIter ''' plugin_class = model[iter][self.plugin_manager.COL_CLASS] if issubclass(plugin_class, gtk.Widget): view_name = \ self.view_manager.getViewNameForPlugin(plugin_class.plugin_name) cell.set_property('sensitive', True) else: view_name = N_('No view') cell.set_property('sensitive', False) cell.set_property('text', _(view_name)) def _pluginNameDataFunc(self, column, cell, model, iter, foo=None): ''' Function for determining the displayed data in the tree's plugin column. @param column: Column number. @type column: integer @param cell: Cellrender. @type cell: gtk.CellRendererText @param model: Tree's model @type model: gtk.ListStore @param iter: Tree iter of current row, @type iter: gtk.TreeIter ''' plugin_class = model[iter][self.plugin_manager.COL_CLASS] cell.set_property('text', plugin_class.plugin_name_localized or \ plugin_class.plugin_name) def _pluginStateDataFunc(self, column, cell, model, iter, foo=None): ''' Function for determining the displayed state of the plugin's checkbox. @param column: Column number. @type column: integer @param cell: Cellrender. @type cell: gtk.CellRendererText @param model: Tree's model @type model: gtk.ListStore @param iter: Tree iter of current row, @type iter: gtk.TreeIter ''' cell.set_property('active', bool(model[iter][self.plugin_manager.COL_INSTANCE])) def _onPluginToggled(self, renderer_toggle, path): ''' Callback for a "toggled" signal from a L{gtk.CellRendererToggle} in the plugin dialog. Passes along the toggle request to the L{PluginManager}. @param renderer_toggle: The toggle cellrenderer that emitted the signal. @type renderer_toggle: L{gtk.CellRendererToggle} @param path: The path that has been toggled. @type path: tuple ''' self.plugin_manager.togglePlugin(path) def _onViewChanged(self, cellrenderertext, path, new_text): ''' Callback for an "edited" signal from a L{gtk.CellRendererCombo} in the plugin dialog. Passes along the new requested view name to the L{PluginManager}. @param cellrenderertext: The combo cellrenderer that emitted the signal. @type renderer_toggle: L{gtk.CellRendererCombo} @param path: The path that has been touched. @type path: tuple @param new_text: The new text that has been entered in to the combo entry. @type new_text: string ''' plugin = \ self.plugin_manager[path][self.plugin_manager.COL_INSTANCE] self.view_manager.changeView(plugin, new_text)
class MultiViewModel(list, BaseViewModel): ''' Manages all plugin views. Implements a gtk.ListStore of all views. Persists plugin view placements across sessions. @cvar COL_NAME: View name column ID. @type COL_NAME: integer @cvar COL_INSTANCE: View instance column ID. @type COL_INSTANCE: integer @ivar perm_views: List of permanent views. @type perm_views: list of L{PluginView} @ivar main_view: Main view. @type main_view: L{PluginView} @ivar _ignore_insertion: A list of tuples with view and plugin names that should be ignored and not go in to gsettings. This is to avoid recursive gsettings modification. @type _ignore_insertion: list of tuples @ivar _placement_cache: A cache of recently disabled plugins with their placement. allowsthem to be enabled in to the same position. @type _placement_cache: dictionary @ivar _closed: Indicator to stop writing plugin remove events to gsettings. @type _closed: boolean ''' COL_NAME = 0 COL_INSTANCE = 1 def __init__(self, *perm_views): ''' Initialize view manager. @param perm_views: List of permanent views, at least one is required. @type perm_views: list of {PluginView} ''' BaseViewModel.__init__(self, *perm_views) for view in self.perm_views: self.append(view) self._connectSignals(view) self._ignore_insertion = [] self._placement_cache = {} self._closed = False def close(self): ''' Stops gsettings maniputaion. ''' self._closed = True def getViewNameForPlugin(self, plugin_name): ''' Get the view name for a given plugin name as defined in gsettings. Or return name of main view. @param plugin_name: Plugin's name to lookup view for. @type plugin_name: string @return: View name for plugin. @rtype: string ''' plugin_layouts = self._getPluginLayouts() for view_name in plugin_layouts: if plugin_name in plugin_layouts[view_name]: return view_name return self.main_view.view_name def _getViewByName(self, view_name): ''' Return the view instance of the given name. @param view_name: Name of view to retrieve. @type view_name: string @return: View instance or None @rtype: L{PluginView} ''' for view in self: if view.view_name == view_name: return view return None def _onPluginDragEnd(self, view, plugin): ''' Callback for the end of a drag operation of a plugin. Only is called when the drag ends on the root window. @param view: Current plugin's view. @type view: L{PluginView} @param plugin: Plugin that was dragged. @type plugin: L{Plugin} ''' new_view = self._newView() view.remove(plugin) new_view.append_page(plugin) new_view.set_tab_detachable(plugin, True) new_view.set_tab_reorderable(plugin, True) def _newView(self, view_name=None): ''' Creates a new view. @param view_name: An optional view name. Gives a more mundane one if no name is provided. @type view_name: string @return: New view @rtype: L{PluginView} ''' if not view_name: view_name = _('Plugin View') view_num = 2 while view_name in self._getViewNames(): view_name = _('Plugin View (%d)') % view_num view_num += 1 w = PluginViewWindow(view_name) view = w.plugin_view self._connectSignals(view) self.append(view) return view def _getViewOrNewView(self, view_name): ''' Get an existing or new view with the current name. @param view_name: View's name @type view_name: string @return: New or existing view. @rtype: L{PluginView} ''' view = self._getViewByName(view_name) or self._newView(view_name) return view def _onViewDelete(self, view_window, event): ''' Callback for a view window's delete event. Puts all orphaned plugins in main view. @param view_window: View window that emitted delete event. @type view_window: L{PluginViewWindow} @param event: Event object. @type event: gtk.gdk.Event ''' view = view_window.plugin_view for child in view.getPlugins(): view.remove(child) self.main_view.append_page(child) self._removeView(view) def _removeView(self, view): ''' Removes view from model. @param view: View to remove. @type view: L{PluginView} ''' if view in self.perm_views: return if view in self: self.remove(view) def _onTabPopupMenu(self, view, event, plugin): ''' Callback for popup menu signal from plugin view. Displays a context menu with available views. @param view: Plugin view that emitted this signal. @type view: L{PluginView} @param event: Relevant event object that will be used in popup menu. @type event: gtk.gdk.Event @param plugin: Plugin of tab that was clicked or pressed. @type plugin: L{Plugin} ''' menu = self.Menu(plugin, view.get_toplevel()) if hasattr(event, 'button'): menu.popup(None, None, None, None, event.button, event.time) else: tab = view.get_tab_label(plugin) x, y, w, h = view.getTabAlloc(tab) rect = gdk.Rectangle(x, y, w, h) menu.popup(None, None, lambda m, r: (r.x+r.width/2, r.y+r.height/2, True), rect, 0, event.time) def _connectSignals(self, view): ''' Convenience function for connecting all needed signal callbacks. @param view: Plugin view to connect. @type view: :{PluginView} ''' if isinstance(view.get_parent(), PluginViewWindow): view.get_parent().connect('delete-event', Proxy(self._onViewDelete)) view.connect('plugin-drag-end', Proxy(self._onPluginDragEnd)) view.connect('tab-popup-menu', Proxy(self._onTabPopupMenu)) view.connect('page-added', Proxy(self._onViewLayoutChanged), 'added') view.connect('page-removed', Proxy(self._onViewLayoutChanged), 'removed') view.connect('page-reordered', Proxy(self._onViewLayoutChanged), 'reordered') def _onViewLayoutChanged(self, view, plugin, page_num, action): ''' Callback for all layout changes. Updates gsettings. @param view: View that emitted the signal. @type view: L{PluginView} @param plugin: Plugin that moved. @type plugin: L{Plugin} @param page_num: Plugin's position in view. @type page_num: integer @param action: Action that triggered this event. @type action: string ''' if self._closed or not isinstance(plugin, Plugin): return if (view.view_name, plugin.plugin_name) in self._ignore_insertion: self._ignore_insertion.remove((view.view_name, plugin.plugin_name)) return if plugin.plugin_name in self._placement_cache: self._placement_cache.pop(plugin.plugin_name) plugin_layouts = self._getPluginLayouts() try: plugin_layout = plugin_layouts[view.view_name] except KeyError: plugin_layouts[view.view_name] = [] plugin_layout = plugin_layouts[view.view_name] if plugin.plugin_name in plugin_layout: plugin_layout.remove(plugin.plugin_name) if action in ('reordered', 'added'): plugin_layout.insert(page_num, plugin.plugin_name) elif action == 'removed': self._placement_cache[plugin.plugin_name] = (view.view_name, page_num) if len(plugin_layout) == 0: self._removeView(view) self._setPluginLayouts(plugin_layouts) def _setPluginLayouts(self, plugin_layouts): self.plugviews = GSettings(schema=PLUGVIEWS_GSCHEMA) self.plugviews.set_strv('top-panel-layout', plugin_layouts.pop('Top panel')) self.plugviews.set_strv('bottom-panel-layout', plugin_layouts.pop('Bottom panel')) for plugview in list(plugin_layouts.keys()): gspath = NEWPLUGVIEWS_PATH + plugview.lower().replace(' ', '-') + '/' newview = GSettings(schema=NEWPLUGVIEWS_GSCHEMA, path=gspath) newview.set_strv('layout', plugin_layouts[plugview]) l = self.plugviews.get_strv('available-newviews') l.append(plugview) self.plugviews.set_strv('available-newviews', l) def _getPluginLayouts(self): plugin_layouts= {} self.plugviews = GSettings(schema=PLUGVIEWS_GSCHEMA) plugin_layouts['Top panel'] = self.plugviews.get_strv('top-panel-layout') plugin_layouts['Bottom panel'] = self.plugviews.get_strv('bottom-panel-layout') for plugview in self.plugviews.get_strv('available-newviews'): gspath = NEWPLUGVIEWS_PATH + plugview.lower().replace(' ', '-') + '/' newview = GSettings(schema=NEWPLUGVIEWS_GSCHEMA, path=gspath) layout = newview.get_strv('layout') if layout: plugin_layouts[plugview] = layout else: l = self.plugviews.get_strv('available-newviews') l.remove(plugview) self.plugviews.set_strv('available-newviews', l) return plugin_layouts def addPlugin(self, plugin): ''' Add a plugin to the view. Check if it's placement is cached in this instance or read it's position from gsettings. By default a plugin is appended to the main view. @param plugin: Plugin to add. @type plugin: L{Plugin} ''' if plugin.plugin_name in self._placement_cache: view_name, index = self._placement_cache.pop(plugin.plugin_name) view = self._getViewOrNewView(view_name) else: view_name = self.getViewNameForPlugin(plugin.plugin_name) view = self._getViewOrNewView(view_name) plugin_layouts = self._getPluginLayouts() try: plugin_layout = plugin_layouts[view.view_name] except KeyError: plugin_layout = [] plugin_layouts[view.view_name] = plugin_layout index = -1 if plugin.plugin_name in plugin_layout: # The plugins that have a higher index. successive = plugin_layout[plugin_layout.index(plugin.plugin_name)+1:] for child_index, preceding_plugin in enumerate(view.getPlugins()): if preceding_plugin.plugin_name in successive: # Place new plugin just before the first successive plugin. index = child_index break self._ignore_insertion.append((view.view_name, plugin.plugin_name)) self._setPluginLayouts(plugin_layouts) view.insert_page(plugin, position=index) view.set_tab_detachable(plugin, True) view.set_tab_reorderable(plugin, True) plugin.show_all() def initialView(self): ''' Set the current tab of all views to be the first one. Used when Accercier first starts. ''' for view in self: view.set_current_page(0) def getViewedPlugins(self): ''' Get all plugins from all views. ''' rv = [] for view in self: rv.extend(view.getPlugins()) return rv def _getViewNames(self): ''' Get a list of all managed view names. @return: A list of view names. @rtype: list of string ''' return [view.view_name for view in self] def changeView(self, plugin, new_view_name): ''' Put a plugin instance in a different view. If given view name does not exist, create it. @param plugin: Plugin to move. @type plugin: L{Plugin} @param new_view_name: New view name. @type new_view_name: string ''' if not plugin or not isinstance(plugin, gtk.Widget): return old_view = plugin.get_parent() new_view = self._getViewOrNewView(new_view_name) if old_view is not new_view: old_view.remove(plugin) new_view.append_page(plugin) new_view.set_tab_detachable(plugin, True) new_view.set_tab_reorderable(plugin, True) def Menu(self, context_plugin, transient_window): ''' Helps emulate a non-static inner class. These don't exist in python, I think. @param context_plugin: Subject plugin of this menu. @type context_plugin: L{Plugin} @param transient_window: Transient parent window. Used for keeping the new view dialog modal. @type transient_window: gtk.Window @return: An inner menu class. @rtype: L{ViewManager._Menu} ''' return self._Menu(self, context_plugin, transient_window) class _Menu(gtk.Menu): ''' Implements a popup menu for a plugin that will allow putting the plugin in a different view. @cvar RADIO_GROUP: Radio menu item's group id. @type RADIO_GROUP: integer @ivar view_manager: View manager to use as data model and controller. @type view_manager: L{ViewManager} ''' RADIO_GROUP = 13 def __init__(self, view_manager, context_plugin, transient_window): ''' Initialize menu. @param view_manager: View manager to use as data model and controller. @type view_manager: L{ViewManager} @param context_plugin: Subject plugin of this menu. @type context_plugin: L{Plugin} @param transient_window: Transient parent window. Used for keeping the new view dialog modal. @type transient_window: gtk.Window ''' gtk.Menu.__init__(self) self.view_manager = view_manager if isinstance(context_plugin, gtk.Widget): self._buildMenu(context_plugin, transient_window) def _buildMenu(self, context_plugin, transient_window): ''' Build the menu according to the view managers model. @param context_plugin: Subject plugin of this menu. @type context_plugin: L{Plugin} @param transient_window: Transient parent window. Used for keeping the new view dialog modal. @type transient_window: gtk.Window ''' menu_item = None for view in self.view_manager: menu_item = gtk.RadioMenuItem(label = _(view.view_name)) menu_item.set_name(view.view_name) menu_item.connect('toggled', self._onItemToggled, view, context_plugin) menu_item.set_active(view == context_plugin.get_parent()) self.append(menu_item) menu_item.show() menu_item = gtk.SeparatorMenuItem() self.append(menu_item) menu_item.show() menu_item = gtk.MenuItem(label="<i>" + _('_New view...') + "</i>") menu_item.get_child().set_use_markup(True) menu_item.connect('activate', self._onItemActivated, context_plugin, transient_window) self.append(menu_item) menu_item.show() def _onItemToggled(self, menu_item, view, context_plugin): ''' Callback for radio item toggles. Change the views accordingly. @param menu_item: Menu item that was toggled @type menu_item: gtk.RadioMenuItem @param view: View that was chosen. @type view: L{PluginView} @param context_plugin: Subject plugin of this menu. @type context_plugin: L{Plugin} ''' self.view_manager.changeView(context_plugin, view.view_name) def _onItemActivated(self, menu_item, context_plugin, transient_window): ''' Callback for "new view" menu item. Creates a dialog for entering a view name. @param menu_item: Menu item that was activated. @type menu_item: gtk.MenuItem @param context_plugin: Subject plugin of this menu. @type context_plugin: L{Plugin} @param transient_window: Transient parent window. Used for keeping the new view dialog modal. @type transient_window: gtk.Window ''' new_view_dialog = \ self._NewViewDialog(self.view_manager, transient_window) response_id = new_view_dialog.run() plugin_name = new_view_dialog.getEntryText() if response_id == gtk.ResponseType.OK and plugin_name: self.view_manager.changeView(context_plugin, plugin_name) new_view_dialog.destroy() class _NewViewDialog(gtk.Dialog): ''' Small dialog that allows entry of a new view name. ''' def __init__(self, view_manager, transient_window): ''' @param view_manager: View manager to use as data model and controller. @type view_manager: L{ViewManager} @param transient_window: Transient parent window. Used for keeping the new view dialog modal. @type transient_window: gtk.Window ''' self.view_manager = view_manager gtk.Dialog.__init__(self, _('New View...'), transient_window) self.add_buttons(gtk.STOCK_OK, gtk.ResponseType.OK, gtk.STOCK_CLOSE, gtk.ResponseType.CLOSE) self.set_default_response(gtk.ResponseType.OK) completion = gtk.EntryCompletion() complete_model = gtk.ListStore(str) for view in self.view_manager: complete_model.append([view.view_name]) completion.set_model(complete_model) completion.set_text_column(0) self.entry = gtk.Entry() self.entry.set_completion(completion) self.entry.connect('activate', self._onEntryActivate) self.box = self.get_children()[0] self.box.add(self.entry) self.entry.show() def getEntryText(self): ''' Get the contents of the entry widget. @return: Text in entry box. @rtype: string ''' return self.entry.get_text() def _onEntryActivate(self, entry): ''' Callback for activation of the entry box. Return an OK response. @param entry: Entry box that was activated. @type entry: gtk.Entry ''' self.response(gtk.ResponseType.OK)
class _HighlighterView(gtk.Alignment): ''' A container widget with the settings for the highlighter. ''' def __init__(self): gtk.Alignment.__init__(self) self.set_padding(12, 12, 18, 12) self.gsettings = GSettings(schema='org.a11y.Accerciser') self._buildUI() def _buildUI(self): ''' Programatically build the UI. ''' table = gtk.Table(3, 2) table.set_col_spacings(6) self.add(table) labels = [None, None, None] controls = [None, None, None] labels[0] = gtk.Label(_('Highlight duration:')) controls[0] = gtk.SpinButton() controls[0].set_range(0.01, 5) controls[0].set_digits(2) controls[0].set_value(self.gsettings.get_double('highlight-duration')) controls[0].set_increments(0.01, 0.1) controls[0].connect('value-changed', self._onDurationChanged) labels[1] = gtk.Label(_('Border color:')) controls[1] = self._ColorButton(node.BORDER_COLOR, node.BORDER_ALPHA) controls[1].connect('color-set', self._onColorSet, 'highlight-border') controls[1].set_tooltip_text( _('The border color of the highlight box')) labels[2] = gtk.Label(_('Fill color:')) controls[2] = self._ColorButton(node.FILL_COLOR, node.FILL_ALPHA) controls[2].connect('color-set', self._onColorSet, 'highlight-fill') controls[2].set_tooltip_text(_('The fill color of the highlight box')) for label, control, row in zip(labels, controls, range(3)): label.set_alignment(0, 0.5) table.attach(label, 0, 1, row, row + 1, gtk.AttachOptions.FILL) table.attach(control, 1, 2, row, row + 1, gtk.AttachOptions.FILL) for label, control in zip(map(lambda x: x.get_accessible(), labels), map(lambda x: x.get_accessible(), controls)): label.add_relationship(atk.RelationType.LABEL_FOR, control) control.add_relationship(atk.RelationType.LABELLED_BY, label) def _onDurationChanged(self, spin_button): ''' Callback for the duration spin button. Update key and the global variable in the L{node} module. @param spin_button: The spin button that emitted the value-changed signal. @type spin_button: gtk.SpinButton ''' node.HL_DURATION = int(spin_button.get_value() * 1000) self.gsettings.set_double('highlight-duration', spin_button.get_value()) def _onColorSet(self, color_button, key): ''' Callback for a color button. Update gsettings and the global variables in the L{node} module. @param color_button: The color button that emitted the color-set signal. @type color_button: l{_HighlighterView._ColorButton} @param key: the key name suffix for this color setting. @type key: string ''' if 'fill' in key: node.FILL_COLOR = color_button.get_rgb_string() node.FILL_ALPHA = color_button.get_alpha_float() else: node.BORDER_COLOR = color_button.get_rgb_string() node.BORDER_ALPHA = color_button.get_alpha_float() self.gsettings.set_string(key, color_button.get_rgba_string()) class _ColorButton(gtk.ColorButton): ''' ColorButton derivative with useful methods for us. ''' def __init__(self, color, alpha): color = gdk.color_parse(color) gtk.ColorButton.__init__(self) self.set_use_alpha(True) self.set_alpha(int(alpha * 0xffff)) self.set_color(color) def get_rgba_string(self): ''' Get the current color and alpha in string format. @return: String in the format of #rrggbbaa. @rtype: string. ''' color = self.get_color() color_val = 0 color_val |= color.red >> 8 << 24 color_val |= color.green >> 8 << 16 color_val |= color.blue >> 8 << 8 color_val |= self.get_alpha() >> 8 return \ '#' + hex(color_val).replace('0x', '').replace('L', '').rjust(8, '0') def get_rgb_string(self): ''' Get the current color in string format. @return: String in the format of #rrggbb. @rtype: string. ''' color = self.get_color() color_val = 0 color_val |= color.red >> 8 << 16 color_val |= color.green >> 8 << 8 color_val |= color.blue >> 8 return \ '#' + hex(color_val).replace('0x', '').replace('L', '').rjust(6, '0') def get_alpha_float(self): ''' Get the current alpha as a value from 0.0 to 1.0. ''' return self.get_alpha() / float(0xffff)
def __init__(self): gtk.Alignment.__init__(self) self.set_padding(12, 12, 18, 12) self.gsettings = GSettings(schema='org.a11y.Accerciser') self._buildUI()
import gi from gi.repository import Gtk as gtk from gi.repository import Gdk as gdk from gi.repository import GLib from gi.repository import GObject from gi.repository.Gio import Settings as GSettings #from gi.repository import cairo import cairo import pyatspi import string from .tools import ToolsAccessor, parseColorString MAX_BLINKS = 6 gsettings = GSettings.new('org.a11y.Accerciser') BORDER_COLOR, BORDER_ALPHA = parseColorString( gsettings.get_string('highlight-border')) FILL_COLOR, FILL_ALPHA = parseColorString( gsettings.get_string('highlight-fill')) HL_DURATION = int(gsettings.get_double('highlight-duration')*1000) class Bag(object): ''' Bag class for converting a dicionary to an object with attributes. ''' def __init__(self, **kwargs): self.__dict__.update(kwargs)
from gi.repository.Gtk import accelerator_parse from gi.repository.Gio import Settings # Check if gschema installed if 'org.gnome.gedit.plugins.imitation' not in Settings.list_schemas(): class ImitationPluginConfigError(Exception): pass raise ImitationPluginConfigError('Imitation gschema not installed') # Functions for getting config values s = Settings.new('org.gnome.gedit.plugins.imitation').get_string def p(accel_str): """ Parse accelerator string and warn of invalid formats """ # Always results in lowercase keyvals (accounted for when matching) accel = accelerator_parse(accel_str) if accel[0] == 0: print('Imitation plugin: invalid accelerator string "' + accel_str + '"') return accel # configurable (restart gedit to apply changes) MARK_TOGGLE = p(s('mark-toggle')) MARK_UP = p(s('mark-up')) MARK_DOWN = p(s('mark-down')) MARK_ALT_UP = p(s('mark-alt-up')) MARK_ALT_DOWN = p(s('mark-alt-down'))
def on_is_sorted_change(self, settings: Gio.Settings, key: str, widget: Gtk.Widget) -> None: if settings.get_boolean(key): self._main_revealer.set_reveal_child(True) else: self._main_revealer.set_reveal_child(False)
class AccerciserMainWindow(gtk.Window): ''' Main window class. @ivar statusbar: Main window's status bar. @type statusbar: gtk.Statusbar @ivar treeview: Main accessible tree view. @type treeview: L{AccessibleTreeView} @ivar pluginview1: Top plugin area. @type pluginview1: L{PluginView} @ivar pluginview2: Bottom plugin area @type pluginview2: L{PluginView} @ivar main_actions: Main action group. @type main_actions: gtk.ActionGroup @ivar _vpaned: Vertical paned. @type _vpaned: gtk.VPaned @ivar _hpaned: Horizontal paned. @type _hpaned: gtk.HPaned ''' def __init__(self, node): ''' Initialize the window. @param node: Main application's node. @type node: L{Node} ''' gtk.Window.__init__(self) self.set_icon_name('accerciser') self.set_title(_('Accerciser Accessibility Explorer')) self.connect('key-press-event', self._onKeyPress) node.connect('blink-done', self._onBlinkDone) self.gsettings = GSettings(schema=GSCHEMA) width = self.gsettings.get_int('window-width') or 640 height = self.gsettings.get_int('window-height') or 640 self.set_default_size(width, height) self.add_accel_group(ui_manager.uimanager.get_accel_group()) # Populate window self._populateUI(node) selection = self.treeview.get_selection() selection.connect('changed', self._onSelectionChanged) def _populateUI(self, node): ''' Populate the top level window widget. @param node: Main application's node. @type node: L{Node} ''' main_vbox = gtk.VBox() menu_bar = ui_manager.uimanager.get_widget(ui_manager.MAIN_MENU_PATH) main_vbox.pack_start(menu_bar, False, True, 0) self._vpaned = gtk.VPaned() self._vpaned.set_position(350) self._vpaned.set_name('vpaned') main_vbox.pack_start(self._vpaned, True, True, 0) self.statusbar = gtk.Statusbar() main_vbox.pack_start(self.statusbar, False, True, 0) self._hpaned = gtk.HPaned() self._hpaned.set_position(250) self._hpaned.set_name('hpaned') self._vpaned.add1(self._hpaned) self.pluginview1 = PluginView(N_('Top panel')) self.pluginview2 = PluginView(N_('Bottom panel')) self.pluginview2.connect('page_added', self._onBottomPanelChange, 'added') self.pluginview2.connect('page_removed', self._onBottomPanelChange, 'removed') self.pluginview2.connect_after('realize', self._onBottomPanelRealize) self._vpaned.add2(self.pluginview2) self._hpaned.add2(self.pluginview1) sw = gtk.ScrolledWindow() sw.set_policy(gtk.PolicyType.AUTOMATIC, gtk.PolicyType.AUTOMATIC) sw.set_shadow_type(gtk.ShadowType.IN) self.treeview = AccessibleTreeView(node) ui_manager.uimanager.insert_action_group(self.treeview.action_group, 0) for action in self.treeview.action_group.list_actions(): merge_id = ui_manager.uimanager.new_merge_id() action_name = action.get_name() ui_manager.uimanager.add_ui(merge_id, ui_manager.TREE_ACTIONS_PATH, action_name, action_name, gtk.UIManagerItemType.MENUITEM, False) merge_id = ui_manager.uimanager.new_merge_id() action_name = self.treeview.refresh_current_action.get_name() ui_manager.uimanager.add_ui(merge_id, ui_manager.POPUP_MENU_PATH, action_name, action_name, gtk.UIManagerItemType.MENUITEM, False) sw.add(self.treeview) self._hpaned.add1(sw) for paned in (self._vpaned, self._hpaned): if not self.gsettings.get_int(paned.get_name()): continue paned_position = self.gsettings.get_int(paned.get_name()) paned.set_position(paned_position) setattr(paned, 'last_position', paned.get_position()) self.add(main_vbox) def _onBottomPanelChange(self, pluginview, page, page_num, action): ''' Callback for changes to the bottom L{PluginView}'s children. If there are no tabs, shrink the paned. @param pluginview: The L{PluginView} that emitted the signal. @type pluginview: L{PluginView} @param page: The child widget affected. @type page: L{gtk.Widget} @param page_num: the new page number for page. @type page_num: integer @param action: The type of event that accured, either "removed" or "added" @type action: string ''' if pluginview.get_n_pages() == 1 and action == 'added': last_pos = getattr(self._vpaned, 'last_position') self._vpaned.set_position(last_pos or 350) elif pluginview.get_n_pages() == 0: setattr(self._vpaned, 'last_position', self._vpaned.get_position()) self._vpaned.set_position(self._vpaned.get_allocated_height() - 30) def _onBottomPanelRealize(self, pluginview): if pluginview.get_n_pages() == 0: self._vpaned.set_position(self._vpaned.get_allocated_height() - 30) def _onKeyPress(self, widget, event): ''' Callback for a keypress event in the main window. Used for navigating plugin tabs (<alt>+num). @param widget: The widget that emitted the event. @type widget: L{gtk.Widget} @param event: The event that accured. @type event: L{gtk.gdk.Event} ''' if event.state & gdk.ModifierType.MOD1_MASK and \ event.keyval in range(gdk.keyval_from_name('0'), gdk.keyval_from_name('9')): tab_num = event.keyval - gdk.keyval_from_name('0') or 10 pages_count1 = self.pluginview1.getNVisiblePages() pages_count2 = self.pluginview2.getNVisiblePages() if pages_count1 + pages_count2 < tab_num: return elif pages_count1 >= tab_num: self.pluginview1.focusTab(tab_num - 1) else: self.pluginview2.focusTab(tab_num - pages_count1 - 1) def saveState(self): ''' Save the dimensions of the main window, and the position of the panes. ''' self.gsettings.set_int('window-width', self.get_allocated_width()) self.gsettings.set_int('window-height', self.get_allocated_height()) self.gsettings.set_int('hpaned', self._hpaned.get_position()) if self.pluginview2.get_n_pages(): position = self._vpaned.get_position() else: position = getattr(self._vpaned, 'last_position') if position is not None: self.gsettings.set_int('vpaned', position) def _onBlinkDone(self, node): ''' Redraw main window after node stops blinking widget. Gets rid of artifacts. @param node: @type node: ''' self.queue_draw() def _onSelectionChanged(self, selection): ''' Callback for selection "changed" of the main treeview selection. Updates the status bar with the path to the selected accessible. @param selection: The main tree view's selection object. @type node: gtk.TreeSelection ''' model, iter = selection.get_selected() context_id = self.statusbar.get_context_id('lineage') if not iter: return tree_path = model.get_path(iter) path_tuple = tuple(tree_path.get_indices()) path = list(map(str, path_tuple)) self.statusbar.pop(context_id) if len(path) > 1: self.statusbar.push(context_id, 'Path: '+' '.join(path[1:]))
import gi from gi.repository import Gtk as gtk from gi.repository import Gdk as gdk from gi.repository import GObject from gi.repository.Gio import Settings as GSettings # from gi.repository import cairo import cairo import pyatspi import string from tools import Tools, parseColorString MAX_BLINKS = 6 gsettings = GSettings(schema="org.a11y.Accerciser") BORDER_COLOR, BORDER_ALPHA = parseColorString(gsettings.get_string("highlight-border")) FILL_COLOR, FILL_ALPHA = parseColorString(gsettings.get_string("highlight-fill")) HL_DURATION = int(gsettings.get_double("highlight-duration") * 1000) class Bag(object): """ Bag class for converting a dicionary to an object with attributes. """ def __init__(self, **kwargs): self.__dict__.update(kwargs)
def __init__(self): gtk.Alignment.__init__(self) self.set_padding(12, 12, 18, 12) self.gsettings = GSettings.new('org.a11y.Accerciser') self._buildUI()
class _HighlighterView(gtk.Alignment): ''' A container widget with the settings for the highlighter. ''' def __init__(self): gtk.Alignment.__init__(self) self.set_padding(12, 12, 18, 12) self.gsettings = GSettings(schema='org.a11y.Accerciser') self._buildUI() def _buildUI(self): ''' Programatically build the UI. ''' table = gtk.Table(3, 2) table.set_col_spacings(6) self.add(table) labels = [None, None, None] controls = [None, None, None] labels[0] = gtk.Label(_('Highlight duration:')) controls[0] = gtk.SpinButton() controls[0].set_range(0.01, 5) controls[0].set_digits(2) controls[0].set_value(self.gsettings.get_double('highlight-duration')) controls[0].set_increments(0.01, 0.1) controls[0].connect('value-changed', self._onDurationChanged) labels[1] = gtk.Label(_('Border color:')) controls[1] = self._ColorButton(node.BORDER_COLOR, node.BORDER_ALPHA) controls[1].connect('color-set', self._onColorSet, 'highlight-border') controls[1].set_tooltip_text(_('The border color of the highlight box')) labels[2] = gtk.Label(_('Fill color:')) controls[2] = self._ColorButton(node.FILL_COLOR, node.FILL_ALPHA) controls[2].connect('color-set', self._onColorSet, 'highlight-fill') controls[2].set_tooltip_text(_('The fill color of the highlight box')) for label, control, row in zip(labels, controls, range(3)): label.set_alignment(0, 0.5) table.attach(label, 0, 1, row, row + 1, gtk.AttachOptions.FILL) table.attach(control, 1, 2, row, row + 1, gtk.AttachOptions.FILL) for label, control in zip([x.get_accessible() for x in labels], [x.get_accessible() for x in controls]): label.add_relationship(atk.RelationType.LABEL_FOR, control) control.add_relationship(atk.RelationType.LABELLED_BY, label) def _onDurationChanged(self, spin_button): ''' Callback for the duration spin button. Update key and the global variable in the L{node} module. @param spin_button: The spin button that emitted the value-changed signal. @type spin_button: gtk.SpinButton ''' node.HL_DURATION = int(spin_button.get_value()*1000) self.gsettings.set_double('highlight-duration', spin_button.get_value()) def _onColorSet(self, color_button, key): ''' Callback for a color button. Update gsettings and the global variables in the L{node} module. @param color_button: The color button that emitted the color-set signal. @type color_button: l{_HighlighterView._ColorButton} @param key: the key name suffix for this color setting. @type key: string ''' if 'fill' in key: node.FILL_COLOR = color_button.get_rgb_string() node.FILL_ALPHA = color_button.get_alpha_float() else: node.BORDER_COLOR = color_button.get_rgb_string() node.BORDER_ALPHA = color_button.get_alpha_float() self.gsettings.set_string(key, color_button.get_rgba_string()) class _ColorButton(gtk.ColorButton): ''' ColorButton derivative with useful methods for us. ''' def __init__(self, color, alpha): color = gdk.color_parse(color) gtk.ColorButton.__init__(self) self.set_use_alpha(True) self.set_alpha(int(alpha*0xffff)) self.set_color(color) def get_rgba_string(self): ''' Get the current color and alpha in string format. @return: String in the format of #rrggbbaa. @rtype: string. ''' color = self.get_color() color_val = 0 color_val |= color.red >> 8 << 24 color_val |= color.green >> 8 << 16 color_val |= color.blue >> 8 << 8 color_val |= self.get_alpha() >> 8 return \ '#' + hex(color_val).replace('0x', '').replace('L', '').rjust(8, '0') def get_rgb_string(self): ''' Get the current color in string format. @return: String in the format of #rrggbb. @rtype: string. ''' color = self.get_color() color_val = 0 color_val |= color.red >> 8 << 16 color_val |= color.green >> 8 << 8 color_val |= color.blue >> 8 return \ '#' + hex(color_val).replace('0x', '').replace('L', '').rjust(6, '0') def get_alpha_float(self): ''' Get the current alpha as a value from 0.0 to 1.0. ''' return self.get_alpha()/float(0xffff)
"Copyright (c) 2012 Igalia, S.L." __license__ = "LGPL" import faulthandler import gi import importlib import os import pyatspi import re import signal import subprocess import sys try: from gi.repository.Gio import Settings a11yAppSettings = Settings(schema_id='org.gnome.desktop.a11y.applications') except: a11yAppSettings = None try: # This can fail due to gtk not being available. We want to # be able to recover from that if possible. The main driver # for this is to allow "orca --text-setup" to work even if # the desktop is not running. # gi.require_version("Gtk", "3.0") from gi.repository import Gtk gi.require_version("Gdk", "3.0") from gi.repository import Gdk
def _refreshSettings(self): self.a11yAppPrefs = Settings('org.gnome.desktop.a11y.applications') self.magPrefs = Settings('org.gnome.desktop.a11y.magnifier')