|
@@ -1,9 +1,12 @@
|
|
|
|
+#!/usr/bin/env python
|
|
|
|
+# -*- coding: utf-8 -*-
|
|
|
|
+
|
|
"""
|
|
"""
|
|
A class which defines a composite object which can store
|
|
A class which defines a composite object which can store
|
|
hieararchical dictionaries with names.
|
|
hieararchical dictionaries with names.
|
|
|
|
|
|
This class is same as a hiearchical dictionary, but it
|
|
This class is same as a hiearchical dictionary, but it
|
|
-provides methods to add/access/modify children by name,
|
|
|
|
|
|
+provides methods to add/access/modify children by name,
|
|
like a Composite.
|
|
like a Composite.
|
|
|
|
|
|
Created Anand B Pillai <abpillai@gmail.com>
|
|
Created Anand B Pillai <abpillai@gmail.com>
|
|
@@ -17,7 +20,7 @@ __version__ = "0.2"
|
|
def normalize(val):
|
|
def normalize(val):
|
|
""" Normalize a string so that it can be used as an attribute
|
|
""" Normalize a string so that it can be used as an attribute
|
|
to a Python object """
|
|
to a Python object """
|
|
-
|
|
|
|
|
|
+
|
|
if val.find('-') != -1:
|
|
if val.find('-') != -1:
|
|
val = val.replace('-', '_')
|
|
val = val.replace('-', '_')
|
|
|
|
|
|
@@ -34,6 +37,7 @@ def denormalize(val):
|
|
|
|
|
|
|
|
|
|
class SpecialDict(dict):
|
|
class SpecialDict(dict):
|
|
|
|
+
|
|
""" A dictionary type which allows direct attribute
|
|
""" A dictionary type which allows direct attribute
|
|
access to its keys """
|
|
access to its keys """
|
|
|
|
|
|
@@ -65,9 +69,10 @@ class SpecialDict(dict):
|
|
else:
|
|
else:
|
|
# New attribute
|
|
# New attribute
|
|
self[name] = value
|
|
self[name] = value
|
|
-
|
|
|
|
|
|
+
|
|
|
|
|
|
class CompositeDict(SpecialDict):
|
|
class CompositeDict(SpecialDict):
|
|
|
|
+
|
|
""" A class which works like a hierarchical dictionary.
|
|
""" A class which works like a hierarchical dictionary.
|
|
This class is based on the Composite design-pattern """
|
|
This class is based on the Composite design-pattern """
|
|
|
|
|
|
@@ -106,7 +111,7 @@ class CompositeDict(SpecialDict):
|
|
attr = getattr(self[self._name], name)
|
|
attr = getattr(self[self._name], name)
|
|
if attr:
|
|
if attr:
|
|
return attr
|
|
return attr
|
|
-
|
|
|
|
|
|
+
|
|
raise AttributeError('no attribute named %s' % name)
|
|
raise AttributeError('no attribute named %s' % name)
|
|
|
|
|
|
def isRoot(self):
|
|
def isRoot(self):
|
|
@@ -114,7 +119,7 @@ class CompositeDict(SpecialDict):
|
|
|
|
|
|
# If I don't have a parent, I am root
|
|
# If I don't have a parent, I am root
|
|
return not self._father
|
|
return not self._father
|
|
-
|
|
|
|
|
|
+
|
|
def isLeaf(self):
|
|
def isLeaf(self):
|
|
""" Return whether I am a leaf component or not """
|
|
""" Return whether I am a leaf component or not """
|
|
|
|
|
|
@@ -128,7 +133,7 @@ class CompositeDict(SpecialDict):
|
|
|
|
|
|
def getIndex(self, child):
|
|
def getIndex(self, child):
|
|
""" Return the index of the child ConfigInfo object 'child' """
|
|
""" Return the index of the child ConfigInfo object 'child' """
|
|
-
|
|
|
|
|
|
+
|
|
if child in self._children:
|
|
if child in self._children:
|
|
return self._children.index(child)
|
|
return self._children.index(child)
|
|
else:
|
|
else:
|
|
@@ -136,7 +141,7 @@ class CompositeDict(SpecialDict):
|
|
|
|
|
|
def getDict(self):
|
|
def getDict(self):
|
|
""" Return the contained dictionary """
|
|
""" Return the contained dictionary """
|
|
-
|
|
|
|
|
|
+
|
|
return self[self._name]
|
|
return self[self._name]
|
|
|
|
|
|
def getProperty(self, child, key):
|
|
def getProperty(self, child, key):
|
|
@@ -156,25 +161,25 @@ class CompositeDict(SpecialDict):
|
|
childDict = self.getInfoDict(child)
|
|
childDict = self.getInfoDict(child)
|
|
if childDict:
|
|
if childDict:
|
|
childDict[key] = value
|
|
childDict[key] = value
|
|
-
|
|
|
|
|
|
+
|
|
def getChildren(self):
|
|
def getChildren(self):
|
|
""" Return the list of immediate children of this object """
|
|
""" Return the list of immediate children of this object """
|
|
-
|
|
|
|
|
|
+
|
|
return self._children
|
|
return self._children
|
|
|
|
|
|
def getAllChildren(self):
|
|
def getAllChildren(self):
|
|
""" Return the list of all children of this object """
|
|
""" Return the list of all children of this object """
|
|
-
|
|
|
|
|
|
+
|
|
l = []
|
|
l = []
|
|
for child in self._children:
|
|
for child in self._children:
|
|
l.append(child)
|
|
l.append(child)
|
|
l.extend(child.getAllChildren())
|
|
l.extend(child.getAllChildren())
|
|
-
|
|
|
|
|
|
+
|
|
return l
|
|
return l
|
|
|
|
|
|
def getChild(self, name):
|
|
def getChild(self, name):
|
|
""" Return the immediate child object with the given name """
|
|
""" Return the immediate child object with the given name """
|
|
-
|
|
|
|
|
|
+
|
|
for child in self._children:
|
|
for child in self._children:
|
|
if child.getName() == name:
|
|
if child.getName() == name:
|
|
return child
|
|
return child
|
|
@@ -185,7 +190,7 @@ class CompositeDict(SpecialDict):
|
|
# Note - this returns the first child of the given name
|
|
# Note - this returns the first child of the given name
|
|
# any other children with similar names down the tree
|
|
# any other children with similar names down the tree
|
|
# is not considered.
|
|
# is not considered.
|
|
-
|
|
|
|
|
|
+
|
|
for child in self.getAllChildren():
|
|
for child in self.getAllChildren():
|
|
if child.getName() == name:
|
|
if child.getName() == name:
|
|
return child
|
|
return child
|
|
@@ -195,33 +200,33 @@ class CompositeDict(SpecialDict):
|
|
|
|
|
|
# Note: this returns a list of all the children of a given
|
|
# Note: this returns a list of all the children of a given
|
|
# name, irrespective of the depth of look-up.
|
|
# name, irrespective of the depth of look-up.
|
|
-
|
|
|
|
|
|
+
|
|
children = []
|
|
children = []
|
|
-
|
|
|
|
|
|
+
|
|
for child in self.getAllChildren():
|
|
for child in self.getAllChildren():
|
|
if child.getName() == name:
|
|
if child.getName() == name:
|
|
children.append(child)
|
|
children.append(child)
|
|
|
|
|
|
return children
|
|
return children
|
|
-
|
|
|
|
|
|
+
|
|
def getPropertyDict(self):
|
|
def getPropertyDict(self):
|
|
""" Return the property dictionary """
|
|
""" Return the property dictionary """
|
|
-
|
|
|
|
|
|
+
|
|
d = self.getChild('__properties')
|
|
d = self.getChild('__properties')
|
|
if d:
|
|
if d:
|
|
return d.getDict()
|
|
return d.getDict()
|
|
else:
|
|
else:
|
|
return {}
|
|
return {}
|
|
-
|
|
|
|
|
|
+
|
|
def getParent(self):
|
|
def getParent(self):
|
|
""" Return the person who created me """
|
|
""" Return the person who created me """
|
|
|
|
|
|
return self._father
|
|
return self._father
|
|
-
|
|
|
|
|
|
+
|
|
def __setChildDict(self, child):
|
|
def __setChildDict(self, child):
|
|
""" Private method to set the dictionary of the child
|
|
""" Private method to set the dictionary of the child
|
|
object 'child' in the internal dictionary """
|
|
object 'child' in the internal dictionary """
|
|
-
|
|
|
|
|
|
+
|
|
d = self[self._name]
|
|
d = self[self._name]
|
|
d[child.getName()] = child.getDict()
|
|
d[child.getName()] = child.getDict()
|
|
|
|
|
|
@@ -236,25 +241,25 @@ class CompositeDict(SpecialDict):
|
|
# child is orphaned - see addChild and addChild2
|
|
# child is orphaned - see addChild and addChild2
|
|
# methods !
|
|
# methods !
|
|
self._father = father
|
|
self._father = father
|
|
-
|
|
|
|
|
|
+
|
|
def setName(self, name):
|
|
def setName(self, name):
|
|
- """ Set the name of this ConfigInfo object to 'name' """
|
|
|
|
|
|
+ """ Set the name of this ConfigInfo object to 'name' """
|
|
|
|
|
|
self._name = name
|
|
self._name = name
|
|
|
|
|
|
def setDict(self, d):
|
|
def setDict(self, d):
|
|
""" Set the contained dictionary """
|
|
""" Set the contained dictionary """
|
|
-
|
|
|
|
|
|
+
|
|
self[self._name] = d.copy()
|
|
self[self._name] = d.copy()
|
|
-
|
|
|
|
|
|
+
|
|
def setAttribute(self, name, value):
|
|
def setAttribute(self, name, value):
|
|
""" Set a name value pair in the contained dictionary """
|
|
""" Set a name value pair in the contained dictionary """
|
|
-
|
|
|
|
|
|
+
|
|
self[self._name][name] = value
|
|
self[self._name][name] = value
|
|
|
|
|
|
def getAttribute(self, name):
|
|
def getAttribute(self, name):
|
|
""" Return value of an attribute from the contained dictionary """
|
|
""" Return value of an attribute from the contained dictionary """
|
|
-
|
|
|
|
|
|
+
|
|
return self[self._name][name]
|
|
return self[self._name][name]
|
|
|
|
|
|
def addChild(self, name, force=False):
|
|
def addChild(self, name, force=False):
|
|
@@ -264,13 +269,13 @@ class CompositeDict(SpecialDict):
|
|
|
|
|
|
This function returns the child object, whether
|
|
This function returns the child object, whether
|
|
new or existing """
|
|
new or existing """
|
|
-
|
|
|
|
|
|
+
|
|
if type(name) != str:
|
|
if type(name) != str:
|
|
raise ValueError('Argument should be a string!')
|
|
raise ValueError('Argument should be a string!')
|
|
-
|
|
|
|
|
|
+
|
|
child = self.getChild(name)
|
|
child = self.getChild(name)
|
|
if child:
|
|
if child:
|
|
- # print 'Child %s present!' % name
|
|
|
|
|
|
+ # print('Child %s present!' % name)
|
|
# Replace it if force==True
|
|
# Replace it if force==True
|
|
if force:
|
|
if force:
|
|
index = self.getIndex(child)
|
|
index = self.getIndex(child)
|
|
@@ -278,22 +283,22 @@ class CompositeDict(SpecialDict):
|
|
child = self.__class__(name)
|
|
child = self.__class__(name)
|
|
self._children[index] = child
|
|
self._children[index] = child
|
|
child.setParent(self)
|
|
child.setParent(self)
|
|
-
|
|
|
|
|
|
+
|
|
self.__setChildDict(child)
|
|
self.__setChildDict(child)
|
|
return child
|
|
return child
|
|
else:
|
|
else:
|
|
child = self.__class__(name)
|
|
child = self.__class__(name)
|
|
child.setParent(self)
|
|
child.setParent(self)
|
|
-
|
|
|
|
|
|
+
|
|
self._children.append(child)
|
|
self._children.append(child)
|
|
self.__setChildDict(child)
|
|
self.__setChildDict(child)
|
|
|
|
|
|
return child
|
|
return child
|
|
-
|
|
|
|
|
|
+
|
|
def addChild2(self, child):
|
|
def addChild2(self, child):
|
|
""" Add the child object 'child'. If it is already present,
|
|
""" Add the child object 'child'. If it is already present,
|
|
it is overwritten by default """
|
|
it is overwritten by default """
|
|
-
|
|
|
|
|
|
+
|
|
currChild = self.getChild(child.getName())
|
|
currChild = self.getChild(child.getName())
|
|
if currChild:
|
|
if currChild:
|
|
index = self.getIndex(currChild)
|
|
index = self.getIndex(currChild)
|
|
@@ -303,10 +308,10 @@ class CompositeDict(SpecialDict):
|
|
# Unset the existing child's parent
|
|
# Unset the existing child's parent
|
|
currChild.setParent(None)
|
|
currChild.setParent(None)
|
|
del currChild
|
|
del currChild
|
|
-
|
|
|
|
|
|
+
|
|
self.__setChildDict(child)
|
|
self.__setChildDict(child)
|
|
else:
|
|
else:
|
|
- child.setParent(self)
|
|
|
|
|
|
+ child.setParent(self)
|
|
self._children.append(child)
|
|
self._children.append(child)
|
|
self.__setChildDict(child)
|
|
self.__setChildDict(child)
|
|
|
|
|
|
@@ -316,7 +321,7 @@ if __name__ == "__main__":
|
|
frame = window.addChild('Frame')
|
|
frame = window.addChild('Frame')
|
|
tfield = frame.addChild('Text Field')
|
|
tfield = frame.addChild('Text Field')
|
|
tfield.setAttribute('size', '20')
|
|
tfield.setAttribute('size', '20')
|
|
-
|
|
|
|
|
|
+
|
|
btn = frame.addChild('Button1')
|
|
btn = frame.addChild('Button1')
|
|
btn.setAttribute('label', 'Submit')
|
|
btn.setAttribute('label', 'Submit')
|
|
|
|
|
|
@@ -329,3 +334,7 @@ if __name__ == "__main__":
|
|
# print(window.Frame.Button2)
|
|
# print(window.Frame.Button2)
|
|
print(window.Frame.Button1.label)
|
|
print(window.Frame.Button1.label)
|
|
print(window.Frame.Button2.label)
|
|
print(window.Frame.Button2.label)
|
|
|
|
+
|
|
|
|
+### OUTPUT ###
|
|
|
|
+# Submit
|
|
|
|
+# Browse
|