Package libxyz :: Package core :: Module skin
[hide private]
[frames] | no frames]

Source Code for Module libxyz.core.skin

  1  #-*- coding: utf8 -* 
  2  # 
  3  # Max E. Kuznecov ~syhpoon <syhpoon@syhpoon.name> 2008 
  4  # 
  5  # This file is part of XYZCommander. 
  6  # XYZCommander is free software: you can redistribute it and/or modify 
  7  # it under the terms of the GNU Lesser Public License as published by 
  8  # the Free Software Foundation, either version 3 of the License, or 
  9  # (at your option) any later version. 
 10  # XYZCommander is distributed in the hope that it will be useful, 
 11  # but WITHOUT ANY WARRANTY; without even the implied warranty of 
 12  # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 
 13  # GNU Lesser Public License for more details. 
 14  # You should have received a copy of the GNU Lesser Public License 
 15  # along with XYZCommander. If not, see <http://www.gnu.org/licenses/>. 
 16   
 17  import os 
 18  import re 
 19   
 20  import libxyz.parser as parser 
 21   
 22  from libxyz.exceptions import ParseError 
 23  from libxyz.exceptions import SkinError 
 24  from libxyz.exceptions import XYZValueError 
 25  from libxyz.exceptions import FSRuleError 
 26  from libxyz.core import FSRule 
 27   
 28  import libxyz.ui as uilib 
 29   
30 -class Skin(object):
31 """ 32 Skin object. Provides simple interface to defined skin rulesets. 33 """ 34
35 - def __init__(self, path):
36 """ 37 @param path: Path to skin file 38 """ 39 40 if not os.access(path, os.R_OK): 41 raise SkinError(_(u"Unable to open skin file for reading")) 42 else: 43 self.path = path 44 45 self._data = {} 46 47 self.screen = None 48 49 # Default fallback palette 50 self._default = uilib.colors.Palette(u"default", 51 uilib.colors.Foreground(u"DEFAULT"), 52 uilib.colors.Background(u"DEFAULT"), 53 uilib.colors.Monochrome(u"DEFAULT")) 54 55 # 1. Parse 56 self._data = self._parse() 57 58 # 2. Order parsed data 59 self._check()
60 61 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 62
63 - def __str__(self):
64 return u"<Skin object: %s>" % str(self.path)
65 66 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 67
68 - def __repr__(self):
69 return self.__str__()
70 71 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 72
73 - def __getitem__(self, key):
74 return self._data[key]
75 76 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 77
78 - def set_screen(self, screen):
79 self.screen = screen
80 81 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 82
83 - def _parse(self):
84 def palette_validator(block, var, val): 85 """ 86 Make L{libxyz.ui.colors.Palette} object of palette definition 87 """ 88 89 _p = self._default.copy() 90 91 if isinstance(val, basestring): 92 _val = (val,) 93 else: 94 _val = [x.strip() for x in val] 95 96 _p.fg = uilib.colors.Foreground(_val[0]) 97 98 if len(_val) > 1: 99 _p.bg = uilib.colors.Background(_val[1]) 100 if len(_val) > 2: 101 _p.ma = tuple([uilib.colors.Monochrome(x) for x in _val[2:]]) 102 103 _p.name = self._make_name(block, var) 104 105 return _p
106 107 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 108 109 def trans_cr(rule): 110 """ 111 Transform string rules to FSRule objects 112 """ 113 114 try: 115 return FSRule(rule) 116 except (ParseError, FSRuleError), e: 117 raise XYZValueError(e)
118 119 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 120 121 # Prepare parsers 122 123 _fs_rules_opt = {u"count": 1, 124 u"value_validator": palette_validator, 125 u"varre": re.compile(r".+"), 126 u"var_transform": trans_cr, 127 } 128 129 _fs_rules_p = parser.BlockParser(_fs_rules_opt) 130 131 _ui_opt = {u"count": 1, 132 u"value_validator": palette_validator, 133 } 134 _ui_p = parser.BlockParser(_ui_opt) 135 136 _plugin_opt = {u"count": 1, 137 u"value_validator": palette_validator, 138 } 139 _plugin_p = parser.BlockParser(_plugin_opt) 140 141 _flat_opt = {u"count": 1} 142 _flat_p = parser.FlatParser(_flat_opt) 143 144 _parsers = { 145 u"fs.rules": _fs_rules_p, 146 re.compile(r"ui\.(\w)+"): _ui_p, 147 re.compile(r"plugin\.([\w_-])+"): _plugin_p, 148 (u"AUTHOR", u"VERSION", u"DESCRIPTION"): _flat_p, 149 } 150 151 _multi_opt = {u"tokens": (":",)} 152 _multi_p = parser.MultiParser(_parsers, _multi_opt) 153 154 _skinfile = open(self.path, "r") 155 156 try: 157 _data = _multi_p.parse(_skinfile) 158 except ParseError, e: 159 raise SkinError(_(u"Error parsing skin file: %s" % str(e))) 160 finally: 161 _skinfile.close() 162 163 return _data 164 165 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 166
167 - def _make_name(self, block, resource):
168 return "%(resource)s@%(block)s" % locals()
169 170 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 171
172 - def _check(self):
173 """ 174 Check and variables 175 """ 176 177 for _required in (u"AUTHOR", u"DESCRIPTION", u"VERSION"): 178 if _required not in self._data: 179 raise SkinError(_(u"Missing required variable: %s"%_required))
180 181 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 182
183 - def get_palette_list(self):
184 """ 185 Return list of defined palettes. 186 It is usually passed to register_palette() function 187 """ 188 189 _list = [self._default.get_palette()] 190 191 for _name, _pdata in self._data.iteritems(): 192 if not isinstance(_pdata, parser.ParsedData): 193 continue 194 195 for _var, _val in _pdata.iteritems(): 196 if isinstance(_val, uilib.colors.Palette): 197 _list.append(_val.get_palette()) 198 199 return _list
200 201 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 202
203 - def attr(self, resolution, name, default=True):
204 """ 205 Search for first matching attribute <name> according to resolution 206 @param resolution: Sequence of ruleset names 207 @param name: Attribute name 208 @param default: If True, return default palette in case attr 209 is not found, otherwise return None 210 @return: Registered palette name 211 """ 212 213 return self.palette(resolution, name, default).name
214 215 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 216
217 - def palette(self, resolution, name, default=True):
218 """ 219 Search for first matching palette <name> according to resolution 220 """ 221 222 for _w in resolution: 223 # Normalize name 224 if not _w.startswith(u"ui."): 225 _w = u"ui.%s" % _w 226 227 try: 228 return self._data[_w][name] 229 except KeyError: 230 pass 231 232 if default: 233 return self._default 234 else: 235 return None
236 237 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 238
239 - def get_palette(self, block, name):
240 try: 241 return self._data[block][name].name 242 except KeyError: 243 return None
244