Adding support for loading datatypes defined in plugins to allow to use them in PLC program
--- a/PLCControler.py Tue Jan 17 20:06:07 2012 +0100
+++ b/PLCControler.py Tue Jan 24 21:42:21 2012 +0100
@@ -1125,6 +1125,8 @@
tree.insert(0, ("EN", "BOOL", ([], [])))
return tree, []
datatype = project.getdataType(typename)
+ if datatype is None:
+ datatype = self.GetPluginDataType(typename)
if datatype is not None:
tree = []
basetype_content = datatype.baseType.getcontent()
@@ -1247,21 +1249,38 @@
return None
# Function that add a new plugin to the plugin list
- def AddPluginBlockList(self, blocklist):
- self.PluginTypes.extend(blocklist)
+ def AddPluginTypesList(self, typeslist):
+ self.PluginTypes.extend(typeslist)
# Function that clear the plugin list
def ClearPluginTypes(self):
for i in xrange(len(self.PluginTypes)):
self.PluginTypes.pop(0)
+ def GetPluginBlockTypes(self):
+ return [{"name": _("%s POUs") % plugintypes["name"],
+ "list": plugintypes["types"].GetCustomBlockTypes()}
+ for plugintypes in self.PluginTypes]
+
+ def GetPluginDataTypes(self, exclude = ""):
+ return [{"name": _("%s Data Types") % plugintypes["name"],
+ "list": [datatype["name"] for datatype in plugintypes["types"].GetCustomDataTypes(exclude, True)]}
+ for plugintypes in self.PluginTypes]
+
+ def GetPluginDataType(self, type):
+ for plugintype in self.PluginTypes:
+ datatype = plugintype["types"].getdataType(type)
+ if datatype is not None:
+ return datatype
+ return None
+
def GetVariableLocationTree(self):
return []
# Function that returns the block definition associated to the block type given
def GetBlockType(self, type, inputs = None, debug = False):
result_blocktype = None
- for category in BlockTypes + self.PluginTypes:
+ for category in BlockTypes + self.GetPluginBlockTypes():
for blocktype in category["list"]:
if blocktype["name"] == type:
if inputs is not None and inputs != "undefined":
@@ -1295,7 +1314,7 @@
type = self.GetPouType(name, debug)
if type == "function" or words[0] == "T":
blocktypes = []
- for category in BlockTypes + self.PluginTypes:
+ for category in BlockTypes + self.GetPluginBlockTypes():
cat = {"name" : category["name"], "list" : []}
for block in category["list"]:
if block["type"] == "function":
@@ -1303,7 +1322,7 @@
if len(cat["list"]) > 0:
blocktypes.append(cat)
else:
- blocktypes = [category for category in BlockTypes + self.PluginTypes]
+ blocktypes = [category for category in BlockTypes + self.GetPluginBlockTypes()]
project = self.GetProject(debug)
if project is not None:
blocktypes.append({"name" : USER_DEFINED_POUS, "list": project.GetCustomBlockTypes(name, type == "function" or words[0] == "T")})
@@ -1312,7 +1331,7 @@
# Return Function Block types checking for recursion
def GetFunctionBlockTypes(self, tagname = "", debug = False):
blocktypes = []
- for category in BlockTypes + self.PluginTypes:
+ for category in BlockTypes + self.GetPluginBlockTypes():
for block in category["list"]:
if block["type"] == "functionBlock":
blocktypes.append(block["name"])
@@ -1349,14 +1368,20 @@
words = tagname.split("::")
if words[0] in ["D"]:
name = words[1]
- datatypes.extend(project.GetCustomDataTypes(name, only_locatables))
+ datatypes.extend([datatype["name"] for datatype in project.GetCustomDataTypes(name, only_locatables)])
return datatypes
# Return Base Type of given possible derived type
def GetBaseType(self, type, debug = False):
project = self.GetProject(debug)
if project is not None:
- return project.GetBaseType(type)
+ result = project.GetBaseType(type)
+ if result is not None:
+ return result
+ for plugintype in self.PluginTypes:
+ result = plugintype["types"].GetBaseType(type)
+ if result is not None:
+ return result
return None
def GetBaseTypes(self):
@@ -1368,17 +1393,20 @@
return [x for x,y in TypeHierarchy_list if not x.startswith("ANY")]
def IsOfType(self, type, reference, debug = False):
- project = self.GetProject(debug)
- if project is not None:
- return project.IsOfType(type, reference)
- elif reference is None:
+ if reference is None:
return True
elif type == reference:
return True
+ elif type in TypeHierarchy:
+ return self.IsOfType(TypeHierarchy[type], reference)
else:
- if type in TypeHierarchy:
- return self.IsOfType(TypeHierarchy[type], reference)
- return None
+ project = self.GetProject(debug)
+ if project is not None and project.IsOfType(type, reference):
+ return True
+ for plugintype in self.PluginTypes:
+ if plugintype["types"].IsOfType(type, reference):
+ return True
+ return False
def IsEndType(self, type):
if type is not None:
@@ -1391,6 +1419,8 @@
project = self.GetProject(debug)
if project is not None:
datatype = project.getdataType(type)
+ if datatype is None:
+ datatype = self.GetPluginDataType(type)
if datatype is not None:
return project.IsLocatableType(datatype)
return True
@@ -1399,32 +1429,51 @@
project = self.GetProject(debug)
if project is not None:
datatype = project.getdataType(type)
+ if datatype is None:
+ datatype = self.GetPluginDataType(type)
if datatype is not None:
basetype_content = datatype.baseType.getcontent()
return basetype_content["name"] == "enum"
return False
def GetDataTypeRange(self, type, debug = False):
- project = self.GetProject(debug)
- if project is not None:
- return project.GetDataTypeRange(type)
- elif type in DataTypeRange:
+ if type in DataTypeRange:
return DataTypeRange[type]
+ else:
+ project = self.GetProject(debug)
+ if project is not None:
+ result = project.GetDataTypeRange(type)
+ if result is not None:
+ return result
+ for plugintype in self.PluginTypes:
+ result = plugintype["types"].GetDataTypeRange(type)
+ if result is not None:
+ return result
return None
# Return Subrange types
def GetSubrangeBaseTypes(self, exclude, debug = False):
- project = self.GetProject(debug)
- if project is not None:
- return project.GetSubrangeBaseTypes(exclude)
- return []
+ subrange_basetypes = []
+ project = self.GetProject(debug)
+ if project is not None:
+ subrange_basetypes.extend(project.GetSubrangeBaseTypes(exclude))
+ for plugintype in self.PluginTypes:
+ subrange_basetypes.extend(plugintype["types"].GetSubrangeBaseTypes(exclude))
+ return DataTypeRange.keys() + subrange_basetypes
# Return Enumerated Values
def GetEnumeratedDataValues(self, type = None, debug = False):
- project = self.GetProject(debug)
- if project is not None:
- return project.GetEnumeratedDataTypeValues(type)
- return []
+ values = []
+ project = self.GetProject(debug)
+ if project is not None:
+ values.extend(project.GetEnumeratedDataTypeValues(type))
+ if type is None and len(values) > 0:
+ return values
+ for plugintype in self.PluginTypes:
+ values.extend(plugintype["types"].GetEnumeratedDataTypeValues(type))
+ if type is None and len(values) > 0:
+ return values
+ return values
#-------------------------------------------------------------------------------
# Project Element tag name computation functions
--- a/controls/VariablePanel.py Tue Jan 17 20:06:07 2012 +0100
+++ b/controls/VariablePanel.py Tue Jan 24 21:42:21 2012 +0100
@@ -729,8 +729,6 @@
# build a submenu containing user-defined types
datatype_menu = wx.Menu(title='')
-
- # TODO : remove complextypes argument when matiec can manage complex types in pou interface
datatypes = self.Controler.GetDataTypes(basetypes = False)
for datatype in datatypes:
new_id = wx.NewId()
@@ -738,6 +736,18 @@
self.Bind(wx.EVT_MENU, self.GetVariableTypeFunction(datatype), id=new_id)
type_menu.AppendMenu(wx.NewId(), _("User Data Types"), datatype_menu)
+
+ for category in self.Controler.GetPluginDataTypes():
+
+ if len(category["list"]) > 0:
+ # build a submenu containing plugin types
+ plugin_datatype_menu = wx.Menu(title='')
+ for datatype in category["list"]:
+ new_id = wx.NewId()
+ AppendMenu(plugin_datatype_menu, help='', id=new_id, kind=wx.ITEM_NORMAL, text=datatype)
+ self.Bind(wx.EVT_MENU, self.GetVariableTypeFunction(datatype), id=new_id)
+
+ type_menu.AppendMenu(wx.NewId(), category["name"], plugin_datatype_menu)
# build a submenu containing function block types
bodytype = self.Controler.GetEditedElementBodyType(self.TagName)
--- a/plcopen/plcopen.py Tue Jan 17 20:06:07 2012 +0100
+++ b/plcopen/plcopen.py Tue Jan 24 21:42:21 2012 +0100
@@ -558,7 +558,7 @@
if self.IsOfType(type, base_type) and not self.IsOfType(type, exclude):
derived.append(type)
break
- return DataTypeRange.keys() + derived
+ return derived
setattr(cls, "GetSubrangeBaseTypes", GetSubrangeBaseTypes)
"""
@@ -679,7 +679,7 @@
if not only_locatable or self.IsLocatableType(customdatatype):
customdatatype_name = customdatatype.getname()
if customdatatype_name != exclude and not self.ElementIsUsedBy(exclude, customdatatype_name):
- customdatatypes.append(customdatatype_name)
+ customdatatypes.append({"name": customdatatype_name, "infos": customdatatype})
return customdatatypes
setattr(cls, "GetCustomDataTypes", GetCustomDataTypes)