def _load_layout(self, layout_filename, color_scheme_filename): self.layout_dir = os.path.dirname(layout_filename) self.svg_cache = {} layout = None if color_scheme_filename: self.color_scheme = ColorScheme.load(color_scheme_filename) f = open(layout_filename) try: dom = minidom.parse(f).documentElement # check layout format format = self.LAYOUT_FORMAT_LEGACY if dom.hasAttribute("format"): format = Version.from_string(dom.attributes["format"].value) if format >= self.LAYOUT_FORMAT_LAYOUT_TREE: items = self._parse_dom_node(dom) else: _logger.warning(_("Loading legacy layout format '{}'. " "Please consider upgrading to current format '{}'" ).format(format, self.LAYOUT_FORMAT)) items = self._parse_legacy_layout(dom) if items: layout = items[0] finally: f.close() self.svg_cache = {} # Free the memory return layout
def load(filename, is_system=False): """ Load a color scheme and return it as a new instance. """ color_scheme = None f = open_utf8(filename) try: dom = minidom.parse(f).documentElement name = dom.attributes["name"].value # check layout format format = ColorScheme.COLOR_SCHEME_FORMAT_LEGACY if dom.hasAttribute("format"): format = Version.from_string(dom.attributes["format"].value) if format >= ColorScheme.COLOR_SCHEME_FORMAT_TREE: # tree format? items = ColorScheme._parse_dom_node(dom, None, {}) else: _logger.warning(_format( \ "Loading legacy color scheme format '{old_format}', " "please consider upgrading to current format " "'{new_format}': '{filename}'", old_format = format, new_format = ColorScheme.COLOR_SCHEME_FORMAT, filename = filename)) items = ColorScheme._parse_legacy_color_scheme(dom) if not items is None: root = Root() root.set_items(items) color_scheme = ColorScheme() color_scheme.name = name color_scheme._filename = filename color_scheme.is_system = is_system color_scheme._root = root #print(root.dumps()) except xml.parsers.expat.ExpatError as ex: _logger.error( _format( "Error loading color scheme '{filename}'. " "{exception}: {cause}", filename=filename, exception=type(ex).__name__, cause=unicode_str(ex))) finally: f.close() return color_scheme
def load(filename, is_system=False): """ Load a color scheme and return it as a new instance. """ color_scheme = None f = open_utf8(filename) try: dom = minidom.parse(f).documentElement name = dom.attributes["name"].value # check layout format format = ColorScheme.COLOR_SCHEME_FORMAT_LEGACY if dom.hasAttribute("format"): format = Version.from_string(dom.attributes["format"].value) if format >= ColorScheme.COLOR_SCHEME_FORMAT_TREE: # tree format? items = ColorScheme._parse_dom_node(dom, None, {}) else: _logger.warning(_format( \ "Loading legacy color scheme format '{old_format}', " "please consider upgrading to current format " "'{new_format}': '{filename}'", old_format = format, new_format = ColorScheme.COLOR_SCHEME_FORMAT, filename = filename)) items = ColorScheme._parse_legacy_color_scheme(dom) if not items is None: root = Root() root.set_items(items) color_scheme = ColorScheme() color_scheme.name = name color_scheme._filename = filename color_scheme.is_system = is_system color_scheme._root = root #print(root.dumps()) except xml.parsers.expat.ExpatError as ex: _logger.error(_format("Error loading color scheme '{filename}'. " "{exception}: {cause}", filename = filename, exception = type(ex).__name__, cause = unicode_str(ex))) finally: f.close() return color_scheme
def _load_layout(self, layout_filename, parent_item=None): self._svg_cache = {} layout = None try: f = open_utf8(layout_filename) except FileNotFoundError as ex: _logger.warning("Failed to open '{}': {}".format( layout_filename, unicode_str(ex))) return None # make sure unlink is called with minidom.parse(f).documentElement as dom: # check layout format, no format version means legacy layout format = self.LAYOUT_FORMAT_LEGACY if dom.hasAttribute("format"): format = Version.from_string(dom.attributes["format"].value) self._format = format root = LayoutPanel() # root, representing the 'keyboard' tag root.set_id("__root__") # id for debug prints # Init included root with the parent item's svg filename. # -> Allows to skip specifying svg filenames in includes. if parent_item: root.filename = parent_item.filename if format >= self.LAYOUT_FORMAT_LAYOUT_TREE: self._parse_dom_node(dom, root) layout = root else: _logger.warning( _format( "Loading legacy layout, format '{}'. " "Please consider upgrading to current format '{}'", format, self.LAYOUT_FORMAT)) items = self._parse_legacy_layout(dom) if items: root.set_items(items) layout = root f.close() self._svg_cache = {} # Free the memory return layout
def load(filename, is_system=False): """ Load a color scheme and return it as a new object. """ color_scheme = None f = open(filename) try: dom = minidom.parse(f).documentElement name = dom.attributes["name"].value # check layout format format = ColorScheme.COLOR_SCHEME_FORMAT_LEGACY if dom.hasAttribute("format"): format = Version.from_string(dom.attributes["format"].value) if format >= ColorScheme.COLOR_SCHEME_FORMAT_TREE: # tree format? items = ColorScheme._parse_dom_node(dom, None, {}) else: _logger.warning( \ _("Loading legacy color scheme format '{old_format}', " "please consider upgrading to current format " \ "'{new_format}': '{filename}'") \ .format(old_format = format, new_format = ColorScheme.COLOR_SCHEME_FORMAT, filename = filename)) items = ColorScheme._parse_legacy_color_scheme(dom) if not items is None: root = Root() root.set_items(items) color_scheme = ColorScheme() color_scheme.name = name color_scheme.filename = filename color_scheme.is_system = is_system color_scheme.root = root #print(root.dumps()) finally: f.close() return color_scheme
def _load_layout(self, layout_filename, parent_item = None): self._svg_cache = {} layout = None f = open_utf8(layout_filename) # make sure unlink is called with minidom.parse(f).documentElement as dom: # check layout format, no format version means legacy layout format = self.LAYOUT_FORMAT_LEGACY if dom.hasAttribute("format"): format = Version.from_string(dom.attributes["format"].value) self._format = format root = LayoutPanel() # root, representing the 'keyboard' tag root.set_id("__root__") # id for debug prints # Init included root with the parent item's svg filename. # -> Allows to skip specifying svg filenames in includes. if parent_item: root.filename = parent_item.filename if format >= self.LAYOUT_FORMAT_LAYOUT_TREE: self._parse_dom_node(dom, root) layout = root else: _logger.warning(_format("Loading legacy layout, format '{}'. " "Please consider upgrading to current format '{}'", format, self.LAYOUT_FORMAT)) items = self._parse_legacy_layout(dom) if items: root.set_items(items) layout = root f.close() self._svg_cache = {} # Free the memory return layout
def copy_layout(src_filename, dst_filename): src_dir = os.path.dirname(src_filename) dst_dir, name_ext = os.path.split(dst_filename) dst_basename, ext = os.path.splitext(name_ext) _logger.info(_("copying layout '{}' to '{}'") \ .format(src_filename, dst_filename)) domdoc = None svg_filenames = {} fallback_layers = {} with open(src_filename) as f: domdoc = minidom.parse(f) keyboard_node = domdoc.documentElement # check layout format format = KeyboardSVG.LAYOUT_FORMAT_LEGACY if keyboard_node.hasAttribute("format"): format = Version.from_string(keyboard_node.attributes["format"].value) keyboard_node.attributes["id"] = dst_basename if format < KeyboardSVG.LAYOUT_FORMAT_LAYOUT_TREE: raise Exceptions.LayoutFileError( \ _("copy_layouts failed, unsupported layout format '{}'.") \ .format(format)) else: # replace the basename of all svg filenames for node in KeyboardSVG._iter_dom_nodes(keyboard_node): if KeyboardSVG.is_layout_node(node): if node.hasAttribute("filename"): filename = node.attributes["filename"].value # Create a replacement layer name for the unlikely # case that the svg-filename doesn't contain a # layer section (as in path/basename-layer.ext). fallback_layer_name = fallback_layers.get(filename, "Layer" + str(len(fallback_layers))) fallback_layers[filename] = fallback_layer_name # replace the basename of this filename new_filename = KeyboardSVG._replace_basename( \ filename, dst_basename, fallback_layer_name) node.attributes["filename"].value = new_filename svg_filenames[filename] = new_filename if domdoc: # write the new layout file with open(dst_filename, "w") as f: xml = toprettyxml(domdoc) f.write(xml.encode("UTF-8")) # copy the svg files for src, dst in list(svg_filenames.items()): dir, name = os.path.split(src) if not dir: src = os.path.join(src_dir, name) dir, name = os.path.split(dst) if not dir: dst = os.path.join(dst_dir, name) _logger.info(_("copying svg file '{}' to '{}'") \ .format(src, dst)) shutil.copyfile(src, dst)
def load(filename, is_system=False): """ Load a theme and return a new theme object. """ result = None _file = open_utf8(filename) try: domdoc = minidom.parse(_file).documentElement try: theme = Theme() node = domdoc.attributes.get("format") format = Version.from_string(node.value) \ if node else Theme.THEME_FORMAT_INITIAL theme.name = domdoc.attributes["name"].value # "color_scheme" is the base file name of the color scheme text = utils.xml_get_text(domdoc, "color_scheme") if not text is None: theme.color_scheme_basename = text # get key label overrides nodes = domdoc.getElementsByTagName("key_label_overrides") if nodes: overrides = nodes[0] tuples = {} for override in overrides.getElementsByTagName("key"): key_id = override.attributes["id"].value node = override.attributes.get("label") label = node.value if node else "" node = override.attributes.get("group") group = node.value if node else "" tuples[key_id] = (label, group) theme.key_label_overrides = tuples # read all other members for name, _type, _default in Theme.attributes: if not name in [ "color_scheme_basename", "key_label_overrides" ]: value = utils.xml_get_text(domdoc, name) if not value is None: if _type == "i": value = int(value) if _type == "d": value = float(value) if _type == "ad": value = [float(s) for s in value.split(",")] # upgrade to current file format if format < Theme.THEME_FORMAT_1_1: # direction was 0..360, ccw # is now -180..180, cw if name == "key_gradient_direction": value = -(value % 360) if value <= -180: value += 360 setattr(theme, name, value) theme._filename = filename theme.is_system = is_system theme.system_exists = is_system result = theme finally: domdoc.unlink() except (Exceptions.ThemeFileError, xml.parsers.expat.ExpatError) as ex: _logger.error( _format( "Error loading theme '{filename}'. " "{exception}: {cause}", filename=filename, exception=type(ex).__name__, cause=unicode_str(ex))) result = None finally: _file.close() return result
def copy_layout(src_filename, dst_filename): src_dir = os.path.dirname(src_filename) dst_dir, name_ext = os.path.split(dst_filename) dst_basename, ext = os.path.splitext(name_ext) _logger.info( _format("copying layout '{}' to '{}'", src_filename, dst_filename)) domdoc = None svg_filenames = {} fallback_layers = {} try: with open_utf8(src_filename) as f: domdoc = minidom.parse(f) keyboard_node = domdoc.documentElement # check layout format format = LayoutLoaderSVG.LAYOUT_FORMAT_LEGACY if keyboard_node.hasAttribute("format"): format = Version.from_string( keyboard_node.attributes["format"].value) keyboard_node.attributes["id"] = dst_basename if format < LayoutLoaderSVG.LAYOUT_FORMAT_LAYOUT_TREE: raise Exceptions.LayoutFileError( \ _format("copy_layouts failed, unsupported layout format '{}'.", format)) else: # replace the basename of all svg filenames for node in LayoutLoaderSVG._iter_dom_nodes(keyboard_node): if LayoutLoaderSVG.is_layout_node(node): if node.hasAttribute("filename"): filename = node.attributes["filename"].value # Create a replacement layer name for the unlikely # case that the svg-filename doesn't contain a # layer section (as in path/basename-layer.ext). fallback_layer_name = fallback_layers.get( filename, "Layer" + str(len(fallback_layers))) fallback_layers[filename] = fallback_layer_name # replace the basename of this filename new_filename = LayoutLoaderSVG._replace_basename( \ filename, dst_basename, fallback_layer_name) node.attributes[ "filename"].value = new_filename svg_filenames[filename] = new_filename if domdoc: XDGDirs.assure_user_dir_exists(config.get_user_layout_dir()) # write the new layout file with open_utf8(dst_filename, "w") as f: xml = toprettyxml(domdoc) if sys.version_info.major == 2: # python 2? xml = xml.encode("UTF-8") f.write(xml) # copy the svg files for src, dst in list(svg_filenames.items()): dir, name = os.path.split(src) if not dir: src = os.path.join(src_dir, name) dir, name = os.path.split(dst) if not dir: dst = os.path.join(dst_dir, name) _logger.info(_format("copying svg file '{}' to '{}'", \ src, dst)) shutil.copyfile(src, dst) except OSError as ex: _logger.error("copy_layout failed: " + \ unicode_str(ex)) except Exceptions.LayoutFileError as ex: _logger.error(unicode_str(ex))
def load(filename, is_system=False): """ Load a theme and return a new theme object. """ result = None _file = open(filename) try: domdoc = minidom.parse(_file).documentElement try: theme = Theme() node = domdoc.attributes.get("format") format = Version.from_string(node.value) \ if node else Theme.THEME_FORMAT_INITIAL theme.name = domdoc.attributes["name"].value # "color_scheme" is the base file name of the color scheme text = utils.xml_get_text(domdoc, "color_scheme") if not text is None: theme.color_scheme_basename = text # get key label overrides nodes = domdoc.getElementsByTagName("key_label_overrides") if nodes: overrides = nodes[0] tuples = {} for override in overrides.getElementsByTagName("key"): key_id = override.attributes["id"].value node = override.attributes.get("label") label = node.value if node else "" node = override.attributes.get("group") group = node.value if node else "" tuples[key_id] = (label, group) theme.key_label_overrides = tuples # read all other members for name, _type, _default in Theme.attributes: if not name in ["color_scheme_basename", "key_label_overrides"]: value = utils.xml_get_text(domdoc, name) if not value is None: if _type == "i": value = int(value) if _type == "f": value = float(value) # upgrade to current file format if format < Theme.THEME_FORMAT_1_1: # direction was 0..360, ccw # is now -180..180, cw if name == "key_gradient_direction": value = -(value % 360) if value <= -180: value += 360 setattr(theme, name, value) theme.filename = filename theme.is_system = is_system theme.system_exists = is_system result = theme except Exceptions.ThemeFileError as xxx_todo_changeme: (ex) = xxx_todo_changeme raise Exceptions.ThemeFileError(_("Error loading ") + filename, chained_exception = ex) finally: domdoc.unlink() finally: _file.close() return result
def init_from_gsettings(self): """ Overloaded to migrate old dconf data to a new gsettings schema """ ConfigObject.init_from_gsettings(self) import osk util = osk.Util() def migrate_dconf_value(dconf_key, config_object, gskey): try: value = util.read_dconf_key(dconf_key) except (ValueError, TypeError) as e: value = None _logger.warning("migrate_dconf_value: {}".format(e)) if not value is None: setattr(config_object, gskey.prop, value) _logger.debug("migrate_dconf_value: {key} -> {path} {gskey}, value={value}" \ .format(key=dconf_key, path=co.schema, gskey=gskey.key, value=value)) def migrate_dconf_key(dconf_key, config_object, key): gskey = config_object.find_key(key) if gskey.is_default(): migrate_dconf_value(dconf_key, config_object, gskey) # --- onboard 0.96 -> 0.97 --------------------------------------------- format = Version.from_string(self.schema_version) if format < SCHEMA_VERSION_0_97: # window rect moves from apps.onboard to # apps.onboard.window.landscape/portrait co = self.window.landscape if co.gskeys["x"].is_default() and \ co.gskeys["y"].is_default() and \ co.gskeys["width"].is_default() and \ co.gskeys["height"].is_default(): co.settings.delay() migrate_dconf_value("/apps/onboard/x", co, co.gskeys["x"]) migrate_dconf_value("/apps/onboard/y", co, co.gskeys["y"]) migrate_dconf_value("/apps/onboard/width", co, co.gskeys["width"]) migrate_dconf_value("/apps/onboard/height", co, co.gskeys["height"]) co.settings.apply() # icon-palette rect moves from apps.onboard.icon-palette to # apps.onboard.icon-palette.landscape/portrait co = self.icp.landscape if co.gskeys["x"].is_default() and \ co.gskeys["y"].is_default() and \ co.gskeys["width"].is_default() and \ co.gskeys["height"].is_default(): co.settings.delay() migrate_dconf_value("/apps/onboard/icon-palette/x", co, co.gskeys["x"]) migrate_dconf_value("/apps/onboard/icon-palette/y", co, co.gskeys["y"]) migrate_dconf_value("/apps/onboard/icon-palette/width", co, co.gskeys["width"]) migrate_dconf_value("/apps/onboard/icon-palette/height", co, co.gskeys["height"]) co.settings.apply() # move keys from root to window co = self.window migrate_dconf_key("/apps/onboard/window-decoration", co, "window-decoration") migrate_dconf_key("/apps/onboard/force-to-top", co, "force-to-top") migrate_dconf_key("/apps/onboard/transparent-background", co, "transparent-background") migrate_dconf_key("/apps/onboard/transparency", co, "transparency") migrate_dconf_key("/apps/onboard/background-transparency", co, "background-transparency") migrate_dconf_key("/apps/onboard/enable-inactive-transparency", co, "enable-inactive-transparency") migrate_dconf_key("/apps/onboard/inactive-transparency", co, "inactive-transparency") migrate_dconf_key("/apps/onboard/inactive-transparency-delay", co, "inactive-transparency-delay") # accessibility keys move from root to universal-access co = self.universal_access migrate_dconf_key("/apps/onboard/hide-click-type-window", co, "hide-click-type-window") migrate_dconf_key("/apps/onboard/enable-click-type-window-on-exit", co, "enable-click-type-window-on-exit") # move keys from root to keyboard co = self.keyboard migrate_dconf_key("/apps/onboard/show-click-buttons", co, "show-click-buttons") self.schema_version = SCHEMA_VERSION.to_string()
def load(filename, is_system=False): """ Load a theme and return a new theme object. """ result = None _file = open_utf8(filename) try: domdoc = minidom.parse(_file).documentElement try: theme = Theme() node = domdoc.attributes.get("format") format = Version.from_string(node.value) \ if node else Theme.THEME_FORMAT_INITIAL theme.name = domdoc.attributes["name"].value # "color_scheme" is the base file name of the color scheme text = utils.xml_get_text(domdoc, "color_scheme") if not text is None: theme.color_scheme_basename = text # get key label overrides nodes = domdoc.getElementsByTagName("key_label_overrides") if nodes: overrides = nodes[0] tuples = {} for override in overrides.getElementsByTagName("key"): key_id = override.attributes["id"].value node = override.attributes.get("label") label = node.value if node else "" node = override.attributes.get("group") group = node.value if node else "" tuples[key_id] = (label, group) theme.key_label_overrides = tuples # read all other members for name, _type, _default in Theme.attributes: if not name in ["color_scheme_basename", "key_label_overrides"]: value = utils.xml_get_text(domdoc, name) if not value is None: if _type == "i": value = int(value) if _type == "d": value = float(value) if _type == "ad": value = [float(s) for s in value.split(",")] # upgrade to current file format if format < Theme.THEME_FORMAT_1_1: # direction was 0..360, ccw # is now -180..180, cw if name == "key_gradient_direction": value = -(value % 360) if value <= -180: value += 360 setattr(theme, name, value) theme._filename = filename theme.is_system = is_system theme.system_exists = is_system result = theme finally: domdoc.unlink() except (Exceptions.ThemeFileError, xml.parsers.expat.ExpatError) as ex: _logger.error(_format("Error loading theme '{filename}'. " "{exception}: {cause}", filename = filename, exception = type(ex).__name__, cause = unicode_str(ex))) result = None finally: _file.close() return result
def copy_layout(src_filename, dst_filename): src_dir = os.path.dirname(src_filename) dst_dir, name_ext = os.path.split(dst_filename) dst_basename, ext = os.path.splitext(name_ext) _logger.info(_format("copying layout '{}' to '{}'", src_filename, dst_filename)) domdoc = None svg_filenames = {} fallback_layers = {} try: with open_utf8(src_filename) as f: domdoc = minidom.parse(f) keyboard_node = domdoc.documentElement # check layout format format = LayoutLoaderSVG.LAYOUT_FORMAT_LEGACY if keyboard_node.hasAttribute("format"): format = Version.from_string(keyboard_node.attributes["format"].value) keyboard_node.attributes["id"] = dst_basename if format < LayoutLoaderSVG.LAYOUT_FORMAT_LAYOUT_TREE: raise Exceptions.LayoutFileError( \ _format("copy_layouts failed, unsupported layout format '{}'.", format)) else: # replace the basename of all svg filenames for node in LayoutLoaderSVG._iter_dom_nodes(keyboard_node): if LayoutLoaderSVG.is_layout_node(node): if node.hasAttribute("filename"): filename = node.attributes["filename"].value # Create a replacement layer name for the unlikely # case that the svg-filename doesn't contain a # layer section (as in path/basename-layer.ext). fallback_layer_name = fallback_layers.get(filename, "Layer" + str(len(fallback_layers))) fallback_layers[filename] = fallback_layer_name # replace the basename of this filename new_filename = LayoutLoaderSVG._replace_basename( \ filename, dst_basename, fallback_layer_name) node.attributes["filename"].value = new_filename svg_filenames[filename] = new_filename if domdoc: XDGDirs.assure_user_dir_exists(config.get_user_layout_dir()) # write the new layout file with open_utf8(dst_filename, "w") as f: xml = toprettyxml(domdoc) if sys.version_info.major == 2: # python 2? xml = xml.encode("UTF-8") f.write(xml) # copy the svg files for src, dst in list(svg_filenames.items()): dir, name = os.path.split(src) if not dir: src = os.path.join(src_dir, name) dir, name = os.path.split(dst) if not dir: dst = os.path.join(dst_dir, name) _logger.info(_format("copying svg file '{}' to '{}'", \ src, dst)) shutil.copyfile(src, dst) except OSError as ex: _logger.error("copy_layout failed: " + \ unicode_str(ex)) except Exceptions.LayoutFileError as ex: _logger.error(unicode_str(ex))