home *** CD-ROM | disk | FTP | other *** search
/ Hackers Magazine 57 / CdHackersMagazineNr57.iso / Software / Multimedia / k3d-setup-0.7.11.0.exe / lib / site-packages / gtk-2.0 / gobject / propertyhelper.py < prev   
Encoding:
Python Source  |  2008-05-23  |  9.3 KB  |  294 lines

  1. # -*- Mode: Python; py-indent-offset: 4 -*-
  2. # pygobject - Python bindings for the GObject library
  3. # Copyright (C) 2007 Johan Dahlin
  4. #
  5. #   gobject/propertyhelper.py: GObject property wrapper/helper
  6. #
  7. # This library is free software; you can redistribute it and/or
  8. # modify it under the terms of the GNU Lesser General Public
  9. # License as published by the Free Software Foundation; either
  10. # version 2.1 of the License, or (at your option) any later version.
  11. #
  12. # This library is distributed in the hope that it will be useful,
  13. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  15. # Lesser General Public License for more details.
  16. #
  17. # You should have received a copy of the GNU Lesser General Public
  18. # License along with this library; if not, write to the Free Software
  19. # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
  20. # USA
  21.  
  22. import _gobject
  23. from gobject.constants import \
  24.      TYPE_NONE, TYPE_INTERFACE, TYPE_CHAR, TYPE_UCHAR, \
  25.      TYPE_BOOLEAN, TYPE_INT, TYPE_UINT, TYPE_LONG, \
  26.      TYPE_ULONG, TYPE_INT64, TYPE_UINT64, TYPE_ENUM, \
  27.      TYPE_FLAGS, TYPE_FLOAT, TYPE_DOUBLE, TYPE_STRING, \
  28.      TYPE_POINTER, TYPE_BOXED, TYPE_PARAM, TYPE_OBJECT, \
  29.      TYPE_PYOBJECT
  30. from gobject.constants import \
  31.      G_MINFLOAT, G_MAXFLOAT, G_MINDOUBLE, G_MAXDOUBLE, \
  32.      G_MININT, G_MAXINT, G_MAXUINT, G_MINLONG, G_MAXLONG, \
  33.      G_MAXULONG
  34.  
  35.  
  36. class property(object):
  37.     """
  38.     Creates a new property which in conjunction with GObject subclass will
  39.     create a property proxy:
  40.  
  41.     >>> class MyObject(gobject.GObject):
  42.     >>> ... prop = gobject.property(type=str)
  43.  
  44.     >>> obj = MyObject()
  45.     >>> obj.prop = 'value'
  46.  
  47.     >>> obj.prop
  48.     'value'
  49.  
  50.     The API is similar to the builtin property:
  51.  
  52.     class AnotherObject(gobject.GObject):
  53.         @gobject.property
  54.         def prop(self):
  55.             return ...
  56.  
  57.     Which will create a read-only property called prop.
  58.     """
  59.  
  60.     class __metaclass__(type):
  61.         def __repr__(self):
  62.             return "<class 'gobject.property'>"
  63.  
  64.     def __init__(self, getter=None, setter=None, type=None, default=None,
  65.                  nick='', blurb='', flags=_gobject.PARAM_READWRITE,
  66.                  minimum=None, maximum=None):
  67.         """
  68.         @param  getter: getter to get the value of the property
  69.         @type   getter: callable
  70.         @param  setter: setter to set the value of the property
  71.         @type   setter: callable
  72.         @param    type: type of property
  73.         @type     type: type
  74.         @param default: default value
  75.         @param    nick: short description
  76.         @type     bick: string
  77.         @param   blurb: long description
  78.         @type    blurb: string
  79.         @param flags:    parameter flags, one of:
  80.         - gobject.PARAM_READABLE
  81.         - gobject.PARAM_READWRITE
  82.         - gobject.PARAM_WRITABLE
  83.         - gobject.PARAM_CONSTRUCT
  84.         - gobject.PARAM_CONSTRUCT_ONLY
  85.         - gobject.PARAM_LAX_VALIDATION
  86.         @keyword minimum:  minimum allowed value (int, float, long only)
  87.         @keyword maximum:  maximum allowed value (int, float, long only)
  88.         """
  89.  
  90.         if getter and not setter:
  91.             setter = self._readonly_setter
  92.         elif setter and not getter:
  93.             getter = self._writeonly_getter
  94.         elif not setter and not getter:
  95.             getter = self._default_getter
  96.             setter = self._default_setter
  97.         self.getter = getter
  98.         self.setter = setter
  99.  
  100.         if type is None:
  101.             type = object
  102.         self.type = self._type_from_python(type)
  103.         self.default = self._get_default(default)
  104.         self._check_default()
  105.  
  106.         if not isinstance(nick, basestring):
  107.             raise TypeError("nick must be a string")
  108.         self.nick = nick
  109.  
  110.         if not isinstance(blurb, basestring):
  111.             raise TypeError("blurb must be a string")
  112.         self.blurb = blurb
  113.  
  114.         if flags < 0 or flags > 32:
  115.             raise TypeError("invalid flag value: %r" % (flags,))
  116.         self.flags = flags
  117.  
  118.         if minimum is not None:
  119.             if minimum < self._get_minimum():
  120.                 raise TypeError(
  121.                     "Minimum for type %s cannot be lower than %d" % (
  122.                     self.type, self._get_minimum()))
  123.         else:
  124.             minimum = self._get_minimum()
  125.         self.minimum = minimum
  126.         if maximum is not None:
  127.             if maximum > self._get_maximum():
  128.                 raise TypeError(
  129.                     "Maximum for type %s cannot be higher than %d" % (
  130.                     self.type, self._get_maximum()))
  131.         else:
  132.             maximum = self._get_maximum()
  133.         self.maximum = maximum
  134.  
  135.         self.name = None
  136.  
  137.         self._values = {}
  138.         self._exc = None
  139.  
  140.     def __repr__(self):
  141.         return '<gobject property %s (%s)>' % (
  142.             self.name or '(uninitialized)',
  143.             _gobject.type_name(self.type))
  144.  
  145.     def __get__(self, instance, klass):
  146.         if instance is None:
  147.             return self
  148.  
  149.         self._exc = None
  150.         value = instance.get_property(self.name)
  151.         if self._exc:
  152.             exc = self._exc
  153.             self._exc = None
  154.             raise exc
  155.  
  156.         return value
  157.  
  158.     def __set__(self, instance, value):
  159.         if instance is None:
  160.             raise TypeError
  161.  
  162.         self._exc = None
  163.         instance.set_property(self.name, value)
  164.         if self._exc:
  165.             exc = self._exc
  166.             self._exc = None
  167.             raise exc
  168.  
  169.     def _type_from_python(self, type):
  170.         if type == int:
  171.             return TYPE_INT
  172.         elif type == bool:
  173.             return TYPE_BOOLEAN
  174.         elif type == long:
  175.             return TYPE_LONG
  176.         elif type == float:
  177.             return TYPE_DOUBLE
  178.         elif type == str:
  179.             return TYPE_STRING
  180.         elif type == object:
  181.             return TYPE_PYOBJECT
  182.         elif type == _gobject.GObject:
  183.             return TYPE_OBJECT
  184.         elif type in [TYPE_NONE, TYPE_INTERFACE, TYPE_CHAR, TYPE_UCHAR,
  185.                       TYPE_INT, TYPE_UINT, TYPE_BOOLEAN, TYPE_LONG,
  186.                       TYPE_ULONG, TYPE_INT64, TYPE_UINT64, TYPE_ENUM,
  187.                       TYPE_FLAGS, TYPE_FLOAT, TYPE_DOUBLE, TYPE_POINTER,
  188.                       TYPE_BOXED, TYPE_PARAM, TYPE_OBJECT, TYPE_STRING,
  189.                       TYPE_PYOBJECT]:
  190.             return type
  191.         else:
  192.             raise TypeError("Unsupported type: %r" % (type,))
  193.  
  194.     def _get_default(self, default):
  195.         ptype = self.type
  196.         if default is not None:
  197.             return default
  198.  
  199.         if ptype in [TYPE_INT, TYPE_UINT, TYPE_LONG, TYPE_ULONG,
  200.                      TYPE_INT64, TYPE_UINT64]:
  201.             return 0
  202.         elif ptype == TYPE_STRING:
  203.             return ''
  204.         elif ptype == TYPE_FLOAT or ptype == TYPE_DOUBLE:
  205.             return 0.0
  206.         else:
  207.             return None
  208.  
  209.     def _check_default(self):
  210.         ptype = self.type
  211.         default = self.default
  212.         if (ptype == TYPE_BOOLEAN and (default not in (True, False))):
  213.             raise TypeError(
  214.                 "default must be True or False, not %r" % (default,))
  215.         elif ptype == TYPE_PYOBJECT:
  216.             if default is not None:
  217.                 raise TypeError("object types does not have default values")
  218.  
  219.     def _get_minimum(self):
  220.         ptype = self.type
  221.         if ptype in [TYPE_UINT, TYPE_ULONG, TYPE_UINT64]:
  222.             return 0
  223.         elif ptype == TYPE_FLOAT:
  224.             return G_MINFLOAT
  225.         elif ptype == TYPE_DOUBLE:
  226.             return G_MINDOUBLE
  227.         elif ptype == TYPE_INT:
  228.             return G_MININT
  229.         elif ptype == TYPE_LONG:
  230.             return G_MINLONG
  231.         elif ptype == TYPE_INT64:
  232.             return -2 ** 62 - 1
  233.  
  234.         return None
  235.  
  236.     def _get_maximum(self):
  237.         ptype = self.type
  238.         if ptype == TYPE_UINT:
  239.             return G_MAXUINT
  240.         elif ptype == TYPE_ULONG:
  241.             return G_MAXULONG
  242.         elif ptype == TYPE_INT64:
  243.             return 2 ** 62 - 1
  244.         elif ptype == TYPE_UINT64:
  245.             return 2 ** 63 - 1
  246.         elif ptype == TYPE_FLOAT:
  247.             return G_MAXFLOAT
  248.         elif ptype == TYPE_DOUBLE:
  249.             return G_MAXDOUBLE
  250.         elif ptype == TYPE_INT:
  251.             return G_MAXINT
  252.         elif ptype == TYPE_LONG:
  253.             return G_MAXLONG
  254.  
  255.         return None
  256.  
  257.     #
  258.     # Getter and Setter
  259.     #
  260.  
  261.     def _default_setter(self, instance, value):
  262.         self._values[instance] = value
  263.  
  264.     def _default_getter(self, instance):
  265.         return self._values.get(instance, self.default)
  266.  
  267.     def _readonly_setter(self, instance, value):
  268.         self._exc = TypeError("%s property of %s is read-only" % (
  269.             self.name, type(instance).__name__))
  270.  
  271.     def _writeonly_getter(self, instance):
  272.         self._exc = TypeError("%s property of %s is write-only" % (
  273.             self.name, type(instance).__name__))
  274.  
  275.     #
  276.     # Public API
  277.     #
  278.  
  279.     def get_pspec_args(self):
  280.         ptype = self.type
  281.         if ptype in [TYPE_INT, TYPE_UINT, TYPE_LONG, TYPE_ULONG,
  282.                      TYPE_INT64, TYPE_UINT64, TYPE_FLOAT, TYPE_DOUBLE]:
  283.             args = self._get_minimum(), self._get_maximum(), self.default
  284.         elif ptype == TYPE_STRING or ptype == TYPE_BOOLEAN:
  285.             args = (self.default,)
  286.         elif ptype == TYPE_PYOBJECT:
  287.             args = ()
  288.         elif ptype == TYPE_OBJECT:
  289.             args = ()
  290.         else:
  291.             raise NotImplementedError(ptype)
  292.  
  293.         return (self.type, self.nick, self.blurb) + args + (self.flags,)
  294.