Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/src/sugar/tutorius/properties.py
diff options
context:
space:
mode:
authorSimon Poirier <simpoir@gmail.com>2009-07-02 05:27:27 (GMT)
committer Simon Poirier <simpoir@gmail.com>2009-07-02 05:27:27 (GMT)
commit9fafb49af210e956d43d6a00106558d1a00d13df (patch)
tree5732d7950fab9915705685e0612ef4186111ef4a /src/sugar/tutorius/properties.py
parent651700dfb6f42c61b8791b75f78cc60f7234ec92 (diff)
* Modularized actions and event filters through add-on components
* Working serialization * Working editor with addons * began refactoring actions and events ** fixed some tests to work with addons ** filters and actions tests won't pass until refactoring is done
Diffstat (limited to 'src/sugar/tutorius/properties.py')
-rw-r--r--src/sugar/tutorius/properties.py197
1 files changed, 158 insertions, 39 deletions
diff --git a/src/sugar/tutorius/properties.py b/src/sugar/tutorius/properties.py
index a0bfa03..34b508a 100644
--- a/src/sugar/tutorius/properties.py
+++ b/src/sugar/tutorius/properties.py
@@ -13,16 +13,91 @@
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+"""
+This module contains properties class that can be included in other types.
+TutoriusProperties have the same behaviour as python properties (assuming you
+also use the TPropContainer), with the added benefit of having builtin dialog
+prompts and constraint validation.
+"""
-from sugar.tutorius.constraints import *
+from sugar.tutorius.constraints import Constraint, \
+ UpperLimitConstraint, LowerLimitConstraint, \
+ MaxSizeConstraint, MinSizeConstraint, \
+ ColorConstraint, FileConstraint, BooleanConstraint, EnumConstraint
-class TutoriusProperty():
+class TPropContainer(object):
+ """
+ A class containing properties. This does the attribute wrapping between
+ the container instance and the property value. As properties are on the
+ containing classes, they allow static introspection of those types
+ at the cost of needing a mapping between container instances, and
+ property values. This is what TPropContainer does.
+ """
+ def __init__(self):
+ """
+ Prepares the instance for property value storage. This is done at
+ object initialization, thus allowing initial mapping of properties
+ declared on the class. Properties won't work correctly without
+ this call.
+ """
+ # create property value storage
+ object.__setattr__(self, "_props", {})
+ for attr_name in dir(type(self)):
+ propinstance = object.__getattribute__(self, attr_name)
+ if isinstance(propinstance, TutoriusProperty):
+ # only care about TutoriusProperty instances
+ propinstance.tname = attr_name
+ self._props[attr_name] = propinstance.validate(
+ propinstance.default)
+
+ def __getattribute__(self, name):
+ """
+ Process the 'fake' read of properties in the appropriate instance
+ container. Pass 'real' attributes as usual.
+ """
+ try:
+ props = object.__getattribute__(self, "_props")
+ except AttributeError:
+ # necessary for deepcopy as order of init can't be guaranteed
+ object.__setattr__(self, "_props", {})
+ props = object.__getattribute__(self, "_props")
+
+ try:
+ # try gettin value from property storage
+ # if it's not in the map, it's not a property or its default wasn't
+ # set at initialization.
+ return props[name]
+ except KeyError:
+ return object.__getattribute__(self, name)
+
+ def __setattr__(self, name, value):
+ """
+ Process the 'fake' write of properties in the appropriate instance
+ container. Pass 'real' attributes as usual.
+
+ @param name the name of the property
+ @param value the value to assign to name
+ @return the setted value
+ """
+ props = object.__getattribute__(self, "_props")
+ try:
+ # We attempt to get the property object with __getattribute__
+ # to work through inheritance and benefit of the MRO.
+ return props.__setitem__(name,
+ object.__getattribute__(self, name).validate(value))
+ except AttributeError:
+ return object.__setattr__(self, name, value)
+
+ def get_properties(self):
+ """
+ Return the list of property names.
+ """
+ return object.__getattribute__(self, "_props").keys()
+
+class TutoriusProperty(object):
"""
The base class for all actions' properties. The interface is the following :
- set() : attempts to change the value (may throw an exception if constraints
- are not respected
-
value : the value of the property
type : the type of the property
@@ -31,13 +106,26 @@ class TutoriusProperty():
what is acceptable or not as values.
"""
def __init__(self):
- self._type = None
+ super(TutoriusProperty, self).__init__()
+ self.type = None
self._constraints = None
- self._value = None
+ self.default = None
- def set(self, value):
+ def get_constraints(self):
"""
- Attempts to set the value of the property. If the value does not respect
+ Returns the list of constraints associated to this property.
+ """
+ if self._constraints is None:
+ self._constraints = []
+ for i in dir(self):
+ typ = getattr(self, i)
+ if isinstance(typ, Constraint):
+ self._constraints.append(i)
+ return self._constraints
+
+ def validate(self, value):
+ """
+ Validates the value of the property. If the value does not respect
the constraints on the property, this method will raise an exception.
The exception should be of the type related to the constraint that
@@ -46,13 +134,16 @@ class TutoriusProperty():
for constraint_name in self.get_constraints():
constraint = getattr(self, constraint_name)
constraint.validate(value)
- self._value = value
- return True
-
- def get(self):
- return self._value
-
- value = property(fget=get)
+ return value
+
+class TAddonListProperty(TutoriusProperty):
+ """
+ Stores an addon component list as a property.
+ The purpose of this class is to allow correct mapping of properties
+ through encapsulated hierarchies.
+ """
+ pass
+
def get_constraints(self):
"""
@@ -61,15 +152,10 @@ class TutoriusProperty():
if self._constraints is None:
self._constraints = []
for i in dir(self):
- t = getattr(self,i)
- if isinstance(t, Constraint):
+ typ = getattr(self, i)
+ if isinstance(typ, Constraint):
self._constraints.append(i)
return self._constraints
-
- def get_type(self):
- return self._type
-
- type = property(fget=get_type)
class TIntProperty(TutoriusProperty):
"""
@@ -79,11 +165,11 @@ class TIntProperty(TutoriusProperty):
def __init__(self, value, lower_limit=None, upper_limit=None):
TutoriusProperty.__init__(self)
- self._type = "int"
+ self.type = "int"
self.upper_limit = UpperLimitConstraint(upper_limit)
self.lower_limit = LowerLimitConstraint(lower_limit)
- self.set(value)
+ self.default = self.validate(value)
class TFloatProperty(TutoriusProperty):
"""
@@ -92,12 +178,12 @@ class TFloatProperty(TutoriusProperty):
"""
def __init__(self, value, lower_limit=None, upper_limit=None):
TutoriusProperty.__init__(self)
- self._type = "float"
+ self.type = "float"
self.upper_limit = UpperLimitConstraint(upper_limit)
self.lower_limit = LowerLimitConstraint(lower_limit)
- self.set(value)
+ self.default = self.validate(value)
class TStringProperty(TutoriusProperty):
"""
@@ -105,10 +191,10 @@ class TStringProperty(TutoriusProperty):
"""
def __init__(self, value, size_limit=None):
TutoriusProperty.__init__(self)
- self._type = "string"
+ self.type = "string"
self.size_limit = MaxSizeConstraint(size_limit)
- self.set(value)
+ self.default = self.validate(value)
class TArrayProperty(TutoriusProperty):
"""
@@ -117,10 +203,10 @@ class TArrayProperty(TutoriusProperty):
"""
def __init__(self, value, min_size_limit=None, max_size_limit=None):
TutoriusProperty.__init__(self)
- self._type = "array"
+ self.type = "array"
self.max_size_limit = MaxSizeConstraint(max_size_limit)
self.min_size_limit = MinSizeConstraint(min_size_limit)
- self.set(value)
+ self.default = self.validate(value)
class TColorProperty(TutoriusProperty):
"""
@@ -130,7 +216,7 @@ class TColorProperty(TutoriusProperty):
"""
def __init__(self, red=None, green=None, blue=None):
TutoriusProperty.__init__(self)
- self._type = "color"
+ self.type = "color"
self.color_constraint = ColorConstraint()
@@ -138,7 +224,7 @@ class TColorProperty(TutoriusProperty):
self._green = green or 0
self._blue = blue or 0
- self.set([self._red, self._green, self._blue])
+ self.default = self.validate([self._red, self._green, self._blue])
class TFileProperty(TutoriusProperty):
"""
@@ -155,11 +241,11 @@ class TFileProperty(TutoriusProperty):
"""
TutoriusProperty.__init__(self)
- self._type = "file"
+ self.type = "file"
self.file_constraint = FileConstraint()
- self.set(path)
+ self.default = self.validate(path)
class TEnumProperty(TutoriusProperty):
"""
@@ -177,11 +263,11 @@ class TEnumProperty(TutoriusProperty):
"""
TutoriusProperty.__init__(self)
- self._type = "enum"
+ self.type = "enum"
self.enum_constraint = EnumConstraint(accepted_values)
- self.set(value)
+ self.default = self.validate(value)
class TBooleanProperty(TutoriusProperty):
"""
@@ -190,11 +276,11 @@ class TBooleanProperty(TutoriusProperty):
def __init__(self, value=False):
TutoriusProperty.__init__(self)
- self._type = "boolean"
+ self.type = "boolean"
self.boolean_constraint = BooleanConstraint()
- self.set(value)
+ self.default = self.validate(value)
class TUAMProperty(TutoriusProperty):
"""
@@ -202,3 +288,36 @@ class TUAMProperty(TutoriusProperty):
"""
# TODO : Pending UAM check-in (LP 355199)
pass
+
+class TAddonProperty(TutoriusProperty):
+ """
+ Reprensents an embedded tutorius Addon Component (action, trigger, etc.)
+ The purpose of this class is to flag the container for proper
+ serialization, as the contained object can't be directly dumped to text
+ for its attributes to be saved.
+ """
+ class NullAction(TPropContainer):
+ def do(self): pass
+ def undo(self): pass
+
+ def __init__(self):
+ super(TAddonProperty, self).__init__()
+ self.type = "addon"
+ self.default = self.NullAction()
+
+ def validate(self, value):
+ if isinstance(value, TPropContainer):
+ return super(TAddonProperty, self).validate(value)
+ raise ValueError("Expected TPropContainer instance as TaddonProperty value")
+
+class TAddonListProperty(TutoriusProperty):
+ """
+ Reprensents an embedded tutorius Addon List Component.
+ See TAddonProperty
+ """
+ def __init__(self):
+ super(TAddonProperty, self).__init__()
+ self.type = "addonlist"
+ self.default = []
+
+