home *** CD-ROM | disk | FTP | other *** search
/ Maximum CD 2009 June / maximum-cd-2009-06.iso / DiscContents / digsby_setup.exe / lib / gui / skin / skintree.pyo (.txt) < prev   
Encoding:
Python Compiled Bytecode  |  2009-02-26  |  11.7 KB  |  403 lines

  1. # Source Generated with Decompyle++
  2. # File: in.pyo (Python 2.5)
  3.  
  4. from __future__ import with_statement
  5. SKIN_FILENAME = 'skin.yaml'
  6. VARIANT_DIR = 'Variants'
  7. SKIN_NAME_KEY = 'name'
  8. VARIANT_NAME_KEY = 'variant'
  9. alternating_keys = [
  10.     'buddiespanel.backgrounds.buddy',
  11.     'filetransfers.backgrounds.normal']
  12. FONT_MULTIPLY_KEY = 'FontPlatform'
  13. FONT_MULTIPLY = {
  14.     'windows_mac': 4 / 3,
  15.     'mac_windows': 3 / 4 }
  16. __metaclass__ = type
  17. from operator import isMappingType
  18. from util import Storage as S
  19. from path import path
  20. from copy import deepcopy
  21. import syck
  22. import sys
  23. import os
  24. import wx
  25. from wx import GetTopLevelWindows, GetApp, MessageBox, StandardPaths
  26. from traceback import print_exc
  27. from gui.toolbox import colorfor
  28. from types import FunctionType
  29. from util.merge import merge, merge_keys, tolower
  30. from util import syck_error_message, funcinfo
  31. from gui.skin.skintransform import transform
  32. from gui.skin import SkinException
  33. from peak.util.plugins import Hook
  34. from logging import getLogger
  35. log = getLogger('skin')
  36. info = log.info
  37. activeTree = None
  38. resource_paths = [
  39.     path('res').abspath(),
  40.     path('res/skins/default').abspath()]
  41.  
  42. def get(dottedpath, default = sentinel):
  43.     
  44.     try:
  45.         return lookup(activeTree, dottedpath.lower().split('.'))
  46.     except (KeyError, TypeError):
  47.         if default is sentinel:
  48.             raise SkinException('not found: ' + dottedpath)
  49.         else:
  50.             return default
  51.     except:
  52.         default is sentinel
  53.         print_exc()
  54.         print >>sys.stderr, 'exception for "%s"' % dottedpath
  55.  
  56.  
  57.  
  58. def refresh_wx_tree():
  59.     UMenu = UMenu
  60.     import gui.uberwidgets.umenu
  61.     skip = (UMenu,)
  62.     for window in GetTopLevelWindows():
  63.         window.FrozenQuick().__enter__()
  64.         
  65.         try:
  66.             _updateskin(window, skip)
  67.         finally:
  68.             pass
  69.  
  70.     
  71.     UMenu.CallAll(UMenu.UpdateSkin)
  72.  
  73.  
  74. def _updateskin(window, skip):
  75.     
  76.     try:
  77.         update = window.UpdateSkin
  78.     except AttributeError:
  79.         pass
  80.  
  81.     if not isinstance(window, skip):
  82.         
  83.         try:
  84.             update()
  85.         print_exc()
  86.  
  87.     
  88.     for c in window.Children:
  89.         _updateskin(c, skip)
  90.     
  91.  
  92.  
  93. def alternating(tree):
  94.     SkinList = SkinList
  95.     import gui.skin.skinobjects
  96.     for k in alternating_keys:
  97.         spath = k.split('.')
  98.         
  99.         try:
  100.             val = lookup(tree, spath)
  101.         except AttributeError:
  102.             continue
  103.  
  104.         if isinstance(val, list):
  105.             lookup(tree, spath[:-1])[spath[-1]] = SkinList(val)
  106.             continue
  107.     
  108.  
  109.  
  110. def fontplatform(finaltree):
  111.     skin = skin
  112.     import gui
  113.     platformName = platformName
  114.     import config
  115.     platform_aliases = {
  116.         'win': 'windows',
  117.         'mac': 'mac' }
  118.     fontplatform = finaltree.get(FONT_MULTIPLY_KEY.lower(), None)
  119.     fp = '%s_%s' % (fontplatform, platform_aliases.get(platformName))
  120.     factor = FONT_MULTIPLY.get(fp, 1)
  121.     log.info('new font multiply factor: %s -> %s', fp, factor)
  122.     skin.font_multiply_factor = factor
  123.  
  124. pretransforms = [
  125.     fontplatform]
  126. posttransforms = [
  127.     alternating]
  128.  
  129. def set_active(skin, variant = None, update_gui = False, callback = None):
  130.     global activeTree
  131.     log.info('set_active(%s, %s)', skin, variant)
  132.     app = GetApp()
  133.     skin = resource_paths[0] / path('skins') / skin
  134.     if variant is not None:
  135.         variant = skin / VARIANT_DIR / variant + '.yaml'
  136.     
  137.     skinpath = skin / SKIN_FILENAME
  138.     default_path = resource_paths[0] / 'skins' / 'default' / SKIN_FILENAME
  139.     paths = [
  140.         default_path]
  141.     if not skinpath.exists():
  142.         log.critical('cannot find %s (%r.exists() == False, defaulting to silverblue', skin, skinpath)
  143.         skin = resource_paths[0] / path('skins') / 'silverblue'
  144.         skinpath = skin / SKIN_FILENAME
  145.         variant = None
  146.     
  147.     if default_path.abspath() != skinpath.abspath():
  148.         paths.append(skinpath)
  149.     
  150.     if variant is not None and variant.exists():
  151.         paths.append(variant)
  152.     else:
  153.         log.warning('cannot find variant %s for skin %s', variant, skin)
  154.     if not update_gui and hasattr(app, 'skin') and app.skin.paths == paths:
  155.         log.info('skin did not change, returning')
  156.     
  157.     log.info('loading YAML from %d path(s):\n  %s', len(paths), '\n  '.join(paths))
  158.     trees = get_skintrees(skin, paths)
  159.     default_tree = deepcopy(trees[0])
  160.     combined_tree = merge(*trees, **dict(keytransform = (lambda k: getattr(k, 'lower', (lambda k: k))()
  161. )))
  162.     if not hasattr(app, 'skin'):
  163.         app.skin = S()
  164.     
  165.     app.skin.update(path = skinpath.parent, paths = get_image_load_paths(paths))
  166.     for pretransform in pretransforms:
  167.         pretransform(combined_tree)
  168.     
  169.     
  170.     try:
  171.         finaltree = transform(combined_tree)
  172.     except Exception:
  173.         e = None
  174.         MessageBox('There was an error processing skin "%s":\n\n%s' % (skin, str(e)), 'Skin Error')
  175.         print_exc()
  176.         finaltree = transform(default_tree)
  177.  
  178.     for posttransform in posttransforms:
  179.         posttransform(finaltree)
  180.     
  181.     activeTree = finaltree
  182.     app.skin.update(tree = finaltree)
  183.     
  184.     def done():
  185.         if update_gui:
  186.             refresh_wx_tree()
  187.         
  188.         if callback is not None:
  189.             callback()
  190.         
  191.  
  192.     wx.CallAfter(done)
  193.     return app.skin
  194.  
  195.  
  196. def list_skins():
  197.     resource_paths = sys.modules['gui.skin.skintree'].resource_paths
  198.     skins = []
  199.     for res in resource_paths:
  200.         skinrootdir = res / 'skins'
  201.         if skinrootdir.exists():
  202.             for skindir in skinrootdir.dirs():
  203.                 if skindir.name.startswith('.'):
  204.                     continue
  205.                 
  206.                 rootfile = skindir / SKIN_FILENAME
  207.                 if rootfile.exists() and skindir.name != 'default':
  208.                     skins.append(skindesc(rootfile))
  209.                     continue
  210.             
  211.     
  212.     return skins
  213.  
  214.  
  215. def get_skintrees(skin, paths):
  216.     trees = []
  217.     errors = []
  218.     successful = False
  219.     for f in paths:
  220.         
  221.         try:
  222.             trees.append(load_skinfile(f))
  223.         except Exception:
  224.             e = None
  225.             errors.append(e)
  226.             del e
  227.             continue
  228.  
  229.         successful = True
  230.     
  231.     if not successful:
  232.         MessageBox('There was an error loading skin "%s":\n\n%s' % (skin, '\n'.join((lambda .0: for e in .0:
  233. str(e))(errors))), 'Skin Error')
  234.     
  235.     for hook in Hook('digsby.skin.load.trees'):
  236.         hook_trees = hook()
  237.         if hook_trees is not None:
  238.             trees.extend(hook_trees)
  239.             continue
  240.     
  241.     return trees
  242.  
  243.  
  244. def get_image_load_paths(paths):
  245.     image_load_paths = [ p.parent for p in paths ]
  246.     for pathhook in Hook('digsby.skin.load.skinpaths'):
  247.         hook_paths = pathhook()
  248.         if hook_paths is not None:
  249.             image_load_paths.extend(hook_paths)
  250.             continue
  251.         []
  252.     
  253.     return image_load_paths
  254.  
  255.  
  256. def quick_name_lookup(p, **names):
  257.     names = dict((lambda .0: for key, name in .0:
  258. (name.lower(), key))(names.iteritems()))
  259.     vals = { }
  260.     
  261.     try:
  262.         f = _[2]
  263.         s = syck.load(f)
  264.         for k, name in getattr(s, ('iteritems',), (lambda : s))():
  265.             
  266.             try:
  267.                 k = k.lower()
  268.             except AttributeError:
  269.                 p.open('r')
  270.                 p.open('r')
  271.                 continue
  272.  
  273.             if k in names and isinstance(name, basestring):
  274.                 vals[k] = name
  275.                 if len(vals) == len(names):
  276.                     break
  277.                 
  278.             len(vals) == len(names)
  279.     finally:
  280.         pass
  281.  
  282.     return vals
  283.  
  284.  
  285. def skindesc(rootfile):
  286.     rootfile = path(rootfile)
  287.     aliases = quick_name_lookup(rootfile, skin_alias = SKIN_NAME_KEY, novariant_alias = VARIANT_NAME_KEY)
  288.     variants = []
  289.     vardir = rootfile.parent / VARIANT_DIR
  290.     if vardir.exists():
  291.         for variant in vardir.files('*.yaml'):
  292.             if variant != rootfile:
  293.                 valias = quick_name_lookup(variant, variant_alias = VARIANT_NAME_KEY).get('variant_alias', variant.namebase)
  294.                 variants.append(S(path = variant, alias = valias))
  295.                 continue
  296.         
  297.     
  298.     return S(name = rootfile.parent.name, alias = aliases.get(SKIN_NAME_KEY, rootfile.parent.name), novariant_alias = aliases.get(VARIANT_NAME_KEY, _('(none)')), base = rootfile, variants = variants)
  299.  
  300.  
  301. def lookup(root, pathseq):
  302.     elem = root
  303.     for p in pathseq:
  304.         elem = elem[p]
  305.     
  306.     return elem
  307.  
  308.  
  309. def load_skinfile(filepath):
  310.     if not filepath.exists():
  311.         raise ValueError('file %s does not exist' % filepath)
  312.     
  313.     return globals()['load_%s' % filepath.ext[1:]](filepath)
  314.  
  315.  
  316. def load_yaml(str_or_path):
  317.     (bytes, fpath) = getcontent(str_or_path)
  318.     if isinstance(bytes, unicode):
  319.         bytes = bytes.encode('utf-8')
  320.     
  321.     if not bytes:
  322.         raise SkinException('no bytes in ' + str_or_path)
  323.     
  324.     content = load_yaml_content(bytes)
  325.     
  326.     try:
  327.         root = syck.load(content)
  328.     except syck.error:
  329.         e = None
  330.         raise SkinException(syck_error_message(e, fpath))
  331.  
  332.     return merge_keys(root)
  333.  
  334.  
  335. def load_yaml_content(bytes, included_paths = None):
  336.     if included_paths is None:
  337.         included_paths = []
  338.     
  339.     lines = []
  340.     for line in bytes.split('\n'):
  341.         if line.lower().startswith('include:'):
  342.             include_path = line[line.index(':') + 1:].strip()
  343.             line = load_yaml_include(include_path, included_paths)
  344.         
  345.         lines.append(line)
  346.     
  347.     return '\n'.join(lines)
  348.  
  349.  
  350. def load_yaml_include(incpath, included_paths):
  351.     incpath = path(incpath).abspath()
  352.     if incpath not in included_paths:
  353.         bytes = load_yaml_content(incpath.bytes(), included_paths)
  354.         included_paths += [
  355.             incpath]
  356.         return bytes
  357.     else:
  358.         return ''
  359.  
  360. from util.data_importer import zipopen
  361. from contextlib import closing
  362.  
  363. def getcontent(str_or_path):
  364.     
  365.     try:
  366.         if str_or_path.exists():
  367.             return (str_or_path.bytes(), str_or_path)
  368.         
  369.         
  370.         try:
  371.             f = _[2]
  372.             return (f.read(), str_or_path)
  373.         finally:
  374.             pass
  375.  
  376.     except AttributeError:
  377.         return (str_or_path, '<String Input>')
  378.  
  379.  
  380. if __name__ == '__main__':
  381.     s = 'common:\n- &mycolor red\n\nmenu:\n  color: *mycolor\n\ncommon:\n- &mycolor blue'
  382.     print load_yaml(s)
  383.  
  384. if __name__ == '_AFDASF':
  385.     import wx
  386.     a = wx.PySimpleApp()
  387.     sys.modules['gui.skin.skintree'].resource_paths = [
  388.         path('../../../res')]
  389.     skins = list_skins()
  390.     if not skins:
  391.         sys.exit()
  392.     
  393.     set_active(skins[1])
  394.     
  395.     try:
  396.         f = _[2]
  397.         f.write('button:\n    color: red')
  398.     finally:
  399.         pass
  400.  
  401.     s = '\ninclude: test.yaml\ninclude: test.yaml\n\nButton:\n    font: Arial\n\nbutton:\n    Font: Comic Sans MS\n'
  402.  
  403.